Skip to content

Commit 6841231

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 8b388ba commit 6841231

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
@@ -9946,7 +9946,7 @@ fi
99469946
99479947
# Crypto Callbacks Utils (Copy/Free/etc)
99489948
AC_ARG_ENABLE([cryptocbutils],
9949-
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
9949+
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
99509950
[Enable crypto callback utilities (default: all)])],
99519951
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
99529952
[ ENABLED_CRYPTOCB_UTILS=no ]
@@ -9959,8 +9959,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99599959
99609960
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
99619961
# Enable all utilities
9962-
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
9963-
# Future utilities go here when added
9962+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
99649963
else
99659964
# Parse comma-separated list
99669965
OIFS="$IFS"
@@ -9973,9 +9972,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
99739972
free)
99749973
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
99759974
;;
9976-
# Add future options here (e.g., malloc, realloc, etc)
9975+
setkey)
9976+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
9977+
;;
9978+
export)
9979+
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
9980+
;;
99779981
*)
9978-
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
9982+
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
99799983
;;
99809984
esac
99819985
done

tests/api.c

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27848,6 +27848,141 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
2784827848
}
2784927849
}
2785027850
#endif /* WOLF_CRYPTO_CB_FREE */
27851+
#ifdef WOLF_CRYPTO_CB_SETKEY
27852+
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
27853+
#ifdef DEBUG_WOLFSSL
27854+
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
27855+
info->setkey.type);
27856+
#endif
27857+
switch (info->setkey.type) {
27858+
#ifndef NO_AES
27859+
case WC_SETKEY_AES:
27860+
{
27861+
Aes* aes = (Aes*)info->setkey.obj;
27862+
aes->devId = INVALID_DEVID;
27863+
ret = wc_AesSetKey(aes,
27864+
(const byte*)info->setkey.key, info->setkey.keySz,
27865+
(const byte*)info->setkey.aux, info->setkey.flags);
27866+
aes->devId = thisDevId;
27867+
break;
27868+
}
27869+
#endif /* !NO_AES */
27870+
#ifndef NO_HMAC
27871+
case WC_SETKEY_HMAC:
27872+
{
27873+
Hmac* hmac = (Hmac*)info->setkey.obj;
27874+
hmac->devId = INVALID_DEVID;
27875+
ret = wc_HmacSetKey(hmac, hmac->macType,
27876+
(const byte*)info->setkey.key, info->setkey.keySz);
27877+
hmac->devId = thisDevId;
27878+
break;
27879+
}
27880+
#endif /* !NO_HMAC */
27881+
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
27882+
case WC_SETKEY_RSA_PUB:
27883+
{
27884+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
27885+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
27886+
int derSz;
27887+
word32 idx = 0;
27888+
byte* der = NULL;
27889+
27890+
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
27891+
if (derSz <= 0) { ret = derSz; break; }
27892+
27893+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27894+
if (der == NULL) { ret = MEMORY_E; break; }
27895+
27896+
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
27897+
(word32)derSz, 1);
27898+
if (derSz <= 0) {
27899+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27900+
ret = derSz; break;
27901+
}
27902+
27903+
rsaObj->devId = INVALID_DEVID;
27904+
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
27905+
(word32)derSz);
27906+
rsaObj->devId = thisDevId;
27907+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27908+
break;
27909+
}
27910+
case WC_SETKEY_RSA_PRIV:
27911+
{
27912+
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
27913+
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
27914+
int derSz;
27915+
word32 idx = 0;
27916+
byte* der = NULL;
27917+
27918+
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
27919+
if (derSz <= 0) { ret = derSz; break; }
27920+
27921+
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27922+
if (der == NULL) { ret = MEMORY_E; break; }
27923+
27924+
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
27925+
if (derSz <= 0) {
27926+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27927+
ret = derSz; break;
27928+
}
27929+
27930+
rsaObj->devId = INVALID_DEVID;
27931+
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
27932+
(word32)derSz);
27933+
rsaObj->devId = thisDevId;
27934+
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
27935+
break;
27936+
}
27937+
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
27938+
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
27939+
defined(HAVE_ECC_KEY_IMPORT)
27940+
case WC_SETKEY_ECC_PUB:
27941+
{
27942+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
27943+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
27944+
byte buf[ECC_BUFSIZE];
27945+
word32 bufSz = sizeof(buf);
27946+
int curveId;
27947+
27948+
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
27949+
if (ret != 0) break;
27950+
27951+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
27952+
eccObj->devId = INVALID_DEVID;
27953+
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
27954+
eccObj->devId = thisDevId;
27955+
break;
27956+
}
27957+
case WC_SETKEY_ECC_PRIV:
27958+
{
27959+
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
27960+
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
27961+
byte pubBuf[ECC_BUFSIZE];
27962+
byte privBuf[MAX_ECC_BYTES];
27963+
word32 pubSz = sizeof(pubBuf);
27964+
word32 privSz = sizeof(privBuf);
27965+
int curveId;
27966+
27967+
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
27968+
if (ret != 0) break;
27969+
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
27970+
if (ret != 0) break;
27971+
27972+
curveId = wc_ecc_get_curve_id(eccTmp->idx);
27973+
eccObj->devId = INVALID_DEVID;
27974+
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
27975+
pubBuf, pubSz, eccObj, curveId);
27976+
eccObj->devId = thisDevId;
27977+
break;
27978+
}
27979+
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
27980+
default:
27981+
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
27982+
break;
27983+
}
27984+
}
27985+
#endif /* WOLF_CRYPTO_CB_SETKEY */
2785127986
(void)thisDevId;
2785227987
(void)keyFormat;
2785327988

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

@@ -45087,9 +45137,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
4508745137
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
4508845138
word32 eSz, RsaKey* key)
4508945139
{
45140+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
45141+
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
45142+
int tmpErr = 0;
45143+
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
45144+
#endif
45145+
4509045146
if (n == NULL || e == NULL || key == NULL)
4509145147
return BAD_FUNC_ARG;
4509245148

45149+
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
45150+
#ifndef WOLF_CRYPTO_CB_FIND
45151+
if (key->devId != INVALID_DEVID)
45152+
#endif
45153+
{
45154+
/* Allocate temp key for callback to export from */
45155+
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
45156+
if (!WC_VAR_OK(tmpKey)) {
45157+
return MEMORY_E;
45158+
}
45159+
XMEMSET(tmpKey, 0, sizeof(RsaKey));
45160+
45161+
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
45162+
if (tmpErr != 0) {
45163+
WC_FREE_VAR(tmpKey, key->heap);
45164+
return tmpErr;
45165+
}
45166+
45167+
/* Recursive call imports n, e into temp via software */
45168+
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
45169+
if (tmpErr == 0) {
45170+
cbRet = wc_CryptoCb_SetKey(key->devId,
45171+
WC_SETKEY_RSA_PUB, key, tmpKey,
45172+
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
45173+
}
45174+
45175+
wc_FreeRsaKey(tmpKey);
45176+
WC_FREE_VAR(tmpKey, key->heap);
45177+
45178+
if (tmpErr != 0) {
45179+
return tmpErr;
45180+
}
45181+
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
45182+
return cbRet;
45183+
}
45184+
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
45185+
}
45186+
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
45187+
4509345188
key->type = RSA_PUBLIC;
4509445189

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

0 commit comments

Comments
 (0)