mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 19:20:49 +02:00
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.
This commit is contained in:
committed by
Zackery Backman
parent
64c4203d96
commit
1295f4fe0e
@@ -61,6 +61,13 @@ jobs:
|
||||
CPPFLAGS=-DWOLFSSL_TLS13_IGNORE_PT_ALERT_ON_ENC',
|
||||
'--enable-all --enable-certgencache',
|
||||
'--enable-all --enable-dilithium --enable-cryptocb --enable-cryptocbutils --enable-pkcallbacks',
|
||||
'--enable-cryptocb --enable-aesgcm CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
|
||||
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=setkey',
|
||||
'--enable-cryptocb --enable-keygen --enable-cryptocbutils CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
|
||||
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
|
||||
'--enable-cryptocb --enable-keygen --enable-cryptocbutils=export',
|
||||
'--enable-cryptocb --enable-keygen CPPFLAGS="-DWOLF_CRYPTO_CB_EXPORT_KEY"',
|
||||
'--enable-cryptocb --enable-keygen --enable-aesgcm --enable-cryptocbutils=setkey,free,export CPPFLAGS="-DWOLF_CRYPTO_CB_AES_SETKEY"',
|
||||
'CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH',
|
||||
'CPPFLAGS=''-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH''',
|
||||
'CPPFLAGS=''-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH''',
|
||||
|
||||
+9
-5
@@ -9968,7 +9968,7 @@ fi
|
||||
|
||||
# Crypto Callbacks Utils (Copy/Free/etc)
|
||||
AC_ARG_ENABLE([cryptocbutils],
|
||||
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,...@:>@],
|
||||
[AS_HELP_STRING([--enable-cryptocbutils@<:@=copy,free,setkey,export,...@:>@],
|
||||
[Enable crypto callback utilities (default: all)])],
|
||||
[ ENABLED_CRYPTOCB_UTILS=$enableval ],
|
||||
[ ENABLED_CRYPTOCB_UTILS=no ]
|
||||
@@ -9981,8 +9981,7 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
|
||||
|
||||
if test "$ENABLED_CRYPTOCB_UTILS" = "yes"; then
|
||||
# Enable all utilities
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE"
|
||||
# Future utilities go here when added
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_COPY -DWOLF_CRYPTO_CB_FREE -DWOLF_CRYPTO_CB_SETKEY -DWOLF_CRYPTO_CB_EXPORT_KEY"
|
||||
else
|
||||
# Parse comma-separated list
|
||||
OIFS="$IFS"
|
||||
@@ -9995,9 +9994,14 @@ if test "$ENABLED_CRYPTOCB_UTILS" != "no"; then
|
||||
free)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_FREE"
|
||||
;;
|
||||
# Add future options here (e.g., malloc, realloc, etc)
|
||||
setkey)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_SETKEY"
|
||||
;;
|
||||
export)
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLF_CRYPTO_CB_EXPORT_KEY"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free])
|
||||
AC_MSG_ERROR([Unknown cryptocbutils option: $util. Valid options: copy, free, setkey, export])
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
+135
@@ -28306,6 +28306,141 @@ static int test_CryptoCb_Func(int thisDevId, wc_CryptoInfo* info, void* ctx)
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
|
||||
#ifdef DEBUG_WOLFSSL
|
||||
fprintf(stderr, "test_CryptoCb_Func: SetKey Type=%d\n",
|
||||
info->setkey.type);
|
||||
#endif
|
||||
switch (info->setkey.type) {
|
||||
#ifndef NO_AES
|
||||
case WC_SETKEY_AES:
|
||||
{
|
||||
Aes* aes = (Aes*)info->setkey.obj;
|
||||
aes->devId = INVALID_DEVID;
|
||||
ret = wc_AesSetKey(aes,
|
||||
(const byte*)info->setkey.key, info->setkey.keySz,
|
||||
(const byte*)info->setkey.aux, info->setkey.flags);
|
||||
aes->devId = thisDevId;
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_AES */
|
||||
#ifndef NO_HMAC
|
||||
case WC_SETKEY_HMAC:
|
||||
{
|
||||
Hmac* hmac = (Hmac*)info->setkey.obj;
|
||||
hmac->devId = INVALID_DEVID;
|
||||
ret = wc_HmacSetKey(hmac, hmac->macType,
|
||||
(const byte*)info->setkey.key, info->setkey.keySz);
|
||||
hmac->devId = thisDevId;
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_HMAC */
|
||||
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
|
||||
case WC_SETKEY_RSA_PUB:
|
||||
{
|
||||
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
|
||||
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
|
||||
int derSz;
|
||||
word32 idx = 0;
|
||||
byte* der = NULL;
|
||||
|
||||
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
|
||||
if (derSz <= 0) { ret = derSz; break; }
|
||||
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) { ret = MEMORY_E; break; }
|
||||
|
||||
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
|
||||
(word32)derSz, 1);
|
||||
if (derSz <= 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ret = derSz; break;
|
||||
}
|
||||
|
||||
rsaObj->devId = INVALID_DEVID;
|
||||
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
|
||||
(word32)derSz);
|
||||
rsaObj->devId = thisDevId;
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
break;
|
||||
}
|
||||
case WC_SETKEY_RSA_PRIV:
|
||||
{
|
||||
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
|
||||
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
|
||||
int derSz;
|
||||
word32 idx = 0;
|
||||
byte* der = NULL;
|
||||
|
||||
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
|
||||
if (derSz <= 0) { ret = derSz; break; }
|
||||
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) { ret = MEMORY_E; break; }
|
||||
|
||||
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
|
||||
if (derSz <= 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ret = derSz; break;
|
||||
}
|
||||
|
||||
rsaObj->devId = INVALID_DEVID;
|
||||
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
|
||||
(word32)derSz);
|
||||
rsaObj->devId = thisDevId;
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
|
||||
defined(HAVE_ECC_KEY_IMPORT)
|
||||
case WC_SETKEY_ECC_PUB:
|
||||
{
|
||||
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
|
||||
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
|
||||
byte buf[ECC_BUFSIZE];
|
||||
word32 bufSz = sizeof(buf);
|
||||
int curveId;
|
||||
|
||||
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
|
||||
if (ret != 0) break;
|
||||
|
||||
curveId = wc_ecc_get_curve_id(eccTmp->idx);
|
||||
eccObj->devId = INVALID_DEVID;
|
||||
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj, curveId, 0);
|
||||
eccObj->devId = thisDevId;
|
||||
break;
|
||||
}
|
||||
case WC_SETKEY_ECC_PRIV:
|
||||
{
|
||||
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
|
||||
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
|
||||
byte pubBuf[ECC_BUFSIZE];
|
||||
byte privBuf[MAX_ECC_BYTES];
|
||||
word32 pubSz = sizeof(pubBuf);
|
||||
word32 privSz = sizeof(privBuf);
|
||||
int curveId;
|
||||
|
||||
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
|
||||
if (ret != 0) break;
|
||||
ret = wc_ecc_export_private_only(eccTmp, privBuf, &privSz);
|
||||
if (ret != 0) break;
|
||||
|
||||
curveId = wc_ecc_get_curve_id(eccTmp->idx);
|
||||
eccObj->devId = INVALID_DEVID;
|
||||
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
|
||||
pubBuf, pubSz, eccObj, curveId);
|
||||
eccObj->devId = thisDevId;
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
|
||||
default:
|
||||
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
(void)thisDevId;
|
||||
(void)keyFormat;
|
||||
|
||||
|
||||
@@ -4518,6 +4518,9 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
|
||||
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
|
||||
const byte* iv, int dir)
|
||||
{
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet;
|
||||
#endif
|
||||
if ((aes == NULL) || (userKey == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
@@ -4559,6 +4562,15 @@ WC_ALL_ARGS_NOT_NULL static WARN_UNUSED_RESULT int wc_AesDecrypt(
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
|
||||
#endif
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
cbRet = wc_CryptoCb_SetKey(aes->devId,
|
||||
WC_SETKEY_AES, aes, (void*)userKey, keylen,
|
||||
(void*)iv,
|
||||
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return cbRet;
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
/* Standard CryptoCB path - copy key to devKey for encrypt/decrypt offload */
|
||||
if (keylen > sizeof(aes->devKey)) {
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -4955,6 +4967,9 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
|
||||
int checkKeyLen)
|
||||
{
|
||||
int ret;
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet;
|
||||
#endif
|
||||
#ifdef WOLFSSL_IMX6_CAAM_BLOB
|
||||
byte local[32];
|
||||
word32 localSz = 32;
|
||||
@@ -5005,6 +5020,15 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: continue to software setup */
|
||||
#endif
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
cbRet = wc_CryptoCb_SetKey(aes->devId,
|
||||
WC_SETKEY_AES, aes, (void*)userKey, keylen,
|
||||
(void*)iv,
|
||||
(iv != NULL) ? WC_AES_BLOCK_SIZE : 0, dir);
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return cbRet;
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software setup */
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
/* Standard CryptoCB path - copy key to devKey */
|
||||
if (keylen > sizeof(aes->devKey)) {
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
@@ -8297,9 +8297,59 @@ static int _RsaPrivateKeyDecode(const byte* input, word32* inOutIdx,
|
||||
int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key,
|
||||
word32 inSz)
|
||||
{
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
int tmpErr = 0;
|
||||
word32 tmpIdx;
|
||||
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
tmpIdx = *inOutIdx;
|
||||
|
||||
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(RsaKey));
|
||||
|
||||
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (tmpErr != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return tmpErr;
|
||||
}
|
||||
|
||||
/* Decode into temp key (software-only, no callback recursion
|
||||
* since tmpKey has INVALID_DEVID) */
|
||||
tmpErr = _RsaPrivateKeyDecode(input, &tmpIdx, tmpKey, NULL, inSz);
|
||||
if (tmpErr == 0) {
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
WC_SETKEY_RSA_PRIV, key, tmpKey,
|
||||
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
wc_FreeRsaKey(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (tmpErr != 0) {
|
||||
return tmpErr;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
*inOutIdx = tmpIdx;
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
}
|
||||
#endif
|
||||
|
||||
return _RsaPrivateKeyDecode(input, inOutIdx, key, NULL, inSz);
|
||||
}
|
||||
|
||||
@@ -36498,9 +36548,54 @@ int wc_Asn1_PrintAll(Asn1* asn1, Asn1PrintOptions* opts, unsigned char* data,
|
||||
int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e,
|
||||
word32 eSz, RsaKey* key)
|
||||
{
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
int tmpErr = 0;
|
||||
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (n == NULL || e == NULL || key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
/* Allocate temp key for callback to export from */
|
||||
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(RsaKey));
|
||||
|
||||
tmpErr = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (tmpErr != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return tmpErr;
|
||||
}
|
||||
|
||||
/* Recursive call imports n, e into temp via software */
|
||||
tmpErr = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, tmpKey);
|
||||
if (tmpErr == 0) {
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
WC_SETKEY_RSA_PUB, key, tmpKey,
|
||||
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
wc_FreeRsaKey(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (tmpErr != 0) {
|
||||
return tmpErr;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
key->type = RSA_PUBLIC;
|
||||
|
||||
if (mp_init(&key->n) != MP_OKAY)
|
||||
|
||||
@@ -105,9 +105,29 @@ static const char* GetAlgoTypeStr(int algo)
|
||||
#ifdef WOLF_CRYPTO_CB_FREE
|
||||
case WC_ALGO_TYPE_FREE: return "Free";
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
case WC_ALGO_TYPE_SETKEY: return "SetKey";
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
case WC_ALGO_TYPE_EXPORT_KEY: return "ExportKey";
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
static const char* GetSetKeyTypeStr(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case WC_SETKEY_HMAC: return "HMAC";
|
||||
case WC_SETKEY_RSA_PUB: return "RSA-Pub";
|
||||
case WC_SETKEY_RSA_PRIV: return "RSA-Priv";
|
||||
case WC_SETKEY_ECC_PUB: return "ECC-Pub";
|
||||
case WC_SETKEY_ECC_PRIV: return "ECC-Priv";
|
||||
case WC_SETKEY_AES: return "AES";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
static const char* GetPkTypeStr(int pk)
|
||||
{
|
||||
switch (pk) {
|
||||
@@ -121,6 +141,8 @@ static const char* GetPkTypeStr(int pk)
|
||||
case WC_PK_TYPE_CURVE25519: return "CURVE25519";
|
||||
case WC_PK_TYPE_RSA_KEYGEN: return "RSA KeyGen";
|
||||
case WC_PK_TYPE_EC_KEYGEN: return "ECC KeyGen";
|
||||
case WC_PK_TYPE_EC_GET_SIZE: return "ECC GetSize";
|
||||
case WC_PK_TYPE_EC_GET_SIG_SIZE: return "ECC GetSigSize";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -291,6 +313,19 @@ void wc_CryptoCb_InfoString(wc_CryptoInfo* info)
|
||||
GetAlgoTypeStr(info->free.algo), info->free.type);
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
|
||||
printf("Crypto CB: %s %s KeySz=%u\n",
|
||||
GetAlgoTypeStr(info->algo_type),
|
||||
GetSetKeyTypeStr(info->setkey.type), info->setkey.keySz);
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) {
|
||||
printf("Crypto CB: %s Type=%d\n",
|
||||
GetAlgoTypeStr(info->algo_type), info->export_key.type);
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
#if (defined(HAVE_HKDF) && !defined(NO_HMAC)) || \
|
||||
defined(HAVE_CMAC_KDF)
|
||||
else if (info->algo_type == WC_ALGO_TYPE_KDF) {
|
||||
@@ -781,6 +816,54 @@ int wc_CryptoCb_EccCheckPrivKey(ecc_key* key, const byte* pubKey,
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int wc_CryptoCb_EccGetSize(const ecc_key* key, int* keySize)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
CryptoCb* dev;
|
||||
|
||||
if (key == NULL)
|
||||
return ret;
|
||||
|
||||
/* locate registered callback */
|
||||
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
|
||||
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
|
||||
cryptoInfo.pk.type = WC_PK_TYPE_EC_GET_SIZE;
|
||||
cryptoInfo.pk.ecc_get_size.key = key;
|
||||
cryptoInfo.pk.ecc_get_size.keySize = keySize;
|
||||
|
||||
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
|
||||
}
|
||||
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
|
||||
int wc_CryptoCb_EccGetSigSize(const ecc_key* key, int* sigSize)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
CryptoCb* dev;
|
||||
|
||||
if (key == NULL)
|
||||
return ret;
|
||||
|
||||
/* locate registered callback */
|
||||
dev = wc_CryptoCb_FindDevice(key->devId, WC_ALGO_TYPE_PK);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
|
||||
cryptoInfo.algo_type = WC_ALGO_TYPE_PK;
|
||||
cryptoInfo.pk.type = WC_PK_TYPE_EC_GET_SIG_SIZE;
|
||||
cryptoInfo.pk.ecc_get_sig_size.key = key;
|
||||
cryptoInfo.pk.ecc_get_sig_size.sigSize = sigSize;
|
||||
|
||||
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
|
||||
}
|
||||
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#ifdef HAVE_CURVE25519
|
||||
@@ -2167,6 +2250,77 @@ int wc_CryptoCb_Free(int devId, int algo, int type, int subType, void* obj)
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
/* Generic SetKey callback for importing keys into hardware.
|
||||
* devId: Device ID for the registered callback
|
||||
* type: enum wc_SetKeyType (AES, HMAC, RSA_PUB, RSA_PRIV, ECC_PUB, ECC_PRIV)
|
||||
* obj: Context struct being operated on (Aes*, Hmac*, RsaKey*, ecc_key*)
|
||||
* key: Key material: raw bytes (AES/HMAC) or temp struct to export from (RSA/ECC)
|
||||
* keySz: Key size in bytes (0 when key is a struct pointer)
|
||||
* aux: Auxiliary data (IV, etc.) or NULL
|
||||
* auxSz: Aux data size, 0 if unused
|
||||
* flags: AES: direction (AES_ENCRYPTION/DECRYPTION). Others: 0
|
||||
* Returns: 0 on success, CRYPTOCB_UNAVAILABLE if not handled, negative on error
|
||||
*/
|
||||
int wc_CryptoCb_SetKey(int devId, int type, void* obj,
|
||||
void* key, word32 keySz,
|
||||
void* aux, word32 auxSz,
|
||||
int flags)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
CryptoCb* dev;
|
||||
|
||||
/* Find registered callback device */
|
||||
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_SETKEY);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
|
||||
cryptoInfo.algo_type = WC_ALGO_TYPE_SETKEY;
|
||||
cryptoInfo.setkey.type = type;
|
||||
cryptoInfo.setkey.obj = obj;
|
||||
cryptoInfo.setkey.key = key;
|
||||
cryptoInfo.setkey.keySz = keySz;
|
||||
cryptoInfo.setkey.aux = aux;
|
||||
cryptoInfo.setkey.auxSz = auxSz;
|
||||
cryptoInfo.setkey.flags = flags;
|
||||
|
||||
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
|
||||
}
|
||||
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
/* Generic ExportKey callback for exporting key material from hardware.
|
||||
* devId: Device ID for the registered callback
|
||||
* type: enum wc_PkType (WC_PK_TYPE_RSA, WC_PK_TYPE_ECDSA, etc.)
|
||||
* obj: Hardware key object (has devCtx, id[], etc.)
|
||||
* out: Software key object to fill (same type as obj, caller-allocated)
|
||||
* The callback exports from hardware into the software key. The caller then
|
||||
* uses normal software export functions on 'out' and frees it.
|
||||
* Returns: 0 on success, CRYPTOCB_UNAVAILABLE if not handled, negative on error
|
||||
*/
|
||||
int wc_CryptoCb_ExportKey(int devId, int type, void* obj, void* out)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
CryptoCb* dev;
|
||||
|
||||
dev = wc_CryptoCb_FindDevice(devId, WC_ALGO_TYPE_EXPORT_KEY);
|
||||
if (dev && dev->cb) {
|
||||
wc_CryptoInfo cryptoInfo;
|
||||
XMEMSET(&cryptoInfo, 0, sizeof(cryptoInfo));
|
||||
cryptoInfo.algo_type = WC_ALGO_TYPE_EXPORT_KEY;
|
||||
cryptoInfo.export_key.type = type;
|
||||
cryptoInfo.export_key.obj = obj;
|
||||
cryptoInfo.export_key.out = out;
|
||||
|
||||
ret = dev->cb(dev->devId, &cryptoInfo, dev->ctx);
|
||||
}
|
||||
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
|
||||
#if defined(HAVE_CMAC_KDF)
|
||||
/* Crypto callback for NIST SP 800 56C two-step CMAC KDF. See software
|
||||
|
||||
+219
-3
@@ -10684,6 +10684,11 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
|
||||
const CRYS_ECPKI_Domain_t* pDomain;
|
||||
CRYS_ECPKI_BUILD_TempData_t tempBuff;
|
||||
#endif
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (in == NULL || key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
@@ -10692,6 +10697,58 @@ int wc_ecc_import_x963_ex2(const byte* in, word32 inLen, ecc_key* key,
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
/* Allocate temp key for callback to export from */
|
||||
WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(ecc_key));
|
||||
|
||||
err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (err != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
/* Copy custom curve params so recursive import uses correct curve */
|
||||
if (key->dp != NULL) {
|
||||
err = wc_ecc_set_custom_curve(tmpKey, key->dp);
|
||||
if (err != 0) {
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recursive call imports X9.63 public key into temp via software */
|
||||
err = wc_ecc_import_x963_ex2(in, inLen, tmpKey, curve_id, untrusted);
|
||||
if (err == MP_OKAY) {
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
WC_SETKEY_ECC_PUB, key, tmpKey,
|
||||
wc_ecc_size(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
err = MP_OKAY;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
/* make sure required variables are reset */
|
||||
wc_ecc_reset(key);
|
||||
|
||||
@@ -11232,9 +11289,68 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
||||
#ifdef WOLFSSL_CRYPTOCELL
|
||||
const CRYS_ECPKI_Domain_t* pDomain;
|
||||
#endif
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
int tmpErr = 0;
|
||||
WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (key == NULL || priv == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
/* Allocate temp key for callback to export from */
|
||||
WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(ecc_key));
|
||||
|
||||
tmpErr = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (tmpErr != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return tmpErr;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
/* Copy custom curve params so recursive import uses correct curve */
|
||||
if (key->dp != NULL) {
|
||||
tmpErr = wc_ecc_set_custom_curve(tmpKey, key->dp);
|
||||
if (tmpErr != 0) {
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return tmpErr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recursive call imports key material into temp via software
|
||||
* (no callback recursion since tmpKey has INVALID_DEVID) */
|
||||
tmpErr = wc_ecc_import_private_key_ex(priv, privSz, pub, pubSz,
|
||||
tmpKey, curve_id);
|
||||
if (tmpErr == 0) {
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
WC_SETKEY_ECC_PRIV, key, tmpKey,
|
||||
wc_ecc_size(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (tmpErr != 0) {
|
||||
return tmpErr;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
/* public optional, NULL if only importing private */
|
||||
if (pub != NULL) {
|
||||
#ifndef NO_ASN
|
||||
@@ -11552,11 +11668,15 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
CRYS_ECPKI_BUILD_TempData_t tempBuff;
|
||||
byte keyRaw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1];
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
|
||||
defined(WOLFSSL_CRYPTOCELL)
|
||||
word32 keySz = 0;
|
||||
#endif
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
int setKeyType = WC_SETKEY_ECC_PRIV;
|
||||
WC_DECLARE_VAR(tmpKey, ecc_key, 1, NULL);
|
||||
#endif
|
||||
|
||||
/* if d is NULL, only import as public key using Qx,Qy */
|
||||
if (key == NULL || qx == NULL || qy == NULL) {
|
||||
@@ -11574,6 +11694,63 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
/* Allocate temp key for callback to export from */
|
||||
WC_ALLOC_VAR(tmpKey, ecc_key, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(ecc_key));
|
||||
|
||||
err = wc_ecc_init_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (err != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CUSTOM_CURVES
|
||||
/* Copy custom curve params so recursive import uses correct curve */
|
||||
if (key->dp != NULL) {
|
||||
err = wc_ecc_set_custom_curve(tmpKey, key->dp);
|
||||
if (err != 0) {
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Recursive call imports key material into temp via software */
|
||||
err = wc_ecc_import_raw_private(tmpKey, qx, qy, d, curve_id, encType);
|
||||
if (err == MP_OKAY) {
|
||||
/* This function handles both public and private imports:
|
||||
* when d is NULL, only Qx/Qy are imported (public only) */
|
||||
if (d == NULL) {
|
||||
setKeyType = WC_SETKEY_ECC_PUB;
|
||||
}
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
setKeyType, key, tmpKey,
|
||||
wc_ecc_size(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
wc_ecc_free(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
err = MP_OKAY;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
/* init key */
|
||||
#ifdef ALT_ECC_SIZE
|
||||
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
|
||||
@@ -11932,7 +12109,27 @@ static int ecc_public_key_size(ecc_key* key, word32* sz)
|
||||
WOLFSSL_ABI
|
||||
int wc_ecc_size(ecc_key* key)
|
||||
{
|
||||
if (key == NULL || key->dp == NULL)
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
int ret;
|
||||
int keySz;
|
||||
#endif
|
||||
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (key->devId != INVALID_DEVID) {
|
||||
keySz = 0;
|
||||
ret = wc_CryptoCb_EccGetSize(key, &keySz);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
if (ret != 0)
|
||||
return 0;
|
||||
return keySz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key->dp == NULL)
|
||||
return 0;
|
||||
|
||||
return key->dp->size;
|
||||
@@ -11962,8 +12159,27 @@ int wc_ecc_sig_size(const ecc_key* key)
|
||||
{
|
||||
int maxSigSz;
|
||||
int orderBits, keySz;
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
int ret;
|
||||
int cbKeySz;
|
||||
#endif
|
||||
|
||||
if (key == NULL || key->dp == NULL)
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (key->devId != INVALID_DEVID) {
|
||||
cbKeySz = 0;
|
||||
ret = wc_CryptoCb_EccGetSigSize(key, &cbKeySz);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
if (ret != 0 || cbKeySz == 0)
|
||||
return 0;
|
||||
return cbKeySz;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key->dp == NULL)
|
||||
return 0;
|
||||
|
||||
/* the signature r and s will always be less than order */
|
||||
|
||||
@@ -470,6 +470,9 @@ int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
|
||||
#endif
|
||||
int ret = 0;
|
||||
void* heap = NULL;
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet;
|
||||
#endif
|
||||
|
||||
if (hmac == NULL || (key == NULL && length != 0) ||
|
||||
!(type == WC_MD5 || type == WC_SHA ||
|
||||
@@ -543,6 +546,19 @@ int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length,
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (hmac->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
cbRet = wc_CryptoCb_SetKey(hmac->devId,
|
||||
WC_SETKEY_HMAC, hmac, (void*)key, length, NULL, 0, 0);
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return cbRet;
|
||||
/* fall-through to software when unavailable */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
hmac->keyRaw = key; /* use buffer directly */
|
||||
hmac->keyLen = (word16)length;
|
||||
|
||||
@@ -655,6 +655,22 @@ int wc_FreeRsaKey(RsaKey* key)
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
ret = wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
|
||||
WC_PK_TYPE_RSA, 0, key);
|
||||
/* If callback wants standard free, it returns CRYPTOCB_UNAVAILABLE.
|
||||
* Otherwise assume the callback handled cleanup. */
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through to software cleanup */
|
||||
ret = 0;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
|
||||
|
||||
#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA)
|
||||
se050_rsa_free_key(key);
|
||||
#endif
|
||||
@@ -4522,11 +4538,46 @@ int wc_RsaFlattenPublicKey(const RsaKey* key, byte* e, word32* eSz, byte* n,
|
||||
word32* nSz)
|
||||
{
|
||||
int sz, ret;
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
|
||||
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(RsaKey));
|
||||
|
||||
ret = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_RSA,
|
||||
(void*)key, tmpKey);
|
||||
if (ret == 0) {
|
||||
/* Recursive call on software tmpKey (INVALID_DEVID) */
|
||||
ret = wc_RsaFlattenPublicKey(tmpKey, e, eSz, n, nSz);
|
||||
}
|
||||
ForceZero(tmpKey, sizeof(RsaKey));
|
||||
wc_FreeRsaKey(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall through to software */
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
|
||||
sz = mp_unsigned_bin_size(&key->e);
|
||||
if ((word32)sz > *eSz)
|
||||
return RSA_BUFFER_E;
|
||||
@@ -4575,10 +4626,48 @@ int wc_RsaExportKey(const RsaKey* key,
|
||||
byte* q, word32* qSz)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(BAD_FUNC_ARG);
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
|
||||
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (key && e && eSz && n && nSz && d && dSz && p && pSz && q && qSz)
|
||||
ret = 0;
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_EXPORT_KEY)
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(RsaKey));
|
||||
|
||||
ret = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wc_CryptoCb_ExportKey(key->devId, WC_PK_TYPE_RSA,
|
||||
(void*)key, tmpKey);
|
||||
if (ret == 0) {
|
||||
/* Recursive call on software tmpKey (INVALID_DEVID) */
|
||||
ret = wc_RsaExportKey(tmpKey, e, eSz, n, nSz,
|
||||
d, dSz, p, pSz, q, qSz);
|
||||
}
|
||||
ForceZero(tmpKey, sizeof(RsaKey));
|
||||
wc_FreeRsaKey(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
ret = 0; /* fall through to software */
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
|
||||
if (ret == 0)
|
||||
ret = RsaGetValue(&key->e, e, eSz);
|
||||
if (ret == 0)
|
||||
@@ -5458,6 +5547,10 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
|
||||
const byte* dQ, word32 dQSz, RsaKey* key)
|
||||
{
|
||||
int err = MP_OKAY;
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
int cbRet = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
WC_DECLARE_VAR(tmpKey, RsaKey, 1, NULL);
|
||||
#endif
|
||||
|
||||
if (n == NULL || nSz == 0 || e == NULL || eSz == 0
|
||||
|| d == NULL || dSz == 0 || p == NULL || pSz == 0
|
||||
@@ -5482,6 +5575,51 @@ int wc_RsaPrivateKeyDecodeRaw(const byte* n, word32 nSz,
|
||||
(void)dQSz;
|
||||
#endif
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_SETKEY)
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (err == MP_OKAY && key->devId != INVALID_DEVID)
|
||||
#else
|
||||
if (err == MP_OKAY)
|
||||
#endif
|
||||
{
|
||||
/* Allocate temp key for callback to export from */
|
||||
WC_ALLOC_VAR(tmpKey, RsaKey, 1, key->heap);
|
||||
if (!WC_VAR_OK(tmpKey)) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(tmpKey, 0, sizeof(RsaKey));
|
||||
|
||||
/* Init temp with INVALID_DEVID to prevent callback recursion */
|
||||
err = wc_InitRsaKey_ex(tmpKey, key->heap, INVALID_DEVID);
|
||||
if (err != MP_OKAY) {
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Recursive call imports key material into temp via software */
|
||||
err = wc_RsaPrivateKeyDecodeRaw(n, nSz, e, eSz, d, dSz,
|
||||
u, uSz, p, pSz, q, qSz, dP, dPSz, dQ, dQSz, tmpKey);
|
||||
if (err == MP_OKAY) {
|
||||
cbRet = wc_CryptoCb_SetKey(key->devId,
|
||||
WC_SETKEY_RSA_PRIV, key, tmpKey,
|
||||
wc_RsaEncryptSize(tmpKey), NULL, 0, 0);
|
||||
}
|
||||
|
||||
/* wc_FreeRsaKey does mp_forcezero on private components */
|
||||
wc_FreeRsaKey(tmpKey);
|
||||
WC_FREE_VAR(tmpKey, key->heap);
|
||||
|
||||
if (err != MP_OKAY) {
|
||||
return err;
|
||||
}
|
||||
if (cbRet != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return cbRet;
|
||||
}
|
||||
/* CRYPTOCB_UNAVAILABLE: fall through to software import */
|
||||
err = MP_OKAY;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
if (err == MP_OKAY)
|
||||
err = mp_read_unsigned_bin(&key->n, n, nSz);
|
||||
if (err == MP_OKAY)
|
||||
|
||||
+366
-4
@@ -65730,6 +65730,37 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
info->pk.ecdh.private_key->devId = devIdArg;
|
||||
#endif
|
||||
}
|
||||
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIZE) {
|
||||
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
|
||||
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
|
||||
if (!WC_VAR_OK(tmpEcc)) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
else {
|
||||
/* Copy key to avoid const and recursive callback */
|
||||
XMEMCPY(tmpEcc, info->pk.ecc_get_size.key, sizeof(ecc_key));
|
||||
tmpEcc->devId = INVALID_DEVID;
|
||||
*info->pk.ecc_get_size.keySize = wc_ecc_size(tmpEcc);
|
||||
WC_FREE_VAR(tmpEcc, NULL);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (info->pk.type == WC_PK_TYPE_EC_GET_SIG_SIZE) {
|
||||
WC_DECLARE_VAR(tmpEcc, ecc_key, 1, NULL);
|
||||
WC_ALLOC_VAR(tmpEcc, ecc_key, 1, NULL);
|
||||
if (!WC_VAR_OK(tmpEcc)) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
else {
|
||||
/* Copy key to avoid const and recursive callback */
|
||||
XMEMCPY(tmpEcc, info->pk.ecc_get_sig_size.key,
|
||||
sizeof(ecc_key));
|
||||
tmpEcc->devId = INVALID_DEVID;
|
||||
*info->pk.ecc_get_sig_size.sigSize = wc_ecc_sig_size(tmpEcc);
|
||||
WC_FREE_VAR(tmpEcc, NULL);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_ECC */
|
||||
#ifdef HAVE_CURVE25519
|
||||
if (info->pk.type == WC_PK_TYPE_CURVE25519_KEYGEN) {
|
||||
@@ -66576,13 +66607,21 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_RSA
|
||||
case WC_PK_TYPE_RSA:
|
||||
{
|
||||
RsaKey* rsa = (RsaKey*)info->free.obj;
|
||||
rsa->devId = INVALID_DEVID;
|
||||
wc_FreeRsaKey(rsa);
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DILITHIUM
|
||||
case WC_PK_TYPE_PQC_SIG_KEYGEN:
|
||||
{
|
||||
if (info->free.subType ==
|
||||
WC_PQC_SIG_TYPE_DILITHIUM) {
|
||||
dilithium_key* dil =
|
||||
(dilithium_key*)info->free.obj;
|
||||
if (info->free.subType == WC_PQC_SIG_TYPE_DILITHIUM) {
|
||||
dilithium_key* dil = (dilithium_key*)info->free.obj;
|
||||
dil->devId = INVALID_DEVID;
|
||||
wc_dilithium_free(dil);
|
||||
ret = 0;
|
||||
@@ -66615,6 +66654,329 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
else if (info->algo_type == WC_ALGO_TYPE_SETKEY) {
|
||||
#ifdef DEBUG_CRYPTOCB
|
||||
wc_CryptoCb_InfoString(info);
|
||||
#endif
|
||||
switch (info->setkey.type) {
|
||||
#ifndef NO_AES
|
||||
case WC_SETKEY_AES:
|
||||
{
|
||||
Aes* aes = (Aes*)info->setkey.obj;
|
||||
/* Delegate to software: disable devId, call SetKey, restore */
|
||||
aes->devId = INVALID_DEVID;
|
||||
ret = wc_AesSetKey(aes,
|
||||
(const byte*)info->setkey.key, info->setkey.keySz,
|
||||
(const byte*)info->setkey.aux, info->setkey.flags);
|
||||
aes->devId = devIdArg;
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_AES */
|
||||
#ifndef NO_HMAC
|
||||
case WC_SETKEY_HMAC:
|
||||
{
|
||||
Hmac* hmac = (Hmac*)info->setkey.obj;
|
||||
/* Delegate to software: disable devId, call SetKey, restore */
|
||||
hmac->devId = INVALID_DEVID;
|
||||
ret = wc_HmacSetKey(hmac, hmac->macType,
|
||||
(const byte*)info->setkey.key, info->setkey.keySz);
|
||||
hmac->devId = devIdArg;
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_HMAC */
|
||||
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
|
||||
case WC_SETKEY_RSA_PUB:
|
||||
{
|
||||
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
|
||||
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
|
||||
int derSz;
|
||||
word32 idx = 0;
|
||||
byte* der = NULL;
|
||||
|
||||
/* Get required DER size for public key */
|
||||
derSz = wc_RsaPublicKeyDerSize(rsaTmp, 1);
|
||||
if (derSz <= 0) {
|
||||
ret = derSz;
|
||||
break;
|
||||
}
|
||||
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Export public key from temp to DER */
|
||||
derSz = wc_RsaKeyToPublicDer_ex(rsaTmp, der,
|
||||
(word32)derSz, 1);
|
||||
if (derSz <= 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ret = derSz;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Import DER into obj via software */
|
||||
rsaObj->devId = INVALID_DEVID;
|
||||
ret = wc_RsaPublicKeyDecode(der, &idx, rsaObj,
|
||||
(word32)derSz);
|
||||
rsaObj->devId = devIdArg;
|
||||
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
break;
|
||||
}
|
||||
case WC_SETKEY_RSA_PRIV:
|
||||
{
|
||||
RsaKey* rsaObj = (RsaKey*)info->setkey.obj;
|
||||
RsaKey* rsaTmp = (RsaKey*)info->setkey.key;
|
||||
int derSz;
|
||||
word32 idx = 0;
|
||||
byte* der = NULL;
|
||||
|
||||
/* Get required DER size for private key */
|
||||
derSz = wc_RsaKeyToDer(rsaTmp, NULL, 0);
|
||||
if (derSz <= 0) {
|
||||
ret = derSz;
|
||||
break;
|
||||
}
|
||||
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Export private key from temp to DER */
|
||||
derSz = wc_RsaKeyToDer(rsaTmp, der, (word32)derSz);
|
||||
if (derSz <= 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
ret = derSz;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Import DER into obj via software */
|
||||
rsaObj->devId = INVALID_DEVID;
|
||||
ret = wc_RsaPrivateKeyDecode(der, &idx, rsaObj,
|
||||
(word32)derSz);
|
||||
rsaObj->devId = devIdArg;
|
||||
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
|
||||
defined(HAVE_ECC_KEY_IMPORT)
|
||||
case WC_SETKEY_ECC_PUB:
|
||||
{
|
||||
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
|
||||
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
|
||||
word32 bufSz = ECC_BUFSIZE;
|
||||
int curveId;
|
||||
WC_DECLARE_VAR(buf, byte, ECC_BUFSIZE, NULL);
|
||||
WC_ALLOC_VAR(buf, byte, ECC_BUFSIZE, NULL);
|
||||
if (!WC_VAR_OK(buf)) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Export public key from temp to X9.63 format */
|
||||
ret = wc_ecc_export_x963(eccTmp, buf, &bufSz);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(buf, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
curveId = wc_ecc_get_curve_id(eccTmp->idx);
|
||||
|
||||
/* Import into obj via software */
|
||||
eccObj->devId = INVALID_DEVID;
|
||||
ret = wc_ecc_import_x963_ex2(buf, bufSz, eccObj,
|
||||
curveId, 0);
|
||||
eccObj->devId = devIdArg;
|
||||
|
||||
WC_FREE_VAR(buf, NULL);
|
||||
break;
|
||||
}
|
||||
case WC_SETKEY_ECC_PRIV:
|
||||
{
|
||||
ecc_key* eccObj = (ecc_key*)info->setkey.obj;
|
||||
ecc_key* eccTmp = (ecc_key*)info->setkey.key;
|
||||
word32 pubSz = ECC_BUFSIZE;
|
||||
word32 privSz = MAX_ECC_BYTES;
|
||||
byte* pubPtr = NULL;
|
||||
int curveId;
|
||||
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
|
||||
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
|
||||
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
|
||||
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
|
||||
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Export public key from temp (if available) */
|
||||
if (eccTmp->type != ECC_PRIVATEKEY_ONLY) {
|
||||
ret = wc_ecc_export_x963(eccTmp, pubBuf, &pubSz);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
pubPtr = pubBuf;
|
||||
}
|
||||
|
||||
ret = wc_ecc_export_private_only(eccTmp, privBuf,
|
||||
&privSz);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
curveId = wc_ecc_get_curve_id(eccTmp->idx);
|
||||
|
||||
/* Import into obj via software */
|
||||
eccObj->devId = INVALID_DEVID;
|
||||
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
|
||||
pubPtr, (pubPtr != NULL) ? pubSz : 0,
|
||||
eccObj, curveId);
|
||||
eccObj->devId = devIdArg;
|
||||
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
|
||||
default:
|
||||
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
else if (info->algo_type == WC_ALGO_TYPE_EXPORT_KEY) {
|
||||
#ifdef DEBUG_CRYPTOCB
|
||||
wc_CryptoCb_InfoString(info);
|
||||
#endif
|
||||
switch (info->export_key.type) {
|
||||
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_TO_DER)
|
||||
case WC_PK_TYPE_RSA:
|
||||
{
|
||||
RsaKey* src = (RsaKey*)info->export_key.obj;
|
||||
RsaKey* dst = (RsaKey*)info->export_key.out;
|
||||
int derSz;
|
||||
word32 idx = 0;
|
||||
byte* der = NULL;
|
||||
|
||||
/* Try private key export first, fall back to public */
|
||||
derSz = wc_RsaKeyToDer(src, NULL, 0);
|
||||
if (derSz > 0) {
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
derSz = wc_RsaKeyToDer(src, der, (word32)derSz);
|
||||
if (derSz > 0) {
|
||||
ret = wc_RsaPrivateKeyDecode(der, &idx, dst,
|
||||
(word32)derSz);
|
||||
}
|
||||
else {
|
||||
ret = derSz;
|
||||
}
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
else {
|
||||
/* Public key only */
|
||||
derSz = wc_RsaPublicKeyDerSize(src, 1);
|
||||
if (derSz <= 0) {
|
||||
ret = derSz;
|
||||
break;
|
||||
}
|
||||
der = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (der == NULL) {
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
derSz = wc_RsaKeyToPublicDer_ex(src, der,
|
||||
(word32)derSz, 1);
|
||||
if (derSz > 0) {
|
||||
ret = wc_RsaPublicKeyDecode(der, &idx, dst,
|
||||
(word32)derSz);
|
||||
}
|
||||
else {
|
||||
ret = derSz;
|
||||
}
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_RSA && WOLFSSL_KEY_TO_DER */
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
|
||||
defined(HAVE_ECC_KEY_IMPORT)
|
||||
case WC_PK_TYPE_ECDSA_SIGN: /* ECC key */
|
||||
{
|
||||
ecc_key* src = (ecc_key*)info->export_key.obj;
|
||||
ecc_key* dst = (ecc_key*)info->export_key.out;
|
||||
word32 pubSz = ECC_BUFSIZE;
|
||||
word32 privSz = MAX_ECC_BYTES;
|
||||
byte* pubPtr = NULL;
|
||||
int curveId;
|
||||
WC_DECLARE_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
|
||||
WC_DECLARE_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
|
||||
WC_ALLOC_VAR(pubBuf, byte, ECC_BUFSIZE, NULL);
|
||||
WC_ALLOC_VAR(privBuf, byte, MAX_ECC_BYTES, NULL);
|
||||
if (!WC_VAR_OK(pubBuf) || !WC_VAR_OK(privBuf)) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
ret = MEMORY_E;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Export public key if available */
|
||||
if (src->type != ECC_PRIVATEKEY_ONLY) {
|
||||
ret = wc_ecc_export_x963(src, pubBuf, &pubSz);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
pubPtr = pubBuf;
|
||||
}
|
||||
|
||||
/* Export private key if available */
|
||||
if (src->type != ECC_PUBLICKEY) {
|
||||
ret = wc_ecc_export_private_only(src, privBuf, &privSz);
|
||||
if (ret != 0) {
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
curveId = wc_ecc_get_curve_id(src->idx);
|
||||
ret = wc_ecc_import_private_key_ex(privBuf, privSz,
|
||||
pubPtr, (pubPtr != NULL) ? pubSz : 0,
|
||||
dst, curveId);
|
||||
}
|
||||
else {
|
||||
/* Public key only */
|
||||
curveId = wc_ecc_get_curve_id(src->idx);
|
||||
ret = wc_ecc_import_x963_ex2(pubBuf, pubSz, dst,
|
||||
curveId, 0);
|
||||
}
|
||||
WC_FREE_VAR(pubBuf, NULL);
|
||||
WC_FREE_VAR(privBuf, NULL);
|
||||
break;
|
||||
}
|
||||
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && HAVE_ECC_KEY_IMPORT */
|
||||
default:
|
||||
ret = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
#ifndef NO_HMAC
|
||||
else if (info->algo_type == WC_ALGO_TYPE_HMAC) {
|
||||
if (info->hmac.hmac == NULL)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
/* Defines the Crypto Callback interface version, for compatibility */
|
||||
/* Increment this when Crypto Callback interface changes are made */
|
||||
#define CRYPTO_CB_VER 2
|
||||
#define CRYPTO_CB_VER 3
|
||||
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
@@ -134,6 +134,18 @@ typedef struct {
|
||||
} wc_CryptoCb_AesAuthDec;
|
||||
#endif
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
enum wc_SetKeyType {
|
||||
WC_SETKEY_NONE = 0,
|
||||
WC_SETKEY_HMAC = 1,
|
||||
WC_SETKEY_RSA_PUB = 2,
|
||||
WC_SETKEY_RSA_PRIV = 3,
|
||||
WC_SETKEY_ECC_PUB = 4,
|
||||
WC_SETKEY_ECC_PRIV = 5,
|
||||
WC_SETKEY_AES = 6,
|
||||
};
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
|
||||
/* Crypto Information Structure for callbacks */
|
||||
typedef struct wc_CryptoInfo {
|
||||
int algo_type; /* enum wc_AlgoType */
|
||||
@@ -218,6 +230,14 @@ typedef struct wc_CryptoInfo {
|
||||
word32 pubKeySz;
|
||||
} ecc_check;
|
||||
#endif
|
||||
struct {
|
||||
const ecc_key* key;
|
||||
int* keySize;
|
||||
} ecc_get_size;
|
||||
struct {
|
||||
const ecc_key* key;
|
||||
int* sigSize;
|
||||
} ecc_get_sig_size;
|
||||
#endif /* HAVE_ECC */
|
||||
#ifdef HAVE_CURVE25519
|
||||
struct {
|
||||
@@ -492,6 +512,24 @@ typedef struct wc_CryptoInfo {
|
||||
void *obj; /* Object structure to free */
|
||||
} free;
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
struct { /* uses wc_AlgoType=WC_ALGO_TYPE_SETKEY */
|
||||
int type; /* enum wc_SetKeyType */
|
||||
void* obj; /* Aes*, Hmac*, RsaKey*, ecc_key* */
|
||||
void* key; /* Raw key bytes or temp struct to export from */
|
||||
word32 keySz; /* Key size (0 when key is a struct ptr) */
|
||||
void* aux; /* Auxiliary data (IV, etc.) or NULL */
|
||||
word32 auxSz; /* Aux data size, 0 if unused */
|
||||
int flags; /* AES: direction (AES_ENCRYPTION/DECRYPTION) */
|
||||
} setkey;
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
struct { /* uses wc_AlgoType=WC_ALGO_TYPE_EXPORT_KEY */
|
||||
int type; /* enum wc_PkType (WC_PK_TYPE_RSA, etc.) */
|
||||
void* obj; /* Hardware key (has devCtx/id[]) */
|
||||
void* out; /* Software key to fill (same type as obj) */
|
||||
} export_key;
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
#if defined(HAVE_HKDF) || defined(HAVE_CMAC_KDF)
|
||||
struct {
|
||||
int type; /* enum wc_KdfType */
|
||||
@@ -592,6 +630,9 @@ WOLFSSL_LOCAL int wc_CryptoCb_EccVerify(const byte* sig, word32 siglen,
|
||||
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_EccCheckPrivKey(ecc_key* key, const byte* pubKey,
|
||||
word32 pubKeySz);
|
||||
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_EccGetSize(const ecc_key* key, int* keySize);
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_EccGetSigSize(const ecc_key* key, int* sigSize);
|
||||
#endif /* HAVE_ECC */
|
||||
|
||||
#ifdef HAVE_CURVE25519
|
||||
@@ -772,6 +813,16 @@ WOLFSSL_LOCAL int wc_CryptoCb_Copy(int devId, int algo, int type, void* src,
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_Free(int devId, int algo, int type, int subType,
|
||||
void* obj);
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
#ifdef WOLF_CRYPTO_CB_SETKEY
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_SetKey(int devId, int type, void* obj,
|
||||
void* key, word32 keySz,
|
||||
void* aux, word32 auxSz,
|
||||
int flags);
|
||||
#endif /* WOLF_CRYPTO_CB_SETKEY */
|
||||
#ifdef WOLF_CRYPTO_CB_EXPORT_KEY
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_ExportKey(int devId, int type,
|
||||
void* obj, void* out);
|
||||
#endif /* WOLF_CRYPTO_CB_EXPORT_KEY */
|
||||
|
||||
#endif /* WOLF_CRYPTO_CB */
|
||||
|
||||
|
||||
@@ -1424,7 +1424,9 @@ enum wc_AlgoType {
|
||||
WC_ALGO_TYPE_KDF = 9,
|
||||
WC_ALGO_TYPE_COPY = 10,
|
||||
WC_ALGO_TYPE_FREE = 11,
|
||||
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_FREE
|
||||
WC_ALGO_TYPE_SETKEY = 12,
|
||||
WC_ALGO_TYPE_EXPORT_KEY = 13,
|
||||
WC_ALGO_TYPE_MAX = WC_ALGO_TYPE_EXPORT_KEY
|
||||
};
|
||||
|
||||
/* KDF types */
|
||||
@@ -1566,6 +1568,8 @@ enum wc_PkType {
|
||||
WC_PK_TYPE_RSA_PKCS = 25,
|
||||
WC_PK_TYPE_RSA_PSS = 26,
|
||||
WC_PK_TYPE_RSA_OAEP = 27,
|
||||
WC_PK_TYPE_EC_GET_SIZE = 28,
|
||||
WC_PK_TYPE_EC_GET_SIG_SIZE = 29,
|
||||
WC_PK_TYPE_MAX = _WC_PK_TYPE_MAX
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user