Merge pull request #9851 from night1rider/setkey-callbacks

Setkey/Export callbacks
This commit is contained in:
David Garske
2026-04-15 10:17:38 -07:00
committed by GitHub
12 changed files with 1789 additions and 101 deletions
+8
View File
@@ -61,6 +61,14 @@ jobs:
CPPFLAGS=-DWOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC',
'--enable-all --enable-certgencache',
'--enable-all --enable-dilithium --enable-cryptocb --enable-cryptocbutils --enable-pkcallbacks',
'--enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey',
'--enable-cryptocb --enable-keygen --enable-cryptocbutils CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=export',
'--enable-cryptocb --enable-keygen CPPFLAGS="-DWOLF_CRYPTO_CB_EXPORT_KEY"',
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free,export CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey,export CPPFLAGS="-DWOLF_CRYPTO_CB_FIND"',
'CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH',
'CPPFLAGS=''-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH''',
'CPPFLAGS=''-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH''',
+9 -5
View File
@@ -9969,7 +9969,7 @@ fi
# Crypto Callbacks Utils (Copy/Free/etc)
AC_ARG_ENABLE([cryptocbutils],
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
[Enable crypto callback utilities (default: all)])],
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
[ ENABLED_CRYPTOCB_UTILS=no ]
@@ -9982,8 +9982,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
# Enable all utilities
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
# Future utilities go here when added
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
else
# Parse comma-separated list
OIFS="$IFS"
@@ -9996,9 +9995,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
free)
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
;;
# Add future options here (e.g., malloc, realloc, etc)
setkey)
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
;;
export)
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
;;
*)
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
;;
esac
done
+327
View File
@@ -28130,6 +28130,35 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
ret, *info->pk.eccsign.outlen);
#endif
}
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIZE) {
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
if (!WC_VAR_OK(tmpEcc)) {
ret = MEMORY_E;
}
else {
XMEMCPY(tmpEcc, info->pk.ecc_get_size.key, sizeof(ecc_key));
tmpEcc->devId = INVALID_DEVID;
*info->pk.ecc_get_size.keySize = wc_ecc_size(tmpEcc);
WC_FREE_VAR(tmpEcc, NULL);
ret = 0;
}
}
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIG_SIZE) {
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
if (!WC_VAR_OK(tmpEcc)) {
ret = MEMORY_E;
}
else {
XMEMCPY(tmpEcc, info->pk.ecc_get_sig_size.key,
sizeof(ecc_key));
tmpEcc->devId = INVALID_DEVID;
*info->pk.ecc_get_sig_size.sigSize = wc_ecc_sig_size(tmpEcc);
WC_FREE_VAR(tmpEcc, NULL);
ret = 0;
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
if (info->pk.type == WC_PK_TYPE_ED25519_SIGN) {
@@ -28462,6 +28491,304 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
}
}
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
info->setkey.type);
#endif
switch (info->setkey.type) {
#ifndef NO_AES
case WC_SETKEY_AES:
{
Aes* aes = (Aes*)info->setkey.obj;
aes->devId = INVALID_DEVID;
ret = wc_AesSetKey(aes,
(const byte*)info->setkey.key, info->setkey.keySz,
(const byte*)info->setkey.aux, info->setkey.flags);
aes->devId = thisDevId;
break;
}
#endif /* !NO_AES */
#ifndef NO_HMAC
case WC_SETKEY_HMAC:
{
Hmac* hmac = (Hmac*)info->setkey.obj;
hmac->devId = INVALID_DEVID;
ret = wc_HmacSetKey(hmac, hmac->macType,
(const byte*)info->setkey.key, info->setkey.keySz);
hmac->devId = thisDevId;
break;
}
#endif /* !NO_HMAC */
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
case WC_SETKEY_RSA_PUB:
{
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
int derSz;
word32 idx = 0;
byte* der = NULL;
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
if (derSz <= 0) { ret = derSz; break; }
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) { ret = MEMORY_E; break; }
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
(word32)derSz, 1);
if (derSz <= 0) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ret = derSz; break;
}
rsaObj->devId = INVALID_DEVID;
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
(word32)derSz);
rsaObj->devId = thisDevId;
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
break;
}
case WC_SETKEY_RSA_PRIV:
{
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
int derSz;
word32 idx = 0;
byte* der = NULL;
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
if (derSz <= 0) { ret = derSz; break; }
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) { ret = MEMORY_E; break; }
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
if (derSz <= 0) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ret = derSz; break;
}
rsaObj->devId = INVALID_DEVID;
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
(word32)derSz);
rsaObj->devId = thisDevId;
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
break;
}
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
defined(HAVE_ECC_KEY_IMPORT)
case WC_SETKEY_ECC_PUB:
{
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
word32 bufSz = ECC_BUFSIZE;
int curveId;
WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(buf, byte, ECC_BUFSIZE, NULL);
if (!WC_VAR_OK(buf)) {
ret = MEMORY_E;
break;
}
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
if (ret != 0) {
WC_FREE_VAR(buf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(eccTmp->idx);
eccObj->devId = INVALID_DEVID;
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
eccObj->devId = thisDevId;
WC_FREE_VAR(buf, NULL);
break;
}
case WC_SETKEY_ECC_PRIV:
{
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
word32 pubSz = ECC_BUFSIZE;
word32 privSz = MAX_ECC_BYTES;
byte* pubPtr = NULL;
int curveId;
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
ret = MEMORY_E;
break;
}
/* Export public key from temp (if available) */
if (eccTmp->type != ECC_PRIVATEKEY_ONLY) {
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
if (ret != 0) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
pubPtr = pubBuf;
}
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
if (ret != 0) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(eccTmp->idx);
eccObj->devId = INVALID_DEVID;
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
pubPtr, (pubPtr != NULL) ? pubSz : 0,
eccObj, curveId);
eccObj->devId = thisDevId;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) {
#ifdef DEBUG_WOLFSSL
fprintf(stderr, "test_CryptoCb_Func: ExportKey Type=%d\n",
info->export_key.type);
#endif
switch (info->export_key.type) {
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
case WC_PK_TYPE_RSA:
{
RsaKey* src = (RsaKey*)info->export_key.obj;
RsaKey* dst = (RsaKey*)info->export_key.out;
int derSz;
word32 idx = 0;
byte* der = NULL;
/* Try private key export first, fall back to public */
derSz = wc_RsaKeyToDer(src, NULL, 0);
if (derSz > 0) {
der = (byte*)XMALLOC(derSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) { ret = MEMORY_E; break; }
derSz = wc_RsaKeyToDer(src, der, (word32)derSz);
if (derSz > 0) {
ret = wc_RsaPrivateKeyDecode(der, &idx, dst,
(word32)derSz);
}
else {
ret = derSz;
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
/* Public key only */
derSz = wc_RsaPublicKeyDerSize(src, 1);
if (derSz <= 0) { ret = derSz; break; }
der = (byte*)XMALLOC(derSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) { ret = MEMORY_E; break; }
derSz = wc_RsaKeyToPublicDer_ex(src, der,
(word32)derSz, 1);
if (derSz > 0) {
ret = wc_RsaPublicKeyDecode(der, &idx, dst,
(word32)derSz);
}
else {
ret = derSz;
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
break;
}
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
defined(HAVE_ECC_KEY_IMPORT)
case WC_PK_TYPE_ECDSA_SIGN: /* ECC key */
{
ecc_key* src = (ecc_key*)info->export_key.obj;
ecc_key* dst = (ecc_key*)info->export_key.out;
word32 pubSz = ECC_BUFSIZE;
word32 privSz = MAX_ECC_BYTES;
byte* pubPtr = NULL;
int curveId;
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
ret = MEMORY_E;
break;
}
/* Use software to export from src - prevent recursion */
{
int savedDevId = src->devId;
src->devId = INVALID_DEVID;
/* Export public key if available */
if (src->type != ECC_PRIVATEKEY_ONLY) {
ret = wc_ecc_export_x963(src, pubBuf, &pubSz);
if (ret != 0) {
src->devId = savedDevId;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
pubPtr = pubBuf;
}
/* Export private key if available */
if (src->type != ECC_PUBLICKEY) {
ret = wc_ecc_export_private_only(src, privBuf,
&privSz);
if (ret != 0) {
src->devId = savedDevId;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(src->idx);
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
pubPtr, (pubPtr != NULL) ? pubSz : 0,
dst, curveId);
}
else {
/* Public key only */
curveId = wc_ecc_get_curve_id(src->idx);
ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst,
curveId, 0);
}
src->devId = savedDevId;
}
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
(void)thisDevId;
(void)keyFormat;
+24
View File
@@ -4518,6 +4518,9 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir)
{
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet;
#endif
if ((aes == NULL) || (userKey == NULL)) {
return BAD_FUNC_ARG;
}
@@ -4559,6 +4562,15 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
}
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
#endif
#ifdef WOLF_CRYPTO_CB_SETKEY
cbRet = wc_CryptoCb_SetKey(aes->devId,
WC_SETKEY_AES, aes, (void*)userKey, keylen,
(void*)iv,
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return cbRet;
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
#endif /* WOLF_CRYPTO_CB_SETKEY */
/* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
if (keylen > sizeof(aes->devKey)) {
return BAD_FUNC_ARG;
@@ -4955,6 +4967,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
int checkKeyLen)
{
int ret;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet;
#endif
#ifdef WOLFSSL_IMX6_CAAM_BLOB
byte local[32];
word32 localSz = 32;
@@ -5005,6 +5020,15 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
}
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
#endif
#ifdef WOLF_CRYPTO_CB_SETKEY
cbRet = wc_CryptoCb_SetKey(aes->devId,
WC_SETKEY_AES, aes, (void*)userKey, keylen,
(void*)iv,
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return cbRet;
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
#endif /* WOLF_CRYPTO_CB_SETKEY */
/* Standard CryptoCB path - copy key to devKey */
if (keylen > sizeof(aes->devKey)) {
return BAD_FUNC_ARG;
+118 -7
View File
@@ -8297,9 +8297,61 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
if (key == NULL) {
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
int tmpErr = 0;
word32 tmpIdx;
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
#endif
if (key == NULL || input == NULL || inOutIdx == 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
{
tmpIdx = *inOutIdx;
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;
}
/* Decode into temp key (software-only, no callback recursion
* since tmpKey has INVALID_DEVID) */
tmpErr = _RsaPrivateKeyDecode(input, &tmpIdx, tmpKey, NULL, inSz);
if (tmpErr == 0) {
cbRet = wc_CryptoCb_SetKey(key->devId,
WC_SETKEY_RSA_PRIV, key, tmpKey,
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);
if (tmpErr != 0) {
return tmpErr;
}
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
*inOutIdx = tmpIdx;
return cbRet;
}
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
}
#endif
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
}
@@ -36493,18 +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 (n == NULL || e == NULL || key == NULL)
if (n == NULL || e == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
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);
@@ -36543,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)
+156
View File
@@ -105,9 +105,31 @@ static const char* GetAlgoTypeStr(int algo)
#ifdef WOLF_CRYPTO_CB_FREE
case WC_ALGO_TYPE_FREE: return "Free";
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
case WC_ALGO_TYPE_SETKEY: return "SetKey";
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
case WC_ALGO_TYPE_EXPORT_KEY: return "ExportKey";
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
}
return NULL;
}
#ifdef WOLF_CRYPTO_CB_SETKEY
static const char* GetSetKeyTypeStr(int type)
{
switch (type) {
case WC_SETKEY_NONE: return "None";
case WC_SETKEY_HMAC: return "HMAC";
case WC_SETKEY_RSA_PUB: return "RSA-Pub";
case WC_SETKEY_RSA_PRIV: return "RSA-Priv";
case WC_SETKEY_ECC_PUB: return "ECC-Pub";
case WC_SETKEY_ECC_PRIV: return "ECC-Priv";
case WC_SETKEY_AES: return "AES";
default: break;
}
return NULL;
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
static const char* GetPkTypeStr(int pk)
{
switch (pk) {
@@ -121,6 +143,8 @@ static const char* GetPkTypeStr(int pk)
case WC_PK_TYPE_CURVE25519: return "CURVE25519";
case WC_PK_TYPE_RSA_KEYGEN: return "RSA KeyGen";
case WC_PK_TYPE_EC_KEYGEN: return "ECC KeyGen";
case WC_PK_TYPE_EC_GET_SIZE: return "ECC GetSize";
case WC_PK_TYPE_EC_GET_SIG_SIZE: return "ECC GetSigSize";
}
return NULL;
}
@@ -291,6 +315,19 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
GetAlgoTypeStr(info->free.algo), info->free.type);
}
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
printf("Crypto CB: %s %s KeySz=%u\n",
GetAlgoTypeStr(info->algo_type),
GetSetKeyTypeStr(info->setkey.type), info->setkey.keySz);
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) {
printf("Crypto CB: %s Type=%d\n",
GetAlgoTypeStr(info->algo_type), info->export_key.type);
}
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#if (defined(HAVE_HKDF) && !defined(NO_HMAC)) || \
defined(HAVE_CMAC_KDF)
else if (info->algo_type == WC_ALGO_TYPE_KDF) {
@@ -781,6 +818,54 @@ int wc_CryptoCb_EccCheckPrivKey(ecc_key* key, const byte* pubKey,
return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif
int wc_CryptoCb_EccGetSize(const ecc_key* key, int* keySize)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;
if (key == NULL)
return ret;
/* locate registered callback */
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
cryptoInfo.pk.type = WC_PK_TYPE_EC_GET_SIZE;
cryptoInfo.pk.ecc_get_size.key = key;
cryptoInfo.pk.ecc_get_size.keySize = keySize;
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}
return wc_CryptoCb_TranslateErrorCode(ret);
}
int wc_CryptoCb_EccGetSigSize(const ecc_key* key, int* sigSize)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;
if (key == NULL)
return ret;
/* locate registered callback */
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
cryptoInfo.pk.type = WC_PK_TYPE_EC_GET_SIG_SIZE;
cryptoInfo.pk.ecc_get_sig_size.key = key;
cryptoInfo.pk.ecc_get_sig_size.sigSize = sigSize;
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}
return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
@@ -2167,6 +2252,77 @@ int wc_CryptoCb_Free(int devId, int algo, int type, int subType, void* obj)
}
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
/* Generic SetKey callback for importing keys into hardware.
* devId: Device ID for the registered callback
* type: enum wc_SetKeyType (AES, HMAC, RSA_PUB, RSA_PRIV, ECC_PUB, ECC_PRIV)
* obj: Context struct being operated on (Aes*, Hmac*, RsaKey*, ecc_key*)
* key: Key material: raw bytes (AES/HMAC) or temp struct to export from (RSA/ECC)
* keySz: Key size in bytes (0 when key is a struct pointer)
* aux: Auxiliary data (IV, etc.) or NULL
* auxSz: Aux data size, 0 if unused
* flags: AES: direction (AES_ENCRYPTION/DECRYPTION). Others: 0
* Returns: 0 on success, CRYPTOCB_UNAVAILABLE if not handled, negative on error
*/
int wc_CryptoCb_SetKey(int devId, int type, void* obj,
void* key, word32 keySz,
void* aux, word32 auxSz,
int flags)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;
/* Find registered callback device */
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_SETKEY);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_SETKEY;
cryptoInfo.setkey.type = type;
cryptoInfo.setkey.obj = obj;
cryptoInfo.setkey.key = key;
cryptoInfo.setkey.keySz = keySz;
cryptoInfo.setkey.aux = aux;
cryptoInfo.setkey.auxSz = auxSz;
cryptoInfo.setkey.flags = flags;
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}
return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
/* Generic ExportKey callback for exporting key material from hardware.
* devId: Device ID for the registered callback
* type: enum wc_PkType (WC_PK_TYPE_RSA, WC_PK_TYPE_ECDSA, etc.)
* obj: Hardware key object (has devCtx, id[], etc.)
* out: Software key object to fill (same type as obj, caller-allocated)
* The callback exports from hardware into the software key. The caller then
* uses normal software export functions on 'out' and frees it.
* Returns: 0 on success, CRYPTOCB_UNAVAILABLE if not handled, negative on error
*/
int wc_CryptoCb_ExportKey(int devId, int type, const void* obj, void* out)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
CryptoCb* dev;
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_EXPORT_KEY);
if (dev && dev->cb) {
wc_CryptoInfo cryptoInfo;
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
cryptoInfo.algo_type = WC_ALGO_TYPE_EXPORT_KEY;
cryptoInfo.export_key.type = type;
cryptoInfo.export_key.obj = obj;
cryptoInfo.export_key.out = out;
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
}
return wc_CryptoCb_TranslateErrorCode(ret);
}
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#if defined(HAVE_CMAC_KDF)
/* Crypto callback for NIST SP 800 56C two-step CMAC KDF. See software
+402 -27
View File
@@ -9858,9 +9858,9 @@ 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;
@@ -9871,15 +9871,18 @@ int wc_ecc_export_x963(ecc_key* key, byte* out, word32* outLen)
if (key != NULL && out == NULL && outLen != NULL) {
/* if key hasn't been setup assume max bytes for size estimation */
numlen = key->dp ? (word32)key->dp->size : MAX_ECC_BYTES;
/* X9.63 uncompressed point: 0x04 header + x coord + y coord */
*outLen = 1 + 2 * numlen;
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(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
/* check if public key in secure memory */
@@ -9946,14 +9949,76 @@ 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;
/* X9.63 uncompressed point: 0x04 header + x coord + y coord */
*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,
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);
@@ -10673,9 +10738,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
@@ -10687,8 +10753,10 @@ 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 (in == NULL || key == NULL)
if (in == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
/* must be odd */
if ((inLen & 1) == 0) {
@@ -11066,12 +11134,81 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
return err;
}
/* 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)
{
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
int err = 0;
WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
#endif
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
{
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_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;
}
}
#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)
{
/* treat as untrusted: validate the point is on the curve */
return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 1);
return wc_ecc_import_x963_ex2(in, inLen, key, curve_id, 0);
}
WOLFSSL_ABI
@@ -11083,11 +11220,11 @@ int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key)
#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)
/* 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;
@@ -11178,6 +11315,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,
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
@@ -11226,23 +11415,26 @@ 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 (key == NULL || priv == NULL)
if (key == NULL || priv == NULL) {
return BAD_FUNC_ARG;
}
/* public optional, NULL if only importing private */
if (pub != NULL) {
#ifndef NO_ASN
word32 idx = 0;
ret = wc_ecc_import_x963_ex(pub, pubSz, key, curve_id);
ret = _ecc_import_x963_ex2(pub, pubSz, key, curve_id, 0);
if (ret < 0)
ret = wc_EccPublicKeyDecode(pub, &idx, key, pubSz);
key->type = ECC_PRIVATEKEY;
@@ -11426,6 +11618,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,
@@ -11545,7 +11806,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;
@@ -11555,7 +11818,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
CRYS_ECPKI_BUILD_TempData_t tempBuff;
byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
#endif
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
defined(WOLFSSL_CRYPTOCELL)
word32 keySz = 0;
@@ -11851,6 +12113,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
@@ -11935,8 +12268,29 @@ static int ecc_public_key_size(ecc_key* key, word32* sz)
WOLFSSL_ABI
int wc_ecc_size(ecc_key* key)
{
if (key == NULL || key->dp == NULL)
if (key == NULL) {
return 0;
}
#if defined(WOLF_CRYPTO_CB) && \
(defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
if (key->devId != INVALID_DEVID) {
int ret;
int keySz = 0;
ret = wc_CryptoCb_EccGetSize(key, &keySz);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
if (ret != 0) {
return 0;
}
return keySz;
}
}
#endif
if (key->dp == NULL) {
return 0;
}
return key->dp->size;
}
@@ -11966,8 +12320,29 @@ int wc_ecc_sig_size(const ecc_key* key)
int maxSigSz;
int orderBits, keySz;
if (key == NULL || key->dp == NULL)
if (key == NULL) {
return 0;
}
#if defined(WOLF_CRYPTO_CB) && \
(defined(WOLF_CRYPTO_CB_SETKEY) || defined(WOLF_CRYPTO_CB_EXPORT_KEY))
if (key->devId != INVALID_DEVID) {
int ret;
int cbKeySz = 0;
ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
if (ret != 0 || cbKeySz == 0) {
return 0;
}
return cbKeySz;
}
}
#endif
if (key->dp == NULL) {
return 0;
}
/* the signature r and s will always be less than order */
/* if the order MSB (top bit of byte) is set then ASN encoding needs
+16
View File
@@ -470,6 +470,9 @@ int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
#endif
int ret = 0;
void* heap = NULL;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet;
#endif
if (hmac == NULL || (key == NULL && length != 0) ||
!(type == WC_MD5 || type == WC_SHA ||
@@ -543,6 +546,19 @@ int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
}
}
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
#ifndef WOLF_CRYPTO_CB_FIND
if (hmac->devId != INVALID_DEVID)
#endif
{
cbRet = wc_CryptoCb_SetKey(hmac->devId,
WC_SETKEY_HMAC, hmac, (void*)key, length, NULL, 0, 0);
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return cbRet;
/* fall-through to software when unavailable */
}
#endif
#ifdef WOLF_CRYPTO_CB
hmac->keyRaw = key; /* use buffer directly */
hmac->keyLen = (word16)length;
+293 -56
View File
@@ -655,6 +655,22 @@ int wc_FreeRsaKey(RsaKey* key)
return BAD_FUNC_ARG;
}
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
#ifndef WOLF_CRYPTO_CB_FIND
if (key->devId != INVALID_DEVID)
#endif
{
ret = wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
WC_PK_TYPE_RSA, 0, key);
/* If callback wants standard free, it returns CRYPTOCB_UNAVAILABLE.
* Otherwise assume the callback handled cleanup. */
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
/* fall-through to software cleanup */
ret = 0;
}
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA)
se050_rsa_free_key(key);
#endif
@@ -4519,9 +4535,10 @@ int wc_RsaEncryptSize(const RsaKey* key)
}
#ifndef WOLFSSL_RSA_VERIFY_ONLY
/* flatten RsaKey structure into individual elements (e, n) */
int wc_RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, byte* n,
word32* nSz)
/* 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;
@@ -4530,23 +4547,77 @@ int wc_RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, byte* n,
}
sz = mp_unsigned_bin_size(&key->e);
if ((word32)sz > *eSz)
if ((word32)sz > *eSz) {
return RSA_BUFFER_E;
}
ret = mp_to_unsigned_bin(&key->e, e);
if (ret != MP_OKAY)
if (ret != MP_OKAY) {
return ret;
}
*eSz = (word32)sz;
sz = wc_RsaEncryptSize(key);
if ((word32)sz > *nSz)
if ((word32)sz > *nSz) {
return RSA_BUFFER_E;
}
ret = mp_to_unsigned_bin(&key->n, n);
if (ret != MP_OKAY)
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)
{
if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == 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
{
int ret;
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
if (!WC_VAR_OK(tmpKey)) {
return MEMORY_E;
}
XMEMSET(tmpKey, 0, sizeof(RsaKey));
ret = wc_InitRsaKey_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_RSA,
key, tmpKey);
if (ret == 0) {
/* Call software helper (no callback recursion) */
ret = _RsaFlattenPublicKey(tmpKey, e, eSz, n, nSz);
}
/* 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)) {
return ret;
}
/* fall through to software */
}
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
return _RsaFlattenPublicKey(key, e, eSz, n, nSz);
}
#endif
#ifndef WOLFSSL_RSA_VERIFY_ONLY
@@ -4571,27 +4642,37 @@ static int RsaGetValue(const mp_int* in, byte* out, word32* outSz)
}
int wc_RsaExportKey(const RsaKey* key,
byte* e, word32* eSz, byte* n, word32* nSz,
byte* d, word32* dSz, byte* p, word32* pSz,
byte* q, word32* qSz)
/* 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 = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
int ret = 0;
if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz)
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)
if (ret == 0) {
ret = RsaGetValue(&key->e, e, eSz);
if (ret == 0)
}
if (ret == 0) {
ret = RsaGetValue(&key->n, n, nSz);
}
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
if (ret == 0)
if (ret == 0) {
ret = RsaGetValue(&key->d, d, dSz);
if (ret == 0)
}
if (ret == 0) {
ret = RsaGetValue(&key->p, p, pSz);
if (ret == 0)
}
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
@@ -4607,6 +4688,63 @@ int wc_RsaExportKey(const RsaKey* key,
return ret;
}
int wc_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 = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
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) {
#ifndef WOLF_CRYPTO_CB_FIND
if (key->devId != INVALID_DEVID)
#endif
{
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
if (!WC_VAR_OK(tmpKey)) {
return MEMORY_E;
}
XMEMSET(tmpKey, 0, sizeof(RsaKey));
ret = wc_InitRsaKey_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_RSA,
key, tmpKey);
if (ret == 0) {
/* Call software helper (no callback recursion) */
ret = _RsaExportKey(tmpKey, e, eSz, n, nSz,
d, dSz, p, pSz, q, qSz);
}
/* 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)) {
return ret;
}
ret = 0; /* fall through to software */
}
}
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
if (ret == 0) {
ret = _RsaExportKey(key, e, eSz, n, nSz, d, dSz, p, pSz, q, qSz);
}
return ret;
}
#endif
@@ -5453,6 +5591,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,
@@ -5460,6 +5685,10 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
const byte* dQ, word32 dQSz, RsaKey* key)
{
int err = MP_OKAY;
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
#endif
if (n == NULL || nSz == 0 || e == NULL || eSz == 0
|| d == NULL || dSz == 0 || p == NULL || pSz == 0
@@ -5484,47 +5713,55 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
(void)dQSz;
#endif
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
#ifndef WOLF_CRYPTO_CB_FIND
if (err == MP_OKAY && key->devId != INVALID_DEVID)
#else
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);
#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));
/* Init temp with INVALID_DEVID to prevent callback recursion */
err = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
if (err != MP_OKAY) {
WC_FREE_VAR(tmpKey, key->heap);
return err;
}
/* 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,
WC_SETKEY_RSA_PRIV, key, tmpKey,
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);
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;
}
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
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
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;
+377 -4
View File
@@ -65795,6 +65795,37 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
info->pk.ecdh.private_key->devId = devIdArg;
#endif
}
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIZE) {
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
if (!WC_VAR_OK(tmpEcc)) {
ret = MEMORY_E;
}
else {
/* Copy key to avoid const and recursive callback */
XMEMCPY(tmpEcc, info->pk.ecc_get_size.key, sizeof(ecc_key));
tmpEcc->devId = INVALID_DEVID;
*info->pk.ecc_get_size.keySize = wc_ecc_size(tmpEcc);
WC_FREE_VAR(tmpEcc, NULL);
ret = 0;
}
}
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIG_SIZE) {
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
if (!WC_VAR_OK(tmpEcc)) {
ret = MEMORY_E;
}
else {
/* Copy key to avoid const and recursive callback */
XMEMCPY(tmpEcc, info->pk.ecc_get_sig_size.key,
sizeof(ecc_key));
tmpEcc->devId = INVALID_DEVID;
*info->pk.ecc_get_sig_size.sigSize = wc_ecc_sig_size(tmpEcc);
WC_FREE_VAR(tmpEcc, NULL);
ret = 0;
}
}
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
if (info->pk.type == WC_PK_TYPE_CURVE25519_KEYGEN) {
@@ -66641,13 +66672,21 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
break;
}
#endif
#ifndef NO_RSA
case WC_PK_TYPE_RSA:
{
RsaKey* rsa = (RsaKey*)info->free.obj;
rsa->devId = INVALID_DEVID;
wc_FreeRsaKey(rsa);
ret = 0;
break;
}
#endif
#ifdef HAVE_DILITHIUM
case WC_PK_TYPE_PQC_SIG_KEYGEN:
{
if (info->free.subType ==
WC_PQC_SIG_TYPE_DILITHIUM) {
dilithium_key* dil =
(dilithium_key*)info->free.obj;
if (info->free.subType == WC_PQC_SIG_TYPE_DILITHIUM) {
dilithium_key* dil = (dilithium_key*)info->free.obj;
dil->devId = INVALID_DEVID;
wc_dilithium_free(dil);
ret = 0;
@@ -66680,6 +66719,340 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
}
}
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
#ifdef DEBUG_CRYPTOCB
wc_CryptoCb_InfoString(info);
#endif
switch (info->setkey.type) {
#ifndef NO_AES
case WC_SETKEY_AES:
{
Aes* aes = (Aes*)info->setkey.obj;
/* Delegate to software: disable devId, call SetKey, restore */
aes->devId = INVALID_DEVID;
ret = wc_AesSetKey(aes,
(const byte*)info->setkey.key, info->setkey.keySz,
(const byte*)info->setkey.aux, info->setkey.flags);
aes->devId = devIdArg;
break;
}
#endif /* !NO_AES */
#ifndef NO_HMAC
case WC_SETKEY_HMAC:
{
Hmac* hmac = (Hmac*)info->setkey.obj;
/* Delegate to software: disable devId, call SetKey, restore */
hmac->devId = INVALID_DEVID;
ret = wc_HmacSetKey(hmac, hmac->macType,
(const byte*)info->setkey.key, info->setkey.keySz);
hmac->devId = devIdArg;
break;
}
#endif /* !NO_HMAC */
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
case WC_SETKEY_RSA_PUB:
{
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
int derSz;
word32 idx = 0;
byte* der = NULL;
/* Get required DER size for public key */
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
if (derSz <= 0) {
ret = derSz;
break;
}
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) {
ret = MEMORY_E;
break;
}
/* Export public key from temp to DER */
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
(word32)derSz, 1);
if (derSz <= 0) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ret = derSz;
break;
}
/* Import DER into obj via software */
rsaObj->devId = INVALID_DEVID;
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
(word32)derSz);
rsaObj->devId = devIdArg;
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
break;
}
case WC_SETKEY_RSA_PRIV:
{
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
int derSz;
word32 idx = 0;
byte* der = NULL;
/* Get required DER size for private key */
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
if (derSz <= 0) {
ret = derSz;
break;
}
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) {
ret = MEMORY_E;
break;
}
/* Export private key from temp to DER */
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
if (derSz <= 0) {
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ret = derSz;
break;
}
/* Import DER into obj via software */
rsaObj->devId = INVALID_DEVID;
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
(word32)derSz);
rsaObj->devId = devIdArg;
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
break;
}
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
defined(HAVE_ECC_KEY_IMPORT)
case WC_SETKEY_ECC_PUB:
{
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
word32 bufSz = ECC_BUFSIZE;
int curveId;
WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(buf, byte, ECC_BUFSIZE, NULL);
if (!WC_VAR_OK(buf)) {
ret = MEMORY_E;
break;
}
/* Export public key from temp to X9.63 format */
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
if (ret != 0) {
WC_FREE_VAR(buf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(eccTmp->idx);
/* Import into obj via software */
eccObj->devId = INVALID_DEVID;
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj,
curveId, 0);
eccObj->devId = devIdArg;
WC_FREE_VAR(buf, NULL);
break;
}
case WC_SETKEY_ECC_PRIV:
{
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
word32 pubSz = ECC_BUFSIZE;
word32 privSz = MAX_ECC_BYTES;
byte* pubPtr = NULL;
int curveId;
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
ret = MEMORY_E;
break;
}
/* Export public key from temp (if available) */
if (eccTmp->type != ECC_PRIVATEKEY_ONLY) {
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
if (ret != 0) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
pubPtr = pubBuf;
}
ret = wc_ecc_export_private_only(eccTmp, privBuf,
&privSz);
if (ret != 0) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(eccTmp->idx);
/* Import into obj via software */
eccObj->devId = INVALID_DEVID;
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
pubPtr, (pubPtr != NULL) ? pubSz : 0,
eccObj, curveId);
eccObj->devId = devIdArg;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) {
#ifdef DEBUG_CRYPTOCB
wc_CryptoCb_InfoString(info);
#endif
switch (info->export_key.type) {
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
case WC_PK_TYPE_RSA:
{
RsaKey* src = (RsaKey*)info->export_key.obj;
RsaKey* dst = (RsaKey*)info->export_key.out;
int derSz;
word32 idx = 0;
byte* der = NULL;
/* Try private key export first, fall back to public */
derSz = wc_RsaKeyToDer(src, NULL, 0);
if (derSz > 0) {
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) {
ret = MEMORY_E;
break;
}
derSz = wc_RsaKeyToDer(src, der, (word32)derSz);
if (derSz > 0) {
ret = wc_RsaPrivateKeyDecode(der, &idx, dst,
(word32)derSz);
}
else {
ret = derSz;
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
else {
/* Public key only */
derSz = wc_RsaPublicKeyDerSize(src, 1);
if (derSz <= 0) {
ret = derSz;
break;
}
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) {
ret = MEMORY_E;
break;
}
derSz = wc_RsaKeyToPublicDer_ex(src, der,
(word32)derSz, 1);
if (derSz > 0) {
ret = wc_RsaPublicKeyDecode(der, &idx, dst,
(word32)derSz);
}
else {
ret = derSz;
}
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
break;
}
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
defined(HAVE_ECC_KEY_IMPORT)
case WC_PK_TYPE_ECDSA_SIGN: /* ECC key */
{
ecc_key* src = (ecc_key*)info->export_key.obj;
ecc_key* dst = (ecc_key*)info->export_key.out;
word32 pubSz = ECC_BUFSIZE;
word32 privSz = MAX_ECC_BYTES;
byte* pubPtr = NULL;
int curveId;
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
ret = MEMORY_E;
break;
}
/* Use software to export from src - prevent recursion */
{
int savedDevId = src->devId;
src->devId = INVALID_DEVID;
/* Export public key if available */
if (src->type != ECC_PRIVATEKEY_ONLY) {
ret = wc_ecc_export_x963(src, pubBuf, &pubSz);
if (ret != 0) {
src->devId = savedDevId;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
pubPtr = pubBuf;
}
/* Export private key if available */
if (src->type != ECC_PUBLICKEY) {
ret = wc_ecc_export_private_only(src, privBuf,
&privSz);
if (ret != 0) {
src->devId = savedDevId;
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
curveId = wc_ecc_get_curve_id(src->idx);
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
pubPtr, (pubPtr != NULL) ? pubSz : 0,
dst, curveId);
}
else {
/* Public key only */
curveId = wc_ecc_get_curve_id(src->idx);
ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst,
curveId, 0);
}
src->devId = savedDevId;
}
WC_FREE_VAR(pubBuf, NULL);
WC_FREE_VAR(privBuf, NULL);
break;
}
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
default:
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
break;
}
}
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#ifndef NO_HMAC
else if (info->algo_type == WC_ALGO_TYPE_HMAC) {
if (info->hmac.hmac == NULL)
+52 -1
View File
@@ -30,7 +30,7 @@
/* Defines the Crypto Callback interface version, for compatibility */
/* Increment this when Crypto Callback interface changes are made */
#define CRYPTO_CB_VER 2
#define CRYPTO_CB_VER 3
#ifdef WOLF_CRYPTO_CB
@@ -134,6 +134,18 @@ typedef struct {
} wc_CryptoCb_AesAuthDec;
#endif
#ifdef WOLF_CRYPTO_CB_SETKEY
enum wc_SetKeyType {
WC_SETKEY_NONE = 0,
WC_SETKEY_HMAC = 1,
WC_SETKEY_RSA_PUB = 2,
WC_SETKEY_RSA_PRIV = 3,
WC_SETKEY_ECC_PUB = 4,
WC_SETKEY_ECC_PRIV = 5,
WC_SETKEY_AES = 6,
};
#endif /* WOLF_CRYPTO_CB_SETKEY */
/* Crypto Information Structure for callbacks */
typedef struct wc_CryptoInfo {
int algo_type; /* enum wc_AlgoType */
@@ -218,6 +230,14 @@ typedef struct wc_CryptoInfo {
word32 pubKeySz;
} ecc_check;
#endif
struct {
const ecc_key* key;
int* keySize;
} ecc_get_size;
struct {
const ecc_key* key;
int* sigSize;
} ecc_get_sig_size;
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
struct {
@@ -492,6 +512,24 @@ typedef struct wc_CryptoInfo {
void *obj; /* Object structure to free */
} free;
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
struct { /* uses wc_AlgoType=WC_ALGO_TYPE_SETKEY */
int type; /* enum wc_SetKeyType */
void* obj; /* Aes*, Hmac*, RsaKey*, ecc_key* */
void* key; /* Raw key bytes or temp struct to export from */
word32 keySz; /* Key size (0 when key is a struct ptr) */
void* aux; /* Auxiliary data (IV, etc.) or NULL */
word32 auxSz; /* Aux data size, 0 if unused */
int flags; /* AES: direction (AES_ENCRYPTION/DECRYPTION) */
} setkey;
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
struct { /* uses wc_AlgoType=WC_ALGO_TYPE_EXPORT_KEY */
int type; /* enum wc_PkType (WC_PK_TYPE_RSA, etc.) */
const void* obj; /* Hardware key (has devCtx/id[]) */
void* out; /* Software key to fill (same type as obj) */
} export_key;
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#if defined(HAVE_HKDF) || defined(HAVE_CMAC_KDF)
struct {
int type; /* enum wc_KdfType */
@@ -592,6 +630,9 @@ WOLFSSL_LOCAL int wc_CryptoCb_EccVerify(const byte* sig, word32 siglen,
WOLFSSL_LOCAL int wc_CryptoCb_EccCheckPrivKey(ecc_key* key, const byte* pubKey,
word32 pubKeySz);
WOLFSSL_LOCAL int wc_CryptoCb_EccGetSize(const ecc_key* key, int* keySize);
WOLFSSL_LOCAL int wc_CryptoCb_EccGetSigSize(const ecc_key* key, int* sigSize);
#endif /* HAVE_ECC */
#ifdef HAVE_CURVE25519
@@ -772,6 +813,16 @@ WOLFSSL_LOCAL int wc_CryptoCb_Copy(int devId, int algo, int type, void* src,
WOLFSSL_LOCAL int wc_CryptoCb_Free(int devId, int algo, int type, int subType,
void* obj);
#endif /* WOLF_CRYPTO_CB_FREE */
#ifdef WOLF_CRYPTO_CB_SETKEY
WOLFSSL_LOCAL int wc_CryptoCb_SetKey(int devId, int type, void* obj,
void* key, word32 keySz,
void* aux, word32 auxSz,
int flags);
#endif /* WOLF_CRYPTO_CB_SETKEY */
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
WOLFSSL_LOCAL int wc_CryptoCb_ExportKey(int devId, int type,
const void* obj, void* out);
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#endif /* WOLF_CRYPTO_CB */
+7 -1
View File
@@ -1424,7 +1424,9 @@ enum wc_AlgoType {
WC_ALGO_TYPE_KDF = 9,
WC_ALGO_TYPE_COPY = 10,
WC_ALGO_TYPE_FREE = 11,
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_FREE
WC_ALGO_TYPE_SETKEY = 12,
WC_ALGO_TYPE_EXPORT_KEY = 13,
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_EXPORT_KEY
};
/* KDF types */
@@ -1566,6 +1568,10 @@ enum wc_PkType {
WC_PK_TYPE_RSA_PKCS = 25,
WC_PK_TYPE_RSA_PSS = 26,
WC_PK_TYPE_RSA_OAEP = 27,
WC_PK_TYPE_EC_GET_SIZE = 28,
WC_PK_TYPE_EC_GET_SIG_SIZE = 29,
#undef _WC_PK_TYPE_MAX
#define _WC_PK_TYPE_MAX WC_PK_TYPE_EC_GET_SIG_SIZE
WC_PK_TYPE_MAX = _WC_PK_TYPE_MAX
};