Browse Source

Merge pull request #7421 from philljj/update_lms_parms

Update enum wc_LmsParm for wolfboot support.
Sean Parkinson 6 months ago
parent
commit
6e49aa7543
4 changed files with 186 additions and 53 deletions
  1. 2 2
      wolfcrypt/benchmark/benchmark.c
  2. 101 22
      wolfcrypt/src/ext_lms.c
  3. 46 17
      wolfcrypt/test/test.c
  4. 37 12
      wolfssl/wolfcrypt/lms.h

+ 2 - 2
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;

+ 101 - 22
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;

+ 46 - 17
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,

+ 37 - 12
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. */