diff --git a/tests/api.c b/tests/api.c index 739efb1dc..747452b5c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -43529,7 +43529,8 @@ static void test_wolfSSL_EVP_PKEY_keygen(void) { WOLFSSL_EVP_PKEY* pkey = NULL; EVP_PKEY_CTX* ctx = NULL; -#ifndef NO_DH +#if !defined(NO_DH) && (!defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ + (HAVE_FIPS_VERSION>2))) WOLFSSL_EVP_PKEY* params = NULL; DH* dh = NULL; const BIGNUM* pubkey = NULL; @@ -43623,6 +43624,60 @@ static void test_wolfSSL_EVP_PKEY_missing_parameters(void) printf(resultFmt, passed); #endif } +static void test_wolfSSL_EVP_PKEY_copy_parameters(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_DH) && defined(WOLFSSL_KEY_GEN) && \ + !defined(HAVE_SELFTEST) && (defined(OPENSSL_ALL) || defined(WOLFSSL_QT) || \ + defined(WOLFSSL_OPENSSH)) && defined(WOLFSSL_DH_EXTRA) && \ + !defined(NO_FILESYSTEM) + + WOLFSSL_EVP_PKEY* params = NULL; + WOLFSSL_EVP_PKEY* copy = NULL; + DH* dh = NULL; + BIGNUM* p1; + BIGNUM* g1; + BIGNUM* q1; + BIGNUM* p2; + BIGNUM* g2; + BIGNUM* q2; + + printf(testingFmt, "wolfSSL_EVP_PKEY_copy_parameters"); + + /* create DH with DH_get_2048_256 params */ + AssertNotNull(params = wolfSSL_EVP_PKEY_new()); + AssertNotNull(dh = DH_get_2048_256()); + AssertIntEQ(EVP_PKEY_set1_DH(params, dh), WOLFSSL_SUCCESS); + DH_get0_pqg(dh, (const BIGNUM**)&p1, + (const BIGNUM**)&q1, + (const BIGNUM**)&g1); + DH_free(dh); + + /* create DH with random generated DH params */ + AssertNotNull(copy = wolfSSL_EVP_PKEY_new()); + AssertNotNull(dh = DH_generate_parameters(2048, 2, NULL, NULL)); + AssertIntEQ(EVP_PKEY_set1_DH(copy, dh), WOLFSSL_SUCCESS); + DH_free(dh); + + AssertIntEQ(EVP_PKEY_copy_parameters(copy, params), WOLFSSL_SUCCESS); + AssertNotNull(dh = EVP_PKEY_get1_DH(copy)); + AssertNotNull(dh->p); + AssertNotNull(dh->g); + AssertNotNull(dh->q); + DH_get0_pqg(dh, (const BIGNUM**)&p2, + (const BIGNUM**)&q2, + (const BIGNUM**)&g2); + + AssertIntEQ(BN_cmp(p1, p2), 0); + AssertIntEQ(BN_cmp(q1, q2), 0); + AssertIntEQ(BN_cmp(g1, g2), 0); + + DH_free(dh); + EVP_PKEY_free(copy); + EVP_PKEY_free(params); + + printf(resultFmt, passed); +#endif +} static void test_wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(void) { WOLFSSL_EVP_PKEY* pkey; @@ -52852,6 +52907,7 @@ void ApiTest(void) test_wolfSSL_EVP_PKEY_keygen(); test_wolfSSL_EVP_PKEY_keygen_init(); test_wolfSSL_EVP_PKEY_missing_parameters(); + test_wolfSSL_EVP_PKEY_copy_parameters(); test_wolfSSL_EVP_PKEY_CTX_set_rsa_keygen_bits(); test_wolfSSL_EVP_CIPHER_CTX_iv_length(); test_wolfSSL_EVP_CIPHER_CTX_key_length(); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index fdec88027..18f11a93e 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -2248,19 +2248,54 @@ int wolfSSL_EVP_PKEY_copy_parameters(WOLFSSL_EVP_PKEY *to, } break; #endif -#ifndef NO_RSA - case EVP_PKEY_RSA: -#endif #ifndef NO_DH case EVP_PKEY_DH: + if (from->dh) { + WOLFSSL_BIGNUM* cpy; + if (!to->dh && !(to->dh = wolfSSL_DH_new())) { + WOLFSSL_MSG("wolfSSL_DH_new error"); + return WOLFSSL_FAILURE; + } + + /* free existing BIGNUMs if needed before copying over new */ + wolfSSL_BN_free(to->dh->p); + wolfSSL_BN_free(to->dh->g); + wolfSSL_BN_free(to->dh->q); + to->dh->p = NULL; + to->dh->g = NULL; + to->dh->q = NULL; + + if (!(cpy = wolfSSL_BN_dup(from->dh->p))) { + WOLFSSL_MSG("wolfSSL_BN_dup error, DH p"); + return WOLFSSL_FAILURE; + } + to->dh->p = cpy; + if (!(cpy = wolfSSL_BN_dup(from->dh->g))) { + WOLFSSL_MSG("wolfSSL_BN_dup error, DH g"); + return WOLFSSL_FAILURE; + } + to->dh->g = cpy; + if (!(cpy = wolfSSL_BN_dup(from->dh->q))) { + WOLFSSL_MSG("wolfSSL_BN_dup error, DH q"); + return WOLFSSL_FAILURE; + } + to->dh->q = cpy; + } + else { + WOLFSSL_MSG("Missing DH struct"); + return WOLFSSL_FAILURE; + } + break; +#endif +#ifndef NO_RSA + case EVP_PKEY_RSA: #endif default: WOLFSSL_MSG("Copy parameters not available for this key type"); return WOLFSSL_FAILURE; } -#if defined(HAVE_ECC) || !defined(NO_DSA) + return WOLFSSL_SUCCESS; -#endif } #ifndef NO_WOLFSSL_STUB