diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index c6d0428dc7..44ad84f96a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -8336,6 +8336,8 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, wc_RsaEncryptSize(tmpKey), NULL, 0, 0); } + /* wc_FreeRsaKey calls mp_forcezero on all private key components, + * so no separate ForceZero of the struct is needed here. */ wc_FreeRsaKey(tmpKey); WC_FREE_VAR(tmpKey, key->heap); @@ -36543,63 +36545,20 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data, /* Functions that parse, but are not using ASN.1 */ #if !defined(NO_RSA) && (!defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH)) -/* import RSA public key elements (n, e) into RsaKey structure (key) */ -/* this function does not use any ASN.1 parsing */ -int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, - word32 eSz, RsaKey* key) +/* Software-only import of RSA public key elements (n, e) into RsaKey. + * This internal helper avoids recursion when called from the SETKEY path. */ +static int _RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, + word32 eSz, RsaKey* key) { -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); - int tmpErr = 0; - WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL); -#endif - - if (n == NULL || e == NULL || key == NULL) + if (n == NULL || e == NULL || key == NULL) { return BAD_FUNC_ARG; - -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - #ifndef WOLF_CRYPTO_CB_FIND - if (key->devId != INVALID_DEVID) - #endif - { - /* Allocate temp key for callback to export from */ - WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap); - if (!WC_VAR_OK(tmpKey)) { - return MEMORY_E; - } - XMEMSET(tmpKey, 0, sizeof(RsaKey)); - - tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID); - if (tmpErr != 0) { - WC_FREE_VAR(tmpKey, key->heap); - return tmpErr; - } - - /* Recursive call imports n, e into temp via software */ - tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey); - if (tmpErr == 0) { - cbRet = wc_CryptoCb_SetKey(key->devId, - WC_SETKEY_RSA_PUB, key, tmpKey, - wc_RsaEncryptSize(tmpKey), NULL, 0, 0); - } - - wc_FreeRsaKey(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - - if (tmpErr != 0) { - return tmpErr; - } - if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - return cbRet; - } - /* CRYPTOCB_UNAVAILABLE: fall through to software import */ } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ key->type = RSA_PUBLIC; - if (mp_init(&key->n) != MP_OKAY) + if (mp_init(&key->n) != MP_OKAY) { return MP_INIT_E; + } if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) { mp_clear(&key->n); @@ -36638,6 +36597,63 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, return 0; } + +/* import RSA public key elements (n, e) into RsaKey structure (key) */ +/* this function does not use any ASN.1 parsing */ +int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, + word32 eSz, RsaKey* key) +{ +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + int tmpErr = 0; + WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL); +#endif + + if (n == NULL || e == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + /* Allocate temp key for callback to export from */ + WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(RsaKey)); + + tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID); + if (tmpErr != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return tmpErr; + } + + /* Import into temp via software helper (no callback recursion) */ + tmpErr = _RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey); + if (tmpErr == 0) { + cbRet = wc_CryptoCb_SetKey(key->devId, + WC_SETKEY_RSA_PUB, key, tmpKey, + wc_RsaEncryptSize(tmpKey), NULL, 0, 0); + } + + wc_FreeRsaKey(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (tmpErr != 0) { + return tmpErr; + } + if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return cbRet; + } + /* CRYPTOCB_UNAVAILABLE: fall through to software import */ + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ + + return _RsaPublicKeyDecodeRaw(n, nSz, e, eSz, key); +} #endif /* !NO_RSA && (!NO_BIG_INT || WOLFSSL_SP_MATH) */ #if defined(WOLFSSL_ACERT) && defined(WOLFSSL_ASN_TEMPLATE) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index c41037f739..8fafb25650 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -9855,17 +9855,14 @@ done: } #endif /* HAVE_COMP_KEY */ -/* export public ECC key in ANSI X9.63 format */ -WOLFSSL_ABI -int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) +/* Software-only export of public ECC key in ANSI X9.63 format. + * This internal helper avoids recursion when called from the EXPORT_KEY path. */ +static int _ecc_export_x963(ecc_key* key, byte* out, word32* outLen) { int ret = MP_OKAY; word32 numlen; WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, 0); word32 pubxlen, pubylen; -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) - WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); -#endif /* return length needed only */ if (key != NULL && out == NULL && outLen != NULL) { @@ -9875,46 +9872,13 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) return WC_NO_ERR_TRACE(LENGTH_ONLY_E); } - if (key == NULL || out == NULL || outLen == NULL) + if (key == NULL || out == NULL || outLen == NULL) { return ECC_BAD_ARG_E; + } - if (key->type == ECC_PRIVATEKEY_ONLY) + if (key->type == ECC_PRIVATEKEY_ONLY) { return ECC_PRIVATEONLY_E; - -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) - #ifndef WOLF_CRYPTO_CB_FIND - if (key->devId != INVALID_DEVID) - #endif - { - WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); - if (!WC_VAR_OK(tmpKey)) { - return MEMORY_E; - } - XMEMSET(tmpKey, 0, sizeof(ecc_key)); - - ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); - if (ret != 0) { - WC_FREE_VAR(tmpKey, key->heap); - return ret; - } - - ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, - (void*)key, tmpKey); - if (ret == 0) { - /* Recursive call on software tmpKey (INVALID_DEVID) */ - ret = wc_ecc_export_x963(tmpKey, out, outLen); - } - - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - - if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - return ret; - } - /* CRYPTOCB_UNAVAILABLE: fall through to software export */ - ret = MP_OKAY; - } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ + } #if defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM) /* check if public key in secure memory */ @@ -9981,14 +9945,75 @@ done: } +/* export public ECC key in ANSI X9.63 format */ +WOLFSSL_ABI +int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen) +{ +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + int ret; + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif + + if (key == NULL || outLen == NULL) { + return ECC_BAD_ARG_E; + } + + /* return length needed only */ + if (out == NULL) { + word32 numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES; + *outLen = 1 + 2 * numlen; + return WC_NO_ERR_TRACE(LENGTH_ONLY_E); + } + + if (key->type == ECC_PRIVATEKEY_ONLY) { + return ECC_PRIVATEONLY_E; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + ret = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (ret != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return ret; + } + + ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, + (void*)key, tmpKey); + if (ret == 0) { + /* Call software helper (no callback recursion) */ + ret = _ecc_export_x963(tmpKey, out, outLen); + } + + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return ret; + } + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ + + return _ecc_export_x963(key, out, outLen); +} + /* export public ECC key in ANSI X9.63 format, extended with * compression option */ WOLFSSL_ABI int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, int compressed) { - if (compressed == 0) + if (compressed == 0) { return wc_ecc_export_x963(key, out, outLen); + } #ifdef HAVE_COMP_KEY else return wc_ecc_export_x963_compressed(key, out, outLen); @@ -10708,9 +10733,10 @@ int wc_ecc_check_key(ecc_key* key) #ifdef HAVE_ECC_KEY_IMPORT -/* import public ECC key in ANSI X9.63 format */ -int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, - int curve_id, int untrusted) +/* Software-only import of public ECC key in ANSI X9.63 format. + * This internal helper avoids recursion when called from the SETKEY path. */ +static int _ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, + int curve_id, int untrusted) { int err = MP_OKAY; #ifdef HAVE_COMP_KEY @@ -10722,71 +10748,16 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_BUILD_TempData_t tempBuff; #endif -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); - WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); -#endif - if (in == NULL || key == NULL) + if (in == NULL || key == NULL) { return BAD_FUNC_ARG; + } /* must be odd */ if ((inLen & 1) == 0) { return ECC_BAD_ARG_E; } -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - #ifndef WOLF_CRYPTO_CB_FIND - if (key->devId != INVALID_DEVID) - #endif - { - /* Allocate temp key for callback to export from */ - WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); - if (!WC_VAR_OK(tmpKey)) { - return MEMORY_E; - } - XMEMSET(tmpKey, 0, sizeof(ecc_key)); - - err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); - if (err != 0) { - WC_FREE_VAR(tmpKey, key->heap); - return err; - } - - #ifdef WOLFSSL_CUSTOM_CURVES - /* Copy custom curve params so recursive import uses correct curve */ - if (key->dp != NULL) { - err = wc_ecc_set_custom_curve(tmpKey, key->dp); - if (err != 0) { - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - return err; - } - } - #endif - - /* Recursive call imports X9.63 public key into temp via software */ - err = wc_ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted); - if (err == MP_OKAY) { - cbRet = wc_CryptoCb_SetKey(key->devId, - WC_SETKEY_ECC_PUB, key, tmpKey, - wc_ecc_size(tmpKey), NULL, 0, 0); - } - - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - - if (err != MP_OKAY) { - return err; - } - if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - return cbRet; - } - /* CRYPTOCB_UNAVAILABLE: fall through to software import */ - err = MP_OKAY; - } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ - /* make sure required variables are reset */ wc_ecc_reset(key); @@ -11159,39 +11130,25 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, } /* import public ECC key in ANSI X9.63 format */ -int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, - int curve_id) -{ - /* treat as untrusted: validate the point is on the curve */ - return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1); -} - -WOLFSSL_ABI -int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) -{ - return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); -} -#endif /* HAVE_ECC_KEY_IMPORT */ - -#ifdef HAVE_ECC_KEY_EXPORT - -/* export ecc key to component form, d is optional if only exporting public - * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR - * return MP_OKAY on success */ -int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, - byte* qy, word32* qyLen, byte* d, word32* dLen, int encType) +int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key, + int curve_id, int untrusted) { +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); int err = 0; - word32 keySz; -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); #endif - if (key == NULL) { + if (in == NULL || key == NULL) { return BAD_FUNC_ARG; } -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + /* must be odd */ + if ((inLen & 1) == 0) { + return ECC_BAD_ARG_E; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) #endif @@ -11208,24 +11165,68 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, return err; } - err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, - (void*)key, tmpKey); - if (err == 0) { - /* Recursive call on software tmpKey (INVALID_DEVID) */ - err = wc_ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen, - encType); + #ifdef WOLFSSL_CUSTOM_CURVES + if (key->dp != NULL) { + err = wc_ecc_set_custom_curve(tmpKey, key->dp); + if (err != 0) { + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + return err; + } + } + #endif + + /* Import into temp via software helper (no callback recursion) */ + err = _ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted); + if (err == MP_OKAY) { + cbRet = wc_CryptoCb_SetKey(key->devId, + WC_SETKEY_ECC_PUB, key, tmpKey, + wc_ecc_size(tmpKey), NULL, 0, 0); } wc_ecc_free(tmpKey); WC_FREE_VAR(tmpKey, key->heap); - if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + if (err != MP_OKAY) { return err; } - /* CRYPTOCB_UNAVAILABLE: fall through to software export */ - err = 0; + if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return cbRet; + } + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ + + return _ecc_import_x963_ex2(in, inLen, key, curve_id, untrusted); +} + +/* import public ECC key in ANSI X9.63 format */ +int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, + int curve_id) +{ + return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 0); +} + +WOLFSSL_ABI +int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) +{ + return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); +} +#endif /* HAVE_ECC_KEY_IMPORT */ + +#ifdef HAVE_ECC_KEY_EXPORT + +/* Software-only export of ecc key to component form. + * This internal helper avoids recursion when called from the EXPORT_KEY path. */ +static int _ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, + byte* qy, word32* qyLen, byte* d, word32* dLen, + int encType) +{ + int err = 0; + word32 keySz; + + if (key == NULL) { + return BAD_FUNC_ARG; } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ if (wc_ecc_is_valid_idx(key->idx) == 0 || key->dp == NULL) { return ECC_BAD_ARG_E; @@ -11309,6 +11310,58 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, } +/* export ecc key to component form, d is optional if only exporting public + * encType is WC_TYPE_UNSIGNED_BIN or WC_TYPE_HEX_STR + * return MP_OKAY on success */ +int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen, + byte* qy, word32* qyLen, byte* d, word32* dLen, int encType) +{ +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + int err; + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif + + if (key == NULL) { + return BAD_FUNC_ARG; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (err != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return err; + } + + err = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_ECDSA_SIGN, + (void*)key, tmpKey); + if (err == 0) { + /* Call software helper (no callback recursion) */ + err = _ecc_export_ex(tmpKey, qx, qxLen, qy, qyLen, d, dLen, + encType); + } + + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return err; + } + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ + + return _ecc_export_ex(key, qx, qxLen, qy, qyLen, d, dLen, encType); +} + /* export ecc private key only raw, outLen is in/out size as unsigned bin return MP_OKAY on success */ WOLFSSL_ABI @@ -11357,76 +11410,20 @@ int wc_ecc_export_private_raw(ecc_key* key, byte* qx, word32* qxLen, #endif /* HAVE_ECC_KEY_EXPORT */ #ifdef HAVE_ECC_KEY_IMPORT -/* import private key, public part optional if (pub) passed as NULL */ -int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, - const byte* pub, word32 pubSz, ecc_key* key, - int curve_id) +/* Software-only import of private key, public part optional. + * This internal helper avoids recursion when called from the SETKEY path. */ +static int _ecc_import_private_key_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + ecc_key* key, int curve_id) { int ret; #ifdef WOLFSSL_CRYPTOCELL const CRYS_ECPKI_Domain_t* pDomain; #endif -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); - int tmpErr = 0; - WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); -#endif - if (key == NULL || priv == NULL) + if (key == NULL || priv == NULL) { return BAD_FUNC_ARG; - -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - #ifndef WOLF_CRYPTO_CB_FIND - if (key->devId != INVALID_DEVID) - #endif - { - /* Allocate temp key for callback to export from */ - WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); - if (!WC_VAR_OK(tmpKey)) { - return MEMORY_E; - } - XMEMSET(tmpKey, 0, sizeof(ecc_key)); - - tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); - if (tmpErr != 0) { - WC_FREE_VAR(tmpKey, key->heap); - return tmpErr; - } - - #ifdef WOLFSSL_CUSTOM_CURVES - /* Copy custom curve params so recursive import uses correct curve */ - if (key->dp != NULL) { - tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp); - if (tmpErr != 0) { - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - return tmpErr; - } - } - #endif - - /* Recursive call imports key material into temp via software - * (no callback recursion since tmpKey has INVALID_DEVID) */ - tmpErr = wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz, - tmpKey, curve_id); - if (tmpErr == 0) { - cbRet = wc_CryptoCb_SetKey(key->devId, - WC_SETKEY_ECC_PRIV, key, tmpKey, - wc_ecc_size(tmpKey), NULL, 0, 0); - } - - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - - if (tmpErr != 0) { - return tmpErr; - } - if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - return cbRet; - } - /* CRYPTOCB_UNAVAILABLE: fall through to software import */ } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ /* public optional, NULL if only importing private */ if (pub != NULL) { @@ -11616,6 +11613,75 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, return ret; } +/* import private key, public part optional if (pub) passed as NULL */ +int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, ecc_key* key, + int curve_id) +{ +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + int tmpErr = 0; + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif + + if (key == NULL || priv == NULL) { + return BAD_FUNC_ARG; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (tmpErr != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return tmpErr; + } + + #ifdef WOLFSSL_CUSTOM_CURVES + if (key->dp != NULL) { + tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp); + if (tmpErr != 0) { + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + return tmpErr; + } + } + #endif + + /* Import into temp via software helper (no callback recursion) */ + tmpErr = _ecc_import_private_key_ex(priv, privSz, pub, pubSz, + tmpKey, curve_id); + if (tmpErr == 0) { + cbRet = wc_CryptoCb_SetKey(key->devId, + WC_SETKEY_ECC_PRIV, key, tmpKey, + wc_ecc_size(tmpKey), NULL, 0, 0); + } + + /* wc_ecc_free calls mp_forcezero on private key components, + * so no separate ForceZero of the struct is needed here. */ + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (tmpErr != 0) { + return tmpErr; + } + if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return cbRet; + } + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ + + return _ecc_import_private_key_ex(priv, privSz, pub, pubSz, key, curve_id); +} + /* ecc private key import, public key in ANSI X9.63 format, private raw */ WOLFSSL_ABI int wc_ecc_import_private_key(const byte* priv, word32 privSz, const byte* pub, @@ -11735,7 +11801,9 @@ int wc_ecc_sig_to_rs(const byte* sig, word32 sigLen, byte* r, word32* rLen, #endif /* !NO_ASN */ #ifdef HAVE_ECC_KEY_IMPORT -static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, +/* Software-only import of raw ECC key material. + * This internal helper avoids recursion when called from the SETKEY path. */ +static int _ecc_import_raw_private(ecc_key* key, const char* qx, const char* qy, const char* d, int curve_id, int encType) { int err = MP_OKAY; @@ -11749,11 +11817,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, defined(WOLFSSL_CRYPTOCELL) word32 keySz = 0; #endif -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); - int setKeyType = WC_SETKEY_ECC_PRIV; - WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); -#endif /* if d is NULL, only import as public key using Qx,Qy */ if (key == NULL || qx == NULL || qy == NULL) { @@ -11771,63 +11834,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, return err; } -#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) - #ifndef WOLF_CRYPTO_CB_FIND - if (key->devId != INVALID_DEVID) - #endif - { - /* Allocate temp key for callback to export from */ - WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); - if (!WC_VAR_OK(tmpKey)) { - return MEMORY_E; - } - XMEMSET(tmpKey, 0, sizeof(ecc_key)); - - err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); - if (err != 0) { - WC_FREE_VAR(tmpKey, key->heap); - return err; - } - - #ifdef WOLFSSL_CUSTOM_CURVES - /* Copy custom curve params so recursive import uses correct curve */ - if (key->dp != NULL) { - err = wc_ecc_set_custom_curve(tmpKey, key->dp); - if (err != 0) { - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - return err; - } - } - #endif - - /* Recursive call imports key material into temp via software */ - err = wc_ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType); - if (err == MP_OKAY) { - /* This function handles both public and private imports: - * when d is NULL, only Qx/Qy are imported (public only) */ - if (d == NULL) { - setKeyType = WC_SETKEY_ECC_PUB; - } - cbRet = wc_CryptoCb_SetKey(key->devId, - setKeyType, key, tmpKey, - wc_ecc_size(tmpKey), NULL, 0, 0); - } - - wc_ecc_free(tmpKey); - WC_FREE_VAR(tmpKey, key->heap); - - if (err != MP_OKAY) { - return err; - } - if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { - return cbRet; - } - /* CRYPTOCB_UNAVAILABLE: fall through to software import */ - err = MP_OKAY; - } -#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ - /* init key */ #ifdef ALT_ECC_SIZE key->pubkey.x = (mp_int*)&key->pubkey.xyz[0]; @@ -12102,6 +12108,77 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, return err; } +static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, + const char* qy, const char* d, int curve_id, int encType) +{ +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); + int setKeyType = WC_SETKEY_ECC_PRIV; + int err; + WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL); +#endif + + /* if d is NULL, only import as public key using Qx,Qy */ + if (key == NULL || qx == NULL || qy == NULL) { + return BAD_FUNC_ARG; + } + +#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY) + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap); + if (!WC_VAR_OK(tmpKey)) { + return MEMORY_E; + } + XMEMSET(tmpKey, 0, sizeof(ecc_key)); + + err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID); + if (err != 0) { + WC_FREE_VAR(tmpKey, key->heap); + return err; + } + + #ifdef WOLFSSL_CUSTOM_CURVES + if (key->dp != NULL) { + err = wc_ecc_set_custom_curve(tmpKey, key->dp); + if (err != 0) { + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + return err; + } + } + #endif + + /* Import into temp via software helper (no callback recursion) */ + err = _ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType); + if (err == MP_OKAY) { + if (d == NULL) { + setKeyType = WC_SETKEY_ECC_PUB; + } + cbRet = wc_CryptoCb_SetKey(key->devId, + setKeyType, key, tmpKey, + wc_ecc_size(tmpKey), NULL, 0, 0); + } + + /* wc_ecc_free calls mp_forcezero on private key components, + * so no separate ForceZero of the struct is needed here. */ + wc_ecc_free(tmpKey); + WC_FREE_VAR(tmpKey, key->heap); + + if (err != MP_OKAY) { + return err; + } + if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + return cbRet; + } + } +#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ + + return _ecc_import_raw_private(key, qx, qy, d, curve_id, encType); +} + /** Import raw ECC key key The destination ecc_key structure diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 7032e85b57..8f16b0ac39 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4533,12 +4533,46 @@ int wc_RsaEncryptSize(const RsaKey* key) } #ifndef WOLFSSL_RSA_VERIFY_ONLY +/* Software-only export of RSA public key elements from RsaKey. + * This internal helper avoids recursion when called from the EXPORT_KEY path. */ +static int _RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, + byte* n, word32* nSz) +{ + int sz, ret; + + if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) { + return BAD_FUNC_ARG; + } + + sz = mp_unsigned_bin_size(&key->e); + if ((word32)sz > *eSz) { + return RSA_BUFFER_E; + } + ret = mp_to_unsigned_bin(&key->e, e); + if (ret != MP_OKAY) { + return ret; + } + *eSz = (word32)sz; + + sz = wc_RsaEncryptSize(key); + if ((word32)sz > *nSz) { + return RSA_BUFFER_E; + } + ret = mp_to_unsigned_bin(&key->n, n); + if (ret != MP_OKAY) { + return ret; + } + *nSz = (word32)sz; + + return 0; +} + /* flatten RsaKey structure into individual elements (e, n) */ int wc_RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, byte* n, word32* nSz) { - int sz, ret; #if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) + int ret; WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL); #endif @@ -4566,35 +4600,23 @@ int wc_RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, byte* n, ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_RSA, (void*)key, tmpKey); if (ret == 0) { - /* Recursive call on software tmpKey (INVALID_DEVID) */ - ret = wc_RsaFlattenPublicKey(tmpKey, e, eSz, n, nSz); + /* Call software helper (no callback recursion) */ + ret = _RsaFlattenPublicKey(tmpKey, e, eSz, n, nSz); } - ForceZero(tmpKey, sizeof(RsaKey)); + /* wc_FreeRsaKey calls mp_forcezero on all private key components, + * so no separate ForceZero of the struct is needed here. Calling + * ForceZero before wc_FreeRsaKey would zero the mp_int metadata + * and cause a crash. */ wc_FreeRsaKey(tmpKey); WC_FREE_VAR(tmpKey, key->heap); - if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { return ret; + } /* fall through to software */ } #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ - sz = mp_unsigned_bin_size(&key->e); - if ((word32)sz > *eSz) - return RSA_BUFFER_E; - ret = mp_to_unsigned_bin(&key->e, e); - if (ret != MP_OKAY) - return ret; - *eSz = (word32)sz; - - sz = wc_RsaEncryptSize(key); - if ((word32)sz > *nSz) - return RSA_BUFFER_E; - ret = mp_to_unsigned_bin(&key->n, n); - if (ret != MP_OKAY) - return ret; - *nSz = (word32)sz; - - return 0; + return _RsaFlattenPublicKey(key, e, eSz, n, nSz); } #endif @@ -4620,6 +4642,53 @@ static int RsaGetValue(const mp_int* in, byte* out, word32* outSz) } +/* Software-only export of RSA key elements from RsaKey. + * This internal helper avoids recursion when called from the EXPORT_KEY path. */ +static int _RsaExportKey(const RsaKey* key, + byte* e, word32* eSz, byte* n, word32* nSz, + byte* d, word32* dSz, byte* p, word32* pSz, + byte* q, word32* qSz) +{ + int ret = 0; + + if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL + || d == NULL || dSz == NULL || p == NULL || pSz == NULL + || q == NULL || qSz == NULL) { + return BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = RsaGetValue(&key->e, e, eSz); + } + if (ret == 0) { + ret = RsaGetValue(&key->n, n, nSz); + } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY + if (ret == 0) { + ret = RsaGetValue(&key->d, d, dSz); + } + if (ret == 0) { + ret = RsaGetValue(&key->p, p, pSz); + } + if (ret == 0) { + ret = RsaGetValue(&key->q, q, qSz); + } +#else + /* no private parts to key */ + if (d == NULL || p == NULL || q == NULL || dSz == NULL || pSz == NULL + || qSz == NULL) { + ret = BAD_FUNC_ARG; + } + else { + *dSz = 0; + *pSz = 0; + *qSz = 0; + } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ + + return ret; +} + int wc_RsaExportKey(const RsaKey* key, byte* e, word32* eSz, byte* n, word32* nSz, byte* d, word32* dSz, byte* p, word32* pSz, @@ -4630,8 +4699,9 @@ int wc_RsaExportKey(const RsaKey* key, WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL); #endif - if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz) + if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz) { ret = 0; + } #if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY) if (ret == 0) { @@ -4654,43 +4724,25 @@ int wc_RsaExportKey(const RsaKey* key, ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_RSA, (void*)key, tmpKey); if (ret == 0) { - /* Recursive call on software tmpKey (INVALID_DEVID) */ - ret = wc_RsaExportKey(tmpKey, e, eSz, n, nSz, - d, dSz, p, pSz, q, qSz); + /* Call software helper (no callback recursion) */ + ret = _RsaExportKey(tmpKey, e, eSz, n, nSz, + d, dSz, p, pSz, q, qSz); } - ForceZero(tmpKey, sizeof(RsaKey)); + /* wc_FreeRsaKey calls mp_forcezero on all private key components, + * so no separate ForceZero of the struct is needed here. */ wc_FreeRsaKey(tmpKey); WC_FREE_VAR(tmpKey, key->heap); - if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { return ret; + } ret = 0; /* fall through to software */ } } #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */ - if (ret == 0) - ret = RsaGetValue(&key->e, e, eSz); - if (ret == 0) - ret = RsaGetValue(&key->n, n, nSz); -#ifndef WOLFSSL_RSA_PUBLIC_ONLY - if (ret == 0) - ret = RsaGetValue(&key->d, d, dSz); - if (ret == 0) - ret = RsaGetValue(&key->p, p, pSz); - if (ret == 0) - ret = RsaGetValue(&key->q, q, qSz); -#else - /* no private parts to key */ - if (d == NULL || p == NULL || q == NULL || dSz == NULL || pSz == NULL - || qSz == NULL) { - ret = BAD_FUNC_ARG; + if (ret == 0) { + ret = _RsaExportKey(key, e, eSz, n, nSz, d, dSz, p, pSz, q, qSz); } - else { - *dSz = 0; - *pSz = 0; - *qSz = 0; - } -#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ return ret; } @@ -5540,6 +5592,93 @@ static int CalcDX(mp_int* y, mp_int* x, mp_int* d) } #endif +/* Software-only import of RSA private key elements into RsaKey. + * This internal helper avoids recursion when called from the SETKEY path. */ +static int _RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, + const byte* e, word32 eSz, const byte* d, word32 dSz, + const byte* u, word32 uSz, const byte* p, word32 pSz, + const byte* q, word32 qSz, const byte* dP, word32 dPSz, + const byte* dQ, word32 dQSz, RsaKey* key) +{ + int err = MP_OKAY; + + if (n == NULL || nSz == 0 || e == NULL || eSz == 0 + || d == NULL || dSz == 0 || p == NULL || pSz == 0 + || q == NULL || qSz == 0 || key == NULL) { + return BAD_FUNC_ARG; + } + +#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) + if ((u == NULL || uSz == 0) + || (dP != NULL && dPSz == 0) + || (dQ != NULL && dQSz == 0)) { + return BAD_FUNC_ARG; + } +#else + (void)u; + (void)uSz; + (void)dP; + (void)dPSz; + (void)dQ; + (void)dQSz; +#endif + + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->n, n, nSz); + } + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->e, e, eSz); + } + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->d, d, dSz); + } + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->p, p, pSz); + } + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->q, q, qSz); + } +#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) + if (err == MP_OKAY) { + err = mp_read_unsigned_bin(&key->u, u, uSz); + } + if (err == MP_OKAY) { + if (dP != NULL) { + err = mp_read_unsigned_bin(&key->dP, dP, dPSz); + } + else { + err = CalcDX(&key->dP, &key->p, &key->d); + } + } + if (err == MP_OKAY) { + if (dQ != NULL) { + err = mp_read_unsigned_bin(&key->dQ, dQ, dQSz); + } + else { + err = CalcDX(&key->dQ, &key->q, &key->d); + } + } +#endif + + if (err == MP_OKAY) { + key->type = RSA_PRIVATE; + } + else { + mp_clear(&key->n); + mp_clear(&key->e); + mp_forcezero(&key->d); + mp_forcezero(&key->p); + mp_forcezero(&key->q); +#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) + mp_forcezero(&key->u); + mp_forcezero(&key->dP); + mp_forcezero(&key->dQ); +#endif + } + + return err; +} + int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz, const byte* d, word32 dSz, const byte* u, word32 uSz, const byte* p, word32 pSz, @@ -5596,8 +5735,8 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, return err; } - /* Recursive call imports key material into temp via software */ - err = wc_RsaPrivateKeyDecodeRaw(n, nSz, e, eSz, d, dSz, + /* Import into temp via software helper (no callback recursion) */ + err = _RsaPrivateKeyDecodeRaw(n, nSz, e, eSz, d, dSz, u, uSz, p, pSz, q, qSz, dP, dPSz, dQ, dQSz, tmpKey); if (err == MP_OKAY) { cbRet = wc_CryptoCb_SetKey(key->devId, @@ -5605,7 +5744,8 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, wc_RsaEncryptSize(tmpKey), NULL, 0, 0); } - /* wc_FreeRsaKey does mp_forcezero on private components */ + /* wc_FreeRsaKey calls mp_forcezero on all private key components, + * so no separate ForceZero of the struct is needed here. */ wc_FreeRsaKey(tmpKey); WC_FREE_VAR(tmpKey, key->heap); @@ -5620,47 +5760,9 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz, } #endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */ - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->n, n, nSz); - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->e, e, eSz); - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->d, d, dSz); - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->p, p, pSz); - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->q, q, qSz); -#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) - if (err == MP_OKAY) - err = mp_read_unsigned_bin(&key->u, u, uSz); if (err == MP_OKAY) { - if (dP != NULL) - err = mp_read_unsigned_bin(&key->dP, dP, dPSz); - else - err = CalcDX(&key->dP, &key->p, &key->d); - } - if (err == MP_OKAY) { - if (dQ != NULL) - err = mp_read_unsigned_bin(&key->dQ, dQ, dQSz); - else - err = CalcDX(&key->dQ, &key->q, &key->d); - } -#endif - - if (err == MP_OKAY) { - key->type = RSA_PRIVATE; - } - else if (key != NULL) { - mp_clear(&key->n); - mp_clear(&key->e); - mp_forcezero(&key->d); - mp_forcezero(&key->p); - mp_forcezero(&key->q); -#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) - mp_forcezero(&key->u); - mp_forcezero(&key->dP); - mp_forcezero(&key->dQ); -#endif + err = _RsaPrivateKeyDecodeRaw(n, nSz, e, eSz, d, dSz, + u, uSz, p, pSz, q, qSz, dP, dPSz, dQ, dQSz, key); } return err;