LMS: SHA-256/192 parameters

Add support for parameter sets with SHA-256/192.
This commit is contained in:
Sean Parkinson
2024-09-24 22:06:34 +10:00
parent bc6881974d
commit ae46f52a66
7 changed files with 1285 additions and 385 deletions

View File

@ -1545,6 +1545,12 @@ do
small) small)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS_SMALL" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS_SMALL"
;; ;;
no-sha256-256)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_NO_LMS_SHA256_256"
;;
sha256-192)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_SHA256_192"
;;
*) *)
AC_MSG_ERROR([Invalid choice for LMS []: $ENABLED_LMS.]) AC_MSG_ERROR([Invalid choice for LMS []: $ENABLED_LMS.])
break;; break;;

View File

@ -1692,7 +1692,8 @@ static const char* bench_result_words3[][5] = {
defined(HAVE_CURVE448) || defined(HAVE_ED448) || \ defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(HAVE_ECC) || !defined(NO_DH) || \ defined(HAVE_ECC) || !defined(NO_DH) || \
!defined(NO_RSA) || defined(HAVE_SCRYPT) || \ !defined(NO_RSA) || defined(HAVE_SCRYPT) || \
defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) || \
defined(WOLFSSL_HAVE_LMS)
#define BENCH_ASYM #define BENCH_ASYM
#endif #endif
@ -1700,7 +1701,8 @@ static const char* bench_result_words3[][5] = {
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \ #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \ defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) || \ defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) || \
defined(WOLFSSL_HAVE_LMS)
static const char* bench_result_words2[][5] = { static const char* bench_result_words2[][5] = {
#ifdef BENCH_MICROSECOND #ifdef BENCH_MICROSECOND
{ "ops took", "μsec" , "avg" , "ops/μsec", NULL }, /* 0 English { "ops took", "μsec" , "avg" , "ops/μsec", NULL }, /* 0 English
@ -2656,7 +2658,8 @@ static void bench_stats_sym_finish(const char* desc, int useDeviceID,
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \ #if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DH) || \
defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \ defined(HAVE_CURVE25519) || defined(HAVE_ED25519) || \
defined(HAVE_CURVE448) || defined(HAVE_ED448) || \ defined(HAVE_CURVE448) || defined(HAVE_ED448) || \
defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) defined(WOLFSSL_HAVE_KYBER) || defined(HAVE_DILITHIUM) || \
defined(WOLFSSL_HAVE_LMS)
static void bench_stats_asym_finish_ex(const char* algo, int strength, static void bench_stats_asym_finish_ex(const char* algo, int strength,
const char* desc, const char* desc_extra, int useDeviceID, int count, const char* desc, const char* desc_extra, int useDeviceID, int count,
double start, int ret) double start, int ret)
@ -9442,6 +9445,7 @@ void bench_kyber(int type)
#endif #endif
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) #if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
#ifndef WOLFSSL_NO_LMS_SHA256_256
/* WC_LMS_PARM_L2_H10_W2 /* WC_LMS_PARM_L2_H10_W2
* signature length: 9300 */ * signature length: 9300 */
static const byte lms_priv_L2_H10_W2[64] = static const byte lms_priv_L2_H10_W2[64] =
@ -9597,6 +9601,7 @@ static const byte lms_pub_L4_H5_W8[60] =
0x85,0x1A,0x7A,0xD8,0xD5,0x46,0x74,0x3B, 0x85,0x1A,0x7A,0xD8,0xD5,0x46,0x74,0x3B,
0x74,0x24,0x12,0xC8 0x74,0x24,0x12,0xC8
}; };
#endif
static int lms_write_key_mem(const byte* priv, word32 privSz, void* context) static int lms_write_key_mem(const byte* priv, word32 privSz, void* context)
{ {
@ -9757,6 +9762,7 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
} }
switch (parm) { switch (parm) {
#ifndef WOLFSSL_NO_LMS_SHA256_256
case WC_LMS_PARM_L2_H10_W2: case WC_LMS_PARM_L2_H10_W2:
XMEMCPY(lms_priv, lms_priv_L2_H10_W2, sizeof(lms_priv_L2_H10_W2)); XMEMCPY(lms_priv, lms_priv_L2_H10_W2, sizeof(lms_priv_L2_H10_W2));
XMEMCPY(key.pub, lms_pub_L2_H10_W2, HSS_MAX_PUBLIC_KEY_LEN); XMEMCPY(key.pub, lms_pub_L2_H10_W2, HSS_MAX_PUBLIC_KEY_LEN);
@ -9817,6 +9823,28 @@ static void bench_lms_sign_verify(enum wc_LmsParm parm, byte* pub)
case WC_LMS_PARM_L4_H5_W4: case WC_LMS_PARM_L4_H5_W4:
case WC_LMS_PARM_L4_H10_W4: case WC_LMS_PARM_L4_H10_W4:
case WC_LMS_PARM_L4_H10_W8: case WC_LMS_PARM_L4_H10_W8:
#endif
#ifdef WOLFSSL_LMS_SHA256_192
case WC_LMS_PARM_SHA256_192_L1_H5_W1:
case WC_LMS_PARM_SHA256_192_L1_H5_W2:
case WC_LMS_PARM_SHA256_192_L1_H5_W4:
case WC_LMS_PARM_SHA256_192_L1_H5_W8:
case WC_LMS_PARM_SHA256_192_L1_H10_W2:
case WC_LMS_PARM_SHA256_192_L1_H10_W4:
case WC_LMS_PARM_SHA256_192_L1_H10_W8:
case WC_LMS_PARM_SHA256_192_L1_H15_W2:
case WC_LMS_PARM_SHA256_192_L1_H15_W4:
case WC_LMS_PARM_SHA256_192_L2_H10_W2:
case WC_LMS_PARM_SHA256_192_L2_H10_W4:
case WC_LMS_PARM_SHA256_192_L2_H10_W8:
case WC_LMS_PARM_SHA256_192_L3_H5_W2:
case WC_LMS_PARM_SHA256_192_L3_H5_W4:
case WC_LMS_PARM_SHA256_192_L3_H5_W8:
case WC_LMS_PARM_SHA256_192_L3_H10_W4:
case WC_LMS_PARM_SHA256_192_L4_H5_W8:
#endif
default: default:
XMEMCPY(key.pub, pub, HSS_MAX_PUBLIC_KEY_LEN); XMEMCPY(key.pub, pub, HSS_MAX_PUBLIC_KEY_LEN);
break; break;
@ -9991,6 +10019,7 @@ void bench_lms(void)
{ {
byte pub[HSS_MAX_PUBLIC_KEY_LEN]; byte pub[HSS_MAX_PUBLIC_KEY_LEN];
#ifndef WOLFSSL_NO_LMS_SHA256_256
#ifdef BENCH_LMS_SLOW_KEYGEN #ifdef BENCH_LMS_SLOW_KEYGEN
#if !defined(WOLFSSL_WC_LMS) || (LMS_MAX_HEIGHT >= 15) #if !defined(WOLFSSL_WC_LMS) || (LMS_MAX_HEIGHT >= 15)
bench_lms_keygen(WC_LMS_PARM_L1_H15_W2, pub); bench_lms_keygen(WC_LMS_PARM_L1_H15_W2, pub);
@ -10036,6 +10065,55 @@ void bench_lms(void)
bench_lms_keygen(WC_LMS_PARM_L1_H5_W1, pub); bench_lms_keygen(WC_LMS_PARM_L1_H5_W1, pub);
bench_lms_sign_verify(WC_LMS_PARM_L1_H5_W1, pub); bench_lms_sign_verify(WC_LMS_PARM_L1_H5_W1, pub);
#endif #endif
#endif /* !WOLFSSL_NO_LMS_SHA256_256 */
#ifdef WOLFSSL_LMS_SHA256_192
#ifdef BENCH_LMS_SLOW_KEYGEN
#if !defined(WOLFSSL_WC_LMS) || (LMS_MAX_HEIGHT >= 15)
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L1_H15_W2, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L1_H15_W2, pub);
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L1_H15_W4, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L1_H15_W4, pub);
#undef LMS_PARAMS_BENCHED
#define LMS_PARAMS_BENCHED
#endif
#endif
#if !defined(WOLFSSL_WC_LMS) || ((LMS_MAX_LEVELS >= 2) && \
(LMS_MAX_HEIGHT >= 10))
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L2_H10_W2, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L2_H10_W2, pub);
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L2_H10_W4, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L2_H10_W4, pub);
#undef LMS_PARAMS_BENCHED
#define LMS_PARAMS_BENCHED
#ifdef BENCH_LMS_SLOW_KEYGEN
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L2_H10_W8, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L2_H10_W8, pub);
#endif
#endif
#if !defined(WOLFSSL_WC_LMS) || (LMS_MAX_LEVELS >= 3)
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L3_H5_W4, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L3_H5_W4, pub);
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L3_H5_W8, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L3_H5_W8, pub);
#undef LMS_PARAMS_BENCHED
#define LMS_PARAMS_BENCHED
#endif
#if !defined(WOLFSSL_WC_LMS) || ((LMS_MAX_LEVELS >= 3) && \
(LMS_MAX_HEIGHT >= 10))
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L3_H10_W4, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L3_H10_W4, pub);
#endif
#if !defined(WOLFSSL_WC_LMS) || (LMS_MAX_LEVELS >= 4)
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L4_H5_W8, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L4_H5_W8, pub);
#endif
#if defined(WOLFSSL_WC_LMS) && !defined(LMS_PARAMS_BENCHED)
bench_lms_keygen(WC_LMS_PARM_SHA256_192_L1_H5_W1, pub);
bench_lms_sign_verify(WC_LMS_PARM_SHA256_192_L1_H5_W1, pub);
#endif
#endif /* WOLFSSL_LMS_SHA256_192 */
return; return;
} }

View File

@ -42,8 +42,8 @@
* *
* @param [in] w Winternitz width. * @param [in] w Winternitz width.
*/ */
#define LMS_U(w) \ #define LMS_U(w, hLen) \
(8 * WC_SHA256_DIGEST_SIZE / (w)) (8 * (hLen) / (w))
/* Calculate u. Appendix B. Works for w of 1, 2, 4, or 8. /* Calculate u. Appendix B. Works for w of 1, 2, 4, or 8.
* *
* @param [in] w Winternitz width. * @param [in] w Winternitz width.
@ -63,17 +63,17 @@
* @param [in] w Winternitz width. * @param [in] w Winternitz width.
* @param [in] wb Winternitz width length in bits. * @param [in] wb Winternitz width length in bits.
*/ */
#define LMS_P(w, wb) \ #define LMS_P(w, wb, hLen) \
(LMS_U(w) + LMS_V(w, wb)) (LMS_U(w, hLen) + LMS_V(w, wb))
/* Calculate signature length. /* Calculate signature length.
* *
* @param [in] l Number of levels. * @param [in] l Number of levels.
* @param [in] h Height of the trees. * @param [in] h Height of the trees.
* @param [in] p Number of n-byte string elements in signature for a tree. * @param [in] p Number of n-byte string elements in signature for a tree.
*/ */
#define LMS_PARAMS_SIG_LEN(l, h, p) \ #define LMS_PARAMS_SIG_LEN(l, h, p, hLen) \
(4 + (l) * (4 + 4 + 4 + WC_SHA256_DIGEST_SIZE * (1 + (p) + (h))) + \ (4 + (l) * (4 + 4 + 4 + (hLen) * (1 + (p) + (h))) + \
((l) - 1) * LMS_PUBKEY_LEN) ((l) - 1) * LMS_PUBKEY_LEN(hLen))
#ifndef WOLFSSL_WC_LMS_SMALL #ifndef WOLFSSL_WC_LMS_SMALL
/* Root levels and leaf cache bits. */ /* Root levels and leaf cache bits. */
@ -94,9 +94,10 @@
* @param [in] t LMS type. * @param [in] t LMS type.
* @param [in] t2 LM-OTS type. * @param [in] t2 LM-OTS type.
*/ */
#define LMS_PARAMS(l, h, w, wb, t, t2) \ #define LMS_PARAMS(l, h, w, wb, t, t2, hLen) \
{ l, h, w, LMS_LS(w, wb), LMS_P(w, wb), t, t2, \ { l, h, w, LMS_LS(w, wb), LMS_P(w, wb, hLen), t, t2, \
LMS_PARAMS_SIG_LEN(l, h, LMS_P(w, wb)), LMS_PARAMS_CACHE(h) } LMS_PARAMS_SIG_LEN(l, h, LMS_P(w, wb, hLen), hLen), \
(hLen), LMS_PARAMS_CACHE(h) }
/* Initialize the working state for LMS operations. /* Initialize the working state for LMS operations.
@ -138,112 +139,230 @@ static void wc_lmskey_state_free(LmsState* state)
/* Supported LMS parameters. */ /* Supported LMS parameters. */
static const wc_LmsParamsMap wc_lms_map[] = { static const wc_LmsParamsMap wc_lms_map[] = {
#ifndef WOLFSSL_NO_LMS_SHA256_256
#if LMS_MAX_HEIGHT >= 15 #if LMS_MAX_HEIGHT >= 15
{ WC_LMS_PARM_NONE , "LMS_NONE" , { WC_LMS_PARM_NONE , "LMS_NONE" ,
LMS_PARAMS(1, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2) }, 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", { 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) }, LMS_PARAMS(1, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H15_W4, "LMS/HSS L1_H15_W4", { WC_LMS_PARM_L1_H15_W4, "LMS/HSS L1_H15_W4",
LMS_PARAMS(1, 15, 4, 2, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(1, 15, 4, 2, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#if LMS_MAX_LEVELS >= 2 #if LMS_MAX_LEVELS >= 2
#if LMS_MAX_HEIGHT >= 10 #if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_L2_H10_W2, "LMS/HSS L2_H10_W2", { WC_LMS_PARM_L2_H10_W2, "LMS/HSS L2_H10_W2",
LMS_PARAMS(2, 10, 2, 1, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W2) }, LMS_PARAMS(2, 10, 2, 1, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H10_W4, "LMS/HSS L2_H10_W4", { WC_LMS_PARM_L2_H10_W4, "LMS/HSS L2_H10_W4",
LMS_PARAMS(2, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(2, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H10_W8, "LMS/HSS L2_H10_W8", { WC_LMS_PARM_L2_H10_W8, "LMS/HSS L2_H10_W8",
LMS_PARAMS(2, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(2, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#endif #endif
#if LMS_MAX_LEVELS >= 3 #if LMS_MAX_LEVELS >= 3
{ WC_LMS_PARM_L3_H5_W2 , "LMS/HSS L3_H5_W2" , { WC_LMS_PARM_L3_H5_W2 , "LMS/HSS L3_H5_W2" ,
LMS_PARAMS(3, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2) }, LMS_PARAMS(3, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L3_H5_W4 , "LMS/HSS L3_H5_W4" , { WC_LMS_PARM_L3_H5_W4 , "LMS/HSS L3_H5_W4" ,
LMS_PARAMS(3, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4) }, LMS_PARAMS(3, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L3_H5_W8 , "LMS/HSS L3_H5_W8" , { WC_LMS_PARM_L3_H5_W8 , "LMS/HSS L3_H5_W8" ,
LMS_PARAMS(3, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8) }, LMS_PARAMS(3, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 10 #if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_L3_H10_W4, "LMS/HSS L3_H10_W4", { WC_LMS_PARM_L3_H10_W4, "LMS/HSS L3_H10_W4",
LMS_PARAMS(3, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(3, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#endif #endif
#if LMS_MAX_LEVELS >= 4 #if LMS_MAX_LEVELS >= 4
{ WC_LMS_PARM_L4_H5_W8 , "LMS/HSS L4_H5_W8" , { WC_LMS_PARM_L4_H5_W8 , "LMS/HSS L4_H5_W8" ,
LMS_PARAMS(4, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8) }, LMS_PARAMS(4, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
/* For when user sets L, H, W explicitly. */ /* For when user sets L, H, W explicitly. */
{ WC_LMS_PARM_L1_H5_W1 , "LMS/HSS_L1_H5_W1" , { WC_LMS_PARM_L1_H5_W1 , "LMS/HSS_L1_H5_W1" ,
LMS_PARAMS(1, 5, 1, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W1) }, LMS_PARAMS(1, 5, 1, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W1,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H5_W2 , "LMS/HSS_L1_H5_W2" , { WC_LMS_PARM_L1_H5_W2 , "LMS/HSS_L1_H5_W2" ,
LMS_PARAMS(1, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2) }, LMS_PARAMS(1, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H5_W4 , "LMS/HSS_L1_H5_W4" , { WC_LMS_PARM_L1_H5_W4 , "LMS/HSS_L1_H5_W4" ,
LMS_PARAMS(1, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4) }, LMS_PARAMS(1, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H5_W8 , "LMS/HSS_L1_H5_W8" , { WC_LMS_PARM_L1_H5_W8 , "LMS/HSS_L1_H5_W8" ,
LMS_PARAMS(1, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8) }, LMS_PARAMS(1, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 10 #if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_L1_H10_W2 , "LMS/HSS_L1_H10_W2", { WC_LMS_PARM_L1_H10_W2 , "LMS/HSS_L1_H10_W2",
LMS_PARAMS(1, 10, 2, 1, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W2) }, LMS_PARAMS(1, 10, 2, 1, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H10_W4 , "LMS/HSS_L1_H10_W4", { WC_LMS_PARM_L1_H10_W4 , "LMS/HSS_L1_H10_W4",
LMS_PARAMS(1, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(1, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H10_W8 , "LMS/HSS_L1_H10_W8", { WC_LMS_PARM_L1_H10_W8 , "LMS/HSS_L1_H10_W8",
LMS_PARAMS(1, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(1, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#if LMS_MAX_HEIGHT >= 15 #if LMS_MAX_HEIGHT >= 15
{ WC_LMS_PARM_L1_H15_W8 , "LMS/HSS L1_H15_W8", { WC_LMS_PARM_L1_H15_W8 , "LMS/HSS L1_H15_W8",
LMS_PARAMS(1, 15, 8, 3, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(1, 15, 8, 3, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#if LMS_MAX_HEIGHT >= 20 #if LMS_MAX_HEIGHT >= 20
{ WC_LMS_PARM_L1_H20_W2 , "LMS/HSS_L1_H20_W2", { WC_LMS_PARM_L1_H20_W2 , "LMS/HSS_L1_H20_W2",
LMS_PARAMS(1, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2) }, LMS_PARAMS(1, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H20_W4 , "LMS/HSS_L1_H20_W4", { WC_LMS_PARM_L1_H20_W4 , "LMS/HSS_L1_H20_W4",
LMS_PARAMS(1, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(1, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H20_W8 , "LMS/HSS_L1_H20_W8", { WC_LMS_PARM_L1_H20_W8 , "LMS/HSS_L1_H20_W8",
LMS_PARAMS(1, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(1, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#if LMS_MAX_LEVELS >= 2 #if LMS_MAX_LEVELS >= 2
{ WC_LMS_PARM_L2_H5_W2 , "LMS/HSS_L2_H5_W2" , { WC_LMS_PARM_L2_H5_W2 , "LMS/HSS_L2_H5_W2" ,
LMS_PARAMS(2, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2) }, LMS_PARAMS(2, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H5_W4 , "LMS/HSS_L2_H5_W4" , { WC_LMS_PARM_L2_H5_W4 , "LMS/HSS_L2_H5_W4" ,
LMS_PARAMS(2, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4) }, LMS_PARAMS(2, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H5_W8 , "LMS/HSS_L2_H5_W8" , { WC_LMS_PARM_L2_H5_W8 , "LMS/HSS_L2_H5_W8" ,
LMS_PARAMS(2, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8) }, LMS_PARAMS(2, 5, 8, 3, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 15 #if LMS_MAX_HEIGHT >= 15
{ WC_LMS_PARM_L2_H15_W2 , "LMS/HSS_L2_H15_W2", { WC_LMS_PARM_L2_H15_W2 , "LMS/HSS_L2_H15_W2",
LMS_PARAMS(2, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2) }, LMS_PARAMS(2, 15, 2, 1, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H15_W4 , "LMS/HSS_L2_H15_W4", { WC_LMS_PARM_L2_H15_W4 , "LMS/HSS_L2_H15_W4",
LMS_PARAMS(2, 15, 4, 2, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(2, 15, 4, 2, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H15_W8 , "LMS/HSS_L2_H15_W8", { WC_LMS_PARM_L2_H15_W8 , "LMS/HSS_L2_H15_W8",
LMS_PARAMS(2, 15, 8, 3, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(2, 15, 8, 3, LMS_SHA256_M32_H15, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#if LMS_MAX_HEIGHT >= 20 #if LMS_MAX_HEIGHT >= 20
{ WC_LMS_PARM_L2_H20_W2 , "LMS/HSS_L2_H20_W2", { WC_LMS_PARM_L2_H20_W2 , "LMS/HSS_L2_H20_W2",
LMS_PARAMS(2, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2) }, LMS_PARAMS(2, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H20_W4 , "LMS/HSS_L2_H20_W4", { WC_LMS_PARM_L2_H20_W4 , "LMS/HSS_L2_H20_W4",
LMS_PARAMS(2, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(2, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L2_H20_W8 , "LMS/HSS_L2_H20_W8", { WC_LMS_PARM_L2_H20_W8 , "LMS/HSS_L2_H20_W8",
LMS_PARAMS(2, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(2, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#endif #endif
#if LMS_MAX_LEVELS >= 3 #if LMS_MAX_LEVELS >= 3
#if LMS_MAX_HEIGHT >= 10 #if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_L3_H10_W8 , "LMS/HSS L3_H10_W8", { WC_LMS_PARM_L3_H10_W8 , "LMS/HSS L3_H10_W8",
LMS_PARAMS(3, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(3, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#endif #endif
#if LMS_MAX_LEVELS >= 4 #if LMS_MAX_LEVELS >= 4
{ WC_LMS_PARM_L4_H5_W2 , "LMS/HSS L4_H5_W2" , { WC_LMS_PARM_L4_H5_W2 , "LMS/HSS L4_H5_W2" ,
LMS_PARAMS(4, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2) }, LMS_PARAMS(4, 5, 2, 1, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W2,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L4_H5_W4 , "LMS/HSS L4_H5_W4" , { WC_LMS_PARM_L4_H5_W4 , "LMS/HSS L4_H5_W4" ,
LMS_PARAMS(4, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4) }, LMS_PARAMS(4, 5, 4, 2, LMS_SHA256_M32_H5 , LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 10 #if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_L4_H10_W4 , "LMS/HSS L4_H10_W4", { WC_LMS_PARM_L4_H10_W4 , "LMS/HSS L4_H10_W4",
LMS_PARAMS(4, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4) }, LMS_PARAMS(4, 10, 4, 2, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W4,
WC_SHA256_DIGEST_SIZE) },
{ WC_LMS_PARM_L4_H10_W8 , "LMS/HSS L4_H10_W8", { WC_LMS_PARM_L4_H10_W8 , "LMS/HSS L4_H10_W8",
LMS_PARAMS(4, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8) }, LMS_PARAMS(4, 10, 8, 3, LMS_SHA256_M32_H10, LMOTS_SHA256_N32_W8,
WC_SHA256_DIGEST_SIZE) },
#endif #endif
#endif #endif
#endif /* !WOLFSSL_NO_LMS_SHA256_256 */
#ifdef WOLFSSL_LMS_SHA256_192
#if LMS_MAX_HEIGHT >= 15
{ WC_LMS_PARM_SHA256_192_L1_H15_W2, "LMS/HSS_SHA256/192 L1_H15_W2",
LMS_PARAMS(1, 15, 2, 1, LMS_SHA256_M24_H15, LMOTS_SHA256_N24_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H15_W4, "LMS/HSS_SHA256/192 L1_H15_W4",
LMS_PARAMS(1, 15, 4, 2, LMS_SHA256_M24_H15, LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
#endif
#if LMS_MAX_LEVELS >= 2
#if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_SHA256_192_L2_H10_W2, "LMS/HSS SHA256/192 L2_H10_W2",
LMS_PARAMS(2, 10, 2, 1, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L2_H10_W4, "LMS/HSS SHA256/192 L2_H10_W4",
LMS_PARAMS(2, 10, 4, 2, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L2_H10_W8, "LMS/HSS SHA256/192 L2_H10_W8",
LMS_PARAMS(2, 10, 8, 3, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W8,
WC_SHA256_192_DIGEST_SIZE) },
#endif
#endif
#if LMS_MAX_LEVELS >= 3
{ WC_LMS_PARM_SHA256_192_L3_H5_W2 , "LMS/HSS_SHA256/192 L3_H5_W2" ,
LMS_PARAMS(3, 5, 2, 1, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L3_H5_W4 , "LMS/HSS_SHA256/192 L3_H5_W4" ,
LMS_PARAMS(3, 5, 4, 2, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L3_H5_W8 , "LMS/HSS_SHA256/192 L3_H5_W8" ,
LMS_PARAMS(3, 5, 8, 3, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W8,
WC_SHA256_192_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_SHA256_192_L3_H10_W4, "LMS/HSS_SHA256/192 L3_H10_W4",
LMS_PARAMS(3, 10, 4, 2, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
#endif
#endif
#if LMS_MAX_LEVELS >= 4
{ WC_LMS_PARM_SHA256_192_L4_H5_W8 , "LMS/HSS_SHA256/192 L4_H5_W8" ,
LMS_PARAMS(4, 5, 8, 3, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W8,
WC_SHA256_192_DIGEST_SIZE) },
#endif
{ WC_LMS_PARM_SHA256_192_L1_H5_W1 , "LMS/HSS_SHA256/192_L1_H5_W1" ,
LMS_PARAMS(1, 5, 1, 1, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W1,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H5_W2 , "LMS/HSS_SHA256/192_L1_H5_W2" ,
LMS_PARAMS(1, 5, 2, 1, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H5_W4 , "LMS/HSS_SHA256/192_L1_H5_W4" ,
LMS_PARAMS(1, 5, 4, 2, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H5_W8 , "LMS/HSS_SHA256/192_L1_H5_W8" ,
LMS_PARAMS(1, 5, 8, 3, LMS_SHA256_M24_H5 , LMOTS_SHA256_N24_W8,
WC_SHA256_192_DIGEST_SIZE) },
#if LMS_MAX_HEIGHT >= 10
{ WC_LMS_PARM_SHA256_192_L1_H10_W2 , "LMS/HSS_SHA256/192_L1_H10_W2",
LMS_PARAMS(1, 10, 2, 1, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H10_W4 , "LMS/HSS_SHA256/192_L1_H10_W4",
LMS_PARAMS(1, 10, 4, 2, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W4,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_SHA256_192_L1_H10_W8 , "LMS/HSS_SHA256/192_L1_H10_W8",
LMS_PARAMS(1, 10, 8, 3, LMS_SHA256_M24_H10, LMOTS_SHA256_N24_W8,
WC_SHA256_192_DIGEST_SIZE) },
#endif
#if LMS_MAX_HEIGHT >= 20
{ WC_LMS_PARM_L1_H20_W2 , "LMS/HSS_SHA256/192_L1_H20_W2",
LMS_PARAMS(1, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H20_W4 , "LMS/HSS_SHA256/192_L1_H20_W4",
LMS_PARAMS(1, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4,
WC_SHA256_192_DIGEST_SIZE) },
{ WC_LMS_PARM_L1_H20_W8 , "LMS/HSS_SHA256/192_L1_H20_W8",
LMS_PARAMS(1, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8,
WC_SHA256_192_DIGEST_SIZE) },
#endif
#endif /* WOLFSSL_LMS_SHA256_192 */
}; };
/* Number of parameter sets supported. */ /* Number of parameter sets supported. */
#define WC_LMS_MAP_LEN ((int)(sizeof(wc_lms_map) / sizeof(*wc_lms_map))) #define WC_LMS_MAP_LEN ((int)(sizeof(wc_lms_map) / sizeof(*wc_lms_map)))
@ -476,7 +595,7 @@ void wc_LmsKey_Free(LmsKey* key)
ForceZero(key->priv_data, LMS_PRIV_DATA_LEN(params->levels, ForceZero(key->priv_data, LMS_PRIV_DATA_LEN(params->levels,
params->height, params->p, params->rootLevels, params->height, params->p, params->rootLevels,
params->cacheBits)); params->cacheBits, params->hash_len));
XFREE(key->priv_data, key->heap, DYNAMIC_TYPE_LMS); XFREE(key->priv_data, key->heap, DYNAMIC_TYPE_LMS);
} }
@ -630,8 +749,8 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
/* Allocate memory for the private key data. */ /* Allocate memory for the private key data. */
key->priv_data = (byte *)XMALLOC(LMS_PRIV_DATA_LEN(params->levels, key->priv_data = (byte *)XMALLOC(LMS_PRIV_DATA_LEN(params->levels,
params->height, params->p, params->rootLevels, params->cacheBits), params->height, params->p, params->rootLevels, params->cacheBits,
key->heap, DYNAMIC_TYPE_LMS); params->hash_len), key->heap, DYNAMIC_TYPE_LMS);
/* Check pointer is valid. */ /* Check pointer is valid. */
if (key->priv_data == NULL) { if (key->priv_data == NULL) {
ret = MEMORY_E; ret = MEMORY_E;
@ -669,8 +788,8 @@ int wc_LmsKey_MakeKey(LmsKey* key, WC_RNG* rng)
} }
if (ret == 0) { if (ret == 0) {
/* Write private key to storage. */ /* Write private key to storage. */
int rv = key->write_private_key(key->priv_raw, HSS_PRIVATE_KEY_LEN, int rv = key->write_private_key(key->priv_raw,
key->context); HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) { if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
ret = IO_FAILED_E; ret = IO_FAILED_E;
} }
@ -729,8 +848,8 @@ int wc_LmsKey_Reload(LmsKey* key)
/* Allocate memory for the private key data. */ /* Allocate memory for the private key data. */
key->priv_data = (byte *)XMALLOC(LMS_PRIV_DATA_LEN(params->levels, key->priv_data = (byte *)XMALLOC(LMS_PRIV_DATA_LEN(params->levels,
params->height, params->p, params->rootLevels, params->cacheBits), params->height, params->p, params->rootLevels, params->cacheBits,
key->heap, DYNAMIC_TYPE_LMS); params->hash_len), key->heap, DYNAMIC_TYPE_LMS);
/* Check pointer is valid. */ /* Check pointer is valid. */
if (key->priv_data == NULL) { if (key->priv_data == NULL) {
ret = MEMORY_E; ret = MEMORY_E;
@ -738,8 +857,8 @@ int wc_LmsKey_Reload(LmsKey* key)
} }
if (ret == 0) { if (ret == 0) {
/* Load private key. */ /* Load private key. */
int rv = key->read_private_key(key->priv_raw, HSS_PRIVATE_KEY_LEN, int rv = key->read_private_key(key->priv_raw,
key->context); HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
if (rv != WC_LMS_RC_READ_TO_MEMORY) { if (rv != WC_LMS_RC_READ_TO_MEMORY) {
ret = IO_FAILED_E; ret = IO_FAILED_E;
} }
@ -808,7 +927,7 @@ int wc_LmsKey_GetPrivLen(const LmsKey* key, word32* len)
if (ret == 0) { if (ret == 0) {
/* Return private key length from parameter set. */ /* Return private key length from parameter set. */
*len = HSS_PRIVATE_KEY_LEN; *len = HSS_PRIVATE_KEY_LEN(key->params->hash_len);
} }
return ret; return ret;
@ -885,8 +1004,8 @@ int wc_LmsKey_Sign(LmsKey* key, byte* sig, word32* sigSz, const byte* msg,
} }
if (ret == 0) { if (ret == 0) {
/* Write private key to storage. */ /* Write private key to storage. */
int rv = key->write_private_key(key->priv_raw, HSS_PRIVATE_KEY_LEN, int rv = key->write_private_key(key->priv_raw,
key->context); HSS_PRIVATE_KEY_LEN(key->params->hash_len), key->context);
if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) { if (rv != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
ret = IO_FAILED_E; ret = IO_FAILED_E;
} }
@ -933,7 +1052,7 @@ int wc_LmsKey_GetPubLen(const LmsKey* key, word32* len)
} }
if (ret == 0) { if (ret == 0) {
*len = HSS_PUBLIC_KEY_LEN; *len = HSS_PUBLIC_KEY_LEN(key->params->hash_len);
} }
return ret; return ret;
@ -996,14 +1115,15 @@ int wc_LmsKey_ExportPubRaw(const LmsKey* key, byte* out, word32* outLen)
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
/* Check size of out is sufficient. */ /* Check size of out is sufficient. */
if ((ret == 0) && (*outLen < HSS_PUBLIC_KEY_LEN)) { if ((ret == 0) &&
(*outLen < (word32)HSS_PUBLIC_KEY_LEN(key->params->hash_len))) {
ret = BUFFER_E; ret = BUFFER_E;
} }
if (ret == 0) { if (ret == 0) {
/* Return encoded public key. */ /* Return encoded public key. */
XMEMCPY(out, key->pub, HSS_PUBLIC_KEY_LEN); XMEMCPY(out, key->pub, HSS_PUBLIC_KEY_LEN(key->params->hash_len));
*outLen = HSS_PUBLIC_KEY_LEN; *outLen = HSS_PUBLIC_KEY_LEN(key->params->hash_len);
} }
return ret; return ret;
@ -1032,7 +1152,8 @@ int wc_LmsKey_ImportPubRaw(LmsKey* key, const byte* in, word32 inLen)
if ((key == NULL) || (in == NULL)) { if ((key == NULL) || (in == NULL)) {
ret = BAD_FUNC_ARG; ret = BAD_FUNC_ARG;
} }
if ((ret == 0) && (inLen != HSS_PUBLIC_KEY_LEN)) { if ((ret == 0) &&
(inLen != (word32)HSS_PUBLIC_KEY_LEN(key->params->hash_len))) {
/* Something inconsistent. Parameters weren't set, or input /* Something inconsistent. Parameters weren't set, or input
* pub key is wrong.*/ * pub key is wrong.*/
return BUFFER_E; return BUFFER_E;

File diff suppressed because it is too large Load Diff

View File

@ -656,8 +656,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#endif #endif
#if defined(WOLFSSL_HAVE_LMS) #if defined(WOLFSSL_HAVE_LMS)
#if !defined(WOLFSSL_SMALL_STACK) #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) !defined(WOLFSSL_NO_LMS_SHA256_256)) || defined(HAVE_LIBLMS)
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void);
#endif #endif
#endif #endif
@ -2192,8 +2192,8 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
#if defined(WOLFSSL_HAVE_LMS) #if defined(WOLFSSL_HAVE_LMS)
#if !defined(WOLFSSL_SMALL_STACK) #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) !defined(WOLFSSL_NO_LMS_SHA256_256)) || defined(HAVE_LIBLMS)
if ( (ret = lms_test_verify_only()) != 0) if ( (ret = lms_test_verify_only()) != 0)
TEST_FAIL("LMS Vfy test failed!\n", ret); TEST_FAIL("LMS Vfy test failed!\n", ret);
else else
@ -45960,7 +45960,11 @@ static int lms_read_key_mem(byte * priv, word32 privSz, void *context)
/* LMS signature sizes are a function of their parameters. This /* LMS signature sizes are a function of their parameters. This
* test has a signature of 8688 bytes. */ * test has a signature of 8688 bytes. */
#ifndef WOLFSSL_NO_LMS_SHA256_256
#define WC_TEST_LMS_SIG_LEN (8688) #define WC_TEST_LMS_SIG_LEN (8688)
#else
#define WC_TEST_LMS_SIG_LEN (4984)
#endif
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void) WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
{ {
@ -46103,8 +46107,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */ #endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_SMALL_STACK) #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) !defined(WOLFSSL_NO_LMS_SHA256_256)) || defined(HAVE_LIBLMS)
/* A simple LMS verify only test. /* A simple LMS verify only test.
* *

View File

@ -78,6 +78,7 @@ enum wc_LmsRc {
* Not predefining many sets with Winternitz=1, because the signatures * Not predefining many sets with Winternitz=1, because the signatures
* will be large. */ * will be large. */
enum wc_LmsParm { enum wc_LmsParm {
#ifndef WOLFSSL_NO_LMS_SHA256_256
WC_LMS_PARM_NONE = 0, WC_LMS_PARM_NONE = 0,
WC_LMS_PARM_L1_H5_W1 = 1, WC_LMS_PARM_L1_H5_W1 = 1,
WC_LMS_PARM_L1_H5_W2 = 2, WC_LMS_PARM_L1_H5_W2 = 2,
@ -114,6 +115,27 @@ enum wc_LmsParm {
WC_LMS_PARM_L4_H5_W8 = 33, WC_LMS_PARM_L4_H5_W8 = 33,
WC_LMS_PARM_L4_H10_W4 = 34, WC_LMS_PARM_L4_H10_W4 = 34,
WC_LMS_PARM_L4_H10_W8 = 35, WC_LMS_PARM_L4_H10_W8 = 35,
#endif
#ifdef WOLFSSL_LMS_SHA256_192
WC_LMS_PARM_SHA256_192_L1_H5_W1 = 36,
WC_LMS_PARM_SHA256_192_L1_H5_W2 = 37,
WC_LMS_PARM_SHA256_192_L1_H5_W4 = 38,
WC_LMS_PARM_SHA256_192_L1_H5_W8 = 39,
WC_LMS_PARM_SHA256_192_L1_H10_W2 = 40,
WC_LMS_PARM_SHA256_192_L1_H10_W4 = 41,
WC_LMS_PARM_SHA256_192_L1_H10_W8 = 42,
WC_LMS_PARM_SHA256_192_L1_H15_W2 = 43,
WC_LMS_PARM_SHA256_192_L1_H15_W4 = 44,
WC_LMS_PARM_SHA256_192_L2_H10_W2 = 45,
WC_LMS_PARM_SHA256_192_L2_H10_W4 = 46,
WC_LMS_PARM_SHA256_192_L2_H10_W8 = 47,
WC_LMS_PARM_SHA256_192_L3_H5_W2 = 48,
WC_LMS_PARM_SHA256_192_L3_H5_W4 = 49,
WC_LMS_PARM_SHA256_192_L3_H5_W8 = 50,
WC_LMS_PARM_SHA256_192_L3_H10_W4 = 51,
WC_LMS_PARM_SHA256_192_L4_H5_W8 = 52,
#endif
}; };
/* enum wc_LmsState is to help track the state of an LMS/HSS Key. */ /* enum wc_LmsState is to help track the state of an LMS/HSS Key. */

View File

@ -134,6 +134,9 @@
/* Length of numeric types when encoding. */ /* Length of numeric types when encoding. */
#define LMS_TYPE_LEN 4 #define LMS_TYPE_LEN 4
/* Size of digest output when truncatint SHA-256 to 192 bits. */
#define WC_SHA256_192_DIGEST_SIZE 24
/* Maximum size of a node hash. */ /* Maximum size of a node hash. */
#define LMS_MAX_NODE_LEN WC_SHA256_DIGEST_SIZE #define LMS_MAX_NODE_LEN WC_SHA256_DIGEST_SIZE
/* Maximum size of SEED (produced by hash). */ /* Maximum size of SEED (produced by hash). */
@ -142,8 +145,6 @@
* Value of P when N=32 and W=1. * Value of P when N=32 and W=1.
*/ */
#define LMS_MAX_P 265 #define LMS_MAX_P 265
/* Length of SEED and I in bytes. */
#define LMS_SEED_I_LEN (LMS_SEED_LEN + LMS_I_LEN)
#ifndef WOLFSSL_LMS_ROOT_LEVELS #ifndef WOLFSSL_LMS_ROOT_LEVELS
@ -192,33 +193,32 @@
(HSS_COMPRESS_PARAM_SET_LEN * HSS_MAX_LEVELS) (HSS_COMPRESS_PARAM_SET_LEN * HSS_MAX_LEVELS)
/* Private key length for one level. */ /* Private key length for one level. */
#define LMS_PRIV_LEN \ #define LMS_PRIV_LEN(hLen) \
(LMS_Q_LEN + LMS_SEED_LEN + LMS_I_LEN) (LMS_Q_LEN + (hLen) + LMS_I_LEN)
/* Public key length in signature. */ /* Public key length in signature. */
#define LMS_PUBKEY_LEN \ #define LMS_PUBKEY_LEN(hLen) \
(LMS_TYPE_LEN + LMS_TYPE_LEN + LMS_I_LEN + LMS_MAX_NODE_LEN) (LMS_TYPE_LEN + LMS_TYPE_LEN + LMS_I_LEN + (hLen))
/* LMS signature data length. */ /* LMS signature data length. */
#define LMS_SIG_LEN(h, p) \ #define LMS_SIG_LEN(h, p, hLen) \
(LMS_Q_LEN + LMS_TYPE_LEN + LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN + \ (LMS_Q_LEN + LMS_TYPE_LEN + (hLen) + (p) * (hLen) + LMS_TYPE_LEN + \
LMS_TYPE_LEN + (h) * LMS_MAX_NODE_LEN) (h) * (hLen))
/* Length of public key. */ /* Length of public key. */
#define HSS_PUBLIC_KEY_LEN (LMS_L_LEN + LMS_PUBKEY_LEN) #define HSS_PUBLIC_KEY_LEN(hLen) (LMS_L_LEN + LMS_PUBKEY_LEN(hLen))
/* Length of private key. */ /* Length of private key. */
#define HSS_PRIVATE_KEY_LEN \ #define HSS_PRIVATE_KEY_LEN(hLen) \
(HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + LMS_SEED_LEN + LMS_I_LEN) (HSS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN + (hLen) + LMS_I_LEN)
/* Maximum public key length - length is constant for all parameters. */ /* Maximum public key length - length is constant for all parameters. */
#define HSS_MAX_PRIVATE_KEY_LEN HSS_PRIVATE_KEY_LEN #define HSS_MAX_PRIVATE_KEY_LEN HSS_PRIVATE_KEY_LEN(LMS_MAX_NODE_LEN)
/* Maximum private key length - length is constant for all parameters. */ /* Maximum private key length - length is constant for all parameters. */
#define HSS_MAX_PUBLIC_KEY_LEN HSS_PUBLIC_KEY_LEN #define HSS_MAX_PUBLIC_KEY_LEN HSS_PUBLIC_KEY_LEN(LMS_MAX_NODE_LEN)
/* Maximum signature length. */ /* Maximum signature length. */
#define HSS_MAX_SIG_LEN \ #define HSS_MAX_SIG_LEN \
(LMS_TYPE_LEN + \ (LMS_TYPE_LEN + \
LMS_MAX_LEVELS * (LMS_Q_LEN + LMS_TYPE_LEN + LMS_TYPE_LEN + \ LMS_MAX_LEVELS * (LMS_Q_LEN + LMS_TYPE_LEN + LMS_TYPE_LEN + \
LMS_MAX_NODE_LEN * (1 + LMS_MAX_P + LMS_MAX_HEIGHT)) + \ LMS_MAX_NODE_LEN * (1 + LMS_MAX_P + LMS_MAX_HEIGHT)) + \
(LMS_MAX_LEVELS - 1) * LMS_PUBKEY_LEN \ (LMS_MAX_LEVELS - 1) * LMS_PUBKEY_LEN(LMS_MAX_NODE_LEN))
)
/* Maximum buffer length required for use when hashing. */ /* Maximum buffer length required for use when hashing. */
#define LMS_MAX_BUFFER_LEN \ #define LMS_MAX_BUFFER_LEN \
@ -229,20 +229,20 @@
* *
* HSSPrivKey.priv * HSSPrivKey.priv
*/ */
#define LMS_PRIV_KEY_LEN(l) \ #define LMS_PRIV_KEY_LEN(l, hLen) \
((l) * LMS_PRIV_LEN) ((l) * LMS_PRIV_LEN(hLen))
/* Stack of nodes. */ /* Stack of nodes. */
#define LMS_STACK_CACHE_LEN(h) \ #define LMS_STACK_CACHE_LEN(h, hLen) \
(((h) + 1) * LMS_MAX_NODE_LEN) (((h) + 1) * (hLen))
/* Root cache length. */ /* Root cache length. */
#define LMS_ROOT_CACHE_LEN(rl) \ #define LMS_ROOT_CACHE_LEN(rl, hLen) \
(((1 << (rl)) - 1) * LMS_MAX_NODE_LEN) (((1 << (rl)) - 1) * (hLen))
/* Leaf cache length. */ /* Leaf cache length. */
#define LMS_LEAF_CACHE_LEN(cb) \ #define LMS_LEAF_CACHE_LEN(cb, hLen) \
((1 << (cb)) * LMS_MAX_NODE_LEN) ((1 << (cb)) * (hLen))
/* Length of LMS private key state. /* Length of LMS private key state.
* *
@ -252,75 +252,103 @@
* stack.stack + stack.offset + * stack.stack + stack.offset +
* cache.leaf + cache.index + cache.offset * cache.leaf + cache.index + cache.offset
*/ */
#define LMS_PRIV_STATE_LEN(h, rl, cb) \ #define LMS_PRIV_STATE_LEN(h, rl, cb, hLen) \
(((h) * LMS_MAX_NODE_LEN) + \ (((h) * (hLen)) + \
LMS_STACK_CACHE_LEN(h) + 4 + \ LMS_STACK_CACHE_LEN(h, hLen) + 4 + \
LMS_ROOT_CACHE_LEN(rl) + \ LMS_ROOT_CACHE_LEN(rl, hLen) + \
LMS_LEAF_CACHE_LEN(cb) + 4 + 4) LMS_LEAF_CACHE_LEN(cb, hLen) + 4 + 4)
#ifndef WOLFSSL_WC_LMS_SMALL #ifndef WOLFSSL_WC_LMS_SMALL
/* Private key data state for all levels. */ /* Private key data state for all levels. */
#define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) \ #define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb, hLen) \
((l) * LMS_PRIV_STATE_LEN(h, rl, cb)) ((l) * LMS_PRIV_STATE_LEN(h, rl, cb, hLen))
#else #else
/* Private key data state for all levels. */ /* Private key data state for all levels. */
#define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) 0 #define LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb, hLen) 0
#endif #endif
#ifndef WOLFSSL_LMS_NO_SIGN_SMOOTHING #ifndef WOLFSSL_LMS_NO_SIGN_SMOOTHING
/* Extra private key data for smoothing. */ /* Extra private key data for smoothing. */
#define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) \ #define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb, hLen) \
(LMS_PRIV_KEY_LEN(l) + \ (LMS_PRIV_KEY_LEN(l, hLen) + \
((l) - 1) * LMS_PRIV_STATE_LEN(h, rl, cb)) ((l) - 1) * LMS_PRIV_STATE_LEN(h, rl, cb, hLen))
#else #else
/* Extra private key data for smoothing. */ /* Extra private key data for smoothing. */
#define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) 0 #define LMS_PRIV_SMOOTH_LEN(l, h, rl, cb, hLen) 0
#endif #endif
#ifndef WOLFSSL_LMS_NO_SIG_CACHE #ifndef WOLFSSL_LMS_NO_SIG_CACHE
#define LMS_PRIV_Y_TREE_LEN(p) \ #define LMS_PRIV_Y_TREE_LEN(p, hLen) \
(LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN) ((hLen) + (p) * (hLen))
/* Length of the y data cached in private key data. */ /* Length of the y data cached in private key data. */
#define LMS_PRIV_Y_LEN(l, p) \ #define LMS_PRIV_Y_LEN(l, p, hLen) \
(((l) - 1) * (LMS_MAX_NODE_LEN + (p) * LMS_MAX_NODE_LEN)) (((l) - 1) * ((hLen) + (p) * (hLen)))
#else #else
/* Length of the y data cached in private key data. */ /* Length of the y data cached in private key data. */
#define LMS_PRIV_Y_LEN(l, p) 0 #define LMS_PRIV_Y_LEN(l, p, hLen) 0
#endif #endif
#ifndef WOLFSSL_WC_LMS_SMALL #ifndef WOLFSSL_WC_LMS_SMALL
/* Length of private key data. */ /* Length of private key data. */
#define LMS_PRIV_DATA_LEN(l, h, p, rl, cb) \ #define LMS_PRIV_DATA_LEN(l, h, p, rl, cb, hLen) \
(LMS_PRIV_KEY_LEN(l) + \ (LMS_PRIV_KEY_LEN(l, hLen) + \
LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb) + \ LMS_PRIV_STATE_ALL_LEN(l, h, rl, cb, hLen) + \
LMS_PRIV_SMOOTH_LEN(l, h, rl, cb) + \ LMS_PRIV_SMOOTH_LEN(l, h, rl, cb, hLen) + \
LMS_PRIV_Y_LEN(l, p)) LMS_PRIV_Y_LEN(l, p, hLen))
#else #else
#define LMS_PRIV_DATA_LEN(l, h, p, rl, cb) \ #define LMS_PRIV_DATA_LEN(l, h, p, rl, cb, hLen) \
LMS_PRIV_KEY_LEN(l) LMS_PRIV_KEY_LEN(l, hLen)
#endif #endif
/* Indicates using SHA-256 for hashing. */
#define LMS_SHA256 0x00
/* Indicates using SHA-256/192 for hashing. */
#define LMS_SHA256_192 0x10
/* Mask to get hashing algorithm from type. */
#define LMS_HASH_MASK 0xf0
/* Mask to get height or Winternitz width from type. */
#define LMS_H_W_MASK 0x0f
/* LMS Parameters. */ /* LMS Parameters. */
/* SHA-256 hash, 32-bytes of hash used, tree height of 5. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 5. */
#define LMS_SHA256_M32_H5 5 #define LMS_SHA256_M32_H5 0x05
/* SHA-256 hash, 32-bytes of hash used, tree height of 10. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 10. */
#define LMS_SHA256_M32_H10 6 #define LMS_SHA256_M32_H10 0x06
/* SHA-256 hash, 32-bytes of hash used, tree height of 15. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 15. */
#define LMS_SHA256_M32_H15 7 #define LMS_SHA256_M32_H15 0x07
/* SHA-256 hash, 32-bytes of hash used, tree height of 20. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 20. */
#define LMS_SHA256_M32_H20 8 #define LMS_SHA256_M32_H20 0x08
/* SHA-256 hash, 32-bytes of hash used, tree height of 25. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 25. */
#define LMS_SHA256_M32_H25 9 #define LMS_SHA256_M32_H25 0x09
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 1 bit. */ /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 1 bit. */
#define LMOTS_SHA256_N32_W1 1 #define LMOTS_SHA256_N32_W1 0x01
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 2 bits. */ /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 2 bits. */
#define LMOTS_SHA256_N32_W2 2 #define LMOTS_SHA256_N32_W2 0x02
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 4 bits. */ /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 4 bits. */
#define LMOTS_SHA256_N32_W4 3 #define LMOTS_SHA256_N32_W4 0x03
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 8 bits. */ /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 8 bits. */
#define LMOTS_SHA256_N32_W8 4 #define LMOTS_SHA256_N32_W8 0x04
/* SHA-256 hash, 32-bytes of hash used, tree height of 5. */
#define LMS_SHA256_M24_H5 (0x05 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, tree height of 10. */
#define LMS_SHA256_M24_H10 (0x06 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, tree height of 15. */
#define LMS_SHA256_M24_H15 (0x07 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, tree height of 20. */
#define LMS_SHA256_M24_H20 (0x08 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, tree height of 25. */
#define LMS_SHA256_M24_H25 (0x09 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 1 bit. */
#define LMOTS_SHA256_N24_W1 (0x01 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 2 bits. */
#define LMOTS_SHA256_N24_W2 (0x02 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 4 bits. */
#define LMOTS_SHA256_N24_W4 (0x03 | LMS_SHA256_192)
/* SHA-256 hash, 32-bytes of hash used, Winternitz width of 8 bits. */
#define LMOTS_SHA256_N24_W8 (0x04 | LMS_SHA256_192)
typedef struct LmsParams { typedef struct LmsParams {
/* Number of tree levels. */ /* Number of tree levels. */
@ -339,6 +367,8 @@ typedef struct LmsParams {
word16 lmOtsType; word16 lmOtsType;
/* Length of LM-OTS signature. */ /* Length of LM-OTS signature. */
word16 sig_len; word16 sig_len;
/* Length of seed. */
word16 hash_len;
#ifndef WOLFSSL_WC_LMS_SMALL #ifndef WOLFSSL_WC_LMS_SMALL
/* Number of root levels of interior nodes to store. */ /* Number of root levels of interior nodes to store. */
word8 rootLevels; word8 rootLevels;
@ -426,10 +456,10 @@ typedef struct HssPrivKey {
struct LmsKey { struct LmsKey {
/* Public key. */ /* Public key. */
ALIGN16 byte pub[HSS_PUBLIC_KEY_LEN]; ALIGN16 byte pub[HSS_PUBLIC_KEY_LEN(LMS_MAX_NODE_LEN)];
#ifndef WOLFSSL_LMS_VERIFY_ONLY #ifndef WOLFSSL_LMS_VERIFY_ONLY
/* Encoded private key. */ /* Encoded private key. */
ALIGN16 byte priv_raw[HSS_PRIVATE_KEY_LEN]; ALIGN16 byte priv_raw[HSS_MAX_PRIVATE_KEY_LEN];
/* Packed private key data. */ /* Packed private key data. */
byte* priv_data; byte* priv_data;