@@ -3499,22 +3499,12 @@ WOLFSSL_EC_KEY* wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY** key,
34993499 /* Internal EC key setup. */
35003500 ret -> inSet = 1 ;
35013501
3502- /* When the RFC 5915 DER encoding omits the optional publicKey field,
3503- * wc_EccPrivateKeyDecode leaves type == ECC_PRIVATEKEY_ONLY with the
3504- * public point uninitialised. Derive the public point now so that
3505- * all downstream operations (sign, ECDH, export) have a valid key,
3506- * matching the behaviour of OpenSSL's d2i_ECPrivateKey.
3507- * In builds without HAVE_ECC_MAKE_PUB (e.g. hardware/CB-only),
3508- * keep the historical import behaviour and leave the key as
3509- * private-only instead of failing import. */
3510- #ifdef HAVE_ECC_MAKE_PUB
3511- if (((ecc_key * )ret -> internal )-> type == ECC_PRIVATEKEY_ONLY ) {
3512- if (wc_ecc_make_pub ((ecc_key * )ret -> internal , NULL ) != 0 ) {
3513- WOLFSSL_MSG ("wc_ecc_make_pub error deriving public key" );
3514- err = 1 ;
3515- }
3502+ /* RFC 5915 makes publicKey optional: derive the point, as OpenSSL
3503+ * does, so sign, ECDH and export have a full key. */
3504+ if (wc_ecc_derive_pub_if_needed ((ecc_key * )ret -> internal , NULL ) != 0 ) {
3505+ WOLFSSL_MSG ("error deriving public key" );
3506+ err = 1 ;
35163507 }
3517- #endif
35183508 }
35193509
35203510 if (!err ) {
@@ -3696,8 +3686,40 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf,
36963686 if (res == 1 ) {
36973687 /* Load into internal EC key based on key type option. */
36983688 if (opt == WOLFSSL_EC_KEY_LOAD_PRIVATE ) {
3699- ret = wc_EccPrivateKeyDecode (derBuf , & idx , (ecc_key * )key -> internal ,
3700- (word32 )derSz );
3689+ void * heap = ((ecc_key * )key -> internal )-> heap ;
3690+ #if defined(PLUTON_CRYPTO_ECC ) || defined(WOLF_CRYPTO_CB )
3691+ int devId = ((ecc_key * )key -> internal )-> devId ;
3692+ #else
3693+ int devId = INVALID_DEVID ;
3694+ #endif
3695+ /* Decode into a new key so a rejected one leaves the internal key
3696+ * as it was. */
3697+ ecc_key * tmp = (ecc_key * )XMALLOC (sizeof (ecc_key ), heap ,
3698+ DYNAMIC_TYPE_ECC );
3699+
3700+ if (tmp == NULL ) {
3701+ ret = MEMORY_E ;
3702+ }
3703+ else {
3704+ ret = wc_ecc_init_ex (tmp , heap , devId );
3705+ if (ret == 0 ) {
3706+ ret = wc_EccPrivateKeyDecode (derBuf , & idx , tmp ,
3707+ (word32 )derSz );
3708+ /* RFC 5915 makes publicKey optional. */
3709+ if (ret == 0 ) {
3710+ ret = wc_ecc_derive_pub_if_needed (tmp , NULL );
3711+ }
3712+ if (ret == 0 ) {
3713+ /* Take ownership of new key - set tmp to the old
3714+ * key which will then be freed below. */
3715+ ecc_key * old = (ecc_key * )key -> internal ;
3716+ key -> internal = tmp ;
3717+ tmp = old ;
3718+ }
3719+ wc_ecc_free (tmp );
3720+ }
3721+ XFREE (tmp , heap , DYNAMIC_TYPE_ECC );
3722+ }
37013723 }
37023724 else {
37033725 ret = wc_EccPublicKeyDecode (derBuf , & idx , (ecc_key * )key -> internal ,
@@ -4419,7 +4441,8 @@ int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
44194441 }
44204442
44214443 /* set the external privkey */
4422- if ((ret == 1 ) && (key -> type == ECC_PRIVATEKEY ) &&
4444+ if ((ret == 1 ) && ((key -> type == ECC_PRIVATEKEY ) ||
4445+ (key -> type == ECC_PRIVATEKEY_ONLY )) &&
44234446 (wolfssl_bn_set_value (& eckey -> priv_key ,
44244447 wc_ecc_key_get_priv (key )) != 1 )) {
44254448 WOLFSSL_MSG ("ec priv key error" );
0 commit comments