Skip to content

Commit 4c23d4d

Browse files
committed
evp: fix EVP_PKEY2PKCS8 returning NULL for private-key-only EC keys
When an EC_KEY is created via EC_KEY_new + EC_KEY_set_group + EC_KEY_set_private_key (no public point set), SetECKeyInternal incorrectly marks the internal ecc_key as ECC_PRIVATEKEY (instead of ECC_PRIVATEKEY_ONLY) because pub_key is always non-NULL — EC_KEY_new always allocates it as an empty, zero-initialised EC_POINT. ECC_populate_EVP_PKEY only calls wc_ecc_make_pub for ECC_PRIVATEKEY_ONLY keys, so the zero public-key point was serialised into the DER stored in pkey->pkey.ptr. After commit 929dd99 made wc_ecc_import_x963_ex always pass untrusted=1, the re-decode inside wolfSSL_EVP_PKEY2PKCS8 → wolfSSL_d2i_PrivateKey_EVP correctly rejected that zero point with an on-curve failure, causing EVP_PKEY2PKCS8 to return NULL. Fix: in ECC_populate_EVP_PKEY, also call wc_ecc_make_pub when the key type is ECC_PRIVATEKEY but pubkey.x is zero (meaning the public key was never actually populated). This reconstructs the public key from the private scalar so that the encoded DER contains a valid on-curve point.
1 parent 2a0b3bd commit 4c23d4d

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

wolfcrypt/src/evp.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3715,6 +3715,10 @@ int wolfSSL_EVP_PKEY_keygen_init(WOLFSSL_EVP_PKEY_CTX *ctx)
37153715
return WOLFSSL_SUCCESS;
37163716
}
37173717

3718+
#ifdef HAVE_ECC
3719+
static int ECC_populate_EVP_PKEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY *key);
3720+
#endif
3721+
37183722
int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
37193723
WOLFSSL_EVP_PKEY **ppkey)
37203724
{
@@ -3769,6 +3773,8 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx,
37693773
ret = wolfSSL_EC_KEY_generate_key(pkey->ecc);
37703774
if (ret == WOLFSSL_SUCCESS) {
37713775
pkey->ownEcc = 1;
3776+
if (ECC_populate_EVP_PKEY(pkey, pkey->ecc) != WOLFSSL_SUCCESS)
3777+
ret = WOLFSSL_FAILURE;
37723778
}
37733779
}
37743780
break;
@@ -9521,7 +9527,15 @@ static int ECC_populate_EVP_PKEY(WOLFSSL_EVP_PKEY* pkey, WOLFSSL_EC_KEY *key)
95219527
else
95229528
#endif /* HAVE_PKCS8 */
95239529
{
9524-
if (ecc->type == ECC_PRIVATEKEY_ONLY) {
9530+
if (ecc->type == ECC_PRIVATEKEY_ONLY ||
9531+
(ecc->type == ECC_PRIVATEKEY &&
9532+
mp_iszero(ecc->pubkey.x))) {
9533+
/* Reconstruct public key from private scalar. This covers
9534+
* both ECC_PRIVATEKEY_ONLY keys and ECC_PRIVATEKEY keys whose
9535+
* public-key point was never populated (e.g. when only
9536+
* EC_KEY_set_private_key was called, SetECKeyInternal copies
9537+
* the zero-initialized pub_key point and marks the type as
9538+
* ECC_PRIVATEKEY, leaving pubkey.x == 0). */
95259539
if (wc_ecc_make_pub(ecc, NULL) != MP_OKAY) {
95269540
return WOLFSSL_FAILURE;
95279541
}

0 commit comments

Comments
 (0)