Skip to content

Commit

Permalink
Merge pull request #7421 from philljj/update_lms_parms
Browse files Browse the repository at this point in the history
Update enum wc_LmsParm for wolfboot support.
  • Loading branch information
SparkiDev authored Apr 24, 2024
2 parents c26f404 + 094ddb6 commit 6e49aa7
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 53 deletions.
4 changes: 2 additions & 2 deletions wolfcrypt/benchmark/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -9860,8 +9860,8 @@ void bench_lms(void)
#endif

#if defined(WOLFSSL_WC_LMS) && !defined(LMS_PARAMS_BENCHED)
bench_lms_keygen(0x100, pub);
bench_lms_sign_verify(0x100, pub);
bench_lms_keygen(WC_LMS_PARM_L1_H5_W1, pub);
bench_lms_sign_verify(WC_LMS_PARM_L1_H5_W1, pub);
#endif

return;
Expand Down
123 changes: 101 additions & 22 deletions wolfcrypt/src/ext_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,38 +160,77 @@ const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm)
{
switch (lmsParm) {
case WC_LMS_PARM_NONE:
return "LMS_NONE";

return "LMS/HSS NONE";
case WC_LMS_PARM_L1_H5_W1:
return "LMS/HSS L1_H5_W1";
case WC_LMS_PARM_L1_H5_W2:
return "LMS/HSS L1_H5_W2";
case WC_LMS_PARM_L1_H5_W4:
return "LMS/HSS L1_H5_W4";
case WC_LMS_PARM_L1_H5_W8:
return "LMS/HSS L1_H5_W8";
case WC_LMS_PARM_L1_H10_W2:
return "LMS/HSS L1_H10_W2";
case WC_LMS_PARM_L1_H10_W4:
return "LMS/HSS L1_H10_W4";
case WC_LMS_PARM_L1_H10_W8:
return "LMS/HSS L1_H10_W8";
case WC_LMS_PARM_L1_H15_W2:
return "LMS/HSS L1_H15_W2";

case WC_LMS_PARM_L1_H15_W4:
return "LMS/HSS L1_H15_W4";

case WC_LMS_PARM_L1_H15_W8:
return "LMS/HSS L1_H15_W8";
case WC_LMS_PARM_L1_H20_W2:
return "LMS/HSS L1_H20_W2";
case WC_LMS_PARM_L1_H20_W4:
return "LMS/HSS L1_H20_W4";
case WC_LMS_PARM_L1_H20_W8:
return "LMS/HSS L1_H20_W8";
case WC_LMS_PARM_L2_H5_W2:
return "LMS/HSS L2_H5_W2";
case WC_LMS_PARM_L2_H5_W4:
return "LMS/HSS L2_H5_W4";
case WC_LMS_PARM_L2_H5_W8:
return "LMS/HSS L2_H5_W8";
case WC_LMS_PARM_L2_H10_W2:
return "LMS/HSS L2_H10_W2";

case WC_LMS_PARM_L2_H10_W4:
return "LMS/HSS L2_H10_W4";

case WC_LMS_PARM_L2_H10_W8:
return "LMS/HSS L2_H10_W8";

case WC_LMS_PARM_L2_H15_W2:
return "LMS/HSS L2_H15_W2";
case WC_LMS_PARM_L2_H15_W4:
return "LMS/HSS L2_H15_W4";
case WC_LMS_PARM_L2_H15_W8:
return "LMS/HSS L2_H15_W8";
case WC_LMS_PARM_L2_H20_W2:
return "LMS/HSS L2_H20_W2";
case WC_LMS_PARM_L2_H20_W4:
return "LMS/HSS L2_H20_W4";
case WC_LMS_PARM_L2_H20_W8:
return "LMS/HSS L2_H20_W8";
case WC_LMS_PARM_L3_H5_W2:
return "LMS/HSS L3_H5_W2";

case WC_LMS_PARM_L3_H5_W4:
return "LMS/HSS L3_H5_W4";

case WC_LMS_PARM_L3_H5_W8:
return "LMS/HSS L3_H5_W8";

case WC_LMS_PARM_L3_H10_W4:
return "LMS/HSS L3_H10_W4";

case WC_LMS_PARM_L3_H10_W8:
return "LMS/HSS L3_H10_W8";
case WC_LMS_PARM_L4_H5_W2:
return "LMS/HSS L4_H5_W2";
case WC_LMS_PARM_L4_H5_W4:
return "LMS/HSS L4_H5_W4";
case WC_LMS_PARM_L4_H5_W8:
return "LMS/HSS L4_H5_W8";

case WC_LMS_PARM_L4_H10_W4:
return "LMS/HSS L4_H10_W4";
case WC_LMS_PARM_L4_H10_W8:
return "LMS/HSS L4_H10_W8";
default:
WOLFSSL_MSG("error: invalid LMS parameter");
break;
Expand Down Expand Up @@ -279,36 +318,76 @@ int wc_LmsKey_SetLmsParm(LmsKey * key, enum wc_LmsParm lmsParm)
/* If NONE is passed, default to the lowest predefined set. */
switch (lmsParm) {
case WC_LMS_PARM_NONE:
case WC_LMS_PARM_L1_H5_W1:
return wc_LmsKey_SetParameters(key, 1, 5, 1);
case WC_LMS_PARM_L1_H5_W2:
return wc_LmsKey_SetParameters(key, 1, 5, 2);
case WC_LMS_PARM_L1_H5_W4:
return wc_LmsKey_SetParameters(key, 1, 5, 4);
case WC_LMS_PARM_L1_H5_W8:
return wc_LmsKey_SetParameters(key, 1, 5, 8);
case WC_LMS_PARM_L1_H10_W2:
return wc_LmsKey_SetParameters(key, 1, 10, 2);
case WC_LMS_PARM_L1_H10_W4:
return wc_LmsKey_SetParameters(key, 1, 10, 4);
case WC_LMS_PARM_L1_H10_W8:
return wc_LmsKey_SetParameters(key, 1, 10, 8);
case WC_LMS_PARM_L1_H15_W2:
return wc_LmsKey_SetParameters(key, 1, 15, 2);

case WC_LMS_PARM_L1_H15_W4:
return wc_LmsKey_SetParameters(key, 1, 15, 4);

case WC_LMS_PARM_L1_H15_W8:
return wc_LmsKey_SetParameters(key, 1, 15, 8);
case WC_LMS_PARM_L1_H20_W2:
return wc_LmsKey_SetParameters(key, 1, 20, 2);
case WC_LMS_PARM_L1_H20_W4:
return wc_LmsKey_SetParameters(key, 1, 20, 4);
case WC_LMS_PARM_L1_H20_W8:
return wc_LmsKey_SetParameters(key, 1, 20, 8);
case WC_LMS_PARM_L2_H5_W2:
return wc_LmsKey_SetParameters(key, 2, 5, 2);
case WC_LMS_PARM_L2_H5_W4:
return wc_LmsKey_SetParameters(key, 2, 5, 4);
case WC_LMS_PARM_L2_H5_W8:
return wc_LmsKey_SetParameters(key, 2, 5, 8);
case WC_LMS_PARM_L2_H10_W2:
return wc_LmsKey_SetParameters(key, 2, 10, 2);

case WC_LMS_PARM_L2_H10_W4:
return wc_LmsKey_SetParameters(key, 2, 10, 4);

case WC_LMS_PARM_L2_H10_W8:
return wc_LmsKey_SetParameters(key, 2, 10, 8);

case WC_LMS_PARM_L2_H15_W2:
return wc_LmsKey_SetParameters(key, 2, 15, 2);
case WC_LMS_PARM_L2_H15_W4:
return wc_LmsKey_SetParameters(key, 2, 15, 4);
case WC_LMS_PARM_L2_H15_W8:
return wc_LmsKey_SetParameters(key, 2, 15, 8);
case WC_LMS_PARM_L2_H20_W2:
return wc_LmsKey_SetParameters(key, 2, 20, 2);
case WC_LMS_PARM_L2_H20_W4:
return wc_LmsKey_SetParameters(key, 2, 20, 4);
case WC_LMS_PARM_L2_H20_W8:
return wc_LmsKey_SetParameters(key, 2, 20, 8);
case WC_LMS_PARM_L3_H5_W2:
return wc_LmsKey_SetParameters(key, 3, 5, 2);

case WC_LMS_PARM_L3_H5_W4:
return wc_LmsKey_SetParameters(key, 3, 5, 4);

case WC_LMS_PARM_L3_H5_W8:
return wc_LmsKey_SetParameters(key, 3, 5, 8);

case WC_LMS_PARM_L3_H10_W4:
return wc_LmsKey_SetParameters(key, 3, 10, 4);

case WC_LMS_PARM_L3_H10_W8:
return wc_LmsKey_SetParameters(key, 3, 10, 8);
case WC_LMS_PARM_L4_H5_W2:
return wc_LmsKey_SetParameters(key, 4, 5, 2);
case WC_LMS_PARM_L4_H5_W4:
return wc_LmsKey_SetParameters(key, 4, 5, 4);
case WC_LMS_PARM_L4_H5_W8:
return wc_LmsKey_SetParameters(key, 4, 5, 8);

case WC_LMS_PARM_L4_H10_W4:
return wc_LmsKey_SetParameters(key, 4, 10, 4);
case WC_LMS_PARM_L4_H10_W8:
return wc_LmsKey_SetParameters(key, 4, 10, 8);
default:
WOLFSSL_MSG("error: invalid LMS parameter set");
break;
Expand Down
63 changes: 46 additions & 17 deletions wolfcrypt/test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#endif
#if defined(WOLFSSL_HAVE_LMS)
#if !defined(WOLFSSL_SMALL_STACK)
#if defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)
#if (defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)) || \
defined(HAVE_LIBLMS)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void);
#endif
#endif
Expand Down Expand Up @@ -1807,7 +1808,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\

#if defined(WOLFSSL_HAVE_LMS)
#if !defined(WOLFSSL_SMALL_STACK)
#if defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)
#if (defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)) || \
defined(HAVE_LIBLMS)
if ( (ret = lms_test_verify_only()) != 0)
TEST_FAIL("LMS Vfy test failed!\n", ret);
else
Expand Down Expand Up @@ -38583,7 +38585,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */

#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_SMALL_STACK)
#if defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)
#if (defined(WOLFSSL_WC_LMS) && (LMS_MAX_HEIGHT >= 10)) || \
defined(HAVE_LIBLMS)

/* A simple LMS verify only test.
*
Expand Down Expand Up @@ -38807,18 +38810,23 @@ static byte lms_L1H10W8_sig[LMS_L1H10W8_SIGLEN] =

WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void)
{
int ret = -1;
int ret2 = -1;
int j = 0;
LmsKey verifyKey;
word32 sigSz = 0;
word32 msgSz = sizeof(lms_msg);
word32 pubLen = 0;
int levels = 0;
int height = 0;
int winternitz = 0;
LmsKey verifyKey;
unsigned char pub_raw[HSS_MAX_PUBLIC_KEY_LEN];
word32 pub_len = sizeof(pub_raw);
word32 sigSz = 0;
word32 msgSz = sizeof(lms_msg);
word32 pubSz = 0;
int levels = 0;
int height = 0;
int winternitz = 0;
int ret = -1;
int ret2 = -1;
int j = 0;
int n_diff = 0;
WOLFSSL_ENTER("lms_test_verify_only");

XMEMSET(pub_raw, 0, sizeof(pub_raw));

ret = wc_LmsKey_Init(&verifyKey, NULL, INVALID_DEVID);
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }

Expand All @@ -38839,12 +38847,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void)
return -1;
}

ret = wc_LmsKey_GetPubLen(&verifyKey, &pubLen);
ret = wc_LmsKey_GetPubLen(&verifyKey, &pubSz);
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }

if (pubLen != HSS_MAX_PUBLIC_KEY_LEN) {
printf("error: got %u, expected %d\n", pubLen, HSS_MAX_PUBLIC_KEY_LEN);
return WC_TEST_RET_ENC_EC(pubLen);
if (pubSz != HSS_MAX_PUBLIC_KEY_LEN) {
printf("error: got %u, expected %d\n", pubSz, HSS_MAX_PUBLIC_KEY_LEN);
return WC_TEST_RET_ENC_EC(pubSz);
}

ret = wc_LmsKey_GetSigLen(&verifyKey, &sigSz);
Expand All @@ -38862,6 +38870,27 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void)
return WC_TEST_RET_ENC_EC(ret);
}

/* Now test the ExportPubRaw API, verify we recover the original pub. */
ret = wc_LmsKey_ExportPubRaw(&verifyKey, pub_raw, &pub_len);
if (ret != 0) {
printf("error: wc_LmsKey_ExportPubRaw returned %d, expected 0\n", ret);
return WC_TEST_RET_ENC_EC(ret);
}

if (pub_len != HSS_MAX_PUBLIC_KEY_LEN) {
printf("error: LMS pub len %d, expected %d\n", pub_len,
HSS_MAX_PUBLIC_KEY_LEN);
return WC_TEST_RET_ENC_EC(pub_len);
}

n_diff = XMEMCMP(pub_raw, lms_L1H10W8_pub, sizeof(lms_L1H10W8_pub));

if (n_diff != 0) {
printf("error: exported and imported pub raw do not match: %d\n",
n_diff);
return WC_TEST_RET_ENC_EC(n_diff);
}

/* Flip bits in message. This should fail. */
lms_msg[msgSz / 2] ^= 1;
ret2 = wc_LmsKey_Verify(&verifyKey, lms_L1H10W8_sig, LMS_L1H10W8_SIGLEN,
Expand Down
49 changes: 37 additions & 12 deletions wolfssl/wolfcrypt/lms.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,45 @@ enum wc_LmsRc {

/* Predefined LMS/HSS parameter sets for convenience.
*
* Not predefining a set with Winternitz=1, because the signatures
* Not predefining many sets with Winternitz=1, because the signatures
* will be large. */
enum wc_LmsParm {
WC_LMS_PARM_NONE = 0,
WC_LMS_PARM_L1_H15_W2 = 1, /* 1 level Merkle tree of 15 height. */
WC_LMS_PARM_L1_H15_W4 = 2,
WC_LMS_PARM_L2_H10_W2 = 3, /* 2 level Merkle tree of 10 height. */
WC_LMS_PARM_L2_H10_W4 = 4,
WC_LMS_PARM_L2_H10_W8 = 5,
WC_LMS_PARM_L3_H5_W2 = 6, /* 3 level Merkle tree of 5 height. */
WC_LMS_PARM_L3_H5_W4 = 7,
WC_LMS_PARM_L3_H5_W8 = 8,
WC_LMS_PARM_L3_H10_W4 = 9, /* 3 level Merkle tree of 10 height. */
WC_LMS_PARM_L4_H5_W8 = 10, /* 4 level Merkle tree of 5 height. */
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,
WC_LMS_PARM_L1_H5_W8 = 4,
WC_LMS_PARM_L1_H10_W2 = 5,
WC_LMS_PARM_L1_H10_W4 = 6,
WC_LMS_PARM_L1_H10_W8 = 7,
WC_LMS_PARM_L1_H15_W2 = 8,
WC_LMS_PARM_L1_H15_W4 = 9,
WC_LMS_PARM_L1_H15_W8 = 10,
WC_LMS_PARM_L1_H20_W2 = 11,
WC_LMS_PARM_L1_H20_W4 = 12,
WC_LMS_PARM_L1_H20_W8 = 13,
WC_LMS_PARM_L2_H5_W2 = 14,
WC_LMS_PARM_L2_H5_W4 = 15,
WC_LMS_PARM_L2_H5_W8 = 16,
WC_LMS_PARM_L2_H10_W2 = 17,
WC_LMS_PARM_L2_H10_W4 = 18,
WC_LMS_PARM_L2_H10_W8 = 19,
WC_LMS_PARM_L2_H15_W2 = 20,
WC_LMS_PARM_L2_H15_W4 = 21,
WC_LMS_PARM_L2_H15_W8 = 22,
WC_LMS_PARM_L2_H20_W2 = 23,
WC_LMS_PARM_L2_H20_W4 = 24,
WC_LMS_PARM_L2_H20_W8 = 25,
WC_LMS_PARM_L3_H5_W2 = 26,
WC_LMS_PARM_L3_H5_W4 = 27,
WC_LMS_PARM_L3_H5_W8 = 28,
WC_LMS_PARM_L3_H10_W4 = 29,
WC_LMS_PARM_L3_H10_W8 = 30,
WC_LMS_PARM_L4_H5_W2 = 31,
WC_LMS_PARM_L4_H5_W4 = 32,
WC_LMS_PARM_L4_H5_W8 = 33,
WC_LMS_PARM_L4_H10_W4 = 34,
WC_LMS_PARM_L4_H10_W8 = 35,
};

/* enum wc_LmsState is to help track the state of an LMS/HSS Key. */
Expand Down

0 comments on commit 6e49aa7

Please sign in to comment.