Skip to content

Commit feca775

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 1cd8edb commit feca775

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
@@ -28293,6 +28293,141 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
2829328293
}
2829428294
}
2829528295
#endif /* WOLF_CRYPTO_CB_FREE */
28296+
#ifdef WOLF_CRYPTO_CB_SETKEY
28297+
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
28298+
#ifdef DEBUG_WOLFSSL
28299+
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
28300+
info->setkey.type);
28301+
#endif
28302+
switch (info->setkey.type) {
28303+
#ifndef NO_AES
28304+
case WC_SETKEY_AES:
28305+
{
28306+
Aes* aes = (Aes*)info->setkey.obj;
28307+
aes->devId = INVALID_DEVID;
28308+
ret = wc_AesSetKey(aes,
28309+
(const byte*)info->setkey.key, info->setkey.keySz,
28310+
(const byte*)info->setkey.aux, info->setkey.flags);
28311+
aes->devId = thisDevId;
28312+
break;
28313+
}
28314+
#endif /* !NO_AES */
28315+
#ifndef NO_HMAC
28316+
case WC_SETKEY_HMAC:
28317+
{
28318+
Hmac* hmac = (Hmac*)info->setkey.obj;
28319+
hmac->devId = INVALID_DEVID;
28320+
ret = wc_HmacSetKey(hmac, hmac->macType,
28321+
(const byte*)info->setkey.key, info->setkey.keySz);
28322+
hmac->devId = thisDevId;
28323+
break;
28324+
}
28325+
#endif /* !NO_HMAC */
28326+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
28327+
case WC_SETKEY_RSA_PUB:
28328+
{
28329+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
28330+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
28331+
int derSz;
28332+
word32 idx = 0;
28333+
byte* der = NULL;
28334+
28335+
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
28336+
if (derSz <= 0) { ret = derSz; break; }
28337+
28338+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28339+
if (der == NULL) { ret = MEMORY_E; break; }
28340+
28341+
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
28342+
(word32)derSz, 1);
28343+
if (derSz <= 0) {
28344+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28345+
ret = derSz; break;
28346+
}
28347+
28348+
rsaObj->devId = INVALID_DEVID;
28349+
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
28350+
(word32)derSz);
28351+
rsaObj->devId = thisDevId;
28352+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28353+
break;
28354+
}
28355+
case WC_SETKEY_RSA_PRIV:
28356+
{
28357+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
28358+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
28359+
int derSz;
28360+
word32 idx = 0;
28361+
byte* der = NULL;
28362+
28363+
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
28364+
if (derSz <= 0) { ret = derSz; break; }
28365+
28366+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28367+
if (der == NULL) { ret = MEMORY_E; break; }
28368+
28369+
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
28370+
if (derSz <= 0) {
28371+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28372+
ret = derSz; break;
28373+
}
28374+
28375+
rsaObj->devId = INVALID_DEVID;
28376+
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
28377+
(word32)derSz);
28378+
rsaObj->devId = thisDevId;
28379+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
28380+
break;
28381+
}
28382+
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
28383+
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
28384+
defined(HAVE_ECC_KEY_IMPORT)
28385+
case WC_SETKEY_ECC_PUB:
28386+
{
28387+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
28388+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
28389+
byte buf[ECC_BUFSIZE];
28390+
word32 bufSz = sizeof(buf);
28391+
int curveId;
28392+
28393+
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
28394+
if (ret != 0) break;
28395+
28396+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
28397+
eccObj->devId = INVALID_DEVID;
28398+
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
28399+
eccObj->devId = thisDevId;
28400+
break;
28401+
}
28402+
case WC_SETKEY_ECC_PRIV:
28403+
{
28404+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
28405+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
28406+
byte pubBuf[ECC_BUFSIZE];
28407+
byte privBuf[MAX_ECC_BYTES];
28408+
word32 pubSz = sizeof(pubBuf);
28409+
word32 privSz = sizeof(privBuf);
28410+
int curveId;
28411+
28412+
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
28413+
if (ret != 0) break;
28414+
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
28415+
if (ret != 0) break;
28416+
28417+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
28418+
eccObj->devId = INVALID_DEVID;
28419+
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
28420+
pubBuf, pubSz, eccObj, curveId);
28421+
eccObj->devId = thisDevId;
28422+
break;
28423+
}
28424+
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
28425+
default:
28426+
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
28427+
break;
28428+
}
28429+
}
28430+
#endif /* WOLF_CRYPTO_CB_SETKEY */
2829628431
(void)thisDevId;
2829728432
(void)keyFormat;
2829828433

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
@@ -8297,9 +8297,59 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
82978297
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
82988298
word32 inSz)
82998299
{
8300+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8301+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
8302+
int tmpErr = 0;
8303+
word32 tmpIdx;
8304+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
8305+
#endif
8306+
83008307
if (key == NULL) {
83018308
return BAD_FUNC_ARG;
83028309
}
8310+
8311+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8312+
#ifndef WOLF_CRYPTO_CB_FIND
8313+
if (key->devId != INVALID_DEVID)
8314+
#endif
8315+
{
8316+
tmpIdx = *inOutIdx;
8317+
8318+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
8319+
if (!WC_VAR_OK(tmpKey)) {
8320+
return MEMORY_E;
8321+
}
8322+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
8323+
8324+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
8325+
if (tmpErr != 0) {
8326+
WC_FREE_VAR(tmpKey, key->heap);
8327+
return tmpErr;
8328+
}
8329+
8330+
/* Decode into temp key (software-only, no callback recursion
8331+
* since tmpKey has INVALID_DEVID) */
8332+
tmpErr = _RsaPrivateKeyDecode(input, &tmpIdx, tmpKey, NULL, inSz);
8333+
if (tmpErr == 0) {
8334+
cbRet = wc_CryptoCb_SetKey(key->devId,
8335+
WC_SETKEY_RSA_PRIV, key, tmpKey,
8336+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
8337+
}
8338+
8339+
wc_FreeRsaKey(tmpKey);
8340+
WC_FREE_VAR(tmpKey, key->heap);
8341+
8342+
if (tmpErr != 0) {
8343+
return tmpErr;
8344+
}
8345+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
8346+
*inOutIdx = tmpIdx;
8347+
return cbRet;
8348+
}
8349+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
8350+
}
8351+
#endif
8352+
83038353
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
83048354
}
83058355

@@ -36373,9 +36423,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
3637336423
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
3637436424
word32 eSz, RsaKey* key)
3637536425
{
36426+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36427+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
36428+
int tmpErr = 0;
36429+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
36430+
#endif
36431+
3637636432
if (n == NULL || e == NULL || key == NULL)
3637736433
return BAD_FUNC_ARG;
3637836434

36435+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36436+
#ifndef WOLF_CRYPTO_CB_FIND
36437+
if (key->devId != INVALID_DEVID)
36438+
#endif
36439+
{
36440+
/* Allocate temp key for callback to export from */
36441+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
36442+
if (!WC_VAR_OK(tmpKey)) {
36443+
return MEMORY_E;
36444+
}
36445+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
36446+
36447+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
36448+
if (tmpErr != 0) {
36449+
WC_FREE_VAR(tmpKey, key->heap);
36450+
return tmpErr;
36451+
}
36452+
36453+
/* Recursive call imports n, e into temp via software */
36454+
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
36455+
if (tmpErr == 0) {
36456+
cbRet = wc_CryptoCb_SetKey(key->devId,
36457+
WC_SETKEY_RSA_PUB, key, tmpKey,
36458+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
36459+
}
36460+
36461+
wc_FreeRsaKey(tmpKey);
36462+
WC_FREE_VAR(tmpKey, key->heap);
36463+
36464+
if (tmpErr != 0) {
36465+
return tmpErr;
36466+
}
36467+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
36468+
return cbRet;
36469+
}
36470+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
36471+
}
36472+
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
36473+
3637936474
key->type = RSA_PUBLIC;
3638036475

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

0 commit comments

Comments
 (0)