Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable Stateful Signatures in the build by default #1676

Merged
merged 10 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .CMake/alg_support.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 simultaneous sign operations.")
endif()

if((OQS_MINIMAL_BUILD STREQUAL "ON"))
message(FATAL_ERROR "OQS_MINIMAL_BUILD option ${OQS_MINIMAL_BUILD} no longer supported")
Expand Down
20 changes: 20 additions & 0 deletions CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` 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 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 are extremely 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.
Expand Down
4 changes: 4 additions & 0 deletions src/oqsconfig.h.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions src/sig_stfl/lms/external/hss_keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "hss_thread.h"
#include "lm_common.h"
#include "lm_ots_common.h"
#include <oqs/oqsconfig.h>

/* 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 */
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -356,6 +358,7 @@ bool hss_generate_private_key(
free(temp_buffer); // IGNORE free-check
return true;
}
#endif

/*
* The length of the private key
Expand Down
3 changes: 3 additions & 0 deletions src/sig_stfl/lms/external/hss_sign_inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "hss_internal.h"
#include "hss_sign_inc.h"
#include "hss_derive.h"
#include <oqs/oqsconfig.h>

/*
* Start the process of creating an HSS signature incrementally. Parameters:
Expand All @@ -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,
Expand Down Expand Up @@ -217,3 +219,4 @@ bool hss_sign_finalize(
hss_zeroize( seed_buff, sizeof seed_buff );
return success;
}
#endif
30 changes: 30 additions & 0 deletions src/sig_stfl/lms/sig_stfl_lms_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) */
/**
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -714,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
Expand Down
17 changes: 17 additions & 0 deletions src/sig_stfl/sig_stfl.c
Original file line number Diff line number Diff line change
Expand Up @@ -878,21 +878,38 @@ 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) {
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
(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) {
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) {
Expand Down
22 changes: 22 additions & 0 deletions src/sig_stfl/xmss/external/xmss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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;
Expand All @@ -42,6 +55,7 @@ int xmss_keypair(unsigned char *pk, unsigned char *sk, const uint32_t oid)
}
return xmss_core_keypair(&params, 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
Expand All @@ -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)
Expand All @@ -73,6 +94,7 @@ int xmss_sign(unsigned char *sk,
}
return xmss_core_sign(&params, 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
Expand Down
8 changes: 7 additions & 1 deletion src/sig_stfl/xmss/sig_stfl_xmss_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {

Expand Down
4 changes: 4 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss_secret_key_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
8 changes: 7 additions & 1 deletion src/sig_stfl/xmss/sig_stfl_xmssmt_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {

Expand Down
Loading
Loading