mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-10-24 04:09:07 +03:00
Report no signatures left for an LMS/XMSS key held by a device
When the device declines a SigsLeft query, wc_LmsKey_SigsLeft and
wc_XmssKey_SigsLeft fall back to software. That is right for a key whose
state software holds, such as one made or reloaded through a devId that
only routes other algorithms. But a key whose state lives on the device,
named by id or reloaded without a read callback, has none in software.
XMSS then called the unset read_private_key and crashed. LMS counted
from the all-zero priv_raw and reported a signature left.
Fall back to software only when it holds the private key: privSet for
LMS, which only a software MakeKey or Reload sets, and sk plus the read
callback for XMSS. Otherwise report no signatures left, as before
d56831c90d. The doc comments list this as a reason for returning 0.
wc_LmsKey_Sign and wc_XmssKey_Sign had the same fallback. When the
device declined to sign with such a key, software signed with the unset
priv_data or sk and crashed. A key generated on the device has no sk
either, so XMSS crashed there even with read and write callbacks set.
Return BAD_STATE_E when the LMS privSet or the XMSS sk is not set.
wc_LmsKey_MakeKey and wc_LmsKey_Reload left priv_raw and priv_data in
place when generating or reading the key, or a later step such as
writing out a new key, failed, so a key that was never saved or loaded
still counted from priv_raw. On any failure after the state and callback
checks, wipe priv_data, priv_raw and the expanded key state and clear
privSet, which is now set as soon as priv_raw holds the key. The
priv_data buffer is kept rather than freed, so a caller that supplied
its own, as WOLFSSL_NO_MALLOC builds must, can retry. A call refused by
those checks leaves a loaded key alone.
test_wc_LmsKey_id_sigsleft and test_wc_XmssKey_id_sigsleft query a key
from InitId on a device that declines, and the LMS test also signs with
it. test_wc_XmssKey_keygen_sign_declined signs with a key generated on
a device that then declines. test_wc_LmsKey_reload_fail_sigsleft and
test_wc_LmsKey_makekey_fail_sigsleft query a key whose Reload failed to
read or whose MakeKey failed to write, and check that a priv_data buffer
the caller supplied is still in place. The reload_devid tests now also
check that a software-held key on a declining devId still reports
signatures left.
This commit is contained in:
committed by
Paul Adelsbach
parent
2a37b112b5
commit
31ecbbbbf7
@@ -470,6 +470,7 @@ int test_wc_LmsKey_reload_devid(void)
|
||||
ExpectIntEQ(wc_LmsKey_Reload(&key), 0);
|
||||
/* The reload must have expanded the private key, not been skipped. */
|
||||
ExpectNotNull(key.priv_data);
|
||||
ExpectIntEQ(wc_LmsKey_SigsLeft(&key), 1);
|
||||
ExpectIntEQ(wc_LmsKey_GetKid(&key, &kid, &kidSz), 0);
|
||||
ExpectIntEQ(kidSz, WC_LMS_I_LEN);
|
||||
|
||||
@@ -617,10 +618,72 @@ int test_wc_LmsKey_reload_devid_verify(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
defined(WOLF_CRYPTO_CB) && defined(WOLF_PRIVATE_KEY_ID) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_LMS)
|
||||
static int test_lms_write_key_ok(const byte* priv, word32 privSz,
|
||||
void* context)
|
||||
{
|
||||
(void)priv;
|
||||
(void)privSz;
|
||||
(void)context;
|
||||
return WC_LMS_RC_SAVED_TO_NV_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Test that an LMS key named by id reports no signatures left, and is not
|
||||
* signed with in software, when the device declines.
|
||||
*/
|
||||
int test_wc_LmsKey_id_sigsleft(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
defined(WOLF_CRYPTO_CB) && defined(WOLF_PRIVATE_KEY_ID)
|
||||
LmsKey key;
|
||||
const byte id[] = { 0x01, 0x02, 0x03, 0x04 };
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_LMS
|
||||
byte msg[] = "test message for LMS signing";
|
||||
byte* sig = NULL;
|
||||
word32 sigSz = 0;
|
||||
#endif
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID,
|
||||
test_lms_xmss_verify_cryptocb, NULL), 0);
|
||||
ExpectIntEQ(wc_LmsKey_InitId(&key, id, (int)sizeof(id), NULL,
|
||||
TEST_LMS_XMSS_CRYPTOCB_DEVID), 0);
|
||||
ExpectIntEQ(test_lms_set_params(&key), 0);
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_LMS
|
||||
ExpectIntEQ(wc_LmsKey_SetWriteCb(&key, test_lms_write_key_ok), 0);
|
||||
#endif
|
||||
ExpectIntEQ(wc_LmsKey_Reload(&key), 0);
|
||||
ExpectIntEQ(wc_LmsKey_SigsLeft(&key), 0);
|
||||
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_LMS
|
||||
ExpectIntEQ(wc_LmsKey_GetSigLen(&key, &sigSz), 0);
|
||||
ExpectNotNull(sig = (byte*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
|
||||
if (sig != NULL) {
|
||||
ExpectIntEQ(wc_LmsKey_Sign(&key, sig, &sigSz, msg, sizeof(msg)),
|
||||
WC_NO_ERR_TRACE(BAD_STATE_E));
|
||||
}
|
||||
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
wc_LmsKey_Free(&key);
|
||||
wc_CryptoCb_UnRegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Must be the exact union of the guards of the tests that register it. */
|
||||
#if defined(WOLF_CRYPTO_CB) && \
|
||||
((defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)) || \
|
||||
(defined(WOLF_CRYPTO_CB_ONLY_XMSS) && !defined(WOLFSSL_SWDEV) && \
|
||||
!defined(WOLFSSL_XMSS_VERIFY_ONLY) && \
|
||||
defined(TEST_XMSS_H10_AVAILABLE)) || \
|
||||
(defined(WOLFSSL_HAVE_XMSS) && !defined(WOLF_CRYPTO_CB_ONLY_XMSS) && \
|
||||
!defined(WOLFSSL_XMSS_VERIFY_ONLY) && defined(TEST_XMSS_H10_AVAILABLE)))
|
||||
/* An accelerator that generates keys and declines everything else. */
|
||||
static int test_lms_xmss_keygen_cryptocb(int devIdArg, wc_CryptoInfo* info,
|
||||
@@ -673,6 +736,86 @@ int test_wc_LmsKey_keygen_no_sigsleft(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_LMS)
|
||||
static int test_lms_read_key_fail(byte* priv, word32 privSz, void* context)
|
||||
{
|
||||
(void)priv;
|
||||
(void)privSz;
|
||||
(void)context;
|
||||
return WC_LMS_RC_READ_FAIL;
|
||||
}
|
||||
|
||||
static int test_lms_write_key_fail(const byte* priv, word32 privSz,
|
||||
void* context)
|
||||
{
|
||||
(void)priv;
|
||||
(void)privSz;
|
||||
(void)context;
|
||||
return WC_LMS_RC_WRITE_FAIL;
|
||||
}
|
||||
|
||||
/* Upper bound on priv_data for the parameters test_lms_set_params uses. */
|
||||
#define TEST_LMS_PRIV_DATA_LEN \
|
||||
(LMS_PRIV_DATA_LEN(1, 10, 8, LMS_ROOT_LEVELS, LMS_CACHE_BITS, \
|
||||
LMS_MAX_NODE_LEN) + HSS_MAX_PRIVATE_KEY_LEN)
|
||||
#endif
|
||||
|
||||
/* An LMS key whose MakeKey failed to save has no private key to count from. */
|
||||
int test_wc_LmsKey_makekey_fail_sigsleft(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_LMS)
|
||||
LmsKey key;
|
||||
WC_RNG rng;
|
||||
static byte privData[TEST_LMS_PRIV_DATA_LEN];
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
XMEMSET(&rng, 0, sizeof(rng));
|
||||
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
ExpectIntEQ(wc_LmsKey_Init(&key, NULL, INVALID_DEVID), 0);
|
||||
key.priv_data = privData;
|
||||
ExpectIntEQ(test_lms_set_params(&key), 0);
|
||||
ExpectIntEQ(wc_LmsKey_SetWriteCb(&key, test_lms_write_key_fail), 0);
|
||||
ExpectIntEQ(wc_LmsKey_MakeKey(&key, &rng), WC_NO_ERR_TRACE(IO_FAILED_E));
|
||||
ExpectIntEQ(wc_LmsKey_SigsLeft(&key), 0);
|
||||
/* A caller-supplied buffer stays with the key for a retry. */
|
||||
ExpectPtrEq(key.priv_data, privData);
|
||||
|
||||
key.priv_data = NULL;
|
||||
wc_LmsKey_Free(&key);
|
||||
wc_FreeRng(&rng);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* An LMS key whose Reload failed has no private key to count from. */
|
||||
int test_wc_LmsKey_reload_fail_sigsleft(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_LMS)
|
||||
LmsKey key;
|
||||
static byte privData[TEST_LMS_PRIV_DATA_LEN];
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
ExpectIntEQ(wc_LmsKey_Init(&key, NULL, INVALID_DEVID), 0);
|
||||
key.priv_data = privData;
|
||||
ExpectIntEQ(test_lms_set_params(&key), 0);
|
||||
ExpectIntEQ(wc_LmsKey_SetReadCb(&key, test_lms_read_key_fail), 0);
|
||||
ExpectIntNE(wc_LmsKey_Reload(&key), 0);
|
||||
ExpectIntEQ(wc_LmsKey_SigsLeft(&key), 0);
|
||||
ExpectPtrEq(key.priv_data, privData);
|
||||
|
||||
key.priv_data = NULL;
|
||||
wc_LmsKey_Free(&key);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_LMS) && !defined(WOLFSSL_SWDEV) && \
|
||||
!defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
static int test_lms_read_fail(byte* priv, word32 privSz, void* context)
|
||||
@@ -859,6 +1002,7 @@ int test_wc_XmssKey_reload_devid(void)
|
||||
ExpectIntEQ(wc_XmssKey_Reload(&key), 0);
|
||||
/* The reload must have allocated the secret key, not been skipped. */
|
||||
ExpectNotNull(key.sk);
|
||||
ExpectIntEQ(wc_XmssKey_SigsLeft(&key), 1);
|
||||
|
||||
/* Sign with the reloaded key and verify with a software-only key. */
|
||||
sigSz = sizeof(sig);
|
||||
@@ -987,6 +1131,100 @@ int test_wc_XmssKey_reload_devid_verify(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) && \
|
||||
defined(WOLF_CRYPTO_CB) && defined(TEST_XMSS_H10_AVAILABLE) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_XMSS)
|
||||
static enum wc_XmssRc test_xmss_write_key_ok(const byte* priv, word32 privSz,
|
||||
void* context)
|
||||
{
|
||||
(void)priv;
|
||||
(void)privSz;
|
||||
(void)context;
|
||||
return WC_XMSS_RC_SAVED_TO_NV_MEMORY;
|
||||
}
|
||||
|
||||
static enum wc_XmssRc test_xmss_read_key_ok(byte* priv, word32 privSz,
|
||||
void* context)
|
||||
{
|
||||
(void)priv;
|
||||
(void)privSz;
|
||||
(void)context;
|
||||
return WC_XMSS_RC_READ_TO_MEMORY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Test that an XMSS key generated on a device is not signed with in software
|
||||
* when the device declines.
|
||||
*/
|
||||
int test_wc_XmssKey_keygen_sign_declined(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) && \
|
||||
defined(WOLF_CRYPTO_CB) && defined(TEST_XMSS_H10_AVAILABLE) && \
|
||||
!defined(WOLF_CRYPTO_CB_ONLY_XMSS)
|
||||
XmssKey key;
|
||||
WC_RNG rng;
|
||||
byte msg[] = "test message for XMSS signing";
|
||||
byte* sig = NULL;
|
||||
word32 sigSz = 0;
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
XMEMSET(&rng, 0, sizeof(rng));
|
||||
|
||||
ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID,
|
||||
test_lms_xmss_keygen_cryptocb, NULL), 0);
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
ExpectIntEQ(wc_XmssKey_Init(&key, NULL, TEST_LMS_XMSS_CRYPTOCB_DEVID), 0);
|
||||
ExpectIntEQ(wc_XmssKey_SetParamStr(&key, "XMSS-SHA2_10_256"), 0);
|
||||
ExpectIntEQ(wc_XmssKey_SetWriteCb(&key, test_xmss_write_key_ok), 0);
|
||||
ExpectIntEQ(wc_XmssKey_SetReadCb(&key, test_xmss_read_key_ok), 0);
|
||||
ExpectIntEQ(wc_XmssKey_MakeKey(&key, &rng), 0);
|
||||
ExpectNull(key.sk);
|
||||
|
||||
ExpectIntEQ(wc_XmssKey_GetSigLen(&key, &sigSz), 0);
|
||||
ExpectNotNull(sig = (byte*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER));
|
||||
if (sig != NULL) {
|
||||
ExpectIntEQ(wc_XmssKey_Sign(&key, sig, &sigSz, msg, sizeof(msg)),
|
||||
WC_NO_ERR_TRACE(BAD_STATE_E));
|
||||
}
|
||||
|
||||
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
wc_XmssKey_Free(&key);
|
||||
wc_FreeRng(&rng);
|
||||
wc_CryptoCb_UnRegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Same scenario as test_wc_LmsKey_id_sigsleft, for XMSS.
|
||||
*/
|
||||
int test_wc_XmssKey_id_sigsleft(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) && \
|
||||
defined(WOLF_CRYPTO_CB) && defined(TEST_XMSS_H10_AVAILABLE) && \
|
||||
defined(WOLF_PRIVATE_KEY_ID)
|
||||
XmssKey key;
|
||||
const byte id[] = { 0x01, 0x02, 0x03, 0x04 };
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
|
||||
ExpectIntEQ(wc_CryptoCb_RegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID,
|
||||
test_lms_xmss_verify_cryptocb, NULL), 0);
|
||||
ExpectIntEQ(wc_XmssKey_InitId(&key, id, (int)sizeof(id), NULL,
|
||||
TEST_LMS_XMSS_CRYPTOCB_DEVID), 0);
|
||||
ExpectIntEQ(wc_XmssKey_SetParamStr(&key, "XMSS-SHA2_10_256"), 0);
|
||||
ExpectIntEQ(wc_XmssKey_Reload(&key), 0);
|
||||
ExpectIntEQ(wc_XmssKey_SigsLeft(&key), 0);
|
||||
|
||||
wc_XmssKey_Free(&key);
|
||||
wc_CryptoCb_UnRegisterDevice(TEST_LMS_XMSS_CRYPTOCB_DEVID);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if defined(WOLF_CRYPTO_CB_ONLY_XMSS) && !defined(WOLFSSL_SWDEV) && \
|
||||
!defined(WOLFSSL_XMSS_VERIFY_ONLY) && defined(TEST_XMSS_H10_AVAILABLE)
|
||||
static enum wc_XmssRc test_xmss_read_fail(byte* priv, word32 privSz,
|
||||
|
||||
@@ -30,11 +30,16 @@ int test_wc_LmsKey_reload_cache(void);
|
||||
int test_wc_LmsKey_reload_devid(void);
|
||||
int test_wc_LmsKey_reload_no_pub(void);
|
||||
int test_wc_LmsKey_reload_devid_verify(void);
|
||||
int test_wc_LmsKey_reload_fail_sigsleft(void);
|
||||
int test_wc_LmsKey_makekey_fail_sigsleft(void);
|
||||
int test_wc_LmsKey_keygen_no_sigsleft(void);
|
||||
int test_wc_LmsKey_id_sigsleft(void);
|
||||
int test_wc_LmsKey_cb_only_no_device(void);
|
||||
int test_wc_XmssKey_reload_devid(void);
|
||||
int test_wc_XmssKey_reload_no_pub(void);
|
||||
int test_wc_XmssKey_reload_devid_verify(void);
|
||||
int test_wc_XmssKey_keygen_sign_declined(void);
|
||||
int test_wc_XmssKey_id_sigsleft(void);
|
||||
int test_wc_XmssKey_cb_only_no_device(void);
|
||||
int test_rfc9802_lms_x509_verify(void);
|
||||
int test_rfc9802_xmss_x509_verify(void);
|
||||
@@ -53,11 +58,16 @@ int test_wc_XmssFeatureCoverage(void);
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_reload_devid), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_reload_no_pub), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_reload_devid_verify), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_reload_fail_sigsleft), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_makekey_fail_sigsleft), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_keygen_no_sigsleft), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_id_sigsleft), \
|
||||
TEST_DECL_GROUP("lms", test_wc_LmsKey_cb_only_no_device), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_reload_devid), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_reload_no_pub), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_reload_devid_verify), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_keygen_sign_declined), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_id_sigsleft), \
|
||||
TEST_DECL_GROUP("xmss", test_wc_XmssKey_cb_only_no_device), \
|
||||
TEST_DECL_GROUP("lms", test_rfc9802_lms_x509_verify), \
|
||||
TEST_DECL_GROUP("xmss", test_rfc9802_xmss_x509_verify), \
|
||||
|
||||
@@ -1007,6 +1007,30 @@ int wc_LmsKey_GetParameters_ex(const LmsKey* key, int* levels, int* height,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
/* Wipe the private key held in software, keeping the priv_data buffer.
|
||||
*
|
||||
* @param [in, out] key LMS key.
|
||||
*/
|
||||
static void wc_lmskey_wipe_priv(LmsKey* key)
|
||||
{
|
||||
if (key->priv_data != NULL) {
|
||||
const LmsParams* params = key->params;
|
||||
word32 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
|
||||
priv_data_len += HSS_PRIVATE_KEY_LEN(params->hash_len);
|
||||
#endif
|
||||
ForceZero(key->priv_data, priv_data_len);
|
||||
}
|
||||
ForceZero(key->priv_raw, sizeof(key->priv_raw));
|
||||
ForceZero(&key->priv, sizeof(HssPrivKey));
|
||||
key->privSet = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Frees the LMS key from memory.
|
||||
*
|
||||
* This does not affect the private key saved to non-volatile storage.
|
||||
@@ -1028,23 +1052,9 @@ void wc_LmsKey_Free(LmsKey* key)
|
||||
}
|
||||
#endif
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
if (key->priv_data != NULL) {
|
||||
const LmsParams* params = key->params;
|
||||
word32 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
|
||||
priv_data_len += HSS_PRIVATE_KEY_LEN(key->params->hash_len);
|
||||
#endif
|
||||
ForceZero(key->priv_data, priv_data_len);
|
||||
XFREE(key->priv_data, key->heap, DYNAMIC_TYPE_LMS);
|
||||
key->priv_data = NULL;
|
||||
}
|
||||
|
||||
ForceZero(key->priv_raw, HSS_MAX_PRIVATE_KEY_LEN);
|
||||
key->privSet = 0;
|
||||
ForceZero(&key->priv, sizeof(HssPrivKey));
|
||||
wc_lmskey_wipe_priv(key);
|
||||
XFREE(key->priv_data, key->heap, DYNAMIC_TYPE_LMS);
|
||||
key->priv_data = NULL;
|
||||
|
||||
key->write_private_key = NULL;
|
||||
key->read_private_key = NULL;
|
||||
@@ -1304,6 +1314,9 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
|
||||
ret = IO_FAILED_E;
|
||||
}
|
||||
else {
|
||||
key->privSet = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* This should not happen, but check whether signatures can be created. */
|
||||
@@ -1313,11 +1326,14 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
|
||||
if ((ret != 0) && (priv_data_len > 0)) {
|
||||
wc_lmskey_wipe_priv(key);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Update state. */
|
||||
key->state = WC_LMS_STATE_OK;
|
||||
key->pubSet = 1;
|
||||
key->privSet = 1;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_LMS */
|
||||
|
||||
@@ -1431,6 +1447,9 @@ int wc_LmsKey_Reload(LmsKey* key)
|
||||
HSS_PRIVATE_KEY_LEN(params->hash_len));
|
||||
}
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
key->privSet = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Double check the key actually has signatures left. */
|
||||
@@ -1461,10 +1480,13 @@ int wc_LmsKey_Reload(LmsKey* key)
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret != 0) && (priv_data_len > 0)) {
|
||||
wc_lmskey_wipe_priv(key);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
/* Update state. */
|
||||
key->state = WC_LMS_STATE_OK;
|
||||
key->privSet = 1;
|
||||
}
|
||||
#endif /* WOLF_CRYPTO_CB_ONLY_LMS */
|
||||
|
||||
@@ -1595,6 +1617,10 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
WOLFSSL_MSG("error: LmsKey write/read callbacks are not set");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && (!key->privSet)) {
|
||||
WOLFSSL_MSG("error: LMS private key not held in software");
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
WC_DECLARE_VAR(state, LmsState, 1, 0);
|
||||
@@ -1671,6 +1697,7 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
|
||||
* @return 1 if there are signatures remaining.
|
||||
* @return 0 if available signatures are exhausted, or the key is NULL, has
|
||||
* no parameters set or is verify-only.
|
||||
* @return 0 when the device declines and software holds no private key.
|
||||
*/
|
||||
int wc_LmsKey_SigsLeft(LmsKey* key)
|
||||
{
|
||||
@@ -1697,14 +1724,14 @@ int wc_LmsKey_SigsLeft(LmsKey* key)
|
||||
WOLFSSL_MSG("PqcStatefulSigSigsLeft returned an error");
|
||||
return 0;
|
||||
}
|
||||
/* Cryptocb declined. priv_raw reflects software state from the
|
||||
* CRYPTOCB_UNAVAILABLE fall-through in MakeKey/Reload, so the
|
||||
* software check below is valid. */
|
||||
WOLFSSL_MSG("LMS SigsLeft not supported by device, using software");
|
||||
}
|
||||
#endif
|
||||
#ifndef WOLF_CRYPTO_CB_ONLY_LMS
|
||||
ret = wc_hss_sigsleft(key->params, key->priv_raw);
|
||||
/* Only a software MakeKey or Reload fills priv_raw. */
|
||||
if (key->privSet) {
|
||||
ret = wc_hss_sigsleft(key->params, key->priv_raw);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1593,6 +1593,10 @@ int wc_XmssKey_Sign(XmssKey* key, byte* sig, word32* sigLen, const byte* msg,
|
||||
WOLFSSL_MSG("error: XmssKey write/read callbacks are not set");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
if ((ret == 0) && (key->sk == NULL)) {
|
||||
WOLFSSL_MSG("error: XMSS secret key not held in software");
|
||||
ret = BAD_STATE_E;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
*sigLen = key->params->sig_len;
|
||||
@@ -1609,6 +1613,7 @@ int wc_XmssKey_Sign(XmssKey* key, byte* sig, word32* sigLen, const byte* msg,
|
||||
* @param [in] key XMSS key to check.
|
||||
* @return 1 when signatures possible.
|
||||
* @return 0 when key exhausted.
|
||||
* @return 0 when the device declines and software holds no private key.
|
||||
*/
|
||||
int wc_XmssKey_SigsLeft(XmssKey* key)
|
||||
{
|
||||
@@ -1635,9 +1640,6 @@ int wc_XmssKey_SigsLeft(XmssKey* key)
|
||||
WOLFSSL_MSG("PqcStatefulSigSigsLeft returned an error");
|
||||
return 0;
|
||||
}
|
||||
/* Cryptocb declined. Fall through to the software path: state
|
||||
* reflects the CRYPTOCB_UNAVAILABLE fall-through in MakeKey/Reload,
|
||||
* and read_private_key can repopulate sk from NV storage. */
|
||||
WOLFSSL_MSG("XMSS SigsLeft not supported by device, using software");
|
||||
}
|
||||
#endif
|
||||
@@ -1652,6 +1654,11 @@ int wc_XmssKey_SigsLeft(XmssKey* key)
|
||||
WOLFSSL_MSG("error: can't sign, XMSS key not in good state");
|
||||
ret = 0;
|
||||
}
|
||||
/* A key held by a device has no secret key in software. */
|
||||
else if ((key->sk == NULL) || (key->read_private_key == NULL)) {
|
||||
WOLFSSL_MSG("error: XMSS secret key not held in software");
|
||||
ret = 0;
|
||||
}
|
||||
/* Read the current secret key from NV storage.*/
|
||||
else if (key->read_private_key(key->sk, key->sk_len, key->context) !=
|
||||
WC_XMSS_RC_READ_TO_MEMORY) {
|
||||
|
||||
Reference in New Issue
Block a user