Merge pull request #7161 from SparkiDev/xmss

XMSS implementation
pull/7173/head
JacobBarthelmeh 2024-01-25 08:41:13 -08:00 committed by GitHub
commit 4c7f038149
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 597 additions and 86 deletions

View File

@ -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;;

View File

@ -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

View File

@ -178,6 +178,8 @@
#include <wolfssl/wolfcrypt/xmss.h>
#ifdef HAVE_LIBXMSS
#include <wolfssl/wolfcrypt/ext_xmss.h>
#else
#include <wolfssl/wolfcrypt/wc_xmss.h>
#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) */

View File

@ -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);

View File

@ -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";

View File

@ -39,6 +39,7 @@
#endif
#include <xmss_callbacks.h>
#include <utils.h>
#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

View File

@ -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 */

View File

@ -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 */

View File

@ -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)

View File

@ -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 <wolfssl/wolfcrypt/settings.h>
#ifdef WOLFSSL_HAVE_XMSS
#error "Contact wolfSSL to get the implementation of this file"
#endif

View File

@ -316,6 +316,8 @@ const byte const_byte_array[] = "A+Gd\0\0\0";
#include <wolfssl/wolfcrypt/xmss.h>
#ifdef HAVE_LIBXMSS
#include <wolfssl/wolfcrypt/ext_xmss.h>
#else
#include <wolfssl/wolfcrypt/wc_xmss.h>
#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)

View File

@ -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 */

View File

@ -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 */

View File

@ -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