[openssl] master update

tomas at openssl.org tomas at openssl.org
Fri Sep 3 10:32:55 UTC 2021


The branch master has been updated
       via  d7b5f06ede163851d39f5a8b507bd0670deeaa21 (commit)
       via  21a0d9f3edda78d27d12cd7704de9e32976393ba (commit)
       via  85407b77543a2d4330dbb40f6b8520ea0894a716 (commit)
      from  6f2f59944826b5b7e033af438f5831493d0362c9 (commit)


- Log -----------------------------------------------------------------
commit d7b5f06ede163851d39f5a8b507bd0670deeaa21
Author: slontis <shane.lontis at oracle.com>
Date:   Thu Sep 2 16:50:45 2021 +1000

    Add KEM dupctx test
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16495)

commit 21a0d9f3edda78d27d12cd7704de9e32976393ba
Author: slontis <shane.lontis at oracle.com>
Date:   Thu Sep 2 16:49:37 2021 +1000

    Fix dh dupctx refcount error
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16495)

commit 85407b77543a2d4330dbb40f6b8520ea0894a716
Author: slontis <shane.lontis at oracle.com>
Date:   Thu Sep 2 16:39:21 2021 +1000

    Fix double free in EVP_PKEY_CTX_dup()
    
    If the internal operations dupctx() fails then a free is done (e.g. EVP_KEYEXCH_free()). If this is not set to NULL the EVP_PKEY_CTX_free() will do a double free.
    This was found by testing kdf_dupctx() in kdf_exch.c (Note this always
    fails since the internal KDF's do not have a dup method).
    
    Reviewed-by: Paul Dale <pauli at openssl.org>
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/16495)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/pmeth_lib.c                       |  4 +++
 providers/implementations/exchange/dh_exch.c |  5 ++-
 test/evp_libctx_test.c                       |  8 +++--
 test/evp_pkey_provided_test.c                | 48 ++++++++++++++++++++++++++++
 test/evp_test.c                              | 11 +++++--
 5 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 954166caae..1af1628823 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -500,6 +500,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
                 = pctx->op.kex.exchange->dupctx(pctx->op.kex.algctx);
             if (rctx->op.kex.algctx == NULL) {
                 EVP_KEYEXCH_free(rctx->op.kex.exchange);
+                rctx->op.kex.exchange = NULL;
                 goto err;
             }
             return rctx;
@@ -517,6 +518,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
                 = pctx->op.sig.signature->dupctx(pctx->op.sig.algctx);
             if (rctx->op.sig.algctx == NULL) {
                 EVP_SIGNATURE_free(rctx->op.sig.signature);
+                rctx->op.sig.signature = NULL;
                 goto err;
             }
             return rctx;
@@ -534,6 +536,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
                 = pctx->op.ciph.cipher->dupctx(pctx->op.ciph.algctx);
             if (rctx->op.ciph.algctx == NULL) {
                 EVP_ASYM_CIPHER_free(rctx->op.ciph.cipher);
+                rctx->op.ciph.cipher = NULL;
                 goto err;
             }
             return rctx;
@@ -551,6 +554,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
                 = pctx->op.encap.kem->dupctx(pctx->op.encap.algctx);
             if (rctx->op.encap.algctx == NULL) {
                 EVP_KEM_free(rctx->op.encap.kem);
+                rctx->op.encap.kem = NULL;
                 goto err;
             }
             return rctx;
diff --git a/providers/implementations/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
index 1dffc8d112..ea05b3177e 100644
--- a/providers/implementations/exchange/dh_exch.c
+++ b/providers/implementations/exchange/dh_exch.c
@@ -238,7 +238,6 @@ static int dh_derive(void *vpdhctx, unsigned char *secret,
     return 0;
 }
 
-
 static void dh_freectx(void *vpdhctx)
 {
     PROV_DH_CTX *pdhctx = (PROV_DH_CTX *)vpdhctx;
@@ -271,12 +270,12 @@ static void *dh_dupctx(void *vpdhctx)
     dstctx->kdf_ukm = NULL;
     dstctx->kdf_cekalg = NULL;
 
-    if (dstctx->dh != NULL && !DH_up_ref(srcctx->dh))
+    if (srcctx->dh != NULL && !DH_up_ref(srcctx->dh))
         goto err;
     else
         dstctx->dh = srcctx->dh;
 
-    if (dstctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer))
+    if (srcctx->dhpeer != NULL && !DH_up_ref(srcctx->dhpeer))
         goto err;
     else
         dstctx->dhpeer = srcctx->dhpeer;
diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c
index bfbbafdbab..e3eac8a068 100644
--- a/test/evp_libctx_test.c
+++ b/test/evp_libctx_test.c
@@ -525,7 +525,7 @@ static int kem_rsa_gen_recover(void)
     int ret = 0;
     EVP_PKEY *pub = NULL;
     EVP_PKEY *priv = NULL;
-    EVP_PKEY_CTX *sctx = NULL, *rctx = NULL;
+    EVP_PKEY_CTX *sctx = NULL, *rctx = NULL, *dctx = NULL;
     unsigned char secret[256] = { 0, };
     unsigned char ct[256] = { 0, };
     unsigned char unwrap[256] = { 0, };
@@ -536,11 +536,12 @@ static int kem_rsa_gen_recover(void)
           && TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pub, NULL))
           && TEST_int_eq(EVP_PKEY_encapsulate_init(sctx, NULL), 1)
           && TEST_int_eq(EVP_PKEY_CTX_set_kem_op(sctx, "RSASVE"), 1)
-          && TEST_int_eq(EVP_PKEY_encapsulate(sctx, NULL, &ctlen, NULL,
+          && TEST_ptr(dctx = EVP_PKEY_CTX_dup(sctx))
+          && TEST_int_eq(EVP_PKEY_encapsulate(dctx, NULL, &ctlen, NULL,
                                               &secretlen), 1)
           && TEST_int_eq(ctlen, secretlen)
           && TEST_int_eq(ctlen, bits / 8)
-          && TEST_int_eq(EVP_PKEY_encapsulate(sctx, ct, &ctlen, secret,
+          && TEST_int_eq(EVP_PKEY_encapsulate(dctx, ct, &ctlen, secret,
                                               &secretlen), 1)
           && TEST_ptr(rctx = EVP_PKEY_CTX_new_from_pkey(libctx, priv, NULL))
           && TEST_int_eq(EVP_PKEY_decapsulate_init(rctx, NULL), 1)
@@ -553,6 +554,7 @@ static int kem_rsa_gen_recover(void)
     EVP_PKEY_free(pub);
     EVP_PKEY_free(priv);
     EVP_PKEY_CTX_free(rctx);
+    EVP_PKEY_CTX_free(dctx);
     EVP_PKEY_CTX_free(sctx);
     return ret;
 }
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index 593f7090eb..15c8ce77bb 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -14,6 +14,7 @@
 #include <openssl/provider.h>
 #include <openssl/param_build.h>
 #include <openssl/core_names.h>
+#include <openssl/sha.h>
 #include "crypto/ecx.h"
 #include "crypto/evp.h"          /* For the internal API */
 #include "crypto/bn_dh.h"        /* _bignum_ffdhe2048_p */
@@ -1622,6 +1623,52 @@ static int test_check_dsa(void)
 #endif /* OPENSSL_NO_DSA */
 
 
+static OSSL_PARAM *do_construct_hkdf_params(char *digest, char *key,
+                                            size_t keylen, char *salt)
+{
+    OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 5);
+    OSSL_PARAM *p = params;
+
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, digest, 0);
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
+                                             salt, strlen(salt));
+    *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
+                                             (unsigned char *)key, keylen);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
+                                            "EXTRACT_ONLY", 0);
+    *p = OSSL_PARAM_construct_end();
+
+    return params;
+}
+
+/* Test that EVP_PKEY_CTX_dup() fails gracefully for a KDF */
+static int test_evp_pkey_ctx_dup_kdf_fail(void)
+{
+    int ret = 0;
+    size_t len = 0;
+    EVP_PKEY_CTX *pctx = NULL, *dctx = NULL;
+    OSSL_PARAM *params = NULL;
+
+    if (!TEST_ptr(params = do_construct_hkdf_params("sha256", "secret", 6,
+                                                    "salt")))
+        goto err;
+    if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "HKDF", NULL)))
+        goto err;
+    if (!TEST_int_eq(EVP_PKEY_derive_init_ex(pctx, params), 1))
+        goto err;
+    if (!TEST_int_eq(EVP_PKEY_derive(pctx, NULL, &len), 1)
+        || !TEST_size_t_eq(len, SHA256_DIGEST_LENGTH))
+        goto err;
+    if (!TEST_ptr_null(dctx = EVP_PKEY_CTX_dup(pctx)))
+        goto err;
+    ret = 1;
+err:
+    OPENSSL_free(params);
+    EVP_PKEY_CTX_free(dctx);
+    EVP_PKEY_CTX_free(pctx);
+    return ret;
+}
+
 int setup_tests(void)
 {
     if (!test_skip_common_options()) {
@@ -1632,6 +1679,7 @@ int setup_tests(void)
     if (!TEST_ptr(datadir = test_get_argument(0)))
         return 0;
 
+    ADD_TEST(test_evp_pkey_ctx_dup_kdf_fail);
     ADD_TEST(test_evp_pkey_get_bn_param_large);
     ADD_TEST(test_fromdata_rsa);
 #ifndef OPENSSL_NO_DH
diff --git a/test/evp_test.c b/test/evp_test.c
index 075abc5ad9..eda8c827f9 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -1848,11 +1848,17 @@ static int pderive_test_parse(EVP_TEST *t,
 
 static int pderive_test_run(EVP_TEST *t)
 {
+    EVP_PKEY_CTX *dctx = NULL;
     PKEY_DATA *expected = t->data;
     unsigned char *got = NULL;
     size_t got_len;
 
-    if (EVP_PKEY_derive(expected->ctx, NULL, &got_len) <= 0) {
+    if (!TEST_ptr(dctx = EVP_PKEY_CTX_dup(expected->ctx))) {
+        t->err = "DERIVE_ERROR";
+        goto err;
+    }
+
+    if (EVP_PKEY_derive(dctx, NULL, &got_len) <= 0) {
         t->err = "DERIVE_ERROR";
         goto err;
     }
@@ -1860,7 +1866,7 @@ static int pderive_test_run(EVP_TEST *t)
         t->err = "DERIVE_ERROR";
         goto err;
     }
-    if (EVP_PKEY_derive(expected->ctx, got, &got_len) <= 0) {
+    if (EVP_PKEY_derive(dctx, got, &got_len) <= 0) {
         t->err = "DERIVE_ERROR";
         goto err;
     }
@@ -1872,6 +1878,7 @@ static int pderive_test_run(EVP_TEST *t)
     t->err = NULL;
  err:
     OPENSSL_free(got);
+    EVP_PKEY_CTX_free(dctx);
     return 1;
 }
 


More information about the openssl-commits mailing list