Skip to content

Commit 724d06d

Browse files
committed
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.
1 parent 7efc962 commit 724d06d

12 files changed

Lines changed: 1219 additions & 14 deletions

File tree

.github/workflows/os-check.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ jobs:
8484
'--disable-tls --enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"',
8585
'--enable-all --enable-dilithium --enable-cryptocb --enable-cryptocbutils --enable-pkcallbacks',
8686
'--enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
87+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey',
88+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
89+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
90+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=export',
91+
'--enable-cryptocb --enable-keygen CPPFLAGS="-DWOLF_CRYPTO_CB_EXPORT_KEY"',
92+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free,export CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
8793
'--disable-examples CPPFLAGS=-DWOLFSSL_NO_MALLOC',
8894
'CPPFLAGS=-DNO_WOLFSSL_CLIENT',
8995
'CPPFLAGS=-DNO_WOLFSSL_SERVER',

configure.ac

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9965,7 +9965,7 @@ fi
99659965
99669966
# Crypto Callbacks Utils (Copy/Free/etc)
99679967
AC_ARG_ENABLE([cryptocbutils],
9968-
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
9968+
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
99699969
[Enable crypto callback utilities (default: all)])],
99709970
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
99719971
[ ENABLED_CRYPTOCB_UTILS=no ]
@@ -9978,8 +9978,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99789978
99799979
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
99809980
# Enable all utilities
9981-
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
9982-
# Future utilities go here when added
9981+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
99839982
else
99849983
# Parse comma-separated list
99859984
OIFS="$IFS"
@@ -9992,9 +9991,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99929991
free)
99939992
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
99949993
;;
9995-
# Add future options here (e.g., malloc, realloc, etc)
9994+
setkey)
9995+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
9996+
;;
9997+
export)
9998+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
9999+
;;
999610000
*)
9997-
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
10001+
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
999810002
;;
999910003
esac
1000010004
done

tests/api.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28072,6 +28072,141 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
2807228072
}
2807328073
}
2807428074
#endif /* WOLF_CRYPTO_CB_FREE */
28075+
#ifdef WOLF_CRYPTO_CB_SETKEY
28076+
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
28077+
#ifdef DEBUG_WOLFSSL
28078+
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
28079+
info->setkey.type);
28080+
#endif
28081+
switch (info->setkey.type) {
28082+
#ifndef NO_AES
28083+
case WC_SETKEY_AES:
28084+
{
28085+
Aes* aes = (Aes*)info->setkey.obj;
28086+
aes->devId = INVALID_DEVID;
28087+
ret = wc_AesSetKey(aes,
28088+
(const byte*)info->setkey.key, info->setkey.keySz,
28089+
(const byte*)info->setkey.aux, info->setkey.flags);
28090+
aes->devId = thisDevId;
28091+
break;
28092+
}
28093+
#endif /* !NO_AES */
28094+
#ifndef NO_HMAC
28095+
case WC_SETKEY_HMAC:
28096+
{
28097+
Hmac* hmac = (Hmac*)info->setkey.obj;
28098+
hmac->devId = INVALID_DEVID;
28099+
ret = wc_HmacSetKey(hmac, hmac->macType,
28100+
(const byte*)info->setkey.key, info->setkey.keySz);
28101+
hmac->devId = thisDevId;
28102+
break;
28103+
}
28104+
#endif /* !NO_HMAC */
28105+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
28106+
case WC_SETKEY_RSA_PUB:
28107+
{
28108+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
28109+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
28110+
int derSz;
28111+
word32 idx = 0;
28112+
byte* der = NULL;
28113+
28114+
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
28115+
if (derSz <= 0) { ret = derSz; break; }
28116+
28117+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28118+
if (der == NULL) { ret = MEMORY_E; break; }
28119+
28120+
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
28121+
(word32)derSz, 1);
28122+
if (derSz <= 0) {
28123+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28124+
ret = derSz; break;
28125+
}
28126+
28127+
rsaObj->devId = INVALID_DEVID;
28128+
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
28129+
(word32)derSz);
28130+
rsaObj->devId = thisDevId;
28131+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28132+
break;
28133+
}
28134+
case WC_SETKEY_RSA_PRIV:
28135+
{
28136+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
28137+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
28138+
int derSz;
28139+
word32 idx = 0;
28140+
byte* der = NULL;
28141+
28142+
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
28143+
if (derSz <= 0) { ret = derSz; break; }
28144+
28145+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28146+
if (der == NULL) { ret = MEMORY_E; break; }
28147+
28148+
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
28149+
if (derSz <= 0) {
28150+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28151+
ret = derSz; break;
28152+
}
28153+
28154+
rsaObj->devId = INVALID_DEVID;
28155+
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
28156+
(word32)derSz);
28157+
rsaObj->devId = thisDevId;
28158+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28159+
break;
28160+
}
28161+
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
28162+
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
28163+
defined(HAVE_ECC_KEY_IMPORT)
28164+
case WC_SETKEY_ECC_PUB:
28165+
{
28166+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
28167+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
28168+
byte buf[ECC_BUFSIZE];
28169+
word32 bufSz = sizeof(buf);
28170+
int curveId;
28171+
28172+
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
28173+
if (ret != 0) break;
28174+
28175+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
28176+
eccObj->devId = INVALID_DEVID;
28177+
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
28178+
eccObj->devId = thisDevId;
28179+
break;
28180+
}
28181+
case WC_SETKEY_ECC_PRIV:
28182+
{
28183+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
28184+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
28185+
byte pubBuf[ECC_BUFSIZE];
28186+
byte privBuf[MAX_ECC_BYTES];
28187+
word32 pubSz = sizeof(pubBuf);
28188+
word32 privSz = sizeof(privBuf);
28189+
int curveId;
28190+
28191+
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
28192+
if (ret != 0) break;
28193+
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
28194+
if (ret != 0) break;
28195+
28196+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
28197+
eccObj->devId = INVALID_DEVID;
28198+
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
28199+
pubBuf, pubSz, eccObj, curveId);
28200+
eccObj->devId = thisDevId;
28201+
break;
28202+
}
28203+
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
28204+
default:
28205+
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
28206+
break;
28207+
}
28208+
}
28209+
#endif /* WOLF_CRYPTO_CB_SETKEY */
2807528210
(void)thisDevId;
2807628211
(void)keyFormat;
2807728212

wolfcrypt/src/aes.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4518,6 +4518,9 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
45184518
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
45194519
const byte* iv, int dir)
45204520
{
4521+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4522+
int cbRet;
4523+
#endif
45214524
if ((aes == NULL) || (userKey == NULL)) {
45224525
return BAD_FUNC_ARG;
45234526
}
@@ -4559,6 +4562,15 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
45594562
}
45604563
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
45614564
#endif
4565+
#ifdef WOLF_CRYPTO_CB_SETKEY
4566+
cbRet = wc_CryptoCb_SetKey(aes->devId,
4567+
WC_SETKEY_AES, aes, (void*)userKey, keylen,
4568+
(void*)iv,
4569+
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
4570+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4571+
return cbRet;
4572+
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
4573+
#endif /* WOLF_CRYPTO_CB_SETKEY */
45624574
/* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
45634575
if (keylen > sizeof(aes->devKey)) {
45644576
return BAD_FUNC_ARG;
@@ -4955,6 +4967,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
49554967
int checkKeyLen)
49564968
{
49574969
int ret;
4970+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4971+
int cbRet;
4972+
#endif
49584973
#ifdef WOLFSSL_IMX6_CAAM_BLOB
49594974
byte local[32];
49604975
word32 localSz = 32;
@@ -5005,6 +5020,15 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
50055020
}
50065021
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
50075022
#endif
5023+
#ifdef WOLF_CRYPTO_CB_SETKEY
5024+
cbRet = wc_CryptoCb_SetKey(aes->devId,
5025+
WC_SETKEY_AES, aes, (void*)userKey, keylen,
5026+
(void*)iv,
5027+
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
5028+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
5029+
return cbRet;
5030+
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
5031+
#endif /* WOLF_CRYPTO_CB_SETKEY */
50085032
/* Standard CryptoCB path - copy key to devKey */
50095033
if (keylen > sizeof(aes->devKey)) {
50105034
return BAD_FUNC_ARG;

wolfcrypt/src/asn.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8294,9 +8294,59 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
82948294
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
82958295
word32 inSz)
82968296
{
8297+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8298+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
8299+
int tmpErr = 0;
8300+
word32 tmpIdx;
8301+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
8302+
#endif
8303+
82978304
if (key == NULL) {
82988305
return BAD_FUNC_ARG;
82998306
}
8307+
8308+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8309+
#ifndef WOLF_CRYPTO_CB_FIND
8310+
if (key->devId != INVALID_DEVID)
8311+
#endif
8312+
{
8313+
tmpIdx = *inOutIdx;
8314+
8315+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
8316+
if (!WC_VAR_OK(tmpKey)) {
8317+
return MEMORY_E;
8318+
}
8319+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
8320+
8321+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
8322+
if (tmpErr != 0) {
8323+
WC_FREE_VAR(tmpKey, key->heap);
8324+
return tmpErr;
8325+
}
8326+
8327+
/* Decode into temp key (software-only, no callback recursion
8328+
* since tmpKey has INVALID_DEVID) */
8329+
tmpErr = _RsaPrivateKeyDecode(input, &tmpIdx, tmpKey, NULL, inSz);
8330+
if (tmpErr == 0) {
8331+
cbRet = wc_CryptoCb_SetKey(key->devId,
8332+
WC_SETKEY_RSA_PRIV, key, tmpKey,
8333+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
8334+
}
8335+
8336+
wc_FreeRsaKey(tmpKey);
8337+
WC_FREE_VAR(tmpKey, key->heap);
8338+
8339+
if (tmpErr != 0) {
8340+
return tmpErr;
8341+
}
8342+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
8343+
*inOutIdx = tmpIdx;
8344+
return cbRet;
8345+
}
8346+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
8347+
}
8348+
#endif
8349+
83008350
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
83018351
}
83028352

@@ -36106,9 +36156,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
3610636156
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
3610736157
word32 eSz, RsaKey* key)
3610836158
{
36159+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36160+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
36161+
int tmpErr = 0;
36162+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
36163+
#endif
36164+
3610936165
if (n == NULL || e == NULL || key == NULL)
3611036166
return BAD_FUNC_ARG;
3611136167

36168+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36169+
#ifndef WOLF_CRYPTO_CB_FIND
36170+
if (key->devId != INVALID_DEVID)
36171+
#endif
36172+
{
36173+
/* Allocate temp key for callback to export from */
36174+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
36175+
if (!WC_VAR_OK(tmpKey)) {
36176+
return MEMORY_E;
36177+
}
36178+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
36179+
36180+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
36181+
if (tmpErr != 0) {
36182+
WC_FREE_VAR(tmpKey, key->heap);
36183+
return tmpErr;
36184+
}
36185+
36186+
/* Recursive call imports n, e into temp via software */
36187+
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
36188+
if (tmpErr == 0) {
36189+
cbRet = wc_CryptoCb_SetKey(key->devId,
36190+
WC_SETKEY_RSA_PUB, key, tmpKey,
36191+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
36192+
}
36193+
36194+
wc_FreeRsaKey(tmpKey);
36195+
WC_FREE_VAR(tmpKey, key->heap);
36196+
36197+
if (tmpErr != 0) {
36198+
return tmpErr;
36199+
}
36200+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
36201+
return cbRet;
36202+
}
36203+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
36204+
}
36205+
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
36206+
3611236207
key->type = RSA_PUBLIC;
3611336208

3611436209
if (mp_init(&key->n) != MP_OKAY)

0 commit comments

Comments
 (0)