diff --git a/configure.ac b/configure.ac index 1250784fb..1da02cc48 100644 --- a/configure.ac +++ b/configure.ac @@ -1167,6 +1167,10 @@ do ENABLED_WC_XMSS=yes AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_XMSS" ;; + small) + ENABLED_WC_XMSS=yes + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_XMSS_SMALL" + ;; *) AC_MSG_ERROR([Invalid choice for XMSS []: $ENABLED_XMSS.]) break;; diff --git a/src/include.am b/src/include.am index b9be36b07..b9a8b3316 100644 --- a/src/include.am +++ b/src/include.am @@ -714,6 +714,7 @@ endif if BUILD_WC_XMSS src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_xmss.c +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_xmss_impl.c endif if BUILD_CURVE25519 diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 05414b486..d3b331afd 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -178,6 +178,8 @@ #include #ifdef HAVE_LIBXMSS #include + #else + #include #endif #endif #ifdef WOLFCRYPT_HAVE_ECCSI @@ -662,7 +664,21 @@ /* Post-Quantum Stateful Hash-Based sig algorithms. */ #define BENCH_LMS_HSS 0x00000001 -#define BENCH_XMSS_XMSSMT 0x00000002 +#define BENCH_XMSS_XMSSMT_SHA256 0x00000002 +#define BENCH_XMSS_XMSSMT_SHA512 0x00000004 +#define BENCH_XMSS_XMSSMT_SHAKE128 0x00000008 +#define BENCH_XMSS_XMSSMT_SHAKE256 0x00000010 +#ifndef NO_SHA256 +#define BENCH_XMSS_XMSSMT BENCH_XMSS_XMSSMT_SHA256 +#elif defined(WOLFSSL_SHA512) +#define BENCH_XMSS_XMSSMT BENCH_XMSS_XMSSMT_SHA512 +#elif defined(WOLFSSL_SHAKE128) +#define BENCH_XMSS_XMSSMT BENCH_XMSS_XMSSMT_SHAKE128 +#elif defined(WOLFSSL_SHAKE256) +#define BENCH_XMSS_XMSSMT BENCH_XMSS_XMSSMT_SHAKE256 +#else +#define BENCH_XMSS_XMSSMT 0x00000000 +#endif /* Other */ #define BENCH_RNG 0x00000001 @@ -987,7 +1003,23 @@ static const bench_pq_hash_sig_alg bench_pq_hash_sig_opt[] = { { "-lms_hss", BENCH_LMS_HSS}, #endif #if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) - { "-xmss_xmssmt", BENCH_XMSS_XMSSMT}, + { "-xmss_xmssmt", BENCH_XMSS_XMSSMT}, +#ifdef WC_XMSS_SHA256 + { "-xmss_xmssmt_sha256", BENCH_XMSS_XMSSMT_SHA256}, +#endif +#ifdef WC_XMSS_SHA512 +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 512 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512 + { "-xmss_xmssmt_sha512", BENCH_XMSS_XMSSMT_SHA512}, +#endif +#endif +#ifdef WC_XMSS_SHAKE128 +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 + { "-xmss_xmssmt_shake128", BENCH_XMSS_XMSSMT_SHAKE128}, +#endif +#endif +#ifdef WC_XMSS_SHAKE256 + { "-xmss_xmssmt_shake256", BENCH_XMSS_XMSSMT_SHAKE256}, +#endif #endif { NULL, 0} }; @@ -3497,9 +3529,29 @@ static void* benchmarks_do(void* args) #endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */ #if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) - if (bench_all || (bench_pq_hash_sig_algs & BENCH_XMSS_XMSSMT)) { - bench_xmss(); + if (bench_all) { + bench_pq_hash_sig_algs |= BENCH_XMSS_XMSSMT; } +#ifndef NO_SHA256 + if (bench_pq_hash_sig_algs & BENCH_XMSS_XMSSMT_SHA256) { + bench_xmss(WC_HASH_TYPE_SHA256); + } +#endif +#ifdef WOLFSSL_SHA512 + if (bench_pq_hash_sig_algs & BENCH_XMSS_XMSSMT_SHA512) { + bench_xmss(WC_HASH_TYPE_SHA512); + } +#endif +#ifdef WOLFSSL_SHAKE128 + if (bench_pq_hash_sig_algs & BENCH_XMSS_XMSSMT_SHAKE128) { + bench_xmss(WC_HASH_TYPE_SHAKE128); + } +#endif +#ifdef WOLFSSL_SHAKE256 + if (bench_pq_hash_sig_algs & BENCH_XMSS_XMSSMT_SHAKE256) { + bench_xmss(WC_HASH_TYPE_SHAKE256); + } +#endif #endif /* if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) */ #ifdef HAVE_ECC @@ -9640,11 +9692,17 @@ static void bench_xmss_sign_verify(const char * params) } ret = wc_XmssKey_GetPubLen(&key, &pkSz); + if (ret != 0) { + fprintf(stderr, "wc_XmssKey_GetPubLen failed: %d\n", ret); + goto exit_xmss_sign_verify; + } +#ifndef WOLFSSL_WC_XMSS if (pkSz != XMSS_SHA256_PUBLEN) { fprintf(stderr, "error: xmss pub len: got %u, expected %d\n", pkSz, XMSS_SHA256_PUBLEN); goto exit_xmss_sign_verify; } +#endif ret = wc_XmssKey_GetPrivLen(&key, &skSz); if (ret != 0 || skSz <= 0) { @@ -9684,7 +9742,7 @@ static void bench_xmss_sign_verify(const char * params) goto exit_xmss_sign_verify; } - ret = wc_XmssKey_SetContext(&key, (void *) sk); + ret = wc_XmssKey_SetContext(&key, (void *)sk); if (ret != 0) { fprintf(stderr, "error: wc_XmssKey_SetContext failed: %d\n", ret); goto exit_xmss_sign_verify; @@ -9697,25 +9755,21 @@ static void bench_xmss_sign_verify(const char * params) fprintf(stderr, "sigSz: %d\n", sigSz); #endif - /* Making the private key is the bottleneck - * for larger heights. Only print load time in debug builds. */ -#if defined(DEBUG_WOLFSSL) + /* Making the private key is the bottleneck for larger heights. */ + count = 0; bench_stats_start(&count, &start); -#endif /* if defined DEBUG_WOLFSSL*/ ret = wc_XmssKey_MakeKey(&key, &rng); if (ret != 0) { printf("wc_XmssKey_MakeKey failed: %d\n", ret); goto exit_xmss_sign_verify; } + /* Can only do one at a time - state changes after make key. */ count +=1; -#if defined(DEBUG_WOLFSSL) bench_stats_check(start); - bench_stats_asym_finish(params, (int)skSz, "load", 0, - count, start, ret); -#endif /* if defined DEBUG_WOLFSSL*/ + bench_stats_asym_finish(params, (int)skSz, "gen", 0, count, start, ret); freeKey = 1; @@ -9724,20 +9778,24 @@ static void bench_xmss_sign_verify(const char * params) do { /* XMSS is stateful. Async queuing not practical. */ - for (times = 0; times < ntimes; ++times) { - +#ifndef WOLFSSL_WC_XMSS_SMALL + for (times = 0; times < ntimes; ++times) +#else + for (times = 0; times < 1; ++times) +#endif + { + if (!wc_XmssKey_SigsLeft(&key)) + break; ret = wc_XmssKey_Sign(&key, sig, &sigSz, (byte *) msg, msgSz); if (ret) { printf("wc_XmssKey_Sign failed: %d\n", ret); goto exit_xmss_sign_verify; } } - count += times; - } while (bench_stats_check(start)); + } while (wc_XmssKey_SigsLeft(&key) && bench_stats_check(start)); - bench_stats_asym_finish(params, (int)sigSz, "sign", 0, - count, start, ret); + bench_stats_asym_finish(params, (int)sigSz, "sign", 0, count, start, ret); count = 0; bench_stats_start(&count, &start); @@ -9751,13 +9809,11 @@ static void bench_xmss_sign_verify(const char * params) goto exit_xmss_sign_verify; } } - count += times; } while (bench_stats_check(start)); exit_xmss_sign_verify: - bench_stats_asym_finish(params, (int)sigSz, "verify", 0, - count, start, ret); + bench_stats_asym_finish(params, (int)sigSz, "verify", 0, count, start, ret); /* Cleanup everything. */ if (sig != NULL) { @@ -9783,7 +9839,7 @@ exit_xmss_sign_verify: return; } -void bench_xmss(void) +void bench_xmss(int hash) { /* All NIST SP 800-208 approved SHA256 XMSS/XMSS^MT parameter * sets. @@ -9799,18 +9855,287 @@ void bench_xmss(void) * * h is the total height of the hyper tree, and d the number of * trees. - * */ - /* h/d h d */ - bench_xmss_sign_verify("XMSS-SHA2_10_256"); /* 10 10 1 */ - /* bench_xmss_sign_verify("XMSS-SHA2_16_256"); */ /* 16 16 1 */ - /* bench_xmss_sign_verify("XMSS-SHA2_20_256"); */ /* 20 20 1 */ - bench_xmss_sign_verify("XMSSMT-SHA2_20/2_256"); /* 10 20 2 */ - bench_xmss_sign_verify("XMSSMT-SHA2_20/4_256"); /* 5 20 4 */ - bench_xmss_sign_verify("XMSSMT-SHA2_40/4_256"); /* 10 40 4 */ - bench_xmss_sign_verify("XMSSMT-SHA2_40/8_256"); /* 5 40 8 */ - /* bench_xmss_sign_verify("XMSSMT-SHA2_60/3_256"); */ /* 20 60 3 */ - bench_xmss_sign_verify("XMSSMT-SHA2_60/6_256"); /* 10 60 6 */ - bench_xmss_sign_verify("XMSSMT-SHA2_60/12_256"); /* 5 60 12 */ + */ + /* h/d h d */ +#ifdef WC_XMSS_SHA256 + if (hash == WC_HASH_TYPE_SHA256) { +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHA2_10_256"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_16_256"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_20_256"); /* 20 20 1 */ +#endif +#endif +#endif /* HASH_SIZE 256 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 192 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 192 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHA2_10_192"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_16_192"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_20_192"); /* 20 20 1 */ +#endif +#endif +#endif /* HASH_SIZE 192 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHA2_20/2_256"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHA2_20/4_256"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_40/2_256"); /* 20 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_40/4_256"); /* 10 40 4 */ + bench_xmss_sign_verify("XMSSMT-SHA2_40/8_256"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_60/3_256"); /* 20 60 3 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_60/6_256"); /* 10 60 6 */ + bench_xmss_sign_verify("XMSSMT-SHA2_60/12_256"); /* 5 60 12 */ +#endif +#endif /* HASH_SIZE 256 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 192 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 192 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHA2_20/2_192"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHA2_20/4_192"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_40/2_192"); /* 20 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_40/4_192"); /* 10 40 4 */ + bench_xmss_sign_verify("XMSSMT-SHA2_40/8_192"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_60/3_192"); /* 20 60 3 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_60/6_192"); /* 10 60 6 */ + bench_xmss_sign_verify("XMSSMT-SHA2_60/12_192"); /* 5 60 12 */ +#endif +#endif /* HASH_SIZE 192 */ + } +#endif +#ifdef WC_XMSS_SHA512 +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 512 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512 + if (hash == WC_HASH_TYPE_SHA512) { +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHA2_10_512"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_16_512"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHA2_20_512"); /* 20 20 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHA2_20/2_512"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHA2_20/4_512"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_40/2_512"); /* 20 40 4 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_40/4_512"); /* 10 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_40/8_512"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_60/3_512"); /* 20 60 3 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHA2_60/6_512"); /* 10 60 6 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHA2_60/12_512"); /* 5 60 12 */ +#endif + } +#endif /* HASH_SIZE 512 */ +#endif +#ifdef WC_XMSS_SHAKE128 +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 + if (hash == WC_HASH_TYPE_SHAKE128) { +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHAKE_10_256"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE_16_256"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE_20_256"); /* 20 20 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHAKE_20/2_256"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHAKE_20/4_256"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_40/2_256"); /* 20 40 4 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_40/4_256"); /* 10 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE_40/8_256"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_60/3_256"); /* 20 60 3 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_60/6_256"); /* 10 60 6 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE_60/12_256"); /* 5 60 12 */ +#endif + } +#endif /* HASH_SIZE 256 */ +#endif +#ifdef WC_XMSS_SHAKE256 + if (hash == WC_HASH_TYPE_SHAKE256) { +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 512 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHAKE_10_512"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE_16_512"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE_20_512"); /* 20 20 1 */ +#endif +#endif +#endif /* HASH_SIZE 512 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHAKE256_10_256"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE256_16_256"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE256_20_256"); /* 20 20 1 */ +#endif +#endif +#endif /* HASH_SIZE 256 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 192 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 192 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 && WOLFSSL_XMSS_MAX_HEIGHT >= 10 + bench_xmss_sign_verify("XMSS-SHAKE256_10_192"); /* 10 10 1 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 16 && WOLFSSL_XMSS_MAX_HEIGHT >= 16 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE256_16_192"); /* 16 16 1 */ +#endif +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSS-SHAKE256_20_192"); /* 20 20 1 */ +#endif +#endif +#endif /* HASH_SIZE 192 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 512 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_20/2_512"); /* 10 20 2 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE_20/4_512"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_40/2_512"); /* 20 40 4 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_40/4_512"); /* 10 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE_40/8_512"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_60/3_512"); /* 20 60 3 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE_60/6_512"); /* 10 60 6 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE_60/12_512"); /* 5 60 12 */ +#endif +#endif /* HASH_SIZE 512 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 256 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 256 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHAKE256_20/2_256"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHAKE256_20/4_256"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/2_256"); /* 20 40 4 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/4_256"); /* 10 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/8_256"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/3_256"); /* 20 60 3 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/6_256"); /* 10 60 6 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/12_256");/* 5 60 12 */ +#endif +#endif /* HASH_SIZE 256 */ +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE <= 192 && WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 192 +#if WOLFSSL_XMSS_MIN_HEIGHT <= 20 && WOLFSSL_XMSS_MAX_HEIGHT >= 20 + bench_xmss_sign_verify("XMSSMT-SHAKE256_20/2_192"); /* 10 20 2 */ + bench_xmss_sign_verify("XMSSMT-SHAKE256_20/4_192"); /* 5 20 4 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 40 && WOLFSSL_XMSS_MAX_HEIGHT >= 40 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/2_192"); /* 20 40 4 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/4_192"); /* 10 40 4 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE256_40/8_192"); /* 5 40 8 */ +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT <= 60 && WOLFSSL_XMSS_MAX_HEIGHT >= 60 +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/3_192"); /* 20 60 3 */ +#endif +#ifdef BENCH_XMSS_SLOW_KEYGEN + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/6_192"); /* 10 60 6 */ +#endif + bench_xmss_sign_verify("XMSSMT-SHAKE256_60/12_192");/* 5 60 12 */ +#endif +#endif /* HASH_SIZE 192 */ + } +#endif return; } #endif /* if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY) */ diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index cefef7ca6..b814a9476 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -103,7 +103,7 @@ void bench_rsa_key(int useDeviceID, word32 keySz); void bench_dh(int useDeviceID); void bench_kyber(int type); void bench_lms(void); -void bench_xmss(void); +void bench_xmss(int hash); void bench_ecc_curve(int curveId); void bench_eccMakeKey(int useDeviceID, int curveId); void bench_ecc(int useDeviceID, int curveId); diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index 929e0bfd0..eebd4dbc0 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -601,6 +601,9 @@ const char* wc_GetErrorString(int error) case AES_EAX_AUTH_E: return "AES-EAX Authentication check fail"; + case KEY_EXHAUSTED_E: + return "Key no longer usable for operation"; + default: return "unknown error number"; diff --git a/wolfcrypt/src/ext_xmss.c b/wolfcrypt/src/ext_xmss.c index b1e5e46dd..4a97d09a8 100644 --- a/wolfcrypt/src/ext_xmss.c +++ b/wolfcrypt/src/ext_xmss.c @@ -39,6 +39,7 @@ #endif #include +#include #ifndef WOLFSSL_XMSS_VERIFY_ONLY static THREAD_LS_T WC_RNG * xmssRng = NULL; @@ -177,6 +178,11 @@ static int wc_XmssKey_SetOid(XmssKey * key, uint32_t oid, int is_xmssmt) WOLFSSL_MSG("error: unsupported XMSS/XMSS^MT parameter set"); return -1; } + if ((key->params.full_height < WOLFSSL_XMSS_MIN_HEIGHT) || + (key->params.full_height > WOLFSSL_XMSS_MAX_HEIGHT)) { + WOLFSSL_MSG("error: unsupported XMSS/XMSS^MT parameter set - height"); + return -1; + } ret = xmss_set_sha_cb(sha256_cb); if (ret != 0) { @@ -747,6 +753,47 @@ int wc_XmssKey_Sign(XmssKey* key, byte * sig, word32 * sigLen, const byte * msg, return (key->state == WC_XMSS_STATE_OK) ? 0 : -1; } + + +/* Check if more signatures are possible with key. + * + * @param [in] key XMSS key to check. + * @return 1 when signatures possible. + * @return 0 when key exhausted. + */ +int wc_XmssKey_SigsLeft(XmssKey* key) +{ + int ret; + + /* Validate parameter. */ + if (key == NULL) { + ret = 0; + } + /* Validate state. */ + else if (key->state == WC_XMSS_STATE_NOSIGS) { + WOLFSSL_MSG("error: XMSS signatures exhausted"); + ret = 0; + } + else if (key->state != WC_XMSS_STATE_OK) { + WOLFSSL_MSG("error: can't sign, XMSS key not in good state"); + 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) { + WOLFSSL_MSG("error: XMSS read_private_key failed"); + ret = 0; + } + else { + xmss_params* params = &key->params; + unsigned long long idx; + + idx = (unsigned long)bytes_to_ull(key->sk, params->index_bytes); + ret = idx < ((1ULL << params->full_height) - 1); + } + + return ret; +} #endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY*/ /* Get the XMSS/XMSS^MT public key length. The public key diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index 62cd9b409..c1726be21 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -760,7 +760,20 @@ WC_MISC_STATIC WC_INLINE void w64Zero(w64wrapper *a) a->n = 0; } +WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftRight(w64wrapper a, int shift) +{ + a.n >>= shift; + return a; +} + +WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftLeft(w64wrapper a, int shift) +{ + a.n <<= shift; + return a; +} + #else + WC_MISC_STATIC WC_INLINE void w64Increment(w64wrapper *n) { n->n[1]++; @@ -899,6 +912,31 @@ WC_MISC_STATIC WC_INLINE byte w64LT(w64wrapper a, w64wrapper b) return 0; } +WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftRight(w64wrapper a, int shift) +{ + if (shift < 32) { + a.n[1] = (a.n[1] >> shift) || (a.n[0] << (32 - shift)); + a.n[0] >>= shift; + } + else { + a.n[1] = a.n[0] >> (shift - 32); + a.n[0] = 0; + } + return a; +} +WC_MISC_STATIC WC_INLINE w64wrapper w64ShiftLeft(w64wrapper a, int shift) +{ + if (shift < 32) { + a.n[0] = (a.n[0] << shift) || (a.n[1] >> (32 - shift)); + a.n[1] <<= shift; + } + else { + a.n[0] = a.n[1] << (shift - 32); + a.n[1] = 0; + } + return a; +} + #endif /* WORD64_AVAILABLE && !WOLFSSL_W64_WRAPPER_TEST */ #endif /* WOLFSSL_W64_WRAPPER */ diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 55860d86b..2fa9adfb3 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -313,6 +313,8 @@ static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 le /* only perform actions if a buffer is passed in */ if (len > 0) { + AddLength(sha256, len); + /* fill leftover buffer with data */ add = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen); XMEMCPY((byte*)(sha256->buffer) + sha256->buffLen, data, add); @@ -330,8 +332,6 @@ static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 le Sha256Transform(sha256, data, numBlocks); data += numBlocks * WC_SHA256_BLOCK_SIZE - sha256->buffLen; - AddLength(sha256, WC_SHA256_BLOCK_SIZE * numBlocks); - /* copy over any remaining data leftover */ XMEMCPY(sha256->buffer, data, add); sha256->buffLen = add; @@ -352,8 +352,6 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) const word32* k; local = (byte*)sha256->buffer; - AddLength(sha256, sha256->buffLen); /* before adding pads */ - local[sha256->buffLen++] = 0x80; /* add 1 */ /* pad with zeros */ @@ -901,6 +899,8 @@ static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 le /* only perform actions if a buffer is passed in */ if (len > 0) { + AddLength(sha256, len); + /* fill leftover buffer with data */ add = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen); XMEMCPY((byte*)(sha256->buffer) + sha256->buffLen, data, add); @@ -918,8 +918,6 @@ static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 le Sha256Transform(sha256, data, numBlocks); data += numBlocks * WC_SHA256_BLOCK_SIZE - sha256->buffLen; - AddLength(sha256, WC_SHA256_BLOCK_SIZE * numBlocks); - /* copy over any remaining data leftover */ XMEMCPY(sha256->buffer, data, add); sha256->buffLen = add; @@ -943,8 +941,6 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) } local = (byte*)sha256->buffer; - AddLength(sha256, sha256->buffLen); /* before adding pads */ - local[sha256->buffLen++] = 0x80; /* add 1 */ /* pad with zeros */ diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index c0a19609b..90e86adfe 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -321,8 +321,6 @@ static int InitSha512_256(wc_Sha512* sha512) #if defined(USE_INTEL_SPEEDUP) && \ (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) -#ifdef WOLFSSL_SHA512 - /***** Intel AVX1/AVX2 Macro Control Structure @@ -486,7 +484,6 @@ static int InitSha512_256(wc_Sha512* sha512) transform_check = 1; } -#endif /* WOLFSSL_SHA512 */ #else #define Transform_Sha512(sha512) _Transform_Sha512(sha512) diff --git a/wolfcrypt/src/wc_xmss_impl.c b/wolfcrypt/src/wc_xmss_impl.c new file mode 100644 index 000000000..4a91f9969 --- /dev/null +++ b/wolfcrypt/src/wc_xmss_impl.c @@ -0,0 +1,26 @@ +/* wc_xmss_impl.c + * + * Copyright (C) 2006-2023 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#ifdef WOLFSSL_HAVE_XMSS + #error "Contact wolfSSL to get the implementation of this file" +#endif diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 3847e8200..6e215f52a 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -316,6 +316,8 @@ const byte const_byte_array[] = "A+Gd\0\0\0"; #include #ifdef HAVE_LIBXMSS #include +#else + #include #endif #endif #if defined(WOLFSSL_HAVE_LMS) @@ -608,12 +610,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void); WOLFSSL_TEST_SUBROUTINE wc_test_ret_t kyber_test(void); #endif #if defined(WOLFSSL_HAVE_XMSS) + #if !defined(WOLFSSL_SMALL_STACK) && WOLFSSL_XMSS_MIN_HEIGHT <= 10 + WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void); + #endif #if !defined(WOLFSSL_XMSS_VERIFY_ONLY) WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test(void); #endif - #if defined(WOLFSSL_XMSS_VERIFY_ONLY) && !defined(WOLFSSL_SMALL_STACK) - WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void); - #endif #endif #if defined(WOLFSSL_HAVE_LMS) #if !defined(WOLFSSL_LMS_VERIFY_ONLY) @@ -1699,15 +1701,15 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #endif #if defined(WOLFSSL_HAVE_XMSS) - #if !defined(WOLFSSL_XMSS_VERIFY_ONLY) - if ( (ret = xmss_test()) != 0) - TEST_FAIL("XMSS test failed!\n", ret); + #if !defined(WOLFSSL_SMALL_STACK) && WOLFSSL_XMSS_MIN_HEIGHT <= 10 + if ( (ret = xmss_test_verify_only()) != 0) + TEST_FAIL("XMSS Vfy test failed!\n", ret); else - TEST_PASS("XMSS test passed!\n"); + TEST_PASS("XMSS Vfy test passed!\n"); #endif - #if defined(WOLFSSL_XMSS_VERIFY_ONLY) && !defined(WOLFSSL_SMALL_STACK) - if ( (ret = xmss_test_verify_only()) != 0) + #if !defined(WOLFSSL_XMSS_VERIFY_ONLY) + if ( (ret = xmss_test()) != 0) TEST_FAIL("XMSS test failed!\n", ret); else TEST_PASS("XMSS test passed!\n"); @@ -2134,7 +2136,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void) int i; int j = 0; /* Values that are not or no longer error codes. */ - int missing[] = { -123, -124, -128, -129, -159, -163, -164, + int missing[] = { -124, -128, -129, -159, -163, -164, -165, -166, -167, -168, -169, -233, 0 }; /* Check that all errors have a string and it's the same through the two @@ -36534,7 +36536,15 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test(void) unsigned char * old_sk = NULL; const char * msg = "XMSS post quantum signature test"; word32 msgSz = (word32) XSTRLEN(msg); +#if WOLFSSL_XMSS_MIN_HEIGHT <= 10 + const char * param = "XMSS-SHA2_10_256"; +#elif WOLFSSL_XMSS_MIN_HEIGHT <= 20 const char * param = "XMSSMT-SHA2_20/4_256"; +#elif WOLFSSL_XMSS_MIN_HEIGHT <= 40 + const char * param = "XMSSMT-SHA2_40/8_256"; +#else + const char * param = "XMSSMT-SHA2_60/12_256"; +#endif byte * sig = NULL; #ifndef HAVE_FIPS @@ -36634,7 +36644,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test(void) ret2 = wc_XmssKey_Verify(&verifyKey, sig, sigSz, (byte *) msg, msgSz); - if (ret2 != -1) { + if ((ret2 != -1) && (ret2 != SIG_VERIFY_E)) { /* Verify passed when it should have failed. */ return WC_TEST_RET_ENC_I(j); } @@ -36667,8 +36677,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test(void) } #endif /*if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_XMSS_VERIFY_ONLY)*/ -#if defined(WOLFSSL_HAVE_XMSS) && defined(WOLFSSL_XMSS_VERIFY_ONLY) && \ - !defined(WOLFSSL_SMALL_STACK) +#if defined(WOLFSSL_HAVE_XMSS) && !defined(WOLFSSL_SMALL_STACK) && \ + WOLFSSL_XMSS_MIN_HEIGHT <= 10 /* A simple xmss verify only test using: * XMSS-SHA2_10_256 @@ -37071,7 +37081,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void) xmss_msg[sizeof(xmss_msg) / 2] ^= 1; ret2 = wc_XmssKey_Verify(&verifyKey, xmss_sig, sizeof(xmss_sig), (byte *) xmss_msg, sizeof(xmss_msg)); - if (ret2 != -1) { + if ((ret2 != -1) && (ret2 != SIG_VERIFY_E)) { printf("error: wc_XmssKey_Verify returned %d, expected -1\n", ret2); return WC_TEST_RET_ENC_EC(ret); } @@ -37092,7 +37102,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void) ret2 = wc_XmssKey_Verify(&verifyKey, xmss_sig, sizeof(xmss_sig), (byte *) xmss_msg, sizeof(xmss_msg)); - if (ret2 != -1) { + if ((ret2 != -1) && (ret2 != SIG_VERIFY_E)) { /* Verify passed when it should have failed. */ return WC_TEST_RET_ENC_I(j); } @@ -37106,8 +37116,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void) return ret; } -#endif /* if defined(WOLFSSL_HAVE_XMSS) && defined(WOLFSSL_XMSS_VERIFY_ONLY) && - * !defined(WOLFSSL_SMALL_STACK) */ +#endif /* WOLFSSL_HAVE_XMSS && !WOLFSSL_SMALL_STACK && + * WOLFSSL_XMSS_MIN_HEIGHT <= 10 */ #if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index d29ac13b8..99afb9660 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -65,11 +65,17 @@ enum { MP_ZERO_E = -121, /* got a mp zero result, not expected */ AES_EAX_AUTH_E = -122, /* AES-EAX Authentication check failure */ + KEY_EXHAUSTED_E = -123, /* No longer usable for operation. */ + + /* -124 unused. */ MEMORY_E = -125, /* out of memory error */ VAR_STATE_CHANGE_E = -126, /* var state modified by different thread */ FIPS_DEGRADED_E = -127, /* FIPS Module in degraded mode */ + /* -128 unused. */ + /* -129 unused. */ + RSA_WRONG_TYPE_E = -130, /* RSA wrong block type for RSA function */ RSA_BUFFER_E = -131, /* RSA buffer error, output too small or input too large */ @@ -101,10 +107,13 @@ enum { ASN_SIG_HASH_E = -156, /* ASN sig error, unsupported hash type */ ASN_SIG_KEY_E = -157, /* ASN sig error, unsupported key type */ ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */ + /* -159 unused. */ ASN_CRIT_EXT_E = -160, /* ASN unsupported critical extension */ ASN_ALT_NAME_E = -161, /* ASN alternate name error */ ASN_NO_PEM_HEADER = -162, /* ASN no PEM header found */ + /* -163..-169 unused. */ + ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */ ASN_ECC_KEY_E = -171, /* ASN ECC bad input */ ECC_CURVE_OID_E = -172, /* Unsupported ECC OID curve type */ @@ -182,6 +191,8 @@ enum { SIG_TYPE_E = -231, /* Signature Type not enabled/available */ HASH_TYPE_E = -232, /* Hash Type not enabled/available */ + /* -233 unused. */ + WC_KEY_SIZE_E = -234, /* Key size error, either too small or large */ ASN_COUNTRY_SIZE_E = -235, /* ASN Cert Gen, invalid country code size */ MISSING_RNG_E = -236, /* RNG required but not provided */ diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 8901733fd..07d23e389 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -152,6 +152,8 @@ WOLFSSL_LOCAL byte w64GTE(w64wrapper a, w64wrapper b); WOLFSSL_LOCAL byte w64LT(w64wrapper a, w64wrapper b); WOLFSSL_LOCAL w64wrapper w64Sub(w64wrapper a, w64wrapper b); WOLFSSL_LOCAL void w64Zero(w64wrapper *a); +WOLFSSL_LOCAL w64wrapper w64ShiftRight(w64wrapper a, int shift); +WOLFSSL_LOCAL w64wrapper w64ShiftLeft(w64wrapper a, int shift); #else /* !NO_INLINE */ diff --git a/wolfssl/wolfcrypt/xmss.h b/wolfssl/wolfcrypt/xmss.h index 70f26c484..7f19aee2b 100644 --- a/wolfssl/wolfcrypt/xmss.h +++ b/wolfssl/wolfcrypt/xmss.h @@ -89,6 +89,53 @@ #define XMSSMT_NAME_MIN_LEN (20) /* strlen("XMSSMT-SHA2_20/2_256") */ #define XMSSMT_NAME_MAX_LEN (21) /* strlen("XMSSMT-SHA2_60/12_256") */ +#if defined(HAVE_FIPS) || defined(HAVE_LIBXMSS) + #undef WOLFSSL_WC_XMSS_NO_SHA512 + #define WOLFSSL_WC_XMSS_NO_SHA512 + #undef WOLFSSL_WC_XMSS_NO_SHAKE128 + #define WOLFSSL_WC_XMSS_NO_SHAKE128 + #undef WOLFSSL_WC_XMSS_MAX_HASH_SIZE + #ifdef HAVE_LIBXMSS + #define WOLFSSL_WC_XMSS_MIN_HASH_SIZE 256 + #else + #define WOLFSSL_WC_XMSS_MIN_HASH_SIZE 192 + #endif + #define WOLFSSL_WC_XMSS_MAX_HASH_SIZE 256 +#endif + +#if !defined(NO_SHA256) && !defined(WOLFSSL_WC_XMSS_NO_SHA256) + #define WC_XMSS_SHA256 +#endif +#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_WC_XMSS_NO_SHA512) + #define WC_XMSS_SHA512 +#endif +#if defined(WOLFSSL_SHAKE128) && !defined(WOLFSSL_WC_XMSS_NO_SHAKE128) + #define WC_XMSS_SHAKE128 +#endif +#if defined(WOLFSSL_SHAKE256) && !defined(WOLFSSL_WC_XMSS_NO_SHAKE256) + #define WC_XMSS_SHAKE256 +#endif + +#ifndef WOLFSSL_WC_XMSS_MIN_HASH_SIZE + #define WOLFSSL_WC_XMSS_MIN_HASH_SIZE 192 +#endif +#ifndef WOLFSSL_WC_XMSS_MAX_HASH_SIZE + #define WOLFSSL_WC_XMSS_MAX_HASH_SIZE 512 +#endif +#if WOLFSSL_WC_XMSS_MIN_HASH_SIZE > WOLFSSL_WC_XMSS_MAX_HASH_SIZE + #error "XMSS minimum hash size is greater than maximum hash size" +#endif + +#ifndef WOLFSSL_XMSS_MIN_HEIGHT + #define WOLFSSL_XMSS_MIN_HEIGHT 10 +#endif +#ifndef WOLFSSL_XMSS_MAX_HEIGHT + #define WOLFSSL_XMSS_MAX_HEIGHT 60 +#endif +#if WOLFSSL_XMSS_MIN_HEIGHT > WOLFSSL_XMSS_MAX_HEIGHT + #error "XMSS minimum height is greater than maximum height" +#endif + typedef struct XmssKey XmssKey; /* Return codes returned by private key callbacks. */ @@ -113,37 +160,41 @@ enum wc_XmssState { }; /* Private key write and read callbacks. */ -typedef enum wc_XmssRc (*write_private_key_cb)(const byte * priv, word32 privSz, void *context); -typedef enum wc_XmssRc (*read_private_key_cb)(byte * priv, word32 privSz, void *context); +typedef enum wc_XmssRc (*write_private_key_cb)(const byte* priv, word32 privSz, + void* context); +typedef enum wc_XmssRc (*read_private_key_cb)(byte* priv, word32 privSz, + void* context); #ifdef __cplusplus extern "C" { #endif -WOLFSSL_API int wc_XmssKey_Init(XmssKey * key, void * heap, int devId); -WOLFSSL_API int wc_XmssKey_SetParamStr(XmssKey * key, const char * str); + +WOLFSSL_API int wc_XmssKey_Init(XmssKey* key, void* heap, int devId); +WOLFSSL_API int wc_XmssKey_SetParamStr(XmssKey* key, const char* str); #ifndef WOLFSSL_XMSS_VERIFY_ONLY -WOLFSSL_API int wc_XmssKey_SetWriteCb(XmssKey * key, +WOLFSSL_API int wc_XmssKey_SetWriteCb(XmssKey* key, write_private_key_cb write_cb); -WOLFSSL_API int wc_XmssKey_SetReadCb(XmssKey * key, +WOLFSSL_API int wc_XmssKey_SetReadCb(XmssKey* key, read_private_key_cb read_cb); -WOLFSSL_API int wc_XmssKey_SetContext(XmssKey * key, void * context); -WOLFSSL_API int wc_XmssKey_MakeKey(XmssKey * key, WC_RNG * rng); -WOLFSSL_API int wc_XmssKey_Reload(XmssKey * key); -WOLFSSL_API int wc_XmssKey_GetPrivLen(const XmssKey * key, word32 * len); -WOLFSSL_API int wc_XmssKey_Sign(XmssKey * key, byte * sig, word32 * sigSz, - const byte * msg, int msgSz); -WOLFSSL_API int wc_XmssKey_SigsLeft(XmssKey * key); +WOLFSSL_API int wc_XmssKey_SetContext(XmssKey* key, void* context); +WOLFSSL_API int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG* rng); +WOLFSSL_API int wc_XmssKey_Reload(XmssKey* key); +WOLFSSL_API int wc_XmssKey_GetPrivLen(const XmssKey* key, word32* len); +WOLFSSL_API int wc_XmssKey_Sign(XmssKey* key, byte* sig, word32* sigSz, + const byte* msg, int msgSz); +WOLFSSL_API int wc_XmssKey_SigsLeft(XmssKey* key); #endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY */ -WOLFSSL_API void wc_XmssKey_Free(XmssKey * key); -WOLFSSL_API int wc_XmssKey_GetSigLen(const XmssKey * key, word32 * len); -WOLFSSL_API int wc_XmssKey_GetPubLen(const XmssKey * key, word32 * len); -WOLFSSL_API int wc_XmssKey_ExportPub(XmssKey * keyDst, const XmssKey * keySrc); -WOLFSSL_API int wc_XmssKey_ExportPubRaw(const XmssKey * key, byte * out, - word32 * outLen); -WOLFSSL_API int wc_XmssKey_ImportPubRaw(XmssKey * key, const byte * in, +WOLFSSL_API void wc_XmssKey_Free(XmssKey* key); +WOLFSSL_API int wc_XmssKey_GetSigLen(const XmssKey* key, word32* len); +WOLFSSL_API int wc_XmssKey_GetPubLen(const XmssKey* key, word32* len); +WOLFSSL_API int wc_XmssKey_ExportPub(XmssKey* keyDst, const XmssKey* keySrc); +WOLFSSL_API int wc_XmssKey_ExportPubRaw(const XmssKey* key, byte* out, + word32* outLen); +WOLFSSL_API int wc_XmssKey_ImportPubRaw(XmssKey* key, const byte* in, word32 inLen); -WOLFSSL_API int wc_XmssKey_Verify(XmssKey * key, const byte * sig, word32 sigSz, - const byte * msg, int msgSz); +WOLFSSL_API int wc_XmssKey_Verify(XmssKey* key, const byte* sig, word32 sigSz, + const byte* msg, int msgSz); + #ifdef __cplusplus } /* extern "C" */ #endif