Add WOLF_CRYPTO_CB_SETKEY and WOLF_CRYPTO_CB_EXPORT_KEY crypto callback

utilities for generic SetKey and ExportKey operations on HMAC, RSA, ECC,
  and AES. Add wc_ecc_size/wc_ecc_sig_size callback hooks for hardware-only
  keys. Integrate into configure.ac as --enable-cryptocbutils=setkey,export
  options with CI test configurations in os-check.yml.

  Add test handlers in test.c and api.c with export/import delegation
  pattern, small-stack-safe allocations, custom curve support, and
  DEBUG_CRYPTOCB helpers.
This commit is contained in:
night1rider
2026-03-02 14:15:35 -07:00
committed by Zackery Backman
parent 64c4203d96
commit 1295f4fe0e
12 changed files with 1220 additions and 14 deletions
+7
View File
@@ -61,6 +61,13 @@ 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"',
'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
@@ -9968,7 +9968,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 ]
@@ -9981,8 +9981,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"
@@ -9995,9 +9994,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
+135
View File
@@ -28306,6 +28306,141 @@ 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;
byte buf[ECC_BUFSIZE];
word32 bufSz = sizeof(buf);
int curveId;
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
if (ret != 0) 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;
break;
}
case WC_SETKEY_ECC_PRIV:
{
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
byte pubBuf[ECC_BUFSIZE];
byte privBuf[MAX_ECC_BYTES];
word32 pubSz = sizeof(pubBuf);
word32 privSz = sizeof(privBuf);
int curveId;
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
if (ret != 0) break;
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
if (ret != 0) break;
curveId = wc_ecc_get_curve_id(eccTmp->idx);
eccObj->devId = INVALID_DEVID;
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
pubBuf, pubSz, eccObj, curveId);
eccObj->devId = thisDevId;
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 */
(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;
+95
View File
@@ -8297,9 +8297,59 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
word32 inSz)
{
#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) {
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(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);
}
@@ -36498,9 +36548,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
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;
}
/* 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)
+154
View File
@@ -105,9 +105,29 @@ 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_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";
}
return "Unknown";
}
#endif /* WOLF_CRYPTO_CB_SETKEY */
static const char* GetPkTypeStr(int pk)
{
switch (pk) {
@@ -121,6 +141,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 +313,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 +816,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 +2250,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, 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
+219 -3
View File
@@ -10684,6 +10684,11 @@ 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)
return BAD_FUNC_ARG;
@@ -10692,6 +10697,58 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
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);
@@ -11232,9 +11289,68 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#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)
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) {
#ifndef NO_ASN
@@ -11552,11 +11668,15 @@ 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;
#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) {
@@ -11574,6 +11694,63 @@ 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];
@@ -11932,7 +12109,27 @@ 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)
#ifdef WOLF_CRYPTO_CB
int ret;
int keySz;
#endif
if (key == NULL)
return 0;
#ifdef WOLF_CRYPTO_CB
if (key->devId != INVALID_DEVID) {
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;
@@ -11962,8 +12159,27 @@ int wc_ecc_sig_size(const ecc_key* key)
{
int maxSigSz;
int orderBits, keySz;
#ifdef WOLF_CRYPTO_CB
int ret;
int cbKeySz;
#endif
if (key == NULL || key->dp == NULL)
if (key == NULL)
return 0;
#ifdef WOLF_CRYPTO_CB
if (key->devId != INVALID_DEVID) {
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 */
+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;
+138
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
@@ -4522,11 +4538,46 @@ 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)
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
#endif
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
{
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,
(void*)key, tmpKey);
if (ret == 0) {
/* Recursive call on software tmpKey (INVALID_DEVID) */
ret = wc_RsaFlattenPublicKey(tmpKey, e, eSz, n, nSz);
}
ForceZero(tmpKey, sizeof(RsaKey));
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 */
sz = mp_unsigned_bin_size(&key->e);
if ((word32)sz > *eSz)
return RSA_BUFFER_E;
@@ -4575,10 +4626,48 @@ int wc_RsaExportKey(const RsaKey* key,
byte* q, word32* qSz)
{
int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
#endif
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_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,
(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);
}
ForceZero(tmpKey, sizeof(RsaKey));
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 = RsaGetValue(&key->e, e, eSz);
if (ret == 0)
@@ -5458,6 +5547,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
@@ -5482,6 +5575,51 @@ 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)
#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;
}
/* Recursive call imports key material into temp via software */
err = wc_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 does mp_forcezero on private components */
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;
}
#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)
+366 -4
View File
@@ -65730,6 +65730,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) {
@@ -66576,13 +66607,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;
@@ -66615,6 +66654,329 @@ 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;
}
/* Export public key if available */
if (src->type != ECC_PRIVATEKEY_ONLY) {
ret = wc_ecc_export_x963(src, pubBuf, &pubSz);
if (ret != 0) {
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) {
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);
}
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.) */
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,
void* obj, void* out);
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
#endif /* WOLF_CRYPTO_CB */
+5 -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,8 @@ 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,
WC_PK_TYPE_MAX = _WC_PK_TYPE_MAX
};