diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 54a1d83272..2c24056ec4 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -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; diff --git a/wolfcrypt/src/ext_lms.c b/wolfcrypt/src/ext_lms.c index a5155076b2..9c64d3544a 100644 --- a/wolfcrypt/src/ext_lms.c +++ b/wolfcrypt/src/ext_lms.c @@ -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; @@ -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; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e6ad01bddc..4a32aaf3c8 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -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 @@ -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 @@ -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. * @@ -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); } @@ -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); @@ -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, diff --git a/wolfssl/wolfcrypt/lms.h b/wolfssl/wolfcrypt/lms.h index 483f349c1e..b4e7e0a468 100644 --- a/wolfssl/wolfcrypt/lms.h +++ b/wolfssl/wolfcrypt/lms.h @@ -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. */