diff --git a/INSTALL b/INSTALL index f98e7ad02..3d82d507c 100644 --- a/INSTALL +++ b/INSTALL @@ -401,10 +401,16 @@ We also have vcpkg ports for wolftpm, wolfmqtt and curl. The patch may be found in the wolfssl-examples repo here: pq/stateful_hash_sig/0001-Patch-to-support-xmss-reference-integration.patch + To build patched xmss-reference: + $ make xmss_lib.a + + To build verify-only patched xmss-reference: + $ make xmss_verify_lib.a + Note that this patch adds wolfCrypt SHA256 hashing to xmss-reference, and thus benefits from all the same asm speedups as wolfCrypt SHA hashing. Depending on architecture you may build with --enable-intelasm, or - and --enable-armasm, and see 30-50% speedups in XMSS/XMSS^MT. + and --enable-armasm, and see 30-40% speedups in XMSS/XMSS^MT. For full keygen, signing, verifying, and benchmarking support, build wolfSSL with: diff --git a/configure.ac b/configure.ac index 64222a44e..9427691d5 100644 --- a/configure.ac +++ b/configure.ac @@ -1201,10 +1201,32 @@ AC_ARG_WITH([libxmss], AC_MSG_ERROR([libxmss isn't found. If it's already installed, specify its path using --with-libxmss=/dir/]) fi + if test "$XMSS_VERIFY_ONLY" = "yes"; then + if test -e $trylibxmssdir/xmss_verify_lib.a; then + CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBXMSS -I$trylibxmssdir" + LIB_STATIC_ADD="$LIB_STATIC_ADD $trylibxmssdir/xmss_verify_lib.a" + enable_shared=no + enable_static=yes + libxmss_linked=yes + else + AC_MSG_ERROR([xmss_verify_lib.a isn't found. + If it's already installed, specify its path using --with-libxmss=/dir/]) + fi + elif test -e $trylibxmssdir/xmss_lib.a; then + CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBXMSS -I$trylibxmssdir" + LIB_STATIC_ADD="$LIB_STATIC_ADD $trylibxmssdir/xmss_lib.a" + enable_shared=no + enable_static=yes + libxmss_linked=yes + else + AC_MSG_ERROR([libxmss isn't found. + If it's already installed, specify its path using --with-libxmss=/dir/]) + fi XMSS_ROOT=$trylibxmssdir AC_MSG_RESULT([yes]) + AM_CPPFLAGS="$CPPFLAGS" AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBXMSS -I$trylibxmssdir" ENABLED_LIBXMSS="yes" @@ -1213,7 +1235,6 @@ AC_ARG_WITH([libxmss], [XMSS_ROOT=""] ) - # LMS AC_ARG_ENABLE([lms], [AS_HELP_STRING([--enable-lms],[Enable stateful LMS/HSS signatures (default: disabled)])], @@ -9032,6 +9053,7 @@ AM_CONDITIONAL([BUILD_GE448], [test "x$ENABLED_GE448" = "xyes" || test "x$ENABLE AM_CONDITIONAL([BUILD_CURVE448],[test "x$ENABLED_CURVE448" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CURVE448_SMALL],[test "x$ENABLED_CURVE448_SMALL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_WC_LMS],[test "x$ENABLED_WC_LMS" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_WC_XMSS],[test "x$ENABLED_WC_XMSS" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_WC_KYBER],[test "x$ENABLED_WC_KYBER" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_ECCSI],[test "x$ENABLED_ECCSI" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SAKKE],[test "x$ENABLED_SAKKE" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) diff --git a/src/include.am b/src/include.am index 93713f196..9d766df30 100644 --- a/src/include.am +++ b/src/include.am @@ -702,6 +702,10 @@ if BUILD_WC_LMS src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_lms.c endif +if BUILD_WC_XMSS +src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/wc_xmss.c +endif + if BUILD_CURVE25519 src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/curve25519.c endif @@ -809,14 +813,6 @@ endif if BUILD_LIBXMSS src_libwolfssl@LIBSUFFIX@_la_SOURCES += wolfcrypt/src/ext_xmss.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/params.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/thash.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/hash_address.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/wots.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/xmss.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/xmss_core_fast.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/xmss_commons.c -src_libwolfssl@LIBSUFFIX@_la_SOURCES += $(XMSS_ROOT)/utils.c endif if BUILD_LIBZ diff --git a/wolfcrypt/src/ext_xmss.c b/wolfcrypt/src/ext_xmss.c index b12ae4440..bbf4f74d1 100644 --- a/wolfcrypt/src/ext_xmss.c +++ b/wolfcrypt/src/ext_xmss.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef WOLFSSL_HAVE_XMSS #include @@ -37,6 +38,63 @@ #include #endif +#include + +#ifndef WOLFSSL_XMSS_VERIFY_ONLY +static THREAD_LS_T WC_RNG * xmssRng = NULL; + +/* RNG callback used by xmss. + * */ +static int rng_cb(void * output, size_t length) +{ + int ret = 0; + + if (output == NULL || xmssRng == NULL) { + return -1; + } + + if (length == 0) { + return 0; + } + + ret = wc_RNG_GenerateBlock(xmssRng, output, (word32) length); + + if (ret) { + WOLFSSL_MSG("error: xmss rng_cb failed"); + return -1; + } + + return 0; +} +#endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY */ + +/* SHA256 callback used by xmss. + * */ +static int sha256_cb(const unsigned char *in, unsigned long long inlen, + unsigned char *out) +{ + wc_Sha256 sha; + + if (wc_InitSha256_ex(&sha, NULL, INVALID_DEVID) != 0) { + WOLFSSL_MSG("SHA256 Init failed"); + return -1; + } + + if (wc_Sha256Update(&sha, in, (word32) inlen) != 0) { + WOLFSSL_MSG("SHA256 Update failed"); + return -1; + } + + if (wc_Sha256Final(&sha, out) != 0) { + WOLFSSL_MSG("SHA256 Final failed"); + wc_Sha256Free(&sha); + return -1; + } + wc_Sha256Free(&sha); + + return 0; +} + /* Init an Xmss key. * * Call this before setting the parms of an Xmss key. @@ -119,6 +177,20 @@ static int wc_XmssKey_SetOid(XmssKey * key, uint32_t oid, int is_xmssmt) return -1; } + ret = xmss_set_sha_cb(sha256_cb); + if (ret != 0) { + WOLFSSL_MSG("error: xmss_set_sha_cb failed"); + return -1; + } + +#ifndef WOLFSSL_XMSS_VERIFY_ONLY + ret = xmss_set_rng_cb(rng_cb); + if (ret != 0) { + WOLFSSL_MSG("error: xmss_set_rng_cb failed"); + return -1; + } +#endif + key->oid = oid; key->is_xmssmt = is_xmssmt; key->state = WC_XMSS_STATE_PARMSET; @@ -401,13 +473,15 @@ int wc_XmssKey_MakeKey(XmssKey* key, WC_RNG * rng) return ret; } + xmssRng = rng; + /* Finally make the secret public key pair. Immediately write it to NV * storage and then clear from memory. */ if (key->is_xmssmt) { - ret = xmssmt_keypair(key->pk, key->sk, key->oid, rng); + ret = xmssmt_keypair(key->pk, key->sk, key->oid); } else { - ret = xmss_keypair(key->pk, key->sk, key->oid, rng); + ret = xmss_keypair(key->pk, key->sk, key->oid); } if (ret == 0) { diff --git a/wolfssl/wolfcrypt/xmss.h b/wolfssl/wolfcrypt/xmss.h index 386e27eae..72da8b15d 100644 --- a/wolfssl/wolfcrypt/xmss.h +++ b/wolfssl/wolfcrypt/xmss.h @@ -144,7 +144,6 @@ 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 const char * wc_XmssKey_RcToStr(enum wc_XmssRc lmsRc); #ifdef __cplusplus } /* extern "C" */ #endif