mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 10:50:53 +02:00
Merge pull request #10448 from SparkiDev/lms_fixes_1
LMS: fixes and improvements
This commit is contained in:
+16
-1
@@ -37899,7 +37899,11 @@ static int test_lms_init_key(LmsKey* key, WC_RNG* rng)
|
||||
ret = wc_LmsKey_Init(key, NULL, INVALID_DEVID);
|
||||
if (ret != 0) return ret;
|
||||
|
||||
#if !defined(WOLFSSL_LMS_MAX_HEIGHT) || (WOLFSSL_LMS_MAX_HEIGHT >= 10)
|
||||
ret = wc_LmsKey_SetParameters(key, 1, 10, 8);
|
||||
#else
|
||||
ret = wc_LmsKey_SetParameters(key, 1, 5, 8);
|
||||
#endif
|
||||
if (ret != 0) return ret;
|
||||
|
||||
ret = wc_LmsKey_SetWriteCb(key, test_lms_write_key);
|
||||
@@ -37973,7 +37977,8 @@ int test_wc_LmsKey_sign_verify(void)
|
||||
int test_wc_LmsKey_reload_cache(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
(!defined(WOLFSSL_LMS_MAX_HEIGHT) || (WOLFSSL_LMS_MAX_HEIGHT >= 10))
|
||||
LmsKey key;
|
||||
LmsKey vkey;
|
||||
WC_RNG rng;
|
||||
@@ -38012,7 +38017,11 @@ int test_wc_LmsKey_reload_cache(void)
|
||||
ExpectIntEQ(wc_LmsKey_Sign(&key, sig, &sigSz, msg, sizeof(msg)), 0);
|
||||
|
||||
ExpectIntEQ(wc_LmsKey_Init(&vkey, NULL, INVALID_DEVID), 0);
|
||||
#if !defined(WOLFSSL_LMS_MAX_HEIGHT) || (WOLFSSL_LMS_MAX_HEIGHT >= 10)
|
||||
ExpectIntEQ(wc_LmsKey_SetParameters(&vkey, 1, 10, 8), 0);
|
||||
#else
|
||||
ExpectIntEQ(wc_LmsKey_SetParameters(&vkey, 1, 5, 8), 0);
|
||||
#endif
|
||||
ExpectIntEQ(wc_LmsKey_ImportPubRaw(&vkey, pub, pubSz), 0);
|
||||
ExpectIntEQ(wc_LmsKey_Verify(&vkey, sig, sigSz, msg, sizeof(msg)), 0);
|
||||
|
||||
@@ -38688,9 +38697,15 @@ int test_rfc9802_lms_x509_verify(void)
|
||||
* or SHAKE-only builds skip this block. */
|
||||
static const char* const lmsFiles[] = {
|
||||
"./certs/lms/bc_lms_sha256_h5_w4_root.der",
|
||||
#if !defined(WOLFSSL_LMS_MAX_HEIGHT) || (WOLFSSL_LMS_MAX_HEIGHT >= 10)
|
||||
"./certs/lms/bc_lms_sha256_h10_w8_root.der",
|
||||
#endif
|
||||
#if !defined(WOLFSSL_LMS_MAX_LEVELS) || (WOLFSSL_LMS_MAX_LEVELS >= 2)
|
||||
"./certs/lms/bc_hss_L2_H5_W8_root.der",
|
||||
#endif
|
||||
#if !defined(WOLFSSL_LMS_MAX_LEVELS) || (WOLFSSL_LMS_MAX_LEVELS >= 3)
|
||||
"./certs/lms/bc_hss_L3_H5_W4_root.der",
|
||||
#endif
|
||||
"./certs/lms/bc_lms_native_bc_root.der",
|
||||
};
|
||||
size_t i;
|
||||
|
||||
@@ -11700,7 +11700,6 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
|
||||
XMEMCPY(key.pub, lms_pub_L4_H5_W8, HSS_MAX_PUBLIC_KEY_LEN);
|
||||
break;
|
||||
|
||||
case WC_LMS_PARM_NONE:
|
||||
case WC_LMS_PARM_L1_H15_W2:
|
||||
case WC_LMS_PARM_L1_H15_W4:
|
||||
case WC_LMS_PARM_L2_H10_W8:
|
||||
|
||||
+252
-107
@@ -98,10 +98,10 @@
|
||||
* @param [in] t LMS type.
|
||||
* @param [in] t2 LM-OTS type.
|
||||
*/
|
||||
#define LMS_PARAMS(l, h, w, wb, t, t2, hLen) \
|
||||
{ l, h, w, LMS_LS(w, wb), LMS_P(w, wb, hLen), t, t2, \
|
||||
LMS_PARAMS_SIG_LEN(l, h, LMS_P(w, wb, hLen), hLen), \
|
||||
(hLen), LMS_PARAMS_CACHE(h) }
|
||||
#define LMS_PARAMS(l, h, w, wb, t, t2, hLen) \
|
||||
{ l, h, w, LMS_LS(w, wb), LMS_P(w, wb, hLen), t, t2, \
|
||||
(hLen), LMS_PARAMS_SIG_LEN(l, h, LMS_P(w, wb, hLen), hLen), \
|
||||
LMS_PARAMS_CACHE(h) }
|
||||
|
||||
|
||||
/* Initialize the working state for LMS operations.
|
||||
@@ -165,9 +165,6 @@ static void wc_lmskey_state_free(LmsState* state)
|
||||
static const wc_LmsParamsMap wc_lms_map[] = {
|
||||
#ifndef WOLFSSL_NO_LMS_SHA256_256
|
||||
#if LMS_MAX_HEIGHT >= 15
|
||||
{ WC_LMS_PARM_NONE , "LMS_NONE" ,
|
||||
LMS_PARAMS(1, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2,
|
||||
WC_SHA256_DIGEST_SIZE) },
|
||||
{ WC_LMS_PARM_L1_H15_W2, "LMS/HSS L1_H15_W2",
|
||||
LMS_PARAMS(1, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2,
|
||||
WC_SHA256_DIGEST_SIZE) },
|
||||
@@ -607,6 +604,7 @@ static const wc_LmsParamsMap wc_lms_map[] = {
|
||||
/* Initialize LMS key.
|
||||
*
|
||||
* Call this before setting the params of an LMS key.
|
||||
* Must call wc_LmsKey_Free before calling this function again.
|
||||
*
|
||||
* @param [out] key LMS key to initialize.
|
||||
* @param [in] heap Heap hint.
|
||||
@@ -627,14 +625,11 @@ int wc_LmsKey_Init(LmsKey* key, void* heap, int devId)
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* Zeroize the key data. */
|
||||
ForceZero(key, sizeof(LmsKey));
|
||||
/* Clear the key data. */
|
||||
XMEMSET(key, 0, sizeof(LmsKey));
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
/* Initialize other fields. */
|
||||
key->write_private_key = NULL;
|
||||
key->read_private_key = NULL;
|
||||
key->context = NULL;
|
||||
key->heap = heap;
|
||||
#endif
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
@@ -657,7 +652,7 @@ int wc_LmsKey_Init(LmsKey* key, void* heap, int devId)
|
||||
* @param [in] devId Device identifier.
|
||||
*
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key is NULL.
|
||||
* @return BAD_FUNC_ARG when key is NULL, or id is NULL and len is not 0.
|
||||
* @return BUFFER_E when len is negative or exceeds LMS_MAX_ID_LEN.
|
||||
*/
|
||||
int wc_LmsKey_InitId(LmsKey* key, const unsigned char* id, int len, void* heap,
|
||||
@@ -665,13 +660,16 @@ int wc_LmsKey_InitId(LmsKey* key, const unsigned char* id, int len, void* heap,
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (key == NULL)
|
||||
if ((key == NULL) || ((id == NULL) && (len != 0))) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
if (ret == 0 && (len < 0 || len > LMS_MAX_ID_LEN))
|
||||
}
|
||||
if ((ret == 0) && ((len < 0) || (len > LMS_MAX_ID_LEN))) {
|
||||
ret = BUFFER_E;
|
||||
if (ret == 0)
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_LmsKey_Init(key, heap, devId);
|
||||
if (ret == 0 && id != NULL && len != 0) {
|
||||
}
|
||||
if ((ret == 0) && (id != NULL) && (len != 0)) {
|
||||
XMEMCPY(key->id, id, (size_t)len);
|
||||
key->idLen = len;
|
||||
}
|
||||
@@ -693,20 +691,23 @@ int wc_LmsKey_InitId(LmsKey* key, const unsigned char* id, int len, void* heap,
|
||||
int wc_LmsKey_InitLabel(LmsKey* key, const char* label, void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
int labelLen = 0;
|
||||
size_t labelLen = 0;
|
||||
|
||||
if (key == NULL || label == NULL)
|
||||
if ((key == NULL) || (label == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
if (ret == 0) {
|
||||
labelLen = (int)XSTRLEN(label);
|
||||
if (labelLen == 0 || labelLen > LMS_MAX_LABEL_LEN)
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = wc_LmsKey_Init(key, heap, devId);
|
||||
if (ret == 0) {
|
||||
XMEMCPY(key->label, label, (size_t)labelLen);
|
||||
key->labelLen = labelLen;
|
||||
labelLen = XSTRLEN(label);
|
||||
if ((labelLen == 0) || (labelLen > LMS_MAX_LABEL_LEN)) {
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_LmsKey_Init(key, heap, devId);
|
||||
}
|
||||
if (ret == 0) {
|
||||
XMEMCPY(key->label, label, labelLen);
|
||||
key->labelLen = (int)labelLen;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -790,10 +791,6 @@ int wc_LmsKey_SetLmsParm(LmsKey* key, enum wc_LmsParm lmsParm)
|
||||
}
|
||||
|
||||
/* Set the parameters of an LMS key.
|
||||
*
|
||||
* Use this if you wish to set specific parameters not found in the
|
||||
* wc_LmsParm predefined sets. See comments in wc_lms.h for allowed
|
||||
* parameters.
|
||||
*
|
||||
* Key must be inited before calling this.
|
||||
*
|
||||
@@ -804,6 +801,7 @@ int wc_LmsKey_SetLmsParm(LmsKey* key, enum wc_LmsParm lmsParm)
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key is NULL.
|
||||
* @return BAD_FUNC_ARG when parameters not supported.
|
||||
* @return BAD_STATE_E when key state is not initialized.
|
||||
* */
|
||||
int wc_LmsKey_SetParameters(LmsKey* key, int levels, int height,
|
||||
int winternitz)
|
||||
@@ -847,6 +845,67 @@ int wc_LmsKey_SetParameters(LmsKey* key, int levels, int height,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Set the parameters of an LMS key including hash length.
|
||||
*
|
||||
* Key must be inited before calling this.
|
||||
*
|
||||
* @param [in, out] key LMS key to set parameters on.
|
||||
* @param [in] levels Number of tree levels.
|
||||
* @param [in] height Height of each tree.
|
||||
* @param [in] winternitz Width or Winternitz coefficient.
|
||||
* @param [in] hash Hash algorithm to use. Valid values:
|
||||
* - LMS_SHA256
|
||||
* - LMS_SHA256_192
|
||||
* - LMS_SHAKE256
|
||||
* - LMS_SHAKE256_192
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key is NULL.
|
||||
* @return BAD_FUNC_ARG when parameters not supported.
|
||||
* @return BAD_STATE_E when key state is not initialized.
|
||||
* */
|
||||
int wc_LmsKey_SetParameters_ex(LmsKey* key, int levels, int height,
|
||||
int winternitz, int hash)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if (key == NULL) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Check state is valid. */
|
||||
if ((ret == 0) && (key->state != WC_LMS_STATE_INITED)) {
|
||||
WOLFSSL_MSG("error: LmsKey needs init");
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
int i;
|
||||
|
||||
ret = BAD_FUNC_ARG;
|
||||
/* Search through table for matching levels, height and width. */
|
||||
for (i = 0; i < WC_LMS_MAP_LEN; i++) {
|
||||
if ((levels == wc_lms_map[i].params.levels) &&
|
||||
(height == wc_lms_map[i].params.height) &&
|
||||
(winternitz == wc_lms_map[i].params.width) &&
|
||||
(hash == (wc_lms_map[i].params.lmsType & LMS_HASH_MASK))) {
|
||||
/* Set the parameters into the key. */
|
||||
key->params = &wc_lms_map[i].params;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Move the state to params set.
|
||||
* Key is ready for MakeKey or Reload. */
|
||||
key->state = WC_LMS_STATE_PARMSET;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the parameters of an LMS key.
|
||||
*
|
||||
* Key must be inited and parameters set before calling this.
|
||||
@@ -855,8 +914,10 @@ int wc_LmsKey_SetParameters(LmsKey* key, int levels, int height,
|
||||
* @param [out] levels Number of levels of trees.
|
||||
* @param [out] height Height of the trees.
|
||||
* @param [out] winternitz Winternitz width.
|
||||
* Returns 0 on success.
|
||||
* */
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key->params, levels, height or winternitz is
|
||||
* NULL.
|
||||
*/
|
||||
int wc_LmsKey_GetParameters(const LmsKey* key, int* levels, int* height,
|
||||
int* winternitz)
|
||||
{
|
||||
@@ -883,6 +944,46 @@ int wc_LmsKey_GetParameters(const LmsKey* key, int* levels, int* height,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the parameters of an LMS key.
|
||||
*
|
||||
* Key must be inited and parameters set before calling this.
|
||||
*
|
||||
* @param [in] key LMS key.
|
||||
* @param [out] levels Number of levels of trees.
|
||||
* @param [out] height Height of the trees.
|
||||
* @param [out] winternitz Winternitz width.
|
||||
* @param [out] hash Hash algorithm.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, key->params, levels, height, winternitz or
|
||||
* hash is NULL.
|
||||
*/
|
||||
int wc_LmsKey_GetParameters_ex(const LmsKey* key, int* levels, int* height,
|
||||
int* winternitz, int* hash)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if ((key == NULL) || (levels == NULL) || (height == NULL) ||
|
||||
(winternitz == NULL) || (hash == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Validate the parameters are available. */
|
||||
if ((ret == 0) && (key->params == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Set the levels, height and Winternitz width from parameters. */
|
||||
*levels = key->params->levels;
|
||||
*height = key->params->height;
|
||||
*winternitz = key->params->width;
|
||||
*hash = key->params->lmsType & LMS_HASH_MASK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Frees the LMS key from memory.
|
||||
*
|
||||
* This does not affect the private key saved to non-volatile storage.
|
||||
@@ -899,15 +1000,34 @@ void wc_LmsKey_Free(LmsKey* key)
|
||||
params->height, params->p, params->rootLevels,
|
||||
params->cacheBits, params->hash_len);
|
||||
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
priv_data_len += HSS_PRIVATE_KEY_LEN(key->params->hash_len);
|
||||
#endif
|
||||
#endif
|
||||
ForceZero(key->priv_data, priv_data_len);
|
||||
XFREE(key->priv_data, key->heap, DYNAMIC_TYPE_LMS);
|
||||
key->priv_data = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
ForceZero(key, sizeof(LmsKey));
|
||||
ForceZero(key->priv_raw, HSS_MAX_PRIVATE_KEY_LEN);
|
||||
ForceZero(&key->priv, sizeof(HssPrivKey));
|
||||
|
||||
key->write_private_key = NULL;
|
||||
key->read_private_key = NULL;
|
||||
key->context = NULL;
|
||||
key->heap = NULL;
|
||||
#endif
|
||||
XMEMSET(key->pub, 0, sizeof(key->pub));
|
||||
key->params = NULL;
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
key->devId = INVALID_DEVID;
|
||||
key->devCtx = NULL;
|
||||
#endif
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
XMEMSET(key->id, 0, sizeof(key->id));
|
||||
key->idLen = 0;
|
||||
XMEMSET(key->label, 0, sizeof(key->label));
|
||||
key->labelLen = 0;
|
||||
#endif
|
||||
|
||||
key->state = WC_LMS_STATE_FREED;
|
||||
}
|
||||
@@ -1051,6 +1171,13 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
ret = wc_CryptoCb_PqcStatefulSigKeyGen(WC_PQC_STATEFUL_SIG_TYPE_LMS,
|
||||
key, rng);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
/* This should not happen, but check whether signatures can be
|
||||
* created. */
|
||||
if ((ret == 0) && (wc_LmsKey_SigsLeft(key) == 0)) {
|
||||
WOLFSSL_MSG("error: generated LMS key signatures exhausted");
|
||||
key->state = WC_LMS_STATE_NOSIGS;
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
/* On success, mirror the software path's terminal state so
|
||||
* subsequent Sign/Verify calls don't fail with BAD_STATE_E. */
|
||||
if (ret == 0) {
|
||||
@@ -1072,9 +1199,9 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
priv_data_len = LMS_PRIV_DATA_LEN(params->levels, params->height,
|
||||
params->p, params->rootLevels, params->cacheBits, params->hash_len);
|
||||
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
priv_data_len += HSS_PRIVATE_KEY_LEN(key->params->hash_len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if ((ret == 0) && (key->priv_data == NULL)) {
|
||||
/* Allocate memory for the private key data. */
|
||||
@@ -1084,9 +1211,11 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
if (key->priv_data == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
XMEMSET(key->priv_data, 0, priv_data_len);
|
||||
#endif
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
else {
|
||||
XMEMSET(key->priv_data, 0, priv_data_len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (ret == 0) {
|
||||
WC_DECLARE_VAR(state, LmsState, 1, 0);
|
||||
@@ -1111,16 +1240,16 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
if (ret == 0) {
|
||||
int rv;
|
||||
/* Write private key to storage. */
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
XMEMCPY(key->priv_data + priv_data_len -
|
||||
HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->priv_raw,
|
||||
HSS_PRIVATE_KEY_LEN(key->params->hash_len));
|
||||
rv = key->write_private_key(key->priv_data, priv_data_len,
|
||||
key->context);
|
||||
#else
|
||||
#else
|
||||
rv = key->write_private_key(key->priv_raw,
|
||||
HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
|
||||
#endif
|
||||
#endif
|
||||
if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
|
||||
ret = IO_FAILED_E;
|
||||
}
|
||||
@@ -1141,8 +1270,10 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Reload a key that has been prepared with the appropriate params and
|
||||
* data. Use this if you wish to resume signing with an existing key.
|
||||
/* Reload a key that has been prepared with the appropriate params and data.
|
||||
*
|
||||
* Use this if you wish to resume signing with an existing key.
|
||||
* Call this function after initializing and setting parameters.
|
||||
*
|
||||
* Write/read callbacks, and context data, must be set prior.
|
||||
* Key must have parameters set.
|
||||
@@ -1185,9 +1316,9 @@ int wc_LmsKey_Reload(LmsKey* key)
|
||||
priv_data_len = LMS_PRIV_DATA_LEN(params->levels, params->height,
|
||||
params->p, params->rootLevels, params->cacheBits, params->hash_len);
|
||||
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
priv_data_len += HSS_PRIVATE_KEY_LEN(params->hash_len);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if ((ret == 0) && (key->priv_data == NULL)) {
|
||||
/* Allocate memory for the private key data. */
|
||||
@@ -1202,24 +1333,24 @@ int wc_LmsKey_Reload(LmsKey* key)
|
||||
int rv;
|
||||
|
||||
/* Load private key. */
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
const LmsParams* params = key->params;
|
||||
|
||||
rv = key->read_private_key(key->priv_data, priv_data_len, key->context);
|
||||
#else
|
||||
#else
|
||||
rv = key->read_private_key(key->priv_raw,
|
||||
HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
|
||||
#endif
|
||||
#endif
|
||||
if (rv != WC_LMS_RC_READ_TO_MEMORY) {
|
||||
ret = IO_FAILED_E;
|
||||
}
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
if (ret == 0) {
|
||||
XMEMCPY(key->priv_raw, key->priv_data + priv_data_len -
|
||||
HSS_PRIVATE_KEY_LEN(params->hash_len),
|
||||
HSS_PRIVATE_KEY_LEN(params->hash_len));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Double check the key actually has signatures left. */
|
||||
@@ -1258,7 +1389,7 @@ int wc_LmsKey_Reload(LmsKey* key)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get the private key length based on parameter set of key.
|
||||
/* Get the raw private key length based on parameter set of key.
|
||||
*
|
||||
* @param [in] key LMS key.
|
||||
* @param [out] len Length of private key.
|
||||
@@ -1292,7 +1423,7 @@ int wc_LmsKey_GetPrivLen(const LmsKey* key, word32* len)
|
||||
* @param [in] msgSz Length of message in bytes.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when key, sig, sigSz or msg is NULL.
|
||||
* @return BAD_FUNC_ARG when msgSz is not greater than 0.
|
||||
* @return BAD_FUNC_ARG when msgSz is less than 0.
|
||||
* @return BAD_FUNC_ARG when a write private key is not set.
|
||||
* @return BAD_FUNC_ARG when a read/write private key context is not set.
|
||||
* @return BUFFER_E when sigSz is too small.
|
||||
@@ -1305,21 +1436,22 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
int ret = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if ((key == NULL) || (sig == NULL) || (sigSz == NULL) || (msg == NULL)) {
|
||||
if ((key == NULL) || (key->params == NULL) || (sig == NULL) ||
|
||||
(sigSz == NULL) || (msg == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && (msgSz <= 0)) {
|
||||
if ((ret == 0) && (msgSz < 0)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
/* Check state. */
|
||||
if ((ret == 0) && (key->state == WC_LMS_STATE_NOSIGS)) {
|
||||
WOLFSSL_MSG("error: LMS signatures exhausted");
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
if ((ret == 0) && (key->state != WC_LMS_STATE_OK)) {
|
||||
/* The key had an error the last time it was used, and we
|
||||
* can't guarantee its state. */
|
||||
WOLFSSL_MSG("error: can't sign, LMS key not in good state");
|
||||
if (key->state == WC_LMS_STATE_NOSIGS) {
|
||||
WOLFSSL_MSG("error: LMS signatures exhausted");
|
||||
}
|
||||
else {
|
||||
/* The key state is not ready for signing. */
|
||||
WOLFSSL_MSG("error: can't sign, LMS key not in good state");
|
||||
}
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
/* Check signature buffer size. */
|
||||
@@ -1336,8 +1468,9 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
if ((ret == 0) && (key->devId != INVALID_DEVID)) {
|
||||
ret = wc_CryptoCb_PqcStatefulSigSign(msg, (word32)msgSz, sig, sigSz,
|
||||
WC_PQC_STATEFUL_SIG_TYPE_LMS, key);
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
|
||||
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
|
||||
return ret;
|
||||
}
|
||||
ret = 0; /* fall through to software path */
|
||||
}
|
||||
#endif
|
||||
@@ -1375,7 +1508,7 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
int rv;
|
||||
|
||||
/* Write private key to storage. */
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
#ifdef WOLFSSL_WC_LMS_SERIALIZE_STATE
|
||||
const LmsParams* params = key->params;
|
||||
word32 priv_data_len = LMS_PRIV_DATA_LEN(params->levels, params->height,
|
||||
params->p, params->rootLevels, params->cacheBits,
|
||||
@@ -1386,10 +1519,10 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
HSS_PRIVATE_KEY_LEN(params->hash_len));
|
||||
rv = key->write_private_key(key->priv_data, priv_data_len,
|
||||
key->context);
|
||||
#else
|
||||
#else
|
||||
rv = key->write_private_key(key->priv_raw,
|
||||
HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
|
||||
#endif
|
||||
#endif
|
||||
if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
|
||||
/* Write to NV storage failed. Erase the signature from
|
||||
* memory to prevent OTS key reuse if state is rolled back. */
|
||||
@@ -1414,7 +1547,7 @@ int wc_LmsKey_SigsLeft(LmsKey* key)
|
||||
|
||||
/* NULL keys have no signatures remaining. */
|
||||
if (key != NULL) {
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (key->devId != INVALID_DEVID) {
|
||||
word32 sigsLeft = 0;
|
||||
int cbRet = wc_CryptoCb_PqcStatefulSigSigsLeft(
|
||||
@@ -1432,7 +1565,7 @@ int wc_LmsKey_SigsLeft(LmsKey* key)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
ret = wc_hss_sigsleft(key->params, key->priv_raw);
|
||||
}
|
||||
|
||||
@@ -1467,8 +1600,8 @@ int wc_LmsKey_GetPubLen(const LmsKey* key, word32* len)
|
||||
/* Export a generated public key and parameter set from one LmsKey
|
||||
* to another, with explicit heap and device bindings.
|
||||
*
|
||||
* The destination is fully (re)initialized as a verify-only key;
|
||||
* any prior state on keyDst is discarded.
|
||||
* The destination key must be unused or have been freed.
|
||||
* The destination is fully initialized as a verify-only key.
|
||||
*
|
||||
* @param [out] keyDst LMS key to copy into.
|
||||
* @param [in] keySrc LMS key to copy.
|
||||
@@ -1477,32 +1610,29 @@ int wc_LmsKey_GetPubLen(const LmsKey* key, word32* len)
|
||||
* Use INVALID_DEVID when not using a device.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when keyDst or keySrc is NULL.
|
||||
* @return BAD_STATE_E when in the wrong state for the operation.
|
||||
*/
|
||||
int wc_LmsKey_ExportPub_ex(LmsKey* keyDst, const LmsKey* keySrc,
|
||||
void* heap, int devId)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
(void)heap;
|
||||
(void)devId;
|
||||
|
||||
if ((keyDst == NULL) || (keySrc == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && (keySrc->state != WC_LMS_STATE_OK) &&
|
||||
(keySrc->state != WC_LMS_STATE_VERIFYONLY) &&
|
||||
(keySrc->state != WC_LMS_STATE_NOSIGS)) {
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ForceZero(keyDst, sizeof(LmsKey));
|
||||
|
||||
ret = wc_LmsKey_Init(keyDst, heap, devId);
|
||||
}
|
||||
if (ret == 0) {
|
||||
keyDst->params = keySrc->params;
|
||||
XMEMCPY(keyDst->pub, keySrc->pub, sizeof(keySrc->pub));
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
keyDst->heap = heap;
|
||||
#endif
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
keyDst->devId = devId;
|
||||
#endif
|
||||
|
||||
/* Mark this key as verify only, to prevent misuse. */
|
||||
keyDst->state = WC_LMS_STATE_VERIFYONLY;
|
||||
}
|
||||
@@ -1752,7 +1882,8 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz,
|
||||
int ret = 0;
|
||||
|
||||
/* Validate parameters. */
|
||||
if ((key == NULL) || (sig == NULL) || (msg == NULL)) {
|
||||
if ((key == NULL) || (key->params == NULL) || (sig == NULL) ||
|
||||
(msg == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && (msgSz < 0)) {
|
||||
@@ -1821,31 +1952,36 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz,
|
||||
* @param [out] kidSz Size of key ID.
|
||||
* @return 0 on success.
|
||||
* @return BAD_FUNC_ARG when a key, kid or kidSz is NULL.
|
||||
* @return NOT_COMPILED_IN when key is on a device.
|
||||
*/
|
||||
int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid, word32* kidSz)
|
||||
int wc_LmsKey_GetKid(LmsKey* key, const byte** kid, word32* kidSz)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 offset;
|
||||
|
||||
if ((key == NULL) || (kid == NULL) || (kidSz == NULL)) {
|
||||
return BAD_FUNC_ARG;
|
||||
if ((key == NULL) || (key->params == NULL) || (kid == NULL) ||
|
||||
(kidSz == NULL)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
/* priv_raw is not populated for HSM-backed keys where the device owns
|
||||
* the private state; the returned KID will be zero bytes. Extend the
|
||||
* CryptoCb surface if device-side KID retrieval becomes a requirement. */
|
||||
if (key->devId != INVALID_DEVID) {
|
||||
* the private state. Extend the CryptoCb surface if device-side KID
|
||||
* retrieval becomes a requirement.
|
||||
*/
|
||||
if ((ret == 0) && (key->devId != INVALID_DEVID)) {
|
||||
WOLFSSL_MSG(
|
||||
"wc_LmsKey_GetKid: priv_raw may be uninitialised for HSM keys");
|
||||
"wc_LmsKey_GetKid: priv_raw may be uninitialised for HSM keys");
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
/* SEED length is hash length. */
|
||||
offset = HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + key->params->hash_len;
|
||||
*kid = key->priv_raw + offset;
|
||||
*kidSz = HSS_PRIVATE_KEY_LEN(key->params->hash_len) - offset;
|
||||
}
|
||||
|
||||
/* SEED length is hash length. */
|
||||
offset = HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + key->params->hash_len;
|
||||
*kid = key->priv_raw + offset;
|
||||
*kidSz = HSS_PRIVATE_KEY_LEN(key->params->hash_len) - offset;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -1859,18 +1995,27 @@ int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid, word32* kidSz)
|
||||
* @param Pointer to 16 byte Key ID in the private key.
|
||||
* @return NULL on failure.
|
||||
*/
|
||||
const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz)
|
||||
const byte* wc_LmsKey_GetKidFromPrivRaw(const byte* priv, word32 privSz)
|
||||
{
|
||||
word32 seedSz = privSz - HSS_Q_LEN - HSS_PRIV_KEY_PARAM_SET_LEN - LMS_I_LEN;
|
||||
const byte* ret;
|
||||
|
||||
if (priv == NULL) {
|
||||
return NULL;
|
||||
if ((priv == NULL) ||
|
||||
(privSz < HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + LMS_I_LEN)) {
|
||||
ret = NULL;
|
||||
}
|
||||
if ((seedSz != WC_SHA256_192_DIGEST_SIZE) &&
|
||||
(seedSz != WC_SHA256_DIGEST_SIZE)) {
|
||||
return NULL;
|
||||
else {
|
||||
word32 seedSz = privSz - HSS_Q_LEN - HSS_PRIV_KEY_PARAM_SET_LEN -
|
||||
LMS_I_LEN;
|
||||
if ((seedSz != WC_SHA256_192_DIGEST_SIZE) &&
|
||||
(seedSz != WC_SHA256_DIGEST_SIZE)) {
|
||||
ret = NULL;
|
||||
}
|
||||
else {
|
||||
ret = priv + privSz - LMS_I_LEN;
|
||||
}
|
||||
}
|
||||
return priv + privSz - LMS_I_LEN;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+46
-27
@@ -926,7 +926,7 @@ static int wc_lmots_msg_hash(LmsState* state, const byte* msg, word32 msgSz,
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (ret == 0) {
|
||||
ret = NOT_COMPILED_IN;
|
||||
}
|
||||
}
|
||||
@@ -2103,7 +2103,7 @@ static int wc_lms_treehash(LmsState* state, const byte* id, const byte* seed,
|
||||
ret = wc_lms_interior_hash(state, sp, r, temp);
|
||||
|
||||
/* Copy out node to authentication path if on path. */
|
||||
if ((ret == 0) && (auth_path != NULL) && ((q >> h) ^ 0x1) == j) {
|
||||
if ((ret == 0) && (auth_path != NULL) && (((q >> h) ^ 0x1) == j)) {
|
||||
XMEMCPY(auth_path + h * params->hash_len, temp,
|
||||
params->hash_len);
|
||||
}
|
||||
@@ -2256,7 +2256,7 @@ static int wc_lms_treehash_init(LmsState* state, LmsPrivState* privState,
|
||||
}
|
||||
|
||||
/* Copy out node to authentication path if on path. */
|
||||
if ((ret == 0) && (auth_path != NULL) && ((q >> h) ^ 0x1) == j) {
|
||||
if ((ret == 0) && (auth_path != NULL) && (((q >> h) ^ 0x1) == j)) {
|
||||
XMEMCPY(auth_path + h * params->hash_len, temp,
|
||||
params->hash_len);
|
||||
}
|
||||
@@ -2350,15 +2350,21 @@ static int wc_lms_treehash_update(LmsState* state, LmsPrivState* privState,
|
||||
params->hash_len;
|
||||
/* Copy cached node into working buffer. */
|
||||
XMEMCPY(temp, leaf->cache + off, params->hash_len);
|
||||
/* I || u32str(i) || ... */
|
||||
c32toa(i, rp);
|
||||
}
|
||||
else {
|
||||
/* Calculate leaf node hash. */
|
||||
ret = wc_lms_leaf_hash(state, seed, i, r, temp);
|
||||
|
||||
/* Check if this is at the end of the cache and not beyond q plus
|
||||
* the number of leaf nodes. */
|
||||
/* Slide the leaf cache forward by one slot when i is exactly the
|
||||
* leaf immediately past the cached window and still within the
|
||||
* window we will need to cover q. Callers (wc_hss_init_auth_path /
|
||||
* wc_hss_update_auth_path) advance i contiguously, so i never
|
||||
* jumps past leaf->idx + max_cb in normal use; if that invariant
|
||||
* is broken, the cache stays put and i is silently uncached
|
||||
* (correct, but defeats the cache). */
|
||||
if (i > leaf->idx + max_cb) {
|
||||
WOLFSSL_MSG("Bad value for index");
|
||||
}
|
||||
if ((i == leaf->idx + max_cb) && (i < (q + max_cb))) {
|
||||
/* Copy working node into cache over old first node. */
|
||||
XMEMCPY(leaf->cache + leaf->offset * params->hash_len, temp,
|
||||
@@ -2834,12 +2840,14 @@ static int wc_lms_verify(LmsState* state, const byte* pub, const byte* msg,
|
||||
* (low 12 bits, LMS_H_W_MASK). The wire format strips the
|
||||
* private flags (see encoder lines 2483, 2510, 1559), so the
|
||||
* comparison is against the RFC type code only. This is safe so
|
||||
* long as the low-12-bit codes remain globally distinct across
|
||||
* hash families (they are today: 0x05-0x09 SHA-256/M32,
|
||||
* 0x0a-0x0e SHA-256/M24, 0x0f-0x13 SHAKE/M32, etc.). Any future
|
||||
* parameter set that introduces a collision in the low 12 bits
|
||||
* would require this check to compare the full lmsType, not the
|
||||
* masked form. */
|
||||
* long as the (lmsType, lmOtsType) pair, masked to the low 12 bits,
|
||||
* is unique across the static map -- i.e., no two entries from
|
||||
* different hash families happen to have the same RFC code pair.
|
||||
* All current entries have matching hash families, so the pair is
|
||||
* trivially unique. A future entry mixing families would need this
|
||||
* checked explicitly. Any future parameter set that introduces a
|
||||
* collision in the low 12 bits would require this check to compare
|
||||
* the full lmsType, not the masked form. */
|
||||
const byte* sig_lms_type = sig + LMS_Q_LEN + LMS_TYPE_LEN +
|
||||
params->hash_len + params->p * params->hash_len;
|
||||
word32 sigType;
|
||||
@@ -3118,12 +3126,13 @@ static int wc_lms_next_subtree_init(LmsState* state, LmsPrivState* privState,
|
||||
byte* priv_i;
|
||||
word32 pq;
|
||||
|
||||
/* Get next key pointer. */
|
||||
priv_q = priv;
|
||||
priv += LMS_Q_LEN;
|
||||
/* Get pointers of current private. */
|
||||
priv_seed = curr + LMS_Q_LEN;
|
||||
priv += params->hash_len;
|
||||
priv_i = curr + LMS_Q_LEN + params->hash_len;
|
||||
priv += LMS_I_LEN;
|
||||
/* Move next private key to next leaf for updating.*/
|
||||
priv += LMS_Q_LEN + params->hash_len + LMS_I_LEN;
|
||||
|
||||
ato32(curr, &pq);
|
||||
pq = (pq + 1U) & ((((word32)1U) << params->height) - (word32)1U);
|
||||
@@ -3182,7 +3191,7 @@ static int wc_hss_next_subtree_inc(LmsState* state, HssPrivKey* priv_key,
|
||||
cp64_hi = w64ShiftRight(p64, (params->levels - i - 1) * params->height);
|
||||
cq64_hi = w64ShiftRight(q64, (params->levels - i - 1) * params->height);
|
||||
/* Get the q for the child. */
|
||||
ato32(curr + LMS_PRIV_LEN(params->hash_len), (unsigned int*)&qc);
|
||||
ato32(curr + LMS_PRIV_LEN(params->hash_len), &qc);
|
||||
|
||||
/* Compare index of parent node with previous value. */
|
||||
if (w64LT(p64_hi, q64_hi)) {
|
||||
@@ -3426,7 +3435,7 @@ static int wc_hss_presign(LmsState* state, HssPrivKey* priv_key)
|
||||
const LmsParams* params = state->params;
|
||||
byte* buffer = state->buffer;
|
||||
byte pub[LMS_PUBKEY_LEN(LMS_MAX_NODE_LEN)];
|
||||
byte* root = pub + LMS_PUBKEY_LEN(LMS_MAX_NODE_LEN) - params->hash_len;
|
||||
byte* root = pub + LMS_PUBKEY_LEN(params->hash_len) - params->hash_len;
|
||||
byte* priv = priv_key->priv;
|
||||
int i;
|
||||
|
||||
@@ -3514,8 +3523,6 @@ static void wc_hss_priv_data_store(const LmsParams* params, HssPrivKey* key,
|
||||
{
|
||||
int l;
|
||||
|
||||
(void)key;
|
||||
|
||||
/* Expanded private keys. */
|
||||
priv_data += LMS_PRIV_KEY_LEN(params->levels, params->hash_len);
|
||||
|
||||
@@ -4022,15 +4029,23 @@ int wc_hss_sign(LmsState* state, byte* priv_raw, HssPrivKey* priv_key,
|
||||
*/
|
||||
int wc_hss_sigsleft(const LmsParams* params, const byte* priv_raw)
|
||||
{
|
||||
int ret;
|
||||
w64wrapper q;
|
||||
w64wrapper cnt;
|
||||
|
||||
/* Get current q - next leaf index to sign with. */
|
||||
ato64(priv_raw, &q);
|
||||
/* 1 << total_height = total leaf nodes. */
|
||||
cnt = w64ShiftLeft(w64From32(0, 1), params->levels * params->height);
|
||||
/* Check q is less than total leaf node count. */
|
||||
return w64LT(q, cnt);
|
||||
if (params->levels * params->height >= 64) {
|
||||
ret = 1;
|
||||
}
|
||||
else {
|
||||
/* Get current q - next leaf index to sign with. */
|
||||
ato64(priv_raw, &q);
|
||||
/* 1 << total_height = total leaf nodes. */
|
||||
cnt = w64ShiftLeft(w64From32(0, 1), params->levels * params->height);
|
||||
/* Check q is less than total leaf node count. */
|
||||
ret = w64LT(q, cnt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* !WOLFSSL_LMS_VERIFY_ONLY */
|
||||
|
||||
@@ -4086,8 +4101,12 @@ int wc_hss_verify(LmsState* state, const byte* pub, const byte* msg,
|
||||
sig += LMS_L_LEN;
|
||||
sigRem = sigSz - LMS_L_LEN;
|
||||
|
||||
/* Validate that the count of levels matches the parameters. */
|
||||
if (levels != state->params->levels) {
|
||||
ret = SIG_VERIFY_E;
|
||||
}
|
||||
/* Line 2: Verify that pub and signature match in levels. */
|
||||
if (nspk + 1 != levels) {
|
||||
if ((ret == 0) && (nspk + 1 != levels)) {
|
||||
/* Line 3: Return invalid signature. */
|
||||
ret = SIG_VERIFY_E;
|
||||
}
|
||||
|
||||
+44
-38
@@ -112,8 +112,10 @@
|
||||
#define WC_LMS_I_LEN 16
|
||||
|
||||
/* Private key write and read callbacks. */
|
||||
typedef int (*wc_lms_write_private_key_cb)(const byte * priv, word32 privSz, void *context);
|
||||
typedef int (*wc_lms_read_private_key_cb)(byte * priv, word32 privSz, void *context);
|
||||
typedef int (*wc_lms_write_private_key_cb)(const byte* priv, word32 privSz,
|
||||
void* context);
|
||||
typedef int (*wc_lms_read_private_key_cb)(byte* priv, word32 privSz,
|
||||
void* context);
|
||||
|
||||
/* Return codes returned by private key callbacks. */
|
||||
enum wc_LmsRc {
|
||||
@@ -157,7 +159,6 @@ enum wc_LmsRc {
|
||||
* will be large. */
|
||||
enum wc_LmsParm {
|
||||
#ifndef WOLFSSL_NO_LMS_SHA256_256
|
||||
WC_LMS_PARM_NONE = 0,
|
||||
WC_LMS_PARM_L1_H5_W1 = 1,
|
||||
WC_LMS_PARM_L1_H5_W2 = 2,
|
||||
WC_LMS_PARM_L1_H5_W4 = 3,
|
||||
@@ -617,10 +618,10 @@ typedef struct LmsParams {
|
||||
word16 lmsType;
|
||||
/* LMOTS type. */
|
||||
word16 lmOtsType;
|
||||
/* Length of LM-OTS signature. */
|
||||
word16 sig_len;
|
||||
/* Length of seed. */
|
||||
word16 hash_len;
|
||||
/* Length of LM-OTS signature. */
|
||||
word32 sig_len;
|
||||
#ifndef WOLFSSL_WC_LMS_SMALL
|
||||
/* Number of root levels of interior nodes to store. */
|
||||
word8 rootLevels;
|
||||
@@ -793,50 +794,55 @@ typedef struct LmsKey {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
WOLFSSL_API int wc_LmsKey_Init(LmsKey * key, void * heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_Init(LmsKey* key, void* heap, int devId);
|
||||
#ifdef WOLF_PRIVATE_KEY_ID
|
||||
WOLFSSL_API int wc_LmsKey_InitId(LmsKey * key, const unsigned char * id,
|
||||
int len, void * heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_InitLabel(LmsKey * key, const char * label,
|
||||
void * heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_InitId(LmsKey* key, const unsigned char* id,
|
||||
int len, void* heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_InitLabel(LmsKey* key, const char* label,
|
||||
void* heap, int devId);
|
||||
#endif
|
||||
WOLFSSL_API int wc_LmsKey_SetLmsParm(LmsKey * key, enum wc_LmsParm lmsParm);
|
||||
WOLFSSL_API int wc_LmsKey_SetParameters(LmsKey * key, int levels,
|
||||
WOLFSSL_API int wc_LmsKey_SetLmsParm(LmsKey* key, enum wc_LmsParm lmsParm);
|
||||
WOLFSSL_API int wc_LmsKey_SetParameters(LmsKey* key, int levels,
|
||||
int height, int winternitz);
|
||||
WOLFSSL_API int wc_LmsKey_GetParameters(const LmsKey * key, int * levels,
|
||||
int * height, int * winternitz);
|
||||
WOLFSSL_API int wc_LmsKey_SetParameters_ex(LmsKey* key, int levels,
|
||||
int height, int winternitz, int hash);
|
||||
WOLFSSL_API int wc_LmsKey_GetParameters(const LmsKey* key, int* levels,
|
||||
int* height, int* winternitz);
|
||||
WOLFSSL_API int wc_LmsKey_GetParameters_ex(const LmsKey* key, int* levels,
|
||||
int* height, int* winternitz, int* hash);
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
WOLFSSL_API int wc_LmsKey_SetWriteCb(LmsKey * key,
|
||||
WOLFSSL_API int wc_LmsKey_SetWriteCb(LmsKey* key,
|
||||
wc_lms_write_private_key_cb write_cb);
|
||||
WOLFSSL_API int wc_LmsKey_SetReadCb(LmsKey * key,
|
||||
WOLFSSL_API int wc_LmsKey_SetReadCb(LmsKey* key,
|
||||
wc_lms_read_private_key_cb read_cb);
|
||||
WOLFSSL_API int wc_LmsKey_SetContext(LmsKey * key, void * context);
|
||||
WOLFSSL_API int wc_LmsKey_MakeKey(LmsKey * key, WC_RNG * rng);
|
||||
WOLFSSL_API int wc_LmsKey_Reload(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_GetPrivLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_Sign(LmsKey * key, byte * sig, word32 * sigSz,
|
||||
const byte * msg, int msgSz);
|
||||
WOLFSSL_API int wc_LmsKey_SigsLeft(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_SetContext(LmsKey* key, void* context);
|
||||
WOLFSSL_API int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng);
|
||||
WOLFSSL_API int wc_LmsKey_Reload(LmsKey* key);
|
||||
WOLFSSL_API int wc_LmsKey_GetPrivLen(const LmsKey* key, word32* len);
|
||||
WOLFSSL_API int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz,
|
||||
const byte* msg, int msgSz);
|
||||
WOLFSSL_API int wc_LmsKey_SigsLeft(LmsKey* key);
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
WOLFSSL_API void wc_LmsKey_Free(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_GetSigLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_GetPubLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub(LmsKey * keyDst, const LmsKey * keySrc);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub_ex(LmsKey * keyDst, const LmsKey * keySrc,
|
||||
void * heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPubRaw(const LmsKey * key, byte * out,
|
||||
word32 * outLen);
|
||||
WOLFSSL_API int wc_LmsKey_ImportPubRaw(LmsKey * key, const byte * in,
|
||||
WOLFSSL_API void wc_LmsKey_Free(LmsKey* key);
|
||||
WOLFSSL_API int wc_LmsKey_GetSigLen(const LmsKey* key, word32* len);
|
||||
WOLFSSL_API int wc_LmsKey_GetPubLen(const LmsKey* key, word32* len);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub(LmsKey* keyDst, const LmsKey* keySrc);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub_ex(LmsKey* keyDst, const LmsKey* keySrc,
|
||||
void* heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPubRaw(const LmsKey* key, byte* out,
|
||||
word32* outLen);
|
||||
WOLFSSL_API int wc_LmsKey_ImportPubRaw(LmsKey* key, const byte* in,
|
||||
word32 inLen);
|
||||
WOLFSSL_API int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
|
||||
const byte * msg, int msgSz);
|
||||
WOLFSSL_API const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm);
|
||||
WOLFSSL_API const char * wc_LmsKey_RcToStr(enum wc_LmsRc lmsRc);
|
||||
WOLFSSL_API int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz,
|
||||
const byte* msg, int msgSz);
|
||||
WOLFSSL_API const char* wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm);
|
||||
|
||||
WOLFSSL_API int wc_LmsKey_GetKid(LmsKey * key, const byte ** kid,
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
WOLFSSL_API int wc_LmsKey_GetKid(LmsKey* key, const byte** kid,
|
||||
word32* kidSz);
|
||||
WOLFSSL_API const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv,
|
||||
WOLFSSL_API const byte* wc_LmsKey_GetKidFromPrivRaw(const byte* priv,
|
||||
word32 privSz);
|
||||
#endif
|
||||
|
||||
int wc_hss_make_key(LmsState* state, WC_RNG* rng, byte* priv_raw,
|
||||
HssPrivKey* priv_key, byte* priv_data, byte* pub);
|
||||
|
||||
@@ -108,7 +108,6 @@ pub struct Lms {
|
||||
|
||||
#[cfg(lms_sha256_256)]
|
||||
impl Lms {
|
||||
pub const PARM_NONE: u32 = sys::wc_LmsParm_WC_LMS_PARM_NONE;
|
||||
pub const PARM_L1_H5_W1: u32 = sys::wc_LmsParm_WC_LMS_PARM_L1_H5_W1;
|
||||
pub const PARM_L1_H5_W2: u32 = sys::wc_LmsParm_WC_LMS_PARM_L1_H5_W2;
|
||||
pub const PARM_L1_H5_W4: u32 = sys::wc_LmsParm_WC_LMS_PARM_L1_H5_W4;
|
||||
|
||||
Reference in New Issue
Block a user