Skip to content

Commit 1295f4f

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 64c4203 commit 1295f4f

12 files changed

Lines changed: 1220 additions & 14 deletions

File tree

.github/workflows/os-check.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ jobs:
6161
CPPFLAGS=-DWOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC',
6262
'--enable-all --enable-certgencache',
6363
'--enable-all --enable-dilithium --enable-cryptocb --enable-cryptocbutils --enable-pkcallbacks',
64+
'--enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
65+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey',
66+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
67+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
68+
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=export',
69+
'--enable-cryptocb --enable-keygen CPPFLAGS="-DWOLF_CRYPTO_CB_EXPORT_KEY"',
70+
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free,export CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
6471
'CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH',
6572
'CPPFLAGS=''-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH''',
6673
'CPPFLAGS=''-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH''',

configure.ac

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9968,7 +9968,7 @@ fi
99689968
99699969
# Crypto Callbacks Utils (Copy/Free/etc)
99709970
AC_ARG_ENABLE([cryptocbutils],
9971-
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
9971+
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
99729972
[Enable crypto callback utilities (default: all)])],
99739973
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
99749974
[ ENABLED_CRYPTOCB_UTILS=no ]
@@ -9981,8 +9981,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99819981
99829982
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
99839983
# Enable all utilities
9984-
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
9985-
# Future utilities go here when added
9984+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
99869985
else
99879986
# Parse comma-separated list
99889987
OIFS="$IFS"
@@ -9995,9 +9994,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99959994
free)
99969995
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
99979996
;;
9998-
# Add future options here (e.g., malloc, realloc, etc)
9997+
setkey)
9998+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
9999+
;;
10000+
export)
10001+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
10002+
;;
999910003
*)
10000-
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
10004+
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
1000110005
;;
1000210006
esac
1000310007
done

tests/api.c

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

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

@@ -36498,9 +36548,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
3649836548
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
3649936549
word32 eSz, RsaKey* key)
3650036550
{
36551+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36552+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
36553+
int tmpErr = 0;
36554+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
36555+
#endif
36556+
3650136557
if (n == NULL || e == NULL || key == NULL)
3650236558
return BAD_FUNC_ARG;
3650336559

36560+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
36561+
#ifndef WOLF_CRYPTO_CB_FIND
36562+
if (key->devId != INVALID_DEVID)
36563+
#endif
36564+
{
36565+
/* Allocate temp key for callback to export from */
36566+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
36567+
if (!WC_VAR_OK(tmpKey)) {
36568+
return MEMORY_E;
36569+
}
36570+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
36571+
36572+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
36573+
if (tmpErr != 0) {
36574+
WC_FREE_VAR(tmpKey, key->heap);
36575+
return tmpErr;
36576+
}
36577+
36578+
/* Recursive call imports n, e into temp via software */
36579+
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
36580+
if (tmpErr == 0) {
36581+
cbRet = wc_CryptoCb_SetKey(key->devId,
36582+
WC_SETKEY_RSA_PUB, key, tmpKey,
36583+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
36584+
}
36585+
36586+
wc_FreeRsaKey(tmpKey);
36587+
WC_FREE_VAR(tmpKey, key->heap);
36588+
36589+
if (tmpErr != 0) {
36590+
return tmpErr;
36591+
}
36592+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
36593+
return cbRet;
36594+
}
36595+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
36596+
}
36597+
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
36598+
3650436599
key->type = RSA_PUBLIC;
3650536600

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

0 commit comments

Comments
 (0)