forked from wolfSSL/wolfssl
Merge pull request #6738 from philljj/wolfcrypt_lms_verify_only
Wolfcrypt LMS verify-only support
This commit is contained in:
23
INSTALL
23
INSTALL
@ -264,20 +264,20 @@ We also have vcpkg ports for wolftpm, wolfmqtt and curl.
|
||||
branch of the hash-sigs project.
|
||||
|
||||
Currently the hash-sigs project only builds static libraries:
|
||||
- hss_verify.a: a single-threaded verify-only static lib.
|
||||
- hss_lib.a: a single-threaded static lib.
|
||||
- hss_lib_thread.a: a multi-threaded static lib.
|
||||
|
||||
The multi-threaded version will mainly have speedups for key
|
||||
generation and signing.
|
||||
|
||||
Additionally, the hash-sigs project can be modified to build
|
||||
and install a shared library in /usr/local with either single
|
||||
or multi-threaded versions. If the shared version has been
|
||||
built, libhss.so is the assumed name.
|
||||
The default LMS build (--enable-lms) will look for
|
||||
hss_lib.a first, and hss_lib_thread.a second, in a specified
|
||||
hash-sigs dir.
|
||||
|
||||
wolfSSL supports either option, and by default will look for
|
||||
hss_lib.a first, and hss_lib_thread.a second, and libhss.so
|
||||
lastly, in a specified hash-sigs dir.
|
||||
The LMS verify-only build (--enable-lms=verify-only) will look
|
||||
for hss_verify.a only, which is a slimmer library that includes
|
||||
only the minimal functions necessary for signature verification.
|
||||
|
||||
How to get and build the hash-sigs library:
|
||||
$ mkdir ~/hash_sigs
|
||||
@ -299,12 +299,17 @@ We also have vcpkg ports for wolftpm, wolfmqtt and curl.
|
||||
$ ls *.a
|
||||
hss_lib_thread.a
|
||||
|
||||
To build verify-only:
|
||||
$ make hss_verify.a
|
||||
$ ls *.a
|
||||
hss_verify.a
|
||||
|
||||
Build wolfSSL with
|
||||
$ ./configure \
|
||||
--enable-static \
|
||||
--disable-shared \
|
||||
--enable-lms=yes \
|
||||
--with-liblms=<path to dir containing hss_lib_thread.a>
|
||||
--enable-lms \
|
||||
--with-liblms=<path to dir containing hss_lib.a or hss_lib_thread.a>
|
||||
$ make
|
||||
|
||||
Run the benchmark against LMS/HSS with:
|
||||
|
133
configure.ac
133
configure.ac
@ -1141,69 +1141,6 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# liblms
|
||||
# Get the path to the hash-sigs LMS HSS lib.
|
||||
ENABLED_LIBLMS="no"
|
||||
tryliblmsdir=""
|
||||
AC_ARG_WITH([liblms],
|
||||
[AS_HELP_STRING([--with-liblms=PATH],[PATH to hash-sigs LMS/HSS install (default /usr/local) EXPERIMENTAL!])],
|
||||
[
|
||||
AC_MSG_CHECKING([for liblms])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <hss.h>]], [[ param_set_t lm_type; param_set_t lm_ots_type; hss_get_public_key_len(4, &lm_type, &lm_ots_type); ]])], [ liblms_linked=yes ],[ liblms_linked=no ])
|
||||
|
||||
if test "x$liblms_linked" = "xno" ; then
|
||||
if test "x$withval" != "xno" ; then
|
||||
tryliblmsdir=$withval
|
||||
fi
|
||||
if test "x$withval" = "xyes" ; then
|
||||
tryliblmsdir="/usr/local"
|
||||
fi
|
||||
|
||||
# 1. By default use the hash-sigs single-threaded static library.
|
||||
# 2. If 1 not found, then use the multi-threaded static lib.
|
||||
# 3. If 2 not found, then use the multi-threaded dynamic lib.
|
||||
if test -e $tryliblmsdir/hss_lib.a; then
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir"
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD $tryliblmsdir/hss_lib.a"
|
||||
enable_shared=no
|
||||
enable_static=yes
|
||||
liblms_linked=yes
|
||||
elif test -e $tryliblmsdir/hss_lib_thread.a; then
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir"
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD $tryliblmsdir/hss_lib_thread.a"
|
||||
enable_shared=no
|
||||
enable_static=yes
|
||||
liblms_linked=yes
|
||||
elif test -e $tryliblmsdir/lib/libhss.so; then
|
||||
LIBS="$LIBS -lhss"
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir/include/hss"
|
||||
LDFLAGS="$AM_LDFLAGS $LDFLAGS -L$tryliblmsdir/lib"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <hss.h>]], [[ param_set_t lm_type; param_set_t lm_ots_type; hss_get_public_key_len(4, &lm_type, &lm_ots_type); ]])], [ liblms_linked=yes ],[ liblms_linked=no ])
|
||||
else
|
||||
AC_MSG_ERROR([liblms isn't found.
|
||||
If it's already installed, specify its path using --with-liblms=/dir/])
|
||||
fi
|
||||
|
||||
if test "x$liblms_linked" = "xno" ; then
|
||||
AC_MSG_ERROR([liblms isn't found.
|
||||
If it's already installed, specify its path using --with-liblms=/dir/])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([yes])
|
||||
AM_CPPFLAGS="$CPPFLAGS"
|
||||
AM_LDFLAGS="$LDFLAGS"
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBLMS"
|
||||
ENABLED_LIBLMS="yes"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# LMS
|
||||
AC_ARG_ENABLE([lms],
|
||||
[AS_HELP_STRING([--enable-lms],[Enable stateful LMS/HSS signatures (default: disabled)])],
|
||||
@ -1219,6 +1156,10 @@ do
|
||||
;;
|
||||
no)
|
||||
;;
|
||||
verify-only)
|
||||
LMS_VERIFY_ONLY=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_LMS_VERIFY_ONLY"
|
||||
;;
|
||||
wolfssl)
|
||||
ENABLED_WC_LMS=yes
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_WC_LMS"
|
||||
@ -1243,6 +1184,72 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
# liblms
|
||||
# Get the path to the hash-sigs LMS HSS lib.
|
||||
ENABLED_LIBLMS="no"
|
||||
tryliblmsdir=""
|
||||
AC_ARG_WITH([liblms],
|
||||
[AS_HELP_STRING([--with-liblms=PATH],[PATH to hash-sigs LMS/HSS install (default /usr/local) EXPERIMENTAL!])],
|
||||
[
|
||||
AC_MSG_CHECKING([for liblms])
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <hss.h>]], [[ param_set_t lm_type; param_set_t lm_ots_type; hss_get_public_key_len(4, &lm_type, &lm_ots_type); ]])], [ liblms_linked=yes ],[ liblms_linked=no ])
|
||||
|
||||
if test "x$liblms_linked" = "xno" ; then
|
||||
if test "x$withval" != "xno" ; then
|
||||
tryliblmsdir=$withval
|
||||
fi
|
||||
if test "x$withval" = "xyes" ; then
|
||||
tryliblmsdir="/usr/local"
|
||||
fi
|
||||
|
||||
# 1. If verify only build, use hss_verify.a
|
||||
# 2. If normal build, by default use single-threaded hss_lib.a
|
||||
# 3. If 2 not found, then use the multi-threaded hss_lib_thread.a
|
||||
if test "$LMS_VERIFY_ONLY" = "yes"; then
|
||||
if test -e $tryliblmsdir/hss_verify.a; then
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir"
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD $tryliblmsdir/hss_verify.a"
|
||||
enable_shared=no
|
||||
enable_static=yes
|
||||
liblms_linked=yes
|
||||
else
|
||||
AC_MSG_ERROR([hss_verify.a isn't found.
|
||||
If it's already installed, specify its path using --with-liblms=/dir/])
|
||||
fi
|
||||
elif test -e $tryliblmsdir/hss_lib.a; then
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir"
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD $tryliblmsdir/hss_lib.a"
|
||||
enable_shared=no
|
||||
enable_static=yes
|
||||
liblms_linked=yes
|
||||
elif test -e $tryliblmsdir/hss_lib_thread.a; then
|
||||
CPPFLAGS="$AM_CPPFLAGS -DHAVE_LIBLMS -I$tryliblmsdir"
|
||||
LIB_STATIC_ADD="$LIB_STATIC_ADD $tryliblmsdir/hss_lib_thread.a"
|
||||
enable_shared=no
|
||||
enable_static=yes
|
||||
liblms_linked=yes
|
||||
else
|
||||
AC_MSG_ERROR([liblms isn't found.
|
||||
If it's already installed, specify its path using --with-liblms=/dir/])
|
||||
fi
|
||||
|
||||
if test "x$liblms_linked" = "xno" ; then
|
||||
AC_MSG_ERROR([liblms isn't found.
|
||||
If it's already installed, specify its path using --with-liblms=/dir/])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([yes])
|
||||
AM_CPPFLAGS="$CPPFLAGS"
|
||||
AM_LDFLAGS="$LDFLAGS"
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_LIBLMS"
|
||||
ENABLED_LIBLMS="yes"
|
||||
]
|
||||
)
|
||||
|
||||
# SINGLE THREADED
|
||||
AC_ARG_ENABLE([singlethreaded],
|
||||
|
@ -157,7 +157,7 @@
|
||||
#include <wolfssl/wolfcrypt/ext_kyber.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
#include <wolfssl/wolfcrypt/lms.h>
|
||||
#ifdef HAVE_LIBLMS
|
||||
#include <wolfssl/wolfcrypt/ext_lms.h>
|
||||
@ -870,7 +870,7 @@ static const bench_alg bench_other_opt[] = {
|
||||
|
||||
#endif /* !WOLFSSL_BENCHMARK_ALL && !NO_MAIN_DRIVER */
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
typedef struct bench_pq_hash_sig_alg {
|
||||
/* Command line option string. */
|
||||
const char* str;
|
||||
@ -883,7 +883,7 @@ static const bench_pq_hash_sig_alg bench_pq_hash_sig_opt[] = {
|
||||
{ "-lms_hss", BENCH_LMS_HSS},
|
||||
{ NULL, 0}
|
||||
};
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
|
||||
|
||||
#if defined(HAVE_PQC) && defined(HAVE_LIBOQS)
|
||||
/* The post-quantum-specific mapping of command line option to bit values and
|
||||
@ -2832,11 +2832,11 @@ static void* benchmarks_do(void* args)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
if (bench_all || (bench_pq_hash_sig_algs & BENCH_LMS_HSS)) {
|
||||
bench_lms();
|
||||
}
|
||||
#endif
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if (bench_all || (bench_asym_algs & BENCH_ECC_MAKEKEY) ||
|
||||
@ -7664,7 +7664,7 @@ void bench_kyber(int type)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
/* WC_LMS_PARM_L2_H10_W2
|
||||
* signature length: 9300 */
|
||||
static const byte lms_priv_L2_H10_W2[64] =
|
||||
@ -8031,7 +8031,7 @@ void bench_lms(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* ifdef WOLFSSL_HAVE_LMS */
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
|
||||
@ -10368,10 +10368,10 @@ static void Usage(void)
|
||||
print_alg(bench_pq_asym_opt2[i].str, &line);
|
||||
#endif /* HAVE_LIBOQS && HAVE_SPHINCS */
|
||||
#endif /* HAVE_PQC */
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
for (i=0; bench_pq_hash_sig_opt[i].str != NULL; i++)
|
||||
print_alg(bench_pq_hash_sig_opt[i].str, &line);
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
|
||||
printf("\n");
|
||||
#endif /* !WOLFSSL_BENCHMARK_ALL */
|
||||
e++;
|
||||
@ -10634,7 +10634,7 @@ int wolfcrypt_benchmark_main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
/* post-quantum stateful hash-based signatures */
|
||||
for (i=0; !optMatched && bench_pq_hash_sig_opt[i].str != NULL; i++) {
|
||||
if (string_matches(argv[1], bench_pq_hash_sig_opt[i].str)) {
|
||||
@ -10643,7 +10643,7 @@ int wolfcrypt_benchmark_main(int argc, char** argv)
|
||||
optMatched = 1;
|
||||
}
|
||||
}
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
||||
#endif
|
||||
#endif
|
||||
if (!optMatched) {
|
||||
printf("Option not recognized: %s\n", argv[1]);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
/* If built against hss_lib_thread.a, the hash-sigs lib will spawn
|
||||
* worker threads to parallelize cpu intensive tasks. This will mainly
|
||||
* speedup key generation and signing, and to a lesser extent
|
||||
@ -101,7 +102,8 @@ static bool LmsWritePrivKey(unsigned char *private_key,
|
||||
}
|
||||
|
||||
/* Use write callback that saves private key to non-volatile storage. */
|
||||
ret = key->write_private_key(private_key, len_private_key, key->context);
|
||||
ret = key->write_private_key(private_key, (word32)len_private_key,
|
||||
key->context);
|
||||
|
||||
if (ret != WC_LMS_RC_SAVED_TO_NV_MEMORY) {
|
||||
WOLFSSL_MSG("error: LmsKey write_private_key failed");
|
||||
@ -140,7 +142,8 @@ static bool LmsReadPrivKey(unsigned char *private_key,
|
||||
}
|
||||
|
||||
/* Use read callback that reads private key from non-volatile storage. */
|
||||
ret = key->read_private_key(private_key, len_private_key, key->context);
|
||||
ret = key->read_private_key(private_key, (word32)len_private_key,
|
||||
key->context);
|
||||
|
||||
if (ret != WC_LMS_RC_READ_TO_MEMORY) {
|
||||
WOLFSSL_MSG("error: LmsKey read_private_key failed");
|
||||
@ -151,6 +154,7 @@ static bool LmsReadPrivKey(unsigned char *private_key,
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
|
||||
const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm)
|
||||
{
|
||||
@ -242,14 +246,16 @@ int wc_LmsKey_Init(LmsKey * key, void * heap, int devId)
|
||||
|
||||
ForceZero(key, sizeof(LmsKey));
|
||||
|
||||
/* Set the max number of worker threads that hash-sigs can spawn. */
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
hss_init_extra_info(&key->info);
|
||||
/* Set the max number of worker threads that hash-sigs can spawn. */
|
||||
hss_extra_info_set_threads(&key->info, EXT_LMS_MAX_THREADS);
|
||||
|
||||
key->working_key = NULL;
|
||||
key->write_private_key = NULL;
|
||||
key->read_private_key = NULL;
|
||||
key->context = NULL;
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
key->state = WC_LMS_STATE_INITED;
|
||||
|
||||
return 0;
|
||||
@ -405,6 +411,70 @@ int wc_LmsKey_SetParameters(LmsKey * key, int levels, int height,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Get the parameters of an LMS key.
|
||||
*
|
||||
* Key must be inited and parameters set before calling this.
|
||||
*
|
||||
* Returns 0 on success.
|
||||
* */
|
||||
int wc_LmsKey_GetParameters(const LmsKey * key, int * levels, int * height,
|
||||
int * winternitz)
|
||||
{
|
||||
if (key == NULL || levels == NULL || height == NULL || winternitz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* This shouldn't happen, but check the LmsKey parameters aren't invalid. */
|
||||
|
||||
if (key->levels < MIN_HSS_LEVELS || key->levels > MAX_HSS_LEVELS) {
|
||||
WOLFSSL_MSG("error: LmsKey invalid level parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*levels = key->levels;
|
||||
|
||||
switch (key->lm_type[0]) {
|
||||
case LMS_SHA256_N32_H5:
|
||||
*height = 5;
|
||||
break;
|
||||
case LMS_SHA256_N32_H10:
|
||||
*height = 10;
|
||||
break;
|
||||
case LMS_SHA256_N32_H15:
|
||||
*height = 15;
|
||||
break;
|
||||
case LMS_SHA256_N32_H20:
|
||||
*height = 20;
|
||||
break;
|
||||
case LMS_SHA256_N32_H25:
|
||||
*height = 25;
|
||||
break;
|
||||
default:
|
||||
WOLFSSL_MSG("error: LmsKey invalid height parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (key->lm_ots_type[0]) {
|
||||
case LMOTS_SHA256_N32_W1:
|
||||
*winternitz = 1;
|
||||
break;
|
||||
case LMOTS_SHA256_N32_W2:
|
||||
*winternitz = 2;
|
||||
break;
|
||||
case LMOTS_SHA256_N32_W4:
|
||||
*winternitz = 4;
|
||||
break;
|
||||
case LMOTS_SHA256_N32_W8:
|
||||
*winternitz = 8;
|
||||
break;
|
||||
default:
|
||||
WOLFSSL_MSG("error: LmsKey invalid winternitz parameter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Frees the LMS key from memory.
|
||||
*
|
||||
* This does not affect the private key saved to non-volatile storage.
|
||||
@ -415,10 +485,12 @@ void wc_LmsKey_Free(LmsKey* key)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
if (key->working_key != NULL) {
|
||||
hss_free_working_key(key->working_key);
|
||||
key->working_key = NULL;
|
||||
}
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
|
||||
ForceZero(key, sizeof(LmsKey));
|
||||
|
||||
@ -427,6 +499,7 @@ void wc_LmsKey_Free(LmsKey* key)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
/* Set the write private key callback to the LMS key structure.
|
||||
*
|
||||
* The callback must be able to write/update the private key to
|
||||
@ -647,7 +720,7 @@ int wc_LmsKey_Reload(LmsKey * key)
|
||||
|
||||
/* Given a levels, height, winternitz parameter set, determine
|
||||
* the private key length */
|
||||
int wc_LmsKey_GetPrivLen(LmsKey * key, word32 * len)
|
||||
int wc_LmsKey_GetPrivLen(const LmsKey * key, word32 * len)
|
||||
{
|
||||
if (key == NULL || len == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
@ -659,65 +732,6 @@ int wc_LmsKey_GetPrivLen(LmsKey * key, word32 * len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a levels, height, winternitz parameter set, determine
|
||||
* the public key length */
|
||||
int wc_LmsKey_GetPubLen(LmsKey * key, word32 * len)
|
||||
{
|
||||
if (key == NULL || len == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
*len = (word32) hss_get_public_key_len(key->levels, key->lm_type,
|
||||
key->lm_ots_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Export a generated public key and parameter set from one LmsKey
|
||||
* to another. Use this to prepare a signature verification LmsKey
|
||||
* that is pub only.
|
||||
*
|
||||
* Though the public key is all that is used to verify signatures,
|
||||
* the parameter set is needed to calculate the signature length
|
||||
* before hand. */
|
||||
int wc_LmsKey_ExportPub(LmsKey * keyDst, const LmsKey * keySrc)
|
||||
{
|
||||
if (keyDst == NULL || keySrc == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ForceZero(keyDst, sizeof(LmsKey));
|
||||
|
||||
XMEMCPY(keyDst->pub, keySrc->pub, sizeof(keySrc->pub));
|
||||
XMEMCPY(keyDst->lm_type, keySrc->lm_type, sizeof(keySrc->lm_type));
|
||||
XMEMCPY(keyDst->lm_ots_type, keySrc->lm_ots_type,
|
||||
sizeof(keySrc->lm_ots_type));
|
||||
|
||||
keyDst->levels = keySrc->levels;
|
||||
|
||||
/* Mark this key as verify only, to prevent misuse. */
|
||||
keyDst->state = WC_LMS_STATE_VERIFYONLY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a levels, height, winternitz parameter set, determine
|
||||
* the signature length.
|
||||
*
|
||||
* Call this before wc_LmsKey_Sign so you know the length of
|
||||
* the required signature buffer. */
|
||||
int wc_LmsKey_GetSigLen(LmsKey * key, word32 * len)
|
||||
{
|
||||
if (key == NULL || len == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
*len = (word32) hss_get_signature_len(key->levels, key->lm_type,
|
||||
key->lm_ots_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_LmsKey_Sign(LmsKey* key, byte * sig, word32 * sigSz, const byte * msg,
|
||||
int msgSz)
|
||||
{
|
||||
@ -773,27 +787,6 @@ int wc_LmsKey_Sign(LmsKey* key, byte * sig, word32 * sigSz, const byte * msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
|
||||
const byte * msg, int msgSz)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (key == NULL || sig == NULL || msg == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
result = hss_validate_signature(key->pub, (const void *) msg, msgSz, sig,
|
||||
sigSz, &key->info);
|
||||
|
||||
if (!result) {
|
||||
WOLFSSL_MSG("error: hss_validate_signature failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Returns 1 if there are signatures remaining.
|
||||
* Returns 0 if available signatures are exhausted.
|
||||
*
|
||||
@ -815,4 +808,165 @@ int wc_LmsKey_SigsLeft(LmsKey * key)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY*/
|
||||
|
||||
/* Given a levels, height, winternitz parameter set, determine
|
||||
* the public key length */
|
||||
int wc_LmsKey_GetPubLen(const LmsKey * key, word32 * len)
|
||||
{
|
||||
if (key == NULL || len == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
*len = (word32) hss_get_public_key_len(key->levels, key->lm_type,
|
||||
key->lm_ots_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Export a generated public key and parameter set from one LmsKey
|
||||
* to another. Use this to prepare a signature verification LmsKey
|
||||
* that is pub only.
|
||||
*
|
||||
* Though the public key is all that is used to verify signatures,
|
||||
* the parameter set is needed to calculate the signature length
|
||||
* before hand. */
|
||||
int wc_LmsKey_ExportPub(LmsKey * keyDst, const LmsKey * keySrc)
|
||||
{
|
||||
if (keyDst == NULL || keySrc == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ForceZero(keyDst, sizeof(LmsKey));
|
||||
|
||||
XMEMCPY(keyDst->pub, keySrc->pub, sizeof(keySrc->pub));
|
||||
XMEMCPY(keyDst->lm_type, keySrc->lm_type, sizeof(keySrc->lm_type));
|
||||
XMEMCPY(keyDst->lm_ots_type, keySrc->lm_ots_type,
|
||||
sizeof(keySrc->lm_ots_type));
|
||||
|
||||
keyDst->levels = keySrc->levels;
|
||||
|
||||
/* Mark this key as verify only, to prevent misuse. */
|
||||
keyDst->state = WC_LMS_STATE_VERIFYONLY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Exports the raw LMS public key buffer from key to out buffer.
|
||||
* The out buffer should be large enough to hold the public key, and
|
||||
* outLen should indicate the size of the buffer.
|
||||
*
|
||||
* - Returns 0 on success, and sets outLen to LMS pubLen.
|
||||
* - Returns BUFFER_E if outLen < LMS pubLen.
|
||||
*
|
||||
* Call wc_LmsKey_GetPubLen beforehand to determine pubLen.
|
||||
* */
|
||||
int wc_LmsKey_ExportPubRaw(const LmsKey * key, byte * out, word32 * outLen)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 pubLen = 0;
|
||||
|
||||
if (key == NULL || out == NULL || outLen == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = wc_LmsKey_GetPubLen(key, &pubLen);
|
||||
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("error: wc_LmsKey_GetPubLen failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*outLen < pubLen) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(out, key->pub, pubLen);
|
||||
*outLen = pubLen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Imports a raw public key buffer from in array to LmsKey key.
|
||||
*
|
||||
* The LMS parameters must be set first with wc_LmsKey_SetLmsParm or
|
||||
* wc_LmsKey_SetParameters, and inLen must match the length returned
|
||||
* by wc_LmsKey_GetPubLen.
|
||||
*
|
||||
* - Returns 0 on success.
|
||||
* - Returns BUFFER_E if inlen != LMS pubLen.
|
||||
*
|
||||
* Call wc_LmsKey_GetPubLen beforehand to determine pubLen.
|
||||
* */
|
||||
int wc_LmsKey_ImportPubRaw(LmsKey * key, const byte * in, word32 inLen)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 pubLen = 0;
|
||||
|
||||
if (key == NULL || in == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = wc_LmsKey_GetPubLen(key, &pubLen);
|
||||
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("error: wc_LmsKey_GetPubLen failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (inLen != pubLen) {
|
||||
/* Something inconsistent. Parameters weren't set, or input
|
||||
* pub key is wrong.*/
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
XMEMCPY(key->pub, in, pubLen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a levels, height, winternitz parameter set, determine
|
||||
* the signature length.
|
||||
*
|
||||
* Call this before wc_LmsKey_Sign so you know the length of
|
||||
* the required signature buffer. */
|
||||
int wc_LmsKey_GetSigLen(const LmsKey * key, word32 * len)
|
||||
{
|
||||
if (key == NULL || len == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
*len = (word32) hss_get_signature_len(key->levels, key->lm_type,
|
||||
key->lm_ots_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
|
||||
const byte * msg, int msgSz)
|
||||
{
|
||||
bool result = true;
|
||||
|
||||
if (key == NULL || sig == NULL || msg == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_LMS_VERIFY_ONLY
|
||||
result = hss_validate_signature(key->pub, (const void *) msg, msgSz, sig,
|
||||
sigSz, NULL);
|
||||
#else
|
||||
result = hss_validate_signature(key->pub, (const void *) msg, msgSz, sig,
|
||||
sigSz, &key->info);
|
||||
#endif
|
||||
|
||||
|
||||
if (!result) {
|
||||
WOLFSSL_MSG("error: hss_validate_signature failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_HAVE_LMS */
|
||||
|
@ -293,7 +293,7 @@ const byte const_byte_array[] = "A+Gd\0\0\0";
|
||||
#include <wolfssl/wolfcrypt/ext_kyber.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#include <wolfssl/wolfcrypt/lms.h>
|
||||
#ifdef HAVE_LIBLMS
|
||||
#include <wolfssl/wolfcrypt/ext_lms.h>
|
||||
@ -574,8 +574,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
|
||||
#ifdef WOLFSSL_HAVE_KYBER
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t kyber_test(void);
|
||||
#endif
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
WOLFSSL_TEST_SUBROUTINE int lms_test(void);
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#if !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void);
|
||||
#endif
|
||||
#if defined(WOLFSSL_LMS_VERIFY_ONLY) && !defined(WOLFSSL_SMALL_STACK)
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef WOLFCRYPT_HAVE_ECCSI
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t eccsi_test(void);
|
||||
@ -1606,12 +1611,21 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
|
||||
TEST_PASS("KYBER test passed!\n");
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS)
|
||||
#if !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
if ( (ret = lms_test()) != 0)
|
||||
TEST_FAIL("LMS test failed!\n", ret);
|
||||
else
|
||||
TEST_PASS("LMS test passed!\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_LMS_VERIFY_ONLY) && !defined(WOLFSSL_SMALL_STACK)
|
||||
if ( (ret = lms_test_verify_only()) != 0)
|
||||
TEST_FAIL("LMS test failed!\n", ret);
|
||||
else
|
||||
TEST_PASS("LMS test passed!\n");
|
||||
#endif
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) */
|
||||
|
||||
#ifdef WOLFCRYPT_HAVE_ECCSI
|
||||
if ( (ret = eccsi_test()) != 0)
|
||||
@ -34957,7 +34971,7 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t kyber_test(void)
|
||||
#endif /* WOLFSSL_HAVE_KYBER */
|
||||
|
||||
|
||||
#ifdef WOLFSSL_HAVE_LMS
|
||||
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY)
|
||||
static int lms_write_key_mem(const byte * priv, word32 privSz, void *context)
|
||||
{
|
||||
/* WARNING: THIS IS AN INSECURE WRITE CALLBACK THAT SHOULD ONLY
|
||||
@ -34979,7 +34993,7 @@ static int lms_read_key_mem(byte * priv, word32 privSz, void *context)
|
||||
* test has a signature of 8688 bytes. */
|
||||
#define WC_TEST_LMS_SIG_LEN (8688)
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE int lms_test(void)
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void)
|
||||
{
|
||||
int ret;
|
||||
int sigsLeft = 0;
|
||||
@ -35092,7 +35106,283 @@ WOLFSSL_TEST_SUBROUTINE int lms_test(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_HAVE_LMS */
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_VERIFY_ONLY) */
|
||||
|
||||
#if defined(WOLFSSL_HAVE_LMS) && defined(WOLFSSL_LMS_VERIFY_ONLY) && \
|
||||
!defined(WOLFSSL_SMALL_STACK)
|
||||
|
||||
/* A simple LMS verify only test.
|
||||
*
|
||||
* Note: LMS signature sizes are a function of their parameters. This
|
||||
* test has a signature of 1456 bytes:
|
||||
* levels: 1
|
||||
* height: 10
|
||||
* winternitz: 8
|
||||
* max sigs: 2 ** (1 * 10) = 1024
|
||||
* signature length: 1456
|
||||
* */
|
||||
|
||||
static byte lms_L1H10W8_pub[HSS_MAX_PUBLIC_KEY_LEN] =
|
||||
{
|
||||
0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x06,
|
||||
0x00,0x00,0x00,0x04,0xA1,0x26,0x76,0xF8,
|
||||
0xBB,0x0B,0xC0,0x82,0x21,0x71,0x0B,0x2E,
|
||||
0x8C,0xA6,0xEF,0x12,0xED,0x41,0x0E,0x8C,
|
||||
0xAF,0x11,0x93,0x34,0x7B,0x49,0x79,0xB7,
|
||||
0xDE,0x63,0x1C,0xFE,0x1F,0xD1,0x17,0x49,
|
||||
0xCD,0x5C,0xD4,0x26,0xA0,0x53,0x26,0x1A,
|
||||
0xC5,0xB4,0x8F,0x23
|
||||
};
|
||||
|
||||
#define LMS_L1H10W8_SIGLEN (1456)
|
||||
|
||||
static byte lms_L1H10W8_sig[LMS_L1H10W8_SIGLEN] =
|
||||
{
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x04,0x18,0x70,0x09,0x2E,
|
||||
0x21,0xC9,0x6A,0xC9,0x5C,0xB6,0xB0,0xAA,
|
||||
0xC3,0xED,0x6E,0x66,0x2F,0xCC,0x45,0x81,
|
||||
0xBC,0xBA,0x44,0x96,0x1C,0xBF,0x4E,0xFB,
|
||||
0x7A,0x46,0xFB,0xBE,0x9A,0x0C,0xE4,0x50,
|
||||
0x90,0xC7,0x92,0xAC,0x53,0xAE,0x53,0x76,
|
||||
0x29,0xA6,0x65,0xF1,0x09,0xED,0x1A,0x8E,
|
||||
0x03,0x2E,0x5A,0x06,0x51,0xE3,0x1E,0xE6,
|
||||
0xF6,0xFE,0x3A,0x6E,0xD1,0x92,0x31,0x1D,
|
||||
0xA1,0x6A,0x5C,0x30,0x3A,0xC7,0xFD,0x5B,
|
||||
0xFE,0x71,0x2C,0x5C,0x2F,0x5B,0x5B,0xCF,
|
||||
0xBC,0x7F,0xBF,0x6C,0xAF,0x44,0x8A,0xAE,
|
||||
0x14,0x60,0xAB,0x88,0xED,0x0E,0x4F,0xF8,
|
||||
0xC7,0x1B,0x74,0x28,0x72,0xB3,0x96,0xA6,
|
||||
0xE6,0x46,0x22,0x82,0xCF,0x1F,0x4D,0xA6,
|
||||
0xEA,0x22,0x06,0x07,0x52,0xF5,0x26,0x16,
|
||||
0x0B,0x90,0xE3,0xFF,0x64,0xA9,0xE4,0x61,
|
||||
0x1E,0x9C,0x12,0x9C,0xF6,0xD4,0x63,0x29,
|
||||
0xEA,0x02,0xF7,0x18,0x52,0x79,0x6C,0x43,
|
||||
0xDC,0xCF,0x43,0x23,0xB9,0xCC,0x4A,0x25,
|
||||
0x9D,0x10,0xAF,0xA3,0xE6,0x47,0x5A,0x1C,
|
||||
0xFE,0x68,0x89,0xAF,0x1B,0x2D,0x88,0x3E,
|
||||
0xCA,0xDC,0x70,0xEA,0xAC,0x11,0x00,0x8A,
|
||||
0x6E,0xE0,0xC7,0xD0,0xD2,0x1A,0x36,0x18,
|
||||
0x97,0xB3,0x5F,0x0E,0x75,0x48,0x28,0xF8,
|
||||
0xA8,0xF5,0x90,0xD1,0xA1,0x84,0xFB,0xA4,
|
||||
0xAD,0x50,0xBE,0xE9,0x39,0x8C,0xC5,0xA1,
|
||||
0x67,0x51,0xA1,0x8C,0xD6,0x6B,0x97,0x1F,
|
||||
0x47,0x99,0xEE,0xE0,0x70,0x01,0xC7,0x07,
|
||||
0x50,0xF3,0x5E,0x3F,0xE7,0x06,0xD6,0x8D,
|
||||
0x26,0xD6,0x5A,0x59,0x18,0x72,0x6B,0x12,
|
||||
0xD2,0xAF,0x9B,0xB4,0x2B,0xD0,0xB2,0xF2,
|
||||
0x96,0x2F,0x40,0xEA,0xBE,0xE6,0xAC,0x1F,
|
||||
0xB8,0x33,0xC2,0x76,0xDC,0x8C,0xAC,0xC1,
|
||||
0x46,0x5E,0x04,0x84,0x1B,0xC8,0xB9,0x65,
|
||||
0x8D,0xAD,0x96,0xB5,0xB1,0xF6,0x17,0x4A,
|
||||
0x19,0x87,0xE7,0xBF,0x29,0xC7,0x9B,0xB9,
|
||||
0xD6,0x11,0x2C,0x92,0x2F,0xB7,0x24,0xD5,
|
||||
0x01,0x1D,0x80,0x37,0x54,0xED,0x33,0x32,
|
||||
0xAB,0x7A,0x12,0xD4,0x02,0x1D,0x27,0x52,
|
||||
0x89,0xDB,0x32,0xBF,0x61,0xD4,0xBB,0xB4,
|
||||
0x46,0x78,0x1B,0x64,0x17,0x84,0x4B,0x8A,
|
||||
0xBA,0xC6,0xC1,0xCF,0xC7,0x5D,0x8F,0x93,
|
||||
0xC5,0x9A,0x27,0x90,0xAC,0x17,0x98,0xFF,
|
||||
0xC8,0x22,0x59,0x55,0x90,0xB2,0x29,0x39,
|
||||
0xA0,0xBE,0x00,0x23,0x55,0x6B,0xDA,0x83,
|
||||
0xD8,0x5B,0x57,0x7C,0x67,0x1B,0xC3,0x6B,
|
||||
0x6D,0xC7,0x9B,0x2B,0x9E,0xB7,0x95,0xB3,
|
||||
0xF0,0x1B,0x89,0x5A,0xD7,0x4B,0x67,0xAF,
|
||||
0xDC,0x9E,0xCF,0x7E,0x1A,0xBA,0x1B,0xB9,
|
||||
0x3B,0x7A,0xDD,0x3F,0x0D,0xEE,0x4C,0x0B,
|
||||
0xD1,0x4F,0x34,0xF2,0x93,0xF7,0x21,0x64,
|
||||
0x2C,0x07,0x00,0x15,0x4F,0xE3,0x6A,0x9F,
|
||||
0x08,0x52,0xC2,0x65,0x47,0x1F,0x34,0x64,
|
||||
0x66,0x07,0xBC,0xEA,0xAF,0x9B,0xAA,0x39,
|
||||
0x15,0x8B,0x08,0x8C,0x24,0x41,0x9B,0x46,
|
||||
0x1B,0x5B,0x91,0x11,0xC4,0xFD,0xA9,0x88,
|
||||
0x35,0x0E,0x7D,0xAF,0xFD,0xB7,0x90,0x7E,
|
||||
0xD7,0x29,0x02,0x0A,0xDC,0xC8,0x3F,0xC0,
|
||||
0xFD,0x97,0xAF,0x50,0x49,0xA6,0x5E,0x12,
|
||||
0xC1,0xCD,0xEC,0x52,0xC5,0x51,0xF2,0x80,
|
||||
0x17,0x61,0xC7,0x7E,0xBE,0xD1,0x1B,0x65,
|
||||
0xA4,0xAB,0x92,0x8D,0x89,0xB2,0xC5,0x8F,
|
||||
0xFF,0xA5,0x6F,0xFA,0x62,0x75,0xE4,0xA1,
|
||||
0xD4,0x22,0xA8,0x9E,0x40,0x04,0x27,0x1F,
|
||||
0xCC,0x81,0xBA,0x28,0x67,0xA0,0x1C,0x80,
|
||||
0xEB,0xCA,0xB0,0x61,0xA5,0x48,0xD0,0x8A,
|
||||
0x25,0xEB,0x9E,0x67,0x8C,0x8E,0x9B,0xD1,
|
||||
0xAD,0xBB,0xC3,0xEA,0xD3,0xD4,0xC5,0x12,
|
||||
0x7B,0xDD,0x00,0x57,0x7F,0xF6,0xF7,0xF6,
|
||||
0x3C,0x05,0xCF,0xFC,0x12,0xE1,0x93,0x05,
|
||||
0xE5,0x9B,0x79,0x87,0x69,0xD8,0x82,0xD9,
|
||||
0xD7,0x1D,0x41,0x73,0xE4,0x52,0x1D,0x3E,
|
||||
0xE5,0x8C,0x8D,0x34,0xE1,0x75,0xA9,0xF1,
|
||||
0x9D,0x09,0xA2,0x5B,0xEF,0xDA,0x96,0x6E,
|
||||
0x76,0x3D,0xEA,0x50,0xD9,0xCF,0x4F,0xAC,
|
||||
0xAD,0x1D,0x35,0x72,0x1B,0x88,0x8B,0xCD,
|
||||
0x8C,0x8A,0x8A,0xE0,0x96,0x04,0xD8,0xBB,
|
||||
0x28,0x43,0x16,0x77,0x60,0x98,0x63,0xF9,
|
||||
0xB9,0x71,0x46,0xB7,0xE1,0xA7,0xA9,0x84,
|
||||
0xC3,0x65,0x82,0xE1,0x1B,0x67,0x04,0x2D,
|
||||
0x55,0x6B,0xF9,0xC0,0x79,0x09,0x09,0xE7,
|
||||
0xFD,0x06,0x4D,0x09,0x9B,0x1A,0xCE,0x35,
|
||||
0xFA,0x27,0x6F,0x2F,0x01,0x65,0x0D,0xA0,
|
||||
0x97,0x59,0x11,0xF0,0x48,0xD2,0xE7,0x46,
|
||||
0xBE,0xB4,0x0A,0xA3,0xE2,0x75,0x0E,0x09,
|
||||
0x94,0xD9,0x69,0x28,0xD4,0xDA,0x64,0xBA,
|
||||
0xFE,0xA4,0xB9,0xF0,0xBA,0xEB,0xBA,0xAC,
|
||||
0xA8,0xF9,0xD3,0x82,0x4C,0x36,0x80,0xFA,
|
||||
0xE5,0xF6,0x76,0xC3,0x80,0xFA,0x90,0x29,
|
||||
0xF4,0x85,0xA4,0xC6,0x25,0x22,0x79,0x7E,
|
||||
0x39,0x1E,0x30,0xB8,0x65,0x72,0xCF,0xE1,
|
||||
0x99,0xF0,0x75,0xE8,0x09,0xB4,0x92,0x96,
|
||||
0x1B,0x68,0x50,0x88,0xF1,0x2C,0x97,0xE3,
|
||||
0x2D,0x26,0x8F,0xC5,0x30,0xCF,0x24,0xCB,
|
||||
0xB2,0x60,0x77,0xDC,0x02,0x72,0x0D,0xD9,
|
||||
0x2E,0xF2,0x52,0xEA,0x00,0xF6,0x32,0x65,
|
||||
0xA5,0xC6,0x43,0x29,0x29,0x69,0xAB,0x27,
|
||||
0x0C,0x39,0xDF,0x76,0x3E,0x93,0x95,0xB1,
|
||||
0x2C,0xA2,0x0D,0x18,0xCE,0xA0,0x97,0x10,
|
||||
0x3C,0x90,0xC0,0xEF,0x0E,0x04,0xA6,0xC8,
|
||||
0xA0,0x21,0x3C,0x0B,0x22,0x77,0x7A,0x66,
|
||||
0xA5,0x90,0x25,0xA4,0x09,0x3E,0xD5,0x27,
|
||||
0x1F,0x6C,0x99,0x85,0x5C,0xA2,0x99,0x7A,
|
||||
0x25,0xEE,0x8D,0x32,0x3D,0xD3,0xDC,0xF5,
|
||||
0x00,0x5A,0x34,0x61,0xB6,0xCD,0x4E,0xBC,
|
||||
0x26,0x36,0xFB,0x44,0x97,0x35,0xBD,0x06,
|
||||
0x7D,0x2E,0x4A,0xA2,0xDC,0x24,0xFE,0x70,
|
||||
0x0A,0xF9,0x57,0xE3,0xEE,0xAB,0xD1,0x17,
|
||||
0xF3,0x7C,0xD6,0x37,0x26,0xFA,0x83,0x9F,
|
||||
0xDD,0xB2,0xE1,0xD7,0xF9,0xC7,0x0E,0x15,
|
||||
0x01,0xA6,0x58,0x32,0x98,0x04,0x32,0xD4,
|
||||
0xDE,0xB9,0xEF,0x09,0xFA,0xE4,0x5A,0xD7,
|
||||
0xDD,0x09,0x1C,0xC9,0xAC,0xB8,0x6A,0xF5,
|
||||
0x00,0x5D,0x6B,0x95,0x12,0x8C,0x2F,0xCC,
|
||||
0xD8,0xB9,0x50,0x3A,0xEB,0x74,0x86,0xD2,
|
||||
0x3F,0xA1,0x05,0x8F,0x6E,0xEF,0xF5,0xA4,
|
||||
0xD6,0x6E,0x53,0xFA,0x9E,0xFA,0xCE,0xDB,
|
||||
0x99,0x46,0xE7,0xC5,0xDA,0x92,0x51,0x4F,
|
||||
0x22,0x07,0xF3,0xA5,0x38,0x26,0xD3,0xEC,
|
||||
0xD6,0x01,0xDD,0x31,0x3A,0x48,0x93,0xF6,
|
||||
0x69,0x4F,0xD8,0xF6,0xC2,0x91,0xA5,0x7C,
|
||||
0xDF,0x51,0x64,0xF1,0x3B,0x79,0xBC,0x0A,
|
||||
0x2C,0xDC,0x33,0x5A,0x29,0xF6,0xB2,0x09,
|
||||
0x66,0xCA,0x24,0x9F,0x1A,0x18,0xF3,0x76,
|
||||
0x4C,0x5E,0x0B,0x81,0x7F,0x29,0x84,0xD8,
|
||||
0x7A,0xA8,0xD6,0x11,0xAC,0xEC,0xD9,0x07,
|
||||
0x91,0xEC,0xB6,0x6D,0xEC,0xDB,0xBE,0x6F,
|
||||
0x9F,0xC5,0x19,0x5E,0x56,0x87,0x20,0x80,
|
||||
0x75,0xD5,0x64,0xE9,0x80,0xBF,0x2D,0xD5,
|
||||
0x94,0x9F,0x8C,0xA4,0x54,0x41,0xAB,0xB1,
|
||||
0x8E,0xAD,0x51,0xE4,0x3C,0x24,0xF7,0x1D,
|
||||
0xFE,0x02,0x48,0x7C,0x6D,0xED,0xF1,0xAC,
|
||||
0xD9,0x79,0x42,0xE5,0x3A,0xCF,0x6A,0x4C,
|
||||
0x6D,0xE2,0x13,0xD2,0x2B,0x9D,0xAB,0x1F,
|
||||
0x70,0xD3,0xC0,0x6F,0x81,0xE9,0x9A,0x86,
|
||||
0x33,0x39,0x60,0xE7,0x6A,0x00,0x1F,0x97,
|
||||
0xEB,0xE5,0x1D,0x0D,0x66,0x15,0xC9,0xA2,
|
||||
0xB1,0xC0,0xF0,0x2E,0xF4,0x07,0xA2,0x2E,
|
||||
0x49,0x92,0x95,0x13,0xA3,0x18,0x46,0x25,
|
||||
0xB9,0x3C,0xA1,0x4B,0x00,0x00,0x00,0x06,
|
||||
0xAB,0xAA,0xF9,0x3F,0x7E,0x21,0xF4,0x0E,
|
||||
0xCE,0xFD,0xE0,0x44,0xAC,0xC7,0x1A,0x30,
|
||||
0x22,0x9D,0x0A,0xD7,0x96,0x2D,0x8F,0x9A,
|
||||
0x99,0x1F,0x40,0x75,0x7F,0x62,0xF9,0xC1,
|
||||
0x81,0x7B,0x4A,0x1B,0xFA,0xD6,0x87,0xB9,
|
||||
0xEF,0x58,0x48,0xE4,0x5C,0x79,0xE5,0xB1,
|
||||
0x2C,0x59,0xA4,0x42,0xDB,0xA6,0x53,0x70,
|
||||
0x80,0x61,0x17,0xD4,0xD3,0x77,0xBD,0x53,
|
||||
0x26,0x7C,0x0E,0x0E,0xFF,0x30,0x4B,0xD0,
|
||||
0x86,0xFC,0x02,0x20,0x24,0x46,0x5B,0xF5,
|
||||
0xE3,0x99,0x73,0x85,0x60,0x00,0x36,0x47,
|
||||
0x17,0xEE,0x0C,0xD2,0x80,0x71,0x46,0x0E,
|
||||
0x2B,0xB0,0xEF,0x7F,0xFE,0x3B,0xE5,0xE1,
|
||||
0x87,0xC2,0xAF,0x1A,0x6F,0x63,0xF4,0x5A,
|
||||
0xC4,0x16,0xF7,0xAD,0x07,0x70,0x71,0x85,
|
||||
0x7D,0x3D,0x67,0x08,0xB8,0xD8,0xE2,0xF0,
|
||||
0xA1,0xAC,0xD2,0x94,0x7D,0x93,0x03,0xDD,
|
||||
0x54,0xF9,0x64,0x19,0xB3,0xED,0x24,0x22,
|
||||
0x01,0xD7,0x12,0x5E,0xC1,0x2B,0x39,0x10,
|
||||
0x13,0xE2,0x56,0x1C,0xEE,0xF4,0x2A,0x49,
|
||||
0x7B,0xFB,0x36,0x8D,0xF8,0xAF,0x60,0xDF,
|
||||
0x10,0xF0,0x72,0xA2,0xED,0xB6,0x53,0x88,
|
||||
0xA9,0x0C,0xED,0x9C,0x18,0x33,0x7D,0x65,
|
||||
0x9B,0xB2,0x9C,0x3E,0xE9,0x1E,0x43,0x51,
|
||||
0x7E,0xBE,0x01,0x95,0xF6,0x60,0x65,0xBE,
|
||||
0xD1,0xF4,0xE2,0x83,0x6B,0xCA,0x7A,0x70,
|
||||
0x41,0x83,0x72,0xC0,0x23,0x51,0x13,0x11,
|
||||
0x2D,0xF9,0xC0,0x0D,0x7D,0x73,0x76,0xA5,
|
||||
0x30,0x83,0x68,0x10,0x35,0xA2,0x18,0x22,
|
||||
0x4E,0x21,0x93,0x27,0x6A,0x19,0x28,0x83,
|
||||
0x7F,0xDD,0xDD,0xFF,0xC3,0x8A,0x64,0x00,
|
||||
0x5F,0x1C,0x0D,0xF8,0xBB,0xD7,0x15,0xB9,
|
||||
0xEF,0xE0,0x07,0x62,0x05,0x9E,0xCF,0xFC,
|
||||
0x08,0x52,0x1E,0x65,0x41,0x56,0x6A,0xEB,
|
||||
0x81,0x53,0x30,0x7B,0xF2,0xFD,0x65,0xFF,
|
||||
0xA2,0x14,0xF5,0x62,0x1E,0x24,0x48,0x47,
|
||||
0xA5,0x41,0x80,0xB4,0xC5,0xDC,0xB2,0xB4,
|
||||
0x2D,0x17,0xE7,0xBE,0x49,0x53,0x7A,0x25,
|
||||
0xC5,0x0D,0x19,0x59,0xF4,0x88,0x59,0xED,
|
||||
0x92,0x13,0xEE,0x7A,0x4F,0x12,0x98,0x4C
|
||||
};
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void)
|
||||
{
|
||||
int ret;
|
||||
LmsKey verifyKey;
|
||||
word32 sigSz = 0;
|
||||
const char * msg = "wolfSSL LMS example message!";
|
||||
word32 msgSz = (word32) XSTRLEN(msg);
|
||||
word32 pubLen = 0;
|
||||
int levels = 0;
|
||||
int height = 0;
|
||||
int winternitz = 0;
|
||||
|
||||
ret = wc_LmsKey_Init(&verifyKey, NULL, INVALID_DEVID);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
ret = wc_LmsKey_SetParameters(&verifyKey, 1, 10, 8);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
ret = wc_LmsKey_ImportPubRaw(&verifyKey, lms_L1H10W8_pub,
|
||||
HSS_MAX_PUBLIC_KEY_LEN);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
/* Verify parameters, pub length, and sig length are correct. */
|
||||
ret = wc_LmsKey_GetParameters(&verifyKey, &levels, &height, &winternitz);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
if (levels != 1 || height != 10 || winternitz != 8) {
|
||||
printf("error: invalid LMS parameters: L%d-H%d-W%d\n", levels, height,
|
||||
winternitz);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wc_LmsKey_GetPubLen(&verifyKey, &pubLen);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
if (pubLen != HSS_MAX_PUBLIC_KEY_LEN) {
|
||||
printf("error: got %d, expected %d\n", pubLen, HSS_MAX_PUBLIC_KEY_LEN);
|
||||
return WC_TEST_RET_ENC_EC(pubLen);
|
||||
}
|
||||
|
||||
ret = wc_LmsKey_GetSigLen(&verifyKey, &sigSz);
|
||||
if (ret != 0) { return WC_TEST_RET_ENC_EC(ret); }
|
||||
|
||||
if (sigSz != LMS_L1H10W8_SIGLEN) {
|
||||
printf("error: got %d, expected %d\n", sigSz, LMS_L1H10W8_SIGLEN);
|
||||
return WC_TEST_RET_ENC_EC(sigSz);
|
||||
}
|
||||
|
||||
ret = wc_LmsKey_Verify(&verifyKey, lms_L1H10W8_sig, LMS_L1H10W8_SIGLEN,
|
||||
(byte *) msg, msgSz);
|
||||
if (ret != 0) {
|
||||
printf("error: wc_LmsKey_Verify returned %d\n", ret);
|
||||
return WC_TEST_RET_ENC_EC(ret);
|
||||
}
|
||||
|
||||
wc_LmsKey_Free(&verifyKey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* if defined(WOLFSSL_HAVE_LMS) && defined(WOLFSSL_LMS_VERIFY_ONLY) &&
|
||||
* !defined(WOLFSSL_SMALL_STACK) */
|
||||
|
||||
static const int fiducial3 = WC_TEST_RET_LN; /* source code reference point --
|
||||
* see print_fiducials() below.
|
||||
|
@ -51,11 +51,13 @@ struct LmsKey {
|
||||
param_set_t lm_type[MAX_HSS_LEVELS]; /* Height parm per level. */
|
||||
param_set_t lm_ots_type[MAX_HSS_LEVELS]; /* Winternitz parm per level. */
|
||||
unsigned char pub[HSS_MAX_PUBLIC_KEY_LEN];
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
hss_working_key * working_key;
|
||||
write_private_key_cb write_private_key; /* Callback to write/update key. */
|
||||
read_private_key_cb read_private_key; /* Callback to read key. */
|
||||
void * context; /* Context arg passed to callbacks. */
|
||||
hss_extra_info info;
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
enum wc_LmsState state;
|
||||
};
|
||||
|
||||
|
@ -109,23 +109,31 @@ WOLFSSL_API int wc_LmsKey_Init(LmsKey * key, void * heap, int devId);
|
||||
WOLFSSL_API int wc_LmsKey_SetLmsParm(LmsKey * key, enum wc_LmsParm lmsParm);
|
||||
WOLFSSL_API int wc_LmsKey_SetParameters(LmsKey * key, int levels,
|
||||
int height, int winternitz);
|
||||
WOLFSSL_API int wc_LmsKey_GetParameters(const LmsKey * key, int * levels,
|
||||
int * height, int * winternitz);
|
||||
#ifndef WOLFSSL_LMS_VERIFY_ONLY
|
||||
WOLFSSL_API int wc_LmsKey_SetWriteCb(LmsKey * key,
|
||||
write_private_key_cb write_cb);
|
||||
WOLFSSL_API int wc_LmsKey_SetReadCb(LmsKey * key,
|
||||
read_private_key_cb read_cb);
|
||||
WOLFSSL_API int wc_LmsKey_SetContext(LmsKey * key, void * context);
|
||||
WOLFSSL_API void wc_LmsKey_Free(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_MakeKey(LmsKey * key, WC_RNG * rng);
|
||||
WOLFSSL_API int wc_LmsKey_Reload(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_GetSigLen(LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_GetPrivLen(LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_GetPubLen(LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub(LmsKey * keyDst, const LmsKey * keySrc);
|
||||
WOLFSSL_API int wc_LmsKey_GetPrivLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_Sign(LmsKey * key, byte * sig, word32 * sigSz,
|
||||
const byte * msg, int msgSz);
|
||||
WOLFSSL_API int wc_LmsKey_SigsLeft(LmsKey * key);
|
||||
#endif /* ifndef WOLFSSL_LMS_VERIFY_ONLY */
|
||||
WOLFSSL_API void wc_LmsKey_Free(LmsKey * key);
|
||||
WOLFSSL_API int wc_LmsKey_GetSigLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_GetPubLen(const LmsKey * key, word32 * len);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPub(LmsKey * keyDst, const LmsKey * keySrc);
|
||||
WOLFSSL_API int wc_LmsKey_ExportPubRaw(const LmsKey * key, byte * out,
|
||||
word32 * outLen);
|
||||
WOLFSSL_API int wc_LmsKey_ImportPubRaw(LmsKey * key, const byte * in,
|
||||
word32 inLen);
|
||||
WOLFSSL_API int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz,
|
||||
const byte * msg, int msgSz);
|
||||
WOLFSSL_API int wc_LmsKey_SigsLeft(LmsKey * key);
|
||||
WOLFSSL_API const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm);
|
||||
WOLFSSL_API const char * wc_LmsKey_RcToStr(enum wc_LmsRc lmsRc);
|
||||
#ifdef __cplusplus
|
||||
|
Reference in New Issue
Block a user