Address feedback from Fenrir

This commit is contained in:
night1rider
2026-03-23 15:54:26 -06:00
committed by Zackery Backman
parent 642a65a34d
commit bf1013bfd4
3 changed files with 602 additions and 407 deletions
+66 -50
View File
@@ -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)
+341 -264
View File
@@ -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
+195 -93
View File
@@ -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;