mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 09:10:53 +02:00
Merge pull request #10466 from Frauschi/slhdsa_cryptocb
Add CryptoCb support for SLH-DSA
This commit is contained in:
@@ -42,6 +42,103 @@
|
||||
int wc_SlhDsaKey_Init(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
void* heap, int devId);
|
||||
|
||||
/*!
|
||||
\ingroup SLH_DSA
|
||||
|
||||
\brief Initializes an SLH-DSA key with a device-side key identifier (id).
|
||||
Equivalent to wc_SlhDsaKey_Init() but also stashes a binary id that a
|
||||
crypto callback can use to look up the underlying key material on the
|
||||
device. Only available when wolfSSL is built with WOLF_PRIVATE_KEY_ID.
|
||||
|
||||
The id is copied into the key object; the caller may free its buffer
|
||||
immediately after this call returns.
|
||||
|
||||
\return 0 on success.
|
||||
\return BAD_FUNC_ARG if key is NULL, or if id is NULL while len > 0.
|
||||
\return BUFFER_E if len is negative or greater than SLHDSA_MAX_ID_LEN.
|
||||
|
||||
\param [in,out] key Pointer to the SlhDsaKey to initialize.
|
||||
\param [in] param Parameter set to use (see wc_SlhDsaKey_Init).
|
||||
\param [in] id Pointer to the device-side key identifier bytes. May be
|
||||
NULL if len is 0.
|
||||
\param [in] len Number of bytes in id. Must be in [0, SLHDSA_MAX_ID_LEN].
|
||||
\param [in] heap Pointer to heap hint for dynamic memory allocation.
|
||||
May be NULL.
|
||||
\param [in] devId Device identifier for the crypto callback. Should be
|
||||
a registered cb devId, not INVALID_DEVID, for the id to be meaningful.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
SlhDsaKey key;
|
||||
unsigned char id[8] = { 0x01, 0x02, 0x03, 0x04,
|
||||
0x05, 0x06, 0x07, 0x08 };
|
||||
int ret;
|
||||
|
||||
ret = wc_SlhDsaKey_Init_id(&key, SLHDSA_SHAKE128F, id, sizeof(id),
|
||||
NULL, devId);
|
||||
if (ret != 0) {
|
||||
// error initializing key with id
|
||||
}
|
||||
// ... use key, the cb resolves id -> device key ...
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
\endcode
|
||||
|
||||
\sa wc_SlhDsaKey_Init
|
||||
\sa wc_SlhDsaKey_Init_label
|
||||
\sa wc_SlhDsaKey_Free
|
||||
*/
|
||||
int wc_SlhDsaKey_Init_id(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const unsigned char* id, int len, void* heap, int devId);
|
||||
|
||||
/*!
|
||||
\ingroup SLH_DSA
|
||||
|
||||
\brief Initializes an SLH-DSA key with a device-side key label.
|
||||
Equivalent to wc_SlhDsaKey_Init() but also stashes a label string that
|
||||
a crypto callback can use to look up the underlying key material on
|
||||
the device. Only available when wolfSSL is built with
|
||||
WOLF_PRIVATE_KEY_ID.
|
||||
|
||||
The label length is taken via XSTRLEN, so embedded NUL bytes terminate
|
||||
the label. The copy stored in key->label is NOT guaranteed to be
|
||||
NUL-terminated (when the input is exactly SLHDSA_MAX_LABEL_LEN bytes
|
||||
the entire array is consumed). Consumers must read at most
|
||||
key->labelLen bytes — do not pass key->label to C-string APIs.
|
||||
|
||||
\return 0 on success.
|
||||
\return BAD_FUNC_ARG if key or label is NULL.
|
||||
\return BUFFER_E if label is empty or longer than SLHDSA_MAX_LABEL_LEN.
|
||||
|
||||
\param [in,out] key Pointer to the SlhDsaKey to initialize.
|
||||
\param [in] param Parameter set to use (see wc_SlhDsaKey_Init).
|
||||
\param [in] label NUL-terminated device-side key label string.
|
||||
\param [in] heap Pointer to heap hint for dynamic memory allocation.
|
||||
May be NULL.
|
||||
\param [in] devId Device identifier for the crypto callback. Should be
|
||||
a registered cb devId, not INVALID_DEVID, for the label to be
|
||||
meaningful.
|
||||
|
||||
_Example_
|
||||
\code
|
||||
SlhDsaKey key;
|
||||
int ret;
|
||||
|
||||
ret = wc_SlhDsaKey_Init_label(&key, SLHDSA_SHAKE128F,
|
||||
"device-key-1", NULL, devId);
|
||||
if (ret != 0) {
|
||||
// error initializing key with label
|
||||
}
|
||||
// ... use key, the cb resolves label -> device key ...
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
\endcode
|
||||
|
||||
\sa wc_SlhDsaKey_Init
|
||||
\sa wc_SlhDsaKey_Init_id
|
||||
\sa wc_SlhDsaKey_Free
|
||||
*/
|
||||
int wc_SlhDsaKey_Init_label(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const char* label, void* heap, int devId);
|
||||
|
||||
/*!
|
||||
\ingroup SLH_DSA
|
||||
|
||||
|
||||
@@ -1288,7 +1288,8 @@ int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, word32 ciphertextLen,
|
||||
}
|
||||
#endif /* WOLFSSL_HAVE_MLKEM */
|
||||
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || \
|
||||
defined(WOLFSSL_HAVE_SLHDSA)
|
||||
int wc_CryptoCb_PqcSigGetDevId(int type, void* key)
|
||||
{
|
||||
int devId = INVALID_DEVID;
|
||||
@@ -1307,6 +1308,11 @@ int wc_CryptoCb_PqcSigGetDevId(int type, void* key)
|
||||
devId = ((falcon_key*) key)->devId;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_SLHDSA)
|
||||
if (type == WC_PQC_SIG_TYPE_SLHDSA) {
|
||||
devId = ((SlhDsaKey*) key)->devId;
|
||||
}
|
||||
#endif
|
||||
|
||||
return devId;
|
||||
}
|
||||
@@ -1456,7 +1462,7 @@ int wc_CryptoCb_PqcSignatureCheckPrivKey(void* key, int type,
|
||||
|
||||
return wc_CryptoCb_TranslateErrorCode(ret);
|
||||
}
|
||||
#endif /* HAVE_FALCON || HAVE_DILITHIUM */
|
||||
#endif /* HAVE_FALCON || HAVE_DILITHIUM || WOLFSSL_HAVE_SLHDSA */
|
||||
|
||||
#ifndef NO_AES
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
+219
-3
@@ -6557,9 +6557,14 @@ int wc_SlhDsaKey_Init(SlhDsaKey* key, enum SlhDsaParam param, void* heap,
|
||||
/* Set heap hint to use with all allocations. */
|
||||
key->heap = heap;
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
/* Set device id. */
|
||||
/* Set device context and id. */
|
||||
key->devCtx = NULL;
|
||||
key->devId = devId;
|
||||
#endif
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
key->idLen = 0;
|
||||
key->labelLen = 0;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
if (SLHDSA_IS_SHA2(param)) {
|
||||
@@ -6595,14 +6600,106 @@ int wc_SlhDsaKey_Init(SlhDsaKey* key, enum SlhDsaParam param, void* heap,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
/* Initialize an SLH-DSA key with a device key id.
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] param SLH-DSA parameter set to use.
|
||||
* @param [in] id Device-side key handle bytes.
|
||||
* @param [in] len Length of id in bytes.
|
||||
* @param [in] heap Dynamic memory allocation hint.
|
||||
* @param [in] devId Device Id.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key is NULL or when id is NULL with len > 0.
|
||||
* @return BUFFER_E when len is negative or larger than SLHDSA_MAX_ID_LEN.
|
||||
*/
|
||||
int wc_SlhDsaKey_Init_id(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const unsigned char* id, int len, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
/* Reject id == NULL with len > 0. */
|
||||
if ((ret == 0) && (id == NULL) && (len > 0)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && ((len < 0) || (len > SLHDSA_MAX_ID_LEN))) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_SlhDsaKey_Init(key, param, heap, devId);
|
||||
}
|
||||
if ((ret == 0) && (id != NULL) && (len > 0)) {
|
||||
XMEMCPY(key->id, id, (size_t)len);
|
||||
key->idLen = len;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize an SLH-DSA key with a device key label.
|
||||
*
|
||||
* Label length is taken via XSTRLEN; embedded NULs terminate the label.
|
||||
*
|
||||
* @param [in] key SLH-DSA key.
|
||||
* @param [in] param SLH-DSA parameter set to use.
|
||||
* @param [in] label NUL-terminated device-side key label.
|
||||
* @param [in] heap Dynamic memory allocation hint.
|
||||
* @param [in] devId Device Id.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key or label is NULL.
|
||||
* @return BUFFER_E when label is empty or longer than SLHDSA_MAX_LABEL_LEN.
|
||||
*/
|
||||
int wc_SlhDsaKey_Init_label(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const char* label, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
int labelLen = 0;
|
||||
|
||||
if ((key == NULL) || (label == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if (ret == 0) {
|
||||
labelLen = (int)XSTRLEN(label);
|
||||
if ((labelLen == 0) || (labelLen > SLHDSA_MAX_LABEL_LEN)) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_SlhDsaKey_Init(key, param, heap, devId);
|
||||
}
|
||||
if (ret == 0) {
|
||||
XMEMCPY(key->label, label, (size_t)labelLen);
|
||||
key->labelLen = labelLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLF_PRIVATE_KEY_ID */
|
||||
|
||||
/* Free the SLH-DSA key.
|
||||
*
|
||||
* @param [in] key SLH-DSA key. Cannot be used after this call.
|
||||
*/
|
||||
void wc_SlhDsaKey_Free(SlhDsaKey* key)
|
||||
{
|
||||
/* Check we have a valid key to free. */
|
||||
if ((key != NULL) && (key->params != NULL)) {
|
||||
if (key == NULL)
|
||||
return;
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
|
||||
if ((key->params != NULL) && (key->devId != INVALID_DEVID)) {
|
||||
(void)wc_CryptoCb_Free(key->devId, WC_ALGO_TYPE_PK,
|
||||
WC_PK_TYPE_PQC_SIG_KEYGEN,
|
||||
WC_PQC_SIG_TYPE_SLHDSA,
|
||||
(void*)key);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (key->params != NULL) {
|
||||
/* Ensure the private key data is zeroized. */
|
||||
ForceZero(key->sk, (size_t)key->params->n * 2);
|
||||
#ifdef WOLFSSL_SLHDSA_SHA2
|
||||
@@ -6641,6 +6738,17 @@ void wc_SlhDsaKey_Free(SlhDsaKey* key)
|
||||
wc_Shake256_Free(&key->hash.shk.shake);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
key->idLen = 0;
|
||||
key->labelLen = 0;
|
||||
#endif
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
key->devCtx = NULL;
|
||||
key->devId = INVALID_DEVID;
|
||||
#endif
|
||||
/* Marks the key freed; subsequent Frees become no-ops. */
|
||||
key->params = NULL;
|
||||
}
|
||||
|
||||
/* Set the HashAddress based on message digest data.
|
||||
@@ -6752,6 +6860,24 @@ int wc_SlhDsaKey_MakeKey(SlhDsaKey* key, WC_RNG* rng)
|
||||
if ((key == NULL) || (key->params == NULL) || (rng == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
/* size is the SlhDsaParam enum (S/F variants are distinct). */
|
||||
ret = wc_CryptoCb_MakePqcSignatureKey(rng,
|
||||
WC_PQC_SIG_TYPE_SLHDSA, (int)key->params->param, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
/* Steps 1-5: Generate the 3 random hashes. */
|
||||
ret = wc_RNG_GenerateBlock(rng, key->sk, 3U * key->params->n);
|
||||
@@ -7251,6 +7377,23 @@ int wc_SlhDsaKey_Sign(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PRIVATE) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
ret = wc_CryptoCb_PqcSign(msg, msgSz, sig, sigSz, ctx, ctxSz,
|
||||
WC_HASH_TYPE_NONE, rng, WC_PQC_SIG_TYPE_SLHDSA, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
/* Generate n bytes of random. */
|
||||
ret = wc_RNG_GenerateBlock(rng, addRnd, key->params->n);
|
||||
@@ -7459,6 +7602,27 @@ int wc_SlhDsaKey_Verify(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PUBLIC) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
int res = 0;
|
||||
ret = wc_CryptoCb_PqcVerify(sig, sigSz, msg, msgSz, ctx, ctxSz,
|
||||
WC_HASH_TYPE_NONE, &res, WC_PQC_SIG_TYPE_SLHDSA, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return (res == 1) ? 0 : SIG_VERIFY_E;
|
||||
}
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
byte md[SLHDSA_MAX_MD];
|
||||
byte n = key->params->n;
|
||||
@@ -8131,6 +8295,30 @@ int wc_SlhDsaKey_SignHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PRIVATE) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
/* The cryptocb path below casts hashType to word32 to fit the
|
||||
* wc_CryptoInfo.preHashType field. Reject negative enum values here so
|
||||
* the cast can't smuggle a huge unsigned value past the callback (the
|
||||
* downstream prehash validator only inspects values it knows about). */
|
||||
else if ((int)hashType < 0) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
ret = wc_CryptoCb_PqcSign(hash, hashSz, sig, sigSz, ctx, ctxSz,
|
||||
(word32)hashType, rng, WC_PQC_SIG_TYPE_SLHDSA, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
return ret;
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
/* Generate n bytes of random. */
|
||||
ret = wc_RNG_GenerateBlock(rng, addRnd, key->params->n);
|
||||
@@ -8233,6 +8421,34 @@ int wc_SlhDsaKey_VerifyHash(SlhDsaKey* key, const byte* ctx, byte ctxSz,
|
||||
else if ((key->flags & WC_SLHDSA_FLAG_PUBLIC) == 0) {
|
||||
ret = MISSING_KEY;
|
||||
}
|
||||
/* The cryptocb path below casts hashType to word32 to fit the
|
||||
* wc_CryptoInfo.preHashType field. Reject negative enum values here so
|
||||
* the cast can't smuggle a huge unsigned value past the callback (the
|
||||
* downstream prehash validator only inspects values it knows about). */
|
||||
else if ((int)hashType < 0) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
#ifndef WOLF_CRYPTO_CB_FIND
|
||||
if (key->devId != INVALID_DEVID)
|
||||
#endif
|
||||
{
|
||||
int res = 0;
|
||||
ret = wc_CryptoCb_PqcVerify(sig, sigSz, hash, hashSz, ctx, ctxSz,
|
||||
(word32)hashType, &res, WC_PQC_SIG_TYPE_SLHDSA, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
return (res == 1) ? 0 : SIG_VERIFY_E;
|
||||
}
|
||||
/* fall-through when unavailable */
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0) {
|
||||
/* Alg 25, Steps 4-19: Validate caller-supplied pre-hashed digest length
|
||||
* and select OID for the chosen hash algorithm. */
|
||||
|
||||
+304
-4
@@ -57342,7 +57342,11 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
|
||||
ret = wc_SlhDsaKey_Init(key, param, NULL, INVALID_DEVID);
|
||||
/* Use the module-global devId so that when cryptocb_test() runs this
|
||||
* test with a registered callback, MakeKey/Sign/Verify route through
|
||||
* the cryptocb dispatcher. In standalone runs devId == INVALID_DEVID
|
||||
* and the calls go straight to the SW implementation. */
|
||||
ret = wc_SlhDsaKey_Init(key, param, NULL, devId);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
@@ -57365,7 +57369,7 @@ static wc_test_ret_t slhdsa_test_param(enum SlhDsaParam param)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
|
||||
ret = wc_SlhDsaKey_Init(key_vfy, param, NULL, INVALID_DEVID);
|
||||
ret = wc_SlhDsaKey_Init(key_vfy, param, NULL, devId);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
@@ -57506,6 +57510,163 @@ out:
|
||||
#define SLHDSA_TEST_HAVE_ANY_PARAM
|
||||
#endif
|
||||
|
||||
#if defined(WOLF_PRIVATE_KEY_ID) && \
|
||||
(defined(WOLFSSL_SLHDSA_PARAM_128S) || defined(WOLFSSL_SLHDSA_PARAM_128F) || \
|
||||
defined(WOLFSSL_SLHDSA_PARAM_SHA2_128S) || \
|
||||
defined(WOLFSSL_SLHDSA_PARAM_SHA2_128F))
|
||||
/* Exercise wc_SlhDsaKey_Init_id / _Init_label argument validation and
|
||||
* id/label storage round-trip. Independent of any cryptocb device. */
|
||||
static wc_test_ret_t slhdsa_id_label_test(void)
|
||||
{
|
||||
wc_test_ret_t ret;
|
||||
SlhDsaKey key;
|
||||
static const unsigned char id[] = {
|
||||
0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf6, 0x07, 0x18,
|
||||
0x29, 0x3a, 0x4b, 0x5c, 0x6d, 0x7e, 0x8f, 0x90
|
||||
};
|
||||
static const char label[] = "slh-dsa-test-label";
|
||||
enum SlhDsaParam param =
|
||||
#ifdef WOLFSSL_SLHDSA_PARAM_128S
|
||||
SLHDSA_SHAKE128S;
|
||||
#elif defined(WOLFSSL_SLHDSA_PARAM_128F)
|
||||
SLHDSA_SHAKE128F;
|
||||
#elif defined(WOLFSSL_SLHDSA_PARAM_SHA2_128S)
|
||||
SLHDSA_SHA2_128S;
|
||||
#else
|
||||
SLHDSA_SHA2_128F;
|
||||
#endif
|
||||
|
||||
/* Zero the stack key so rejection-path tests below don't read
|
||||
* uninitialized fields if a future Init refactor inspects key state
|
||||
* before zeroizing it. */
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
/* NULL key rejected. */
|
||||
ret = wc_SlhDsaKey_Init_id(NULL, param, id, (int)sizeof(id), HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* (id == NULL, len > 0) is the silent-contradiction case the original
|
||||
* review flagged; must be rejected. */
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, NULL, 8, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* Length over the cap rejected with BUFFER_E. */
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, id, SLHDSA_MAX_ID_LEN + 1,
|
||||
HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BUFFER_E))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* Negative length rejected. */
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, id, -1, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BUFFER_E))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* Successful init copies the id and stores its length. */
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, id, (int)sizeof(id), HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
if (key.idLen != (int)sizeof(id))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
if ((ret == 0) && (XMEMCMP(key.id, id, sizeof(id)) != 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
/* (id != NULL, len == 0) is accepted as a no-op. */
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, id, 0, HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
if (key.idLen != 0)
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
/* Boundary: exactly SLHDSA_MAX_ID_LEN bytes must be accepted and round
|
||||
* trip byte-for-byte. */
|
||||
{
|
||||
unsigned char id_max[SLHDSA_MAX_ID_LEN];
|
||||
int i;
|
||||
for (i = 0; i < SLHDSA_MAX_ID_LEN; i++)
|
||||
id_max[i] = (unsigned char)(0x40 + i);
|
||||
ret = wc_SlhDsaKey_Init_id(&key, param, id_max, SLHDSA_MAX_ID_LEN,
|
||||
HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
if (key.idLen != SLHDSA_MAX_ID_LEN)
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
if ((ret == 0) &&
|
||||
(XMEMCMP(key.id, id_max, SLHDSA_MAX_ID_LEN) != 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
}
|
||||
|
||||
/* Init_label: NULL label / NULL key rejected. */
|
||||
ret = wc_SlhDsaKey_Init_label(NULL, param, label, HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
ret = wc_SlhDsaKey_Init_label(&key, param, NULL, HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* Empty label is rejected. */
|
||||
ret = wc_SlhDsaKey_Init_label(&key, param, "", HEAP_HINT, INVALID_DEVID);
|
||||
if (ret != WC_NO_ERR_TRACE(BUFFER_E))
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
|
||||
/* Successful init copies the label and stores its length. */
|
||||
ret = wc_SlhDsaKey_Init_label(&key, param, label, HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
if (key.labelLen != (int)XSTRLEN(label))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
if ((ret == 0) &&
|
||||
(XMEMCMP(key.label, label, (size_t)key.labelLen) != 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
/* Boundary: a SLHDSA_MAX_LABEL_LEN-char label (33-byte buffer with the
|
||||
* trailing NUL) must be accepted. The stored copy fills the whole
|
||||
* key->label array and is NOT NUL-terminated; callers must use
|
||||
* key->labelLen. */
|
||||
{
|
||||
char label_max[SLHDSA_MAX_LABEL_LEN + 1];
|
||||
int i;
|
||||
for (i = 0; i < SLHDSA_MAX_LABEL_LEN; i++)
|
||||
label_max[i] = 'L';
|
||||
label_max[SLHDSA_MAX_LABEL_LEN] = '\0';
|
||||
ret = wc_SlhDsaKey_Init_label(&key, param, label_max, HEAP_HINT,
|
||||
INVALID_DEVID);
|
||||
if (ret != 0)
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
if (key.labelLen != SLHDSA_MAX_LABEL_LEN)
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
if ((ret == 0) &&
|
||||
(XMEMCMP(key.label, label_max, SLHDSA_MAX_LABEL_LEN) != 0))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
wc_SlhDsaKey_Free(&key);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLF_PRIVATE_KEY_ID && (SHAKE128S|F || SHA2_128S|F) */
|
||||
|
||||
wc_test_ret_t slhdsa_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -58598,7 +58759,10 @@ wc_test_ret_t slhdsa_test(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = wc_SlhDsaKey_Init(key_vfy, SLHDSA_SHAKE128S, NULL, INVALID_DEVID);
|
||||
/* Use module-global devId so this verify routes through the cryptocb
|
||||
* when registered. In VERIFY_ONLY builds this is the only path through
|
||||
* slhdsa_test() that exercises the cb. */
|
||||
ret = wc_SlhDsaKey_Init(key_vfy, SLHDSA_SHAKE128S, NULL, devId);
|
||||
if (ret != 0) {
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
}
|
||||
@@ -59317,6 +59481,22 @@ wc_test_ret_t slhdsa_test(void)
|
||||
|
||||
#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */
|
||||
|
||||
#if defined(WOLF_PRIVATE_KEY_ID) && \
|
||||
(defined(WOLFSSL_SLHDSA_PARAM_128S) || defined(WOLFSSL_SLHDSA_PARAM_128F) || \
|
||||
defined(WOLFSSL_SLHDSA_PARAM_SHA2_128S) || \
|
||||
defined(WOLFSSL_SLHDSA_PARAM_SHA2_128F))
|
||||
/* Init_id/Init_label/Free are available in VERIFY_ONLY builds, so this
|
||||
* runs regardless of VERIFY_ONLY. Fall through to cleanup on failure
|
||||
* (no `goto out;` because `out:` is not defined in 128F-only +
|
||||
* VERIFY_ONLY builds, and no allocations precede this point that
|
||||
* would need an early bail-out). */
|
||||
if (ret == 0) {
|
||||
ret = slhdsa_id_label_test();
|
||||
if (ret != 0)
|
||||
wc_test_render_error_message("SLHDSA_ID_LABEL", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SLHDSA_TEST_HAVE_ANY_PARAM
|
||||
out:
|
||||
#endif
|
||||
@@ -71995,6 +72175,95 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
ret = 0;
|
||||
}
|
||||
#endif /* WOLFSSL_HAVE_LMS || WOLFSSL_HAVE_XMSS */
|
||||
#if defined(WOLFSSL_HAVE_SLHDSA)
|
||||
#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_SIG_KEYGEN) {
|
||||
int pqcType = info->pk.pqc_sig_kg.type;
|
||||
(void)pqcType;
|
||||
if (pqcType == WC_PQC_SIG_TYPE_SLHDSA) {
|
||||
SlhDsaKey* sk = (SlhDsaKey*)info->pk.pqc_sig_kg.key;
|
||||
sk->devId = INVALID_DEVID;
|
||||
ret = wc_SlhDsaKey_MakeKey(sk, info->pk.pqc_sig_kg.rng);
|
||||
sk->devId = devIdArg;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
}
|
||||
else if (info->pk.type == WC_PK_TYPE_PQC_SIG_SIGN) {
|
||||
int pqcType = info->pk.pqc_sign.type;
|
||||
(void)pqcType;
|
||||
if (pqcType == WC_PQC_SIG_TYPE_SLHDSA) {
|
||||
SlhDsaKey* sk = (SlhDsaKey*)info->pk.pqc_sign.key;
|
||||
enum wc_HashType phType =
|
||||
(enum wc_HashType)info->pk.pqc_sign.preHashType;
|
||||
sk->devId = INVALID_DEVID;
|
||||
if (phType == WC_HASH_TYPE_NONE) {
|
||||
ret = wc_SlhDsaKey_Sign(sk,
|
||||
info->pk.pqc_sign.context,
|
||||
info->pk.pqc_sign.contextLen,
|
||||
info->pk.pqc_sign.in,
|
||||
info->pk.pqc_sign.inlen,
|
||||
info->pk.pqc_sign.out,
|
||||
info->pk.pqc_sign.outlen,
|
||||
info->pk.pqc_sign.rng);
|
||||
}
|
||||
else {
|
||||
ret = wc_SlhDsaKey_SignHash(sk,
|
||||
info->pk.pqc_sign.context,
|
||||
info->pk.pqc_sign.contextLen,
|
||||
info->pk.pqc_sign.in,
|
||||
info->pk.pqc_sign.inlen,
|
||||
phType,
|
||||
info->pk.pqc_sign.out,
|
||||
info->pk.pqc_sign.outlen,
|
||||
info->pk.pqc_sign.rng);
|
||||
}
|
||||
sk->devId = devIdArg;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* !WOLFSSL_SLHDSA_VERIFY_ONLY */
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_SIG_VERIFY) {
|
||||
int pqcType = info->pk.pqc_verify.type;
|
||||
(void)pqcType;
|
||||
if (pqcType == WC_PQC_SIG_TYPE_SLHDSA) {
|
||||
SlhDsaKey* sk = (SlhDsaKey*)info->pk.pqc_verify.key;
|
||||
enum wc_HashType phType =
|
||||
(enum wc_HashType)info->pk.pqc_verify.preHashType;
|
||||
int verifyRet = WC_NO_ERR_TRACE(NOT_COMPILED_IN);
|
||||
sk->devId = INVALID_DEVID;
|
||||
if (phType == WC_HASH_TYPE_NONE) {
|
||||
verifyRet = wc_SlhDsaKey_Verify(sk,
|
||||
info->pk.pqc_verify.context,
|
||||
info->pk.pqc_verify.contextLen,
|
||||
info->pk.pqc_verify.msg,
|
||||
info->pk.pqc_verify.msglen,
|
||||
info->pk.pqc_verify.sig,
|
||||
info->pk.pqc_verify.siglen);
|
||||
}
|
||||
else {
|
||||
verifyRet = wc_SlhDsaKey_VerifyHash(sk,
|
||||
info->pk.pqc_verify.context,
|
||||
info->pk.pqc_verify.contextLen,
|
||||
info->pk.pqc_verify.msg,
|
||||
info->pk.pqc_verify.msglen,
|
||||
phType,
|
||||
info->pk.pqc_verify.sig,
|
||||
info->pk.pqc_verify.siglen);
|
||||
}
|
||||
sk->devId = devIdArg;
|
||||
if (info->pk.pqc_verify.res != NULL) {
|
||||
*info->pk.pqc_verify.res = (verifyRet == 0) ? 1 : 0;
|
||||
}
|
||||
/* SIG_VERIFY_E is a validity signal, not a crypto error, so
|
||||
* translate it back to success for the dispatcher. */
|
||||
if (verifyRet == WC_NO_ERR_TRACE(SIG_VERIFY_E))
|
||||
verifyRet = 0;
|
||||
ret = verifyRet;
|
||||
myCtx->exampleVar++;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSL_HAVE_SLHDSA */
|
||||
#ifdef WOLFSSL_HAVE_MLKEM
|
||||
if (info->pk.type == WC_PK_TYPE_PQC_KEM_KEYGEN) {
|
||||
if ((info->pk.pqc_kem_kg.type == WC_PQC_KEM_TYPE_KYBER) &&
|
||||
@@ -72778,15 +73047,25 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_DILITHIUM
|
||||
#if defined(HAVE_DILITHIUM) || defined(WOLFSSL_HAVE_SLHDSA)
|
||||
case WC_PK_TYPE_PQC_SIG_KEYGEN:
|
||||
{
|
||||
#ifdef HAVE_DILITHIUM
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_SLHDSA
|
||||
if (info->free.subType == WC_PQC_SIG_TYPE_SLHDSA) {
|
||||
SlhDsaKey* slh = (SlhDsaKey*)info->free.obj;
|
||||
slh->devId = INVALID_DEVID;
|
||||
wc_SlhDsaKey_Free(slh);
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -73454,6 +73733,27 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void)
|
||||
if (ret == 0)
|
||||
ret = dilithium_test();
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_SLHDSA
|
||||
if (ret == 0) {
|
||||
/* Reuse exampleVar as a hit counter for the SLH-DSA cb branches.
|
||||
* baseline holds the value seen by every other cb at this point;
|
||||
* we restore it after, so subsequent tests are unaffected.
|
||||
* Confirms the SLH-DSA cb path was actually exercised; a silent
|
||||
* SW fallback would otherwise mask a regression in the dispatch.
|
||||
*
|
||||
* Only enforce when slhdsa_test() actually runs a cb-routed op:
|
||||
* !VERIFY_ONLY runs slhdsa_test_param (uses devId), or
|
||||
* PARAM_128S enables the in-tree KAT verify (also uses devId). */
|
||||
int baseline = myCtx.exampleVar;
|
||||
ret = slhdsa_test();
|
||||
#if !defined(WOLFSSL_SLHDSA_VERIFY_ONLY) || \
|
||||
defined(WOLFSSL_SLHDSA_PARAM_128S)
|
||||
if ((ret == 0) && (myCtx.exampleVar == baseline))
|
||||
ret = WC_TEST_RET_ENC_NC;
|
||||
#endif
|
||||
myCtx.exampleVar = baseline;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)
|
||||
if (ret == 0)
|
||||
ret = xmss_test();
|
||||
|
||||
@@ -86,6 +86,9 @@
|
||||
#if defined(HAVE_FALCON)
|
||||
#include <wolfssl/wolfcrypt/falcon.h>
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_SLHDSA)
|
||||
#include <wolfssl/wolfcrypt/wc_slhdsa.h>
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#include <wolfssl/wolfcrypt/wc_lms.h>
|
||||
#endif
|
||||
@@ -312,7 +315,8 @@ typedef struct wc_CryptoInfo {
|
||||
int type; /* enum wc_PqcKemType */
|
||||
} pqc_decaps;
|
||||
#endif
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || \
|
||||
defined(WOLFSSL_HAVE_SLHDSA)
|
||||
struct {
|
||||
WC_RNG* rng;
|
||||
int size;
|
||||
@@ -776,7 +780,8 @@ WOLFSSL_LOCAL int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext,
|
||||
int type, void* key);
|
||||
#endif /* WOLFSSL_HAVE_MLKEM */
|
||||
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM)
|
||||
#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) || \
|
||||
defined(WOLFSSL_HAVE_SLHDSA)
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_PqcSigGetDevId(int type, void* key);
|
||||
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_MakePqcSignatureKey(WC_RNG* rng, int type,
|
||||
@@ -792,7 +797,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen,
|
||||
|
||||
WOLFSSL_LOCAL int wc_CryptoCb_PqcSignatureCheckPrivKey(void* key, int type,
|
||||
const byte* pubKey, word32 pubKeySz);
|
||||
#endif /* HAVE_FALCON || HAVE_DILITHIUM */
|
||||
#endif /* HAVE_FALCON || HAVE_DILITHIUM || WOLFSSL_HAVE_SLHDSA */
|
||||
|
||||
#ifndef NO_AES
|
||||
#ifdef HAVE_AESGCM
|
||||
|
||||
@@ -1559,7 +1559,8 @@ enum wc_PkType {
|
||||
#undef _WC_PK_TYPE_MAX
|
||||
#define _WC_PK_TYPE_MAX WC_PK_TYPE_PQC_KEM_DECAPS
|
||||
#endif
|
||||
#if defined(HAVE_DILITHIUM) || defined(HAVE_FALCON)
|
||||
#if defined(HAVE_DILITHIUM) || defined(HAVE_FALCON) || \
|
||||
defined(WOLFSSL_HAVE_SLHDSA)
|
||||
WC_PK_TYPE_PQC_SIG_KEYGEN = 21,
|
||||
WC_PK_TYPE_PQC_SIG_SIGN = 22,
|
||||
WC_PK_TYPE_PQC_SIG_VERIFY = 23,
|
||||
@@ -1597,7 +1598,8 @@ enum wc_PkType {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DILITHIUM) || defined(HAVE_FALCON)
|
||||
#if defined(HAVE_DILITHIUM) || defined(HAVE_FALCON) || \
|
||||
defined(WOLFSSL_HAVE_SLHDSA)
|
||||
/* Post quantum signature algorithms */
|
||||
enum wc_PqcSignatureType {
|
||||
WC_PQC_SIG_TYPE_NONE = 0,
|
||||
@@ -1611,6 +1613,11 @@ enum wc_PkType {
|
||||
WC_PQC_SIG_TYPE_FALCON = 2,
|
||||
#undef _WC_PQC_SIG_TYPE_MAX
|
||||
#define _WC_PQC_SIG_TYPE_MAX WC_PQC_SIG_TYPE_FALCON
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_SLHDSA)
|
||||
WC_PQC_SIG_TYPE_SLHDSA = 3,
|
||||
#undef _WC_PQC_SIG_TYPE_MAX
|
||||
#define _WC_PQC_SIG_TYPE_MAX WC_PQC_SIG_TYPE_SLHDSA
|
||||
#endif
|
||||
WC_PQC_SIG_TYPE_MAX = _WC_PQC_SIG_TYPE_MAX
|
||||
};
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/types.h>
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#include <wolfssl/wolfcrypt/cryptocb.h>
|
||||
#endif
|
||||
|
||||
#if FIPS_VERSION3_GE(7,0,0)
|
||||
#include <wolfssl/wolfcrypt/fips.h>
|
||||
#endif
|
||||
@@ -591,6 +595,11 @@ typedef struct SlhDsaParameters {
|
||||
#define WC_SLHDSA_FLAG_BOTH_KEYS (WC_SLHDSA_FLAG_PRIVATE | \
|
||||
WC_SLHDSA_FLAG_PUBLIC)
|
||||
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
#define SLHDSA_MAX_ID_LEN 32
|
||||
#define SLHDSA_MAX_LABEL_LEN 32
|
||||
#endif
|
||||
|
||||
/* SLH-DSA key data and state. */
|
||||
typedef struct SlhDsaKey {
|
||||
/* Parameters. */
|
||||
@@ -600,9 +609,17 @@ typedef struct SlhDsaKey {
|
||||
/* Dynamic memory hint. */
|
||||
void* heap;
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
/* Device context (opaque, owned by the registered callback). */
|
||||
void* devCtx;
|
||||
/* Device Identifier. */
|
||||
int devId;
|
||||
#endif
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
byte id[SLHDSA_MAX_ID_LEN];
|
||||
int idLen;
|
||||
char label[SLHDSA_MAX_LABEL_LEN];
|
||||
int labelLen;
|
||||
#endif
|
||||
|
||||
/* sk_seed | sk_prf | pk_seed, pk_root */
|
||||
byte sk[32 * 4];
|
||||
@@ -641,6 +658,12 @@ typedef struct SlhDsaKey {
|
||||
|
||||
WOLFSSL_API int wc_SlhDsaKey_Init(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
void* heap, int devId);
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
WOLFSSL_API int wc_SlhDsaKey_Init_id(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const unsigned char* id, int len, void* heap, int devId);
|
||||
WOLFSSL_API int wc_SlhDsaKey_Init_label(SlhDsaKey* key, enum SlhDsaParam param,
|
||||
const char* label, void* heap, int devId);
|
||||
#endif
|
||||
WOLFSSL_API void wc_SlhDsaKey_Free(SlhDsaKey* key);
|
||||
|
||||
#ifndef WOLFSSL_SLHDSA_VERIFY_ONLY
|
||||
|
||||
Reference in New Issue
Block a user