@@ -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,46 @@ 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+ ecc_key * cur = (ecc_key * )key -> internal ;
3690+ void * heap = cur -> heap ;
3691+ #if defined(PLUTON_CRYPTO_ECC ) || defined(WOLF_CRYPTO_CB )
3692+ int devId = cur -> devId ;
3693+ #else
3694+ int devId = INVALID_DEVID ;
3695+ #endif
3696+ /* Decode into a new key so a rejected one leaves the internal key
3697+ * as it was. */
3698+ ecc_key * tmp = (ecc_key * )XMALLOC (sizeof (ecc_key ), heap ,
3699+ DYNAMIC_TYPE_ECC );
3700+
3701+ if (tmp == NULL ) {
3702+ ret = MEMORY_E ;
3703+ }
3704+ else {
3705+ ret = wc_ecc_init_ex (tmp , heap , devId );
3706+ if (ret == 0 ) {
3707+ #ifdef ECC_TIMING_RESISTANT
3708+ /* Caller-owned. devCtx is not carried over: freeing the
3709+ * old key tells the device to release it. */
3710+ tmp -> rng = cur -> rng ;
3711+ #endif
3712+ ret = wc_EccPrivateKeyDecode (derBuf , & idx , tmp ,
3713+ (word32 )derSz );
3714+ /* RFC 5915 makes publicKey optional. */
3715+ if (ret == 0 ) {
3716+ ret = wc_ecc_derive_pub_if_needed (tmp , NULL );
3717+ }
3718+ if (ret == 0 ) {
3719+ /* Take ownership of new key - set tmp to the old
3720+ * key which will then be freed below. */
3721+ ecc_key * old = (ecc_key * )key -> internal ;
3722+ key -> internal = tmp ;
3723+ tmp = old ;
3724+ }
3725+ wc_ecc_free (tmp );
3726+ }
3727+ XFREE (tmp , heap , DYNAMIC_TYPE_ECC );
3728+ }
37013729 }
37023730 else {
37033731 ret = wc_EccPublicKeyDecode (derBuf , & idx , (ecc_key * )key -> internal ,
@@ -4419,7 +4447,8 @@ int SetECKeyExternal(WOLFSSL_EC_KEY* eckey)
44194447 }
44204448
44214449 /* set the external privkey */
4422- if ((ret == 1 ) && (key -> type == ECC_PRIVATEKEY ) &&
4450+ if ((ret == 1 ) && ((key -> type == ECC_PRIVATEKEY ) ||
4451+ (key -> type == ECC_PRIVATEKEY_ONLY )) &&
44234452 (wolfssl_bn_set_value (& eckey -> priv_key ,
44244453 wc_ecc_key_get_priv (key )) != 1 )) {
44254454 WOLFSSL_MSG ("ec priv key error" );
0 commit comments