mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 17:50:48 +02:00
Address feedback from Fenrir
This commit is contained in:
committed by
Zackery Backman
parent
642a65a34d
commit
bf1013bfd4
+66
-50
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user