Skip to content

Commit 3284bc5

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 a6195c3 commit 3284bc5

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
@@ -78,6 +78,12 @@ jobs:
7878
'--disable-tls --enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY -DWOLF_CRYPTO_CB_FREE"',
7979
'--enable-all --enable-dilithium --enable-cryptocb --enable-cryptocbutils --enable-pkcallbacks',
8080
'--enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
81+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey',
82+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
83+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
84+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=export',
85+
'--enable-cryptocb --enable-keygen CPPFLAGS="-DWOLF_CRYPTO_CB_EXPORT_KEY"',
86+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free,export CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
8187
'--disable-examples CPPFLAGS=-DWOLFSSL_NO_MALLOC',
8288
'CPPFLAGS=-DNO_WOLFSSL_CLIENT',
8389
'CPPFLAGS=-DNO_WOLFSSL_SERVER',

configure.ac

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9834,7 +9834,7 @@ fi
98349834
98359835
# Crypto Callbacks Utils (Copy/Free/etc)
98369836
AC_ARG_ENABLE([cryptocbutils],
9837-
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
9837+
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
98389838
[Enable crypto callback utilities (default: all)])],
98399839
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
98409840
[ ENABLED_CRYPTOCB_UTILS=no ]
@@ -9847,8 +9847,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
98479847
98489848
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
98499849
# Enable all utilities
9850-
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
9851-
# Future utilities go here when added
9850+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
98529851
else
98539852
# Parse comma-separated list
98549853
OIFS="$IFS"
@@ -9861,9 +9860,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
98619860
free)
98629861
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
98639862
;;
9864-
# Add future options here (e.g., malloc, realloc, etc)
9863+
setkey)
9864+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
9865+
;;
9866+
export)
9867+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
9868+
;;
98659869
*)
9866-
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
9870+
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
98679871
;;
98689872
esac
98699873
done

tests/api.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27811,6 +27811,141 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
2781127811
}
2781227812
}
2781327813
#endif /* WOLF_CRYPTO_CB_FREE */
27814+
#ifdef WOLF_CRYPTO_CB_SETKEY
27815+
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
27816+
#ifdef DEBUG_WOLFSSL
27817+
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
27818+
info->setkey.type);
27819+
#endif
27820+
switch (info->setkey.type) {
27821+
#ifndef NO_AES
27822+
case WC_SETKEY_AES:
27823+
{
27824+
Aes* aes = (Aes*)info->setkey.obj;
27825+
aes->devId = INVALID_DEVID;
27826+
ret = wc_AesSetKey(aes,
27827+
(const byte*)info->setkey.key, info->setkey.keySz,
27828+
(const byte*)info->setkey.aux, info->setkey.flags);
27829+
aes->devId = thisDevId;
27830+
break;
27831+
}
27832+
#endif /* !NO_AES */
27833+
#ifndef NO_HMAC
27834+
case WC_SETKEY_HMAC:
27835+
{
27836+
Hmac* hmac = (Hmac*)info->setkey.obj;
27837+
hmac->devId = INVALID_DEVID;
27838+
ret = wc_HmacSetKey(hmac, hmac->macType,
27839+
(const byte*)info->setkey.key, info->setkey.keySz);
27840+
hmac->devId = thisDevId;
27841+
break;
27842+
}
27843+
#endif /* !NO_HMAC */
27844+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
27845+
case WC_SETKEY_RSA_PUB:
27846+
{
27847+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
27848+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
27849+
int derSz;
27850+
word32 idx = 0;
27851+
byte* der = NULL;
27852+
27853+
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
27854+
if (derSz <= 0) { ret = derSz; break; }
27855+
27856+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27857+
if (der == NULL) { ret = MEMORY_E; break; }
27858+
27859+
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
27860+
(word32)derSz, 1);
27861+
if (derSz <= 0) {
27862+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27863+
ret = derSz; break;
27864+
}
27865+
27866+
rsaObj->devId = INVALID_DEVID;
27867+
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
27868+
(word32)derSz);
27869+
rsaObj->devId = thisDevId;
27870+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27871+
break;
27872+
}
27873+
case WC_SETKEY_RSA_PRIV:
27874+
{
27875+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
27876+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
27877+
int derSz;
27878+
word32 idx = 0;
27879+
byte* der = NULL;
27880+
27881+
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
27882+
if (derSz <= 0) { ret = derSz; break; }
27883+
27884+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27885+
if (der == NULL) { ret = MEMORY_E; break; }
27886+
27887+
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
27888+
if (derSz <= 0) {
27889+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27890+
ret = derSz; break;
27891+
}
27892+
27893+
rsaObj->devId = INVALID_DEVID;
27894+
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
27895+
(word32)derSz);
27896+
rsaObj->devId = thisDevId;
27897+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27898+
break;
27899+
}
27900+
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
27901+
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
27902+
defined(HAVE_ECC_KEY_IMPORT)
27903+
case WC_SETKEY_ECC_PUB:
27904+
{
27905+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
27906+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
27907+
byte buf[ECC_BUFSIZE];
27908+
word32 bufSz = sizeof(buf);
27909+
int curveId;
27910+
27911+
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
27912+
if (ret != 0) break;
27913+
27914+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
27915+
eccObj->devId = INVALID_DEVID;
27916+
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
27917+
eccObj->devId = thisDevId;
27918+
break;
27919+
}
27920+
case WC_SETKEY_ECC_PRIV:
27921+
{
27922+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
27923+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
27924+
byte pubBuf[ECC_BUFSIZE];
27925+
byte privBuf[MAX_ECC_BYTES];
27926+
word32 pubSz = sizeof(pubBuf);
27927+
word32 privSz = sizeof(privBuf);
27928+
int curveId;
27929+
27930+
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
27931+
if (ret != 0) break;
27932+
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
27933+
if (ret != 0) break;
27934+
27935+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
27936+
eccObj->devId = INVALID_DEVID;
27937+
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
27938+
pubBuf, pubSz, eccObj, curveId);
27939+
eccObj->devId = thisDevId;
27940+
break;
27941+
}
27942+
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
27943+
default:
27944+
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
27945+
break;
27946+
}
27947+
}
27948+
#endif /* WOLF_CRYPTO_CB_SETKEY */
2781427949
(void)thisDevId;
2781527950
(void)keyFormat;
2781627951

wolfcrypt/src/aes.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4437,6 +4437,9 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
44374437
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
44384438
const byte* iv, int dir)
44394439
{
4440+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4441+
int cbRet;
4442+
#endif
44404443
if ((aes == NULL) || (userKey == NULL)) {
44414444
return BAD_FUNC_ARG;
44424445
}
@@ -4478,6 +4481,15 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
44784481
}
44794482
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
44804483
#endif
4484+
#ifdef WOLF_CRYPTO_CB_SETKEY
4485+
cbRet = wc_CryptoCb_SetKey(aes->devId,
4486+
WC_SETKEY_AES, aes, (void*)userKey, keylen,
4487+
(void*)iv,
4488+
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
4489+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4490+
return cbRet;
4491+
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
4492+
#endif /* WOLF_CRYPTO_CB_SETKEY */
44814493
/* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
44824494
if (keylen > sizeof(aes->devKey)) {
44834495
return BAD_FUNC_ARG;
@@ -4874,6 +4886,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
48744886
int checkKeyLen)
48754887
{
48764888
int ret;
4889+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
4890+
int cbRet;
4891+
#endif
48774892
#ifdef WOLFSSL_IMX6_CAAM_BLOB
48784893
byte local[32];
48794894
word32 localSz = 32;
@@ -4924,6 +4939,15 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
49244939
}
49254940
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
49264941
#endif
4942+
#ifdef WOLF_CRYPTO_CB_SETKEY
4943+
cbRet = wc_CryptoCb_SetKey(aes->devId,
4944+
WC_SETKEY_AES, aes, (void*)userKey, keylen,
4945+
(void*)iv,
4946+
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
4947+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
4948+
return cbRet;
4949+
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
4950+
#endif /* WOLF_CRYPTO_CB_SETKEY */
49274951
/* Standard CryptoCB path - copy key to devKey */
49284952
if (keylen > sizeof(aes->devKey)) {
49294953
return BAD_FUNC_ARG;

wolfcrypt/src/asn.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8248,9 +8248,59 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
82488248
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
82498249
word32 inSz)
82508250
{
8251+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8252+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
8253+
int tmpErr = 0;
8254+
word32 tmpIdx;
8255+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
8256+
#endif
8257+
82518258
if (key == NULL) {
82528259
return BAD_FUNC_ARG;
82538260
}
8261+
8262+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
8263+
#ifndef WOLF_CRYPTO_CB_FIND
8264+
if (key->devId != INVALID_DEVID)
8265+
#endif
8266+
{
8267+
tmpIdx = *inOutIdx;
8268+
8269+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
8270+
if (!WC_VAR_OK(tmpKey)) {
8271+
return MEMORY_E;
8272+
}
8273+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
8274+
8275+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
8276+
if (tmpErr != 0) {
8277+
WC_FREE_VAR(tmpKey, key->heap);
8278+
return tmpErr;
8279+
}
8280+
8281+
/* Decode into temp key (software-only, no callback recursion
8282+
* since tmpKey has INVALID_DEVID) */
8283+
tmpErr = _RsaPrivateKeyDecode(input, &tmpIdx, tmpKey, NULL, inSz);
8284+
if (tmpErr == 0) {
8285+
cbRet = wc_CryptoCb_SetKey(key->devId,
8286+
WC_SETKEY_RSA_PRIV, key, tmpKey,
8287+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
8288+
}
8289+
8290+
wc_FreeRsaKey(tmpKey);
8291+
WC_FREE_VAR(tmpKey, key->heap);
8292+
8293+
if (tmpErr != 0) {
8294+
return tmpErr;
8295+
}
8296+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
8297+
*inOutIdx = tmpIdx;
8298+
return cbRet;
8299+
}
8300+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
8301+
}
8302+
#endif
8303+
82548304
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
82558305
}
82568306

@@ -45063,9 +45113,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
4506345113
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
4506445114
word32 eSz, RsaKey* key)
4506545115
{
45116+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
45117+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
45118+
int tmpErr = 0;
45119+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
45120+
#endif
45121+
4506645122
if (n == NULL || e == NULL || key == NULL)
4506745123
return BAD_FUNC_ARG;
4506845124

45125+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
45126+
#ifndef WOLF_CRYPTO_CB_FIND
45127+
if (key->devId != INVALID_DEVID)
45128+
#endif
45129+
{
45130+
/* Allocate temp key for callback to export from */
45131+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
45132+
if (!WC_VAR_OK(tmpKey)) {
45133+
return MEMORY_E;
45134+
}
45135+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
45136+
45137+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
45138+
if (tmpErr != 0) {
45139+
WC_FREE_VAR(tmpKey, key->heap);
45140+
return tmpErr;
45141+
}
45142+
45143+
/* Recursive call imports n, e into temp via software */
45144+
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
45145+
if (tmpErr == 0) {
45146+
cbRet = wc_CryptoCb_SetKey(key->devId,
45147+
WC_SETKEY_RSA_PUB, key, tmpKey,
45148+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
45149+
}
45150+
45151+
wc_FreeRsaKey(tmpKey);
45152+
WC_FREE_VAR(tmpKey, key->heap);
45153+
45154+
if (tmpErr != 0) {
45155+
return tmpErr;
45156+
}
45157+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
45158+
return cbRet;
45159+
}
45160+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
45161+
}
45162+
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
45163+
4506945164
key->type = RSA_PUBLIC;
4507045165

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

0 commit comments

Comments
 (0)