From 4dbc9a63619d60d54a8ad5f8e2467459739f0d48 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 23 Jan 2024 01:29:28 -0500 Subject: [PATCH 01/10] Disable stateful signature as default. When enabled, key and signature generation is disabled by default. Only signature verification is allowed. Key and signature generation can be enabled by defining OQS_ENABLE_SIG_STFL_KEY_SIG_GEN --- .CMake/alg_support.cmake | 22 ++++++++++- CONFIGURE.md | 20 ++++++++++ src/oqsconfig.h.cmake | 4 ++ src/sig_stfl/lms/external/hss_keygen.c | 3 ++ src/sig_stfl/lms/external/hss_sign_inc.c | 3 ++ src/sig_stfl/lms/sig_stfl_lms_functions.c | 26 +++++++++++++ src/sig_stfl/sig_stfl.c | 8 ++++ src/sig_stfl/xmss/external/xmss.c | 22 +++++++++++ src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 8 +++- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 8 +++- tests/example_sig_stfl.c | 14 +++++++ tests/kat_sig_stfl.c | 38 +++++++++++++++++++ tests/test_sig_stfl.c | 5 +++ 13 files changed, 177 insertions(+), 4 deletions(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index 78f2e76287..fe69445615 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -384,7 +384,7 @@ endif() ##### OQS_COPY_FROM_UPSTREAM_FRAGMENT_ADD_ENABLE_BY_ALG_END -option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" ON) +option(OQS_ENABLE_SIG_STFL_XMSS "Enable XMSS algorithm family" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h10 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h16 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmss_sha256_h20 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) @@ -415,7 +415,7 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_6 "" ON "OQS_ENAB cmake_dependent_option(OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_12 "" ON "OQS_ENABLE_SIG_STFL_XMSS" OFF) -option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" ON) +option(OQS_ENABLE_SIG_STFL_LMS "Enable LMS algorithm family" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w1 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w2 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h5_w4 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) @@ -450,6 +450,24 @@ cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h10_w8 "" ON "OQS_E cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h15_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) cmake_dependent_option(OQS_ENABLE_SIG_STFL_lms_sha256_h20_w8_h20_w8 "" ON "OQS_ENABLE_SIG_STFL_LMS" OFF) +option(OQS_ENABLE_SIG_STFL_KEY_SIG_GEN "Enable stateful key and signature generation for research and experimentation" OFF) +cmake_dependent_option(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN "" ON "OQS_ENABLE_SIG_STFL_KEY_SIG_GEN" OFF) + +if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_XMSS}) + set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN ON) +else() + set(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN OFF) +endif() + +if (${OQS_ENABLE_SIG_STFL_KEY_SIG_GEN} AND ${OQS_ENABLE_SIG_STFL_LMS}) + set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN ON) +else() + set(OQS_ALLOW_LMS_KEY_AND_SIG_GEN OFF) +endif() + +if(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN STREQUAL "ON") + message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultanous sign operations.") +endif() if((OQS_MINIMAL_BUILD STREQUAL "ON")) message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported") diff --git a/CONFIGURE.md b/CONFIGURE.md index b6b45cce64..9e77b3469b 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -112,6 +112,26 @@ When `OQS_USE_OPENSSL` is `ON`, CMake also scans the filesystem to find the mini **Default**: `ON`. +## Stateful Hash Based Signatures + +XMSS and LMS are the two supported Hash-Based Signatures schemes +OQS_ENABLE_SIG_STFL_XMSS and OQS_ENABLE_SIG_STFL_LMS contorl these algorithms which are disabled by default. +A thrid variable, OQS_ENABLE_SIG_STFL_KEY_SIG_GEN also controls the ability to generate keys and signatures. This is also disabled by efault. +Each of these variables can be set to `ON` or `OFF`. +When all three are `ON`, stateful signatures is fully functional and can generate key-pairs, sign data, and verify signatures. +If OQS_ENABLE_SIG_STFL_KEY_SIG_GEN is `OFF` signature verification is the only functioanl operation. + +Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in-order to best enforce the one-time use of secret keys. +Keys stored in a file system is extreamly susceptible to simultaneous use. +When enabled in this library a warning message will be generated by the config process. + +By default, +- `OQS_ENABLE_SIG_STFL_XMSS` is `OFF` +- `OQS_ENABLE_SIG_STFL_LMS` is `OFF` +- `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF`. + +**Default**: `OFF`. + ## OQS_OPT_TARGET An optimization target. Only has an effect if the compiler is GCC or Clang and `OQS_DIST_BUILD=OFF`. Can take any valid input to the `-march` (on x86-64) or `-mcpu` (on ARM32v7 or ARM64v8) option for `CMAKE_C_COMPILER`. Can also be set to one of the following special values. diff --git a/src/oqsconfig.h.cmake b/src/oqsconfig.h.cmake index c5985b4c2f..9f29832a03 100644 --- a/src/oqsconfig.h.cmake +++ b/src/oqsconfig.h.cmake @@ -199,3 +199,7 @@ #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h5_w8_h5_w8 1 #cmakedefine OQS_ENABLE_SIG_STFL_lms_sha256_h10_w4_h5_w8 1 +#cmakedefine OQS_ENABLE_SIG_STFL_KEY_SIG_GEN 1 +#cmakedefine OQS_ALLOW_SFTL_KEY_AND_SIG_GEN 1 +#cmakedefine OQS_ALLOW_XMSS_KEY_AND_SIG_GEN 1 +#cmakedefine OQS_ALLOW_LMS_KEY_AND_SIG_GEN 1 \ No newline at end of file diff --git a/src/sig_stfl/lms/external/hss_keygen.c b/src/sig_stfl/lms/external/hss_keygen.c index 71da413325..d85d9626c7 100644 --- a/src/sig_stfl/lms/external/hss_keygen.c +++ b/src/sig_stfl/lms/external/hss_keygen.c @@ -10,6 +10,7 @@ #include "hss_thread.h" #include "lm_common.h" #include "lm_ots_common.h" +#include /* Count the number of 1 bits at the end (lsbits) of the integer */ /* Do it in the obvious way; straightline code may be faster (no */ @@ -51,6 +52,7 @@ static int trailing_1_bits(merkle_index_t n) { * * This returns true on success, false on failure */ +#ifdef OQS_ALLOW_LMS_KEY_AND_SIG_GEN bool hss_generate_private_key( bool (*generate_random)(void *output, size_t length), unsigned levels, @@ -356,6 +358,7 @@ bool hss_generate_private_key( free(temp_buffer); // IGNORE free-check return true; } +#endif /* * The length of the private key diff --git a/src/sig_stfl/lms/external/hss_sign_inc.c b/src/sig_stfl/lms/external/hss_sign_inc.c index 72a8a22c91..ab3112ee03 100644 --- a/src/sig_stfl/lms/external/hss_sign_inc.c +++ b/src/sig_stfl/lms/external/hss_sign_inc.c @@ -16,6 +16,7 @@ #include "hss_internal.h" #include "hss_sign_inc.h" #include "hss_derive.h" +#include /* * Start the process of creating an HSS signature incrementally. Parameters: @@ -28,6 +29,7 @@ * this_is_the_last_signature - if non-NULL, this will be set if this * signature is the last for this private key */ +#ifdef OQS_ALLOW_LMS_KEY_AND_SIG_GEN bool hss_sign_init( struct hss_sign_inc *ctx, struct hss_working_key *w, @@ -217,3 +219,4 @@ bool hss_sign_finalize( hss_zeroize( seed_buff, sizeof seed_buff ); return success; } +#endif diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index be709fc71c..df0957aba9 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -11,6 +11,12 @@ #include "external/hss_internal.h" #include "sig_stfl_lms_wrap.h" +#ifdef __GNUC__ +#define UNUSED __attribute__((unused)) +#else +#define UNUSED +#endif + #define DEFAULT_AUX_DATA 10916 /* Use 10+k of aux data (which works well */ /* with the above default parameter set) */ /** @@ -46,6 +52,12 @@ typedef struct OQS_LMS_KEY_DATA { void *context; } oqs_lms_key_data; +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(UNUSED uint8_t *signature, UNUSED size_t *signature_length, UNUSED const uint8_t *message, + UNUSED size_t message_len, UNUSED OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_ERROR; @@ -117,6 +129,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu } return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { @@ -219,6 +232,11 @@ bool LMS_randombytes(void *buffer, size_t length) { return true; } +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +int oqs_sig_stfl_lms_keypair(UNUSED uint8_t *pk, UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED const uint32_t oid) { + return -1; +} +#else int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid) { int ret = -1; @@ -522,7 +540,14 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin ret = 0; return ret; } +#endif +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN +int oqs_sig_stfl_lms_sign(UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED uint8_t *sm, UNUSED size_t *smlen, + UNUSED const uint8_t *m, UNUSED size_t mlen) { + return -1; +} +#else int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen) { @@ -598,6 +623,7 @@ int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, return 0; } +#endif int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, size_t smlen, diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index e3a9d0f71c..6c4ee20508 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -878,21 +878,29 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { } OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + return OQS_ERROR; +#else if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } return OQS_ERROR; +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + return OQS_ERROR; +#else if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/external/xmss.c b/src/sig_stfl/xmss/external/xmss.c index 17b40f5627..71d3f0a463 100644 --- a/src/sig_stfl/xmss/external/xmss.c +++ b/src/sig_stfl/xmss/external/xmss.c @@ -6,6 +6,13 @@ #include "utils.h" #include "xmss.h" + +#if defined(__GNUC__) || defined(__clang__) +#define XMSS_UNUSED_ATT __attribute__((unused)) +#else +#define XMSS_UNUSED_ATT +#endif + /* This file provides wrapper functions that take keys that include OIDs to identify the parameter set to be used. After setting the parameters accordingly it falls back to the regular XMSS core functions. */ @@ -25,6 +32,12 @@ it falls back to the regular XMSS core functions. */ * @return an integer value. If the function executes successfully, it will return 0. If there is an * error, it will return -1. */ +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +int xmss_keypair(XMSS_UNUSED_ATT unsigned char *pk, XMSS_UNUSED_ATT unsigned char *sk, XMSS_UNUSED_ATT const uint32_t oid) +{ + return -1; +} +#else int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) { xmss_params params; @@ -42,6 +55,7 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) } return xmss_core_keypair(¶ms, pk + XMSS_OID_LEN, sk + XMSS_OID_LEN); } +#endif /** * This function parses the XMSS OID from a secret key, uses it to determine the XMSS parameters, and @@ -57,6 +71,13 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid) * @return an integer value. If the function executes successfully, it will return 0. If there is an * error, it will return -1. */ +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +int xmss_sign(XMSS_UNUSED_ATT unsigned char *sk, XMSS_UNUSED_ATT unsigned char *sm, XMSS_UNUSED_ATT unsigned long long *smlen, + XMSS_UNUSED_ATT const unsigned char *m, XMSS_UNUSED_ATT unsigned long long mlen) +{ + return -1; +} +#else int xmss_sign(unsigned char *sk, unsigned char *sm, unsigned long long *smlen, const unsigned char *m, unsigned long long mlen) @@ -73,6 +94,7 @@ int xmss_sign(unsigned char *sk, } return xmss_core_sign(¶ms, sk + XMSS_OID_LEN, sm, smlen, m, mlen); } +#endif /** * The function xmss_sign_open verifies a signature and retrieves the original message using the XMSS diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index a19cdc7527..9b02d51e0a 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -14,7 +14,12 @@ #endif /* -------------- XMSS -------------- */ - +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_SUCCESS; @@ -59,6 +64,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signat return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index a3a2257b1c..cdd33c23c2 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -15,7 +15,12 @@ #endif /* -------------- XMSSMT -------------- */ - +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; +} +#else OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { OQS_STATUS status = OQS_SUCCESS; @@ -60,6 +65,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *sign return status; } +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index cbabee8b14..7d017004a9 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -121,13 +121,27 @@ static OQS_STATUS stfl_example(char *method_name) { } int main(void) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + printf("Stateful signature algorithms key and signature generation is not enabled.\n"); + return EXIT_SUCCESS; +#else OQS_init(); +# if defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) && defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { +# elif defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) + OQS_init(); + if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS) { +# elif defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) + if ( stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { +# else + if ( stfl_example((char *)"") == OQS_SUCCESS) { +#endif OQS_destroy(); return EXIT_SUCCESS; } else { OQS_destroy(); return EXIT_FAILURE; } +#endif } diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 498c324813..99b352d964 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -251,6 +251,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { fprintBstr(fh, "msg = ", msg, msg_len); +#ifdef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN rc = OQS_SIG_STFL_sign(sig, signature, &signature_len, msg, msg_len, secret_key); if (rc != OQS_SUCCESS) { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sign failed!\n", method_name); @@ -297,7 +298,44 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { ret = OQS_SUCCESS; goto cleanup; +#else + /* + * Signature generation is disabled so only signature verification can be tested. + */ + signature_len = sig->length_signature; + if (!ReadHex(fp_rsp, signature_kat, signature_len, "sm = ")) { + fprintf(stderr, "ERROR: unable to read 'msg' from <%s>\n", katfile); + goto err; + } + + //Echo back the signature read to keep the test tool happy. + fprintf(fh, "smlen = %zu\n", sig->length_signature); + fprintBstr(fh, "sm = ", signature_kat, sig->length_signature); + rc = OQS_SIG_STFL_verify(sig, msg, msg_len, signature_kat, signature_len, public_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_verify failed!\n", method_name); + goto err; + } + + rc = OQS_SIG_STFL_sigs_remaining(sig, &sigs_remain, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); + goto err; + } + //Update value to keep the test tool happy + fprintf(fh, "remain = %llu\n", sigs_remain-1); + + rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); + if (rc != OQS_SUCCESS) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); + goto err; + } + fprintf(fh, "max = %llu", sigs_maximum); + + ret = OQS_SUCCESS; + goto cleanup; +#endif err: ret = OQS_ERROR; goto cleanup; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index a8b3e7962d..4dc81cbbc6 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -989,6 +989,10 @@ void *test_wrapper(void *arg) { #endif int main(int argc, char **argv) { +#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + printf("Stateful signature algorithms key and signature generation is not enabled.\n"); + return EXIT_SUCCESS; +#else OQS_init(); oqs_fstore_init(); @@ -1127,4 +1131,5 @@ int main(int argc, char **argv) { } return exit_status; #endif +#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN } From e25962b6b60c0cbf3eb2e4bee6299cf6041cf162 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 23 Jan 2024 06:46:05 +0000 Subject: [PATCH 02/10] Fixed format --- src/sig_stfl/lms/sig_stfl_lms_functions.c | 10 +++++----- src/sig_stfl/sig_stfl.c | 12 ++++++------ src/sig_stfl/xmss/sig_stfl_xmss_functions.c | 6 +++--- src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c | 6 +++--- tests/example_sig_stfl.c | 16 ++++++++-------- tests/kat_sig_stfl.c | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index df0957aba9..d2d0aa157a 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -55,7 +55,7 @@ typedef struct OQS_LMS_KEY_DATA { #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(UNUSED uint8_t *signature, UNUSED size_t *signature_length, UNUSED const uint8_t *message, UNUSED size_t message_len, UNUSED OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_ERROR; + return OQS_ERROR; } #else OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signature_length, const uint8_t *message, @@ -234,7 +234,7 @@ bool LMS_randombytes(void *buffer, size_t length) { #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN int oqs_sig_stfl_lms_keypair(UNUSED uint8_t *pk, UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED const uint32_t oid) { - return -1; + return -1; } #else int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid) { @@ -540,12 +540,12 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uin ret = 0; return ret; } -#endif +#endif #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN int oqs_sig_stfl_lms_sign(UNUSED OQS_SIG_STFL_SECRET_KEY *sk, UNUSED uint8_t *sm, UNUSED size_t *smlen, - UNUSED const uint8_t *m, UNUSED size_t mlen) { - return -1; + UNUSED const uint8_t *m, UNUSED size_t mlen) { + return -1; } #else int oqs_sig_stfl_lms_sign(OQS_SIG_STFL_SECRET_KEY *sk, diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index 6c4ee20508..dbf18f7e5c 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -879,28 +879,28 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN - return OQS_ERROR; -#else + return OQS_ERROR; +#else if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } return OQS_ERROR; -#endif +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN - return OQS_ERROR; -#else + return OQS_ERROR; +#else if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { return OQS_ERROR; } else { return OQS_SUCCESS; } -#endif +#endif } OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c index 9b02d51e0a..ce2df38238 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_functions.c @@ -15,8 +15,8 @@ /* -------------- XMSS -------------- */ #ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, - XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { return OQS_ERROR; } #else @@ -64,7 +64,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sign(uint8_t *signature, size_t *signat return status; } -#endif +#endif OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_verify(XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, const uint8_t *signature, size_t signature_len, XMSS_UNUSED_ATT const uint8_t *public_key) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c index cdd33c23c2..f5d99705d3 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c @@ -16,9 +16,9 @@ /* -------------- XMSSMT -------------- */ #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN -OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, - XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { - return OQS_ERROR; +OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(XMSS_UNUSED_ATT uint8_t *signature, XMSS_UNUSED_ATT size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, + XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { + return OQS_ERROR; } #else OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmssmt_sign(uint8_t *signature, size_t *signature_len, XMSS_UNUSED_ATT const uint8_t *message, XMSS_UNUSED_ATT size_t message_len, XMSS_UNUSED_ATT OQS_SIG_STFL_SECRET_KEY *secret_key) { diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index 7d017004a9..74ff1004c4 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -122,20 +122,20 @@ static OQS_STATUS stfl_example(char *method_name) { int main(void) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN - printf("Stateful signature algorithms key and signature generation is not enabled.\n"); - return EXIT_SUCCESS; + printf("Stateful signature algorithms key and signature generation is not enabled.\n"); + return EXIT_SUCCESS; #else OQS_init(); # if defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) && defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { -# elif defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) - OQS_init(); +# elif defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) + OQS_init(); if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS) { # elif defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) - if ( stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { -# else - if ( stfl_example((char *)"") == OQS_SUCCESS) { -#endif + if ( stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { +# else + if ( stfl_example((char *)"") == OQS_SUCCESS) { +#endif OQS_destroy(); return EXIT_SUCCESS; } else { diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 99b352d964..5ef1e8db8e 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -324,7 +324,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { goto err; } //Update value to keep the test tool happy - fprintf(fh, "remain = %llu\n", sigs_remain-1); + fprintf(fh, "remain = %llu\n", sigs_remain - 1); rc = OQS_SIG_STFL_sigs_total(sig, &sigs_maximum, secret_key); if (rc != OQS_SUCCESS) { @@ -335,7 +335,7 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { ret = OQS_SUCCESS; goto cleanup; -#endif +#endif err: ret = OQS_ERROR; goto cleanup; From 7d20dc0052d4a12bc138ec46711514b1584f4d89 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 23 Jan 2024 07:13:17 +0000 Subject: [PATCH 03/10] Address unused variables --- src/sig_stfl/sig_stfl.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sig_stfl/sig_stfl.c b/src/sig_stfl/sig_stfl.c index dbf18f7e5c..0f6ebff7af 100644 --- a/src/sig_stfl/sig_stfl.c +++ b/src/sig_stfl/sig_stfl.c @@ -879,6 +879,9 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name) { OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)public_key; + (void)secret_key; return OQS_ERROR; #else if (sig == NULL || sig->keypair == NULL || sig->keypair(public_key, secret_key) != 0) { @@ -893,6 +896,12 @@ OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + (void)sig; + (void)signature; + (void)signature_len; + (void)message; + (void)message_len; + (void)secret_key; return OQS_ERROR; #else if (sig == NULL || sig->sign == NULL || sig->sign(signature, signature_len, message, message_len, secret_key) != 0) { From 9c89da50937d752d8ac089c1beb8cb3e9f444f2d Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Wed, 24 Jan 2024 14:30:25 -0500 Subject: [PATCH 04/10] Update .CMake/alg_support.cmake Co-authored-by: Spencer Wilson --- .CMake/alg_support.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CMake/alg_support.cmake b/.CMake/alg_support.cmake index fe69445615..b0c8cf13db 100644 --- a/.CMake/alg_support.cmake +++ b/.CMake/alg_support.cmake @@ -466,7 +466,7 @@ else() endif() if(OQS_ALLOW_SFTL_KEY_AND_SIG_GEN STREQUAL "ON") - message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultanous sign operations.") + message(STATUS "Experimental stateful key and signature generation is enabled. Ensure secret keys are securely stored to prevent multiple simultaneous sign operations.") endif() if((OQS_MINIMAL_BUILD STREQUAL "ON")) From deff896a26e80c1f32eae6ba6148b2fb01226449 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Wed, 24 Jan 2024 14:30:46 -0500 Subject: [PATCH 05/10] Update CONFIGURE.md Co-authored-by: Spencer Wilson --- CONFIGURE.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CONFIGURE.md b/CONFIGURE.md index 9e77b3469b..f65d4492e7 100644 --- a/CONFIGURE.md +++ b/CONFIGURE.md @@ -114,15 +114,15 @@ When `OQS_USE_OPENSSL` is `ON`, CMake also scans the filesystem to find the mini ## Stateful Hash Based Signatures -XMSS and LMS are the two supported Hash-Based Signatures schemes -OQS_ENABLE_SIG_STFL_XMSS and OQS_ENABLE_SIG_STFL_LMS contorl these algorithms which are disabled by default. -A thrid variable, OQS_ENABLE_SIG_STFL_KEY_SIG_GEN also controls the ability to generate keys and signatures. This is also disabled by efault. +XMSS and LMS are the two supported Hash-Based Signatures schemes. +`OQS_ENABLE_SIG_STFL_XMSS` and `OQS_ENABLE_SIG_STFL_LMS` control these algorithms, which are disabled by default. +A thrid variable, `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN`, also controls the ability to generate keys and signatures. This is also disabled by default. Each of these variables can be set to `ON` or `OFF`. -When all three are `ON`, stateful signatures is fully functional and can generate key-pairs, sign data, and verify signatures. -If OQS_ENABLE_SIG_STFL_KEY_SIG_GEN is `OFF` signature verification is the only functioanl operation. +When all three are `ON`, stateful signatures are fully functional and can generate key pairs, sign data, and verify signatures. +If `OQS_ENABLE_SIG_STFL_KEY_SIG_GEN` is `OFF` signature verification is the only functional operation. -Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in-order to best enforce the one-time use of secret keys. -Keys stored in a file system is extreamly susceptible to simultaneous use. +Standards bodies, such as NIST, recommend that key and signature generation only by done in hardware in order to best enforce the one-time use of secret keys. +Keys stored in a file system are extremely susceptible to simultaneous use. When enabled in this library a warning message will be generated by the config process. By default, From 7e231879d1f6704b1f8afc880bf71a9aa8b8b871 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Thu, 25 Jan 2024 01:52:57 -0500 Subject: [PATCH 06/10] Update example_sig_stfl.c Fixed compile error, unused function. Added a negative test when stateful signature is disabled. --- tests/example_sig_stfl.c | 41 ++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/tests/example_sig_stfl.c b/tests/example_sig_stfl.c index 74ff1004c4..cdcd9f6472 100644 --- a/tests/example_sig_stfl.c +++ b/tests/example_sig_stfl.c @@ -122,26 +122,43 @@ static OQS_STATUS stfl_example(char *method_name) { int main(void) { #ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN + OQS_init(); printf("Stateful signature algorithms key and signature generation is not enabled.\n"); - return EXIT_SUCCESS; + if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_ERROR && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_ERROR) { + OQS_destroy(); + return EXIT_SUCCESS; + } else { + OQS_destroy(); + return EXIT_FAILURE; + } #else + OQS_STATUS lms_status; + OQS_STATUS xmss_status; OQS_init(); -# if defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) && defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) - if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS && stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { -# elif defined(OQS_ALLOW_XMSS_KEY_AND_SIG_GEN) - OQS_init(); - if (stfl_example((char *)"XMSS-SHA2_10_256") == OQS_SUCCESS) { -# elif defined(OQS_ALLOW_LMS_KEY_AND_SIG_GEN) - if ( stfl_example((char *)"LMS_SHA256_H10_W4") == OQS_SUCCESS) { -# else - if ( stfl_example((char *)"") == OQS_SUCCESS) { + xmss_status = stfl_example((char *)"XMSS-SHA2_10_256"); + lms_status = stfl_example((char *)"LMS_SHA256_H10_W4"); + OQS_destroy(); + +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + if (xmss_status == OQS_ERROR) { + xmss_status = OQS_SUCCESS; + } else { + xmss_status = OQS_ERROR; + } #endif - OQS_destroy(); +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + if (lms_status == OQS_ERROR) { + lms_status = OQS_SUCCESS; + } else { + lms_status = OQS_ERROR; + } +#endif + if ((xmss_status == OQS_SUCCESS) && (lms_status == OQS_SUCCESS)) { return EXIT_SUCCESS; } else { - OQS_destroy(); return EXIT_FAILURE; } #endif } + From 34d35cd8dd38e713620b9ea76013a5714a4214cb Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 29 Jan 2024 01:53:48 -0500 Subject: [PATCH 07/10] Fix build error. Allow some key generation tests to run as negative tests when key and sig gen is off --- src/sig_stfl/lms/sig_stfl_lms_functions.c | 4 + .../xmss/sig_stfl_xmss_secret_key_functions.c | 4 + tests/test_sig_stfl.c | 91 ++++++++++++++++--- 3 files changed, 86 insertions(+), 13 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index d2d0aa157a..939666c1ef 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -740,6 +740,10 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ return OQS_ERROR; } +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + return OQS_ERROR; +#endif + aux_buf_len = sk_len - lms_sk_len; if (sk->secret_key_data) { // Key data already present diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 40ad786c4e..8f184983ed 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -112,6 +112,10 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t /* Deserialize XMSS byte string into an XMSS secret key data. */ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + return OQS_ERROR; +#endif + if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { return OQS_ERROR; } diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 4dc81cbbc6..d6fba8720a 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -947,7 +947,7 @@ typedef struct thread_data { const char *alg_name; const char *katfile; OQS_STATUS rc; - OQS_STATUS rc1; + // OQS_STATUS rc1; } thread_data_t; typedef struct lock_test_data { @@ -980,19 +980,48 @@ void *test_create_keys(void *arg) { return NULL; } -void *test_wrapper(void *arg) { +void *test_correctness_wrapper(void *arg) { struct thread_data *td = arg; td->rc = sig_stfl_test_correctness(td->alg_name, td->katfile); - td->rc1 = sig_stfl_test_secret_key(td->alg_name, td->katfile); return NULL; } + +void *test_secret_key_wrapper(void *arg) { + struct thread_data *td = arg; + td->rc = sig_stfl_test_secret_key(td->alg_name, td->katfile); + return NULL; +} +#endif + +/* + * When key and signature generation is off + * these operations should fail. So flip the results. + */ +static OQS_STATUS update_test_result( OQS_STATUS rc, int xmss_or_lms) { + OQS_STATUS rc_update = rc; + if (xmss_or_lms) { + ; +#ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN + if (rc_update == OQS_ERROR) { + rc_update = OQS_SUCCESS; + } else { + rc_update = OQS_ERROR; + } #endif + } else { + ; +#ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN + if (rc_update == OQS_ERROR) { + rc_update = OQS_SUCCESS; + } else { + rc_update = OQS_ERROR; + } +#endif + } + return rc_update; +} int main(int argc, char **argv) { -#ifndef OQS_ALLOW_SFTL_KEY_AND_SIG_GEN - printf("Stateful signature algorithms key and signature generation is not enabled.\n"); - return EXIT_SUCCESS; -#else OQS_init(); oqs_fstore_init(); @@ -1016,12 +1045,32 @@ int main(int argc, char **argv) { const char *alg_name = argv[1]; const char *katfile = argv[2]; + int is_xmss = 0; + if (strstr(alg_name, "XMSS") != NULL) { + is_xmss = 1; + } + /* + * Tests executed by CI/DI only run algoritms that have been emabled. + * + */ if (!OQS_SIG_STFL_alg_is_enabled(alg_name)) { printf("Stateful signature algorithm %s not enabled!\n", alg_name); OQS_destroy(); - return EXIT_FAILURE; - } + if (is_xmss) { +#ifndef OQS_ENABLE_SIG_STFL_XMSS + return EXIT_SUCCESS; +#else + return EXIT_FAILURE; +#endif + } else { +#ifndef OQS_ENABLE_SIG_STFL_LMS + return EXIT_SUCCESS; +#else + return EXIT_FAILURE; +#endif + } + } #ifdef OQS_ENABLE_TEST_CONSTANT_TIME OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); @@ -1041,7 +1090,9 @@ int main(int argc, char **argv) { pthread_t sign_key_thread; pthread_t query_key_thread; - thread_data_t td = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR, .rc1 = OQS_ERROR}; + thread_data_t td = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + thread_data_t td_2 = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; + lock_test_data_t td_create = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; lock_test_data_t td_sign = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; lock_test_data_t td_query = {.alg_name = alg_name, .katfile = katfile, .rc = OQS_ERROR}; @@ -1061,14 +1112,23 @@ int main(int argc, char **argv) { goto err; } - if (pthread_create(&thread, NULL, test_wrapper, &td)) { + if (pthread_create(&thread, NULL, test_correctness_wrapper, &td)) { fprintf(stderr, "ERROR: Creating pthread for test_wrapper\n"); exit_status = EXIT_FAILURE; goto err; } pthread_join(thread, NULL); rc = td.rc; - rc1 = td.rc1; + rc = update_test_result(rc, is_xmss); + + if (pthread_create(&thread, NULL, test_secret_key_wrapper, &td_2)) { + fprintf(stderr, "ERROR: Creating pthread for test_wrapper_2\n"); + exit_status = EXIT_FAILURE; + goto err; + } + pthread_join(thread, NULL); + rc1 = td_2.rc; + rc1 = update_test_result(rc1, is_xmss); if (pthread_create(&create_key_thread, NULL, test_create_keys, &td_create)) { fprintf(stderr, "ERROR: Creating pthread for test_create_keys\n"); @@ -1077,6 +1137,7 @@ int main(int argc, char **argv) { } pthread_join(create_key_thread, NULL); rc_create = td_create.rc; + rc_create = update_test_result(rc_create, is_xmss); if (pthread_create(&sign_key_thread, NULL, test_sig_gen, &td_sign)) { fprintf(stderr, "ERROR: Creating pthread for test_sig_gen\n"); @@ -1085,6 +1146,7 @@ int main(int argc, char **argv) { } pthread_join(sign_key_thread, NULL); rc_sign = td_sign.rc; + rc_sign = update_test_result(rc_sign, is_xmss); if (pthread_create(&query_key_thread, NULL, test_query_key, &td_query)) { fprintf(stderr, "ERROR: Creating pthread for test_query_key\n"); @@ -1093,6 +1155,7 @@ int main(int argc, char **argv) { } pthread_join(query_key_thread, NULL); rc_query = td_query.rc; + rc_query = update_test_result(rc_query, is_xmss); err: if (test_sk_lock) { @@ -1125,11 +1188,13 @@ int main(int argc, char **argv) { rc1 = sig_stfl_test_secret_key(alg_name, katfile); OQS_destroy(); + rc = update_test_result(rc, is_xmss); + rc1 = update_test_result(rc1, is_xmss); + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { return EXIT_FAILURE; } return exit_status; #endif -#endif //OQS_ALLOW_SFTL_KEY_AND_SIG_GEN } From b982601c56661999968949202eeee1eb6ea9df46 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 29 Jan 2024 06:59:44 +0000 Subject: [PATCH 08/10] Fix format --- src/sig_stfl/lms/sig_stfl_lms_functions.c | 2 +- .../xmss/sig_stfl_xmss_secret_key_functions.c | 4 +-- tests/test_sig_stfl.c | 28 +++++++++---------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 939666c1ef..d0b1559e2d 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -742,7 +742,7 @@ OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_ #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN return OQS_ERROR; -#endif +#endif aux_buf_len = sk_len - lms_sk_len; if (sk->secret_key_data) { diff --git a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c index 8f184983ed..4f6413a98b 100644 --- a/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c +++ b/src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c @@ -113,8 +113,8 @@ OQS_STATUS OQS_SECRET_KEY_XMSS_inner_serialize_key(uint8_t **sk_buf_ptr, size_t /* Deserialize XMSS byte string into an XMSS secret key data. */ OQS_STATUS OQS_SECRET_KEY_XMSS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf, XMSS_UNUSED_ATT void *context) { #ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN - return OQS_ERROR; -#endif + return OQS_ERROR; +#endif if (sk == NULL || sk_buf == NULL || (sk_len != sk->length_secret_key)) { return OQS_ERROR; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index d6fba8720a..d45684277e 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -1002,22 +1002,22 @@ static OQS_STATUS update_test_result( OQS_STATUS rc, int xmss_or_lms) { if (xmss_or_lms) { ; #ifndef OQS_ALLOW_XMSS_KEY_AND_SIG_GEN - if (rc_update == OQS_ERROR) { + if (rc_update == OQS_ERROR) { rc_update = OQS_SUCCESS; } else { rc_update = OQS_ERROR; } #endif - } else { + } else { ; #ifndef OQS_ALLOW_LMS_KEY_AND_SIG_GEN - if (rc_update == OQS_ERROR) { + if (rc_update == OQS_ERROR) { rc_update = OQS_SUCCESS; } else { rc_update = OQS_ERROR; } -#endif - } +#endif + } return rc_update; } @@ -1048,7 +1048,7 @@ int main(int argc, char **argv) { int is_xmss = 0; if (strstr(alg_name, "XMSS") != NULL) { is_xmss = 1; - } + } /* * Tests executed by CI/DI only run algoritms that have been emabled. @@ -1059,18 +1059,18 @@ int main(int argc, char **argv) { OQS_destroy(); if (is_xmss) { #ifndef OQS_ENABLE_SIG_STFL_XMSS - return EXIT_SUCCESS; + return EXIT_SUCCESS; #else - return EXIT_FAILURE; + return EXIT_FAILURE; #endif - } else { + } else { #ifndef OQS_ENABLE_SIG_STFL_LMS return EXIT_SUCCESS; #else - return EXIT_FAILURE; -#endif - } - } + return EXIT_FAILURE; +#endif + } + } #ifdef OQS_ENABLE_TEST_CONSTANT_TIME OQS_randombytes_custom_algorithm(&TEST_SIG_STFL_randombytes); @@ -1190,7 +1190,7 @@ int main(int argc, char **argv) { OQS_destroy(); rc = update_test_result(rc, is_xmss); rc1 = update_test_result(rc1, is_xmss); - + if (rc != OQS_SUCCESS || rc1 != OQS_SUCCESS) { return EXIT_FAILURE; From 89d41d6bcee9a7565b7973e1dc886192aa7980d7 Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 29 Jan 2024 07:22:55 +0000 Subject: [PATCH 09/10] Fix build error --- tests/test_sig_stfl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index d45684277e..f34bb63675 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -321,9 +321,10 @@ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_ } else { goto from_keygen; } - +#ifdef OQS_ENABLE_SIG_STFL_XMSS from_kats: return sig_stfl_keypair_from_KATs(sig, public_key, secret_key, katfile); +#endif from_keygen: return sig_stfl_keypair_from_keygen(sig, public_key, secret_key); From 79e9457caed4a7d2203ea376772dae77da65ad8f Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Mon, 29 Jan 2024 13:14:39 +0000 Subject: [PATCH 10/10] Fix build error --- tests/test_sig_stfl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index f34bb63675..f0a51aac74 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -327,6 +327,7 @@ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_ #endif from_keygen: + (void)(katfile); return sig_stfl_keypair_from_keygen(sig, public_key, secret_key); }