From ab2eb39daf4eae3849dd3602b5773815201dd19c Mon Sep 17 00:00:00 2001 From: Norman Ashley Date: Tue, 29 Aug 2023 15:48:49 -0400 Subject: [PATCH] LMS updated to use new SK API (#1533) * Use secret key struct in LMS. Update de/serialize sk API * Updates per comments * Update per comments * Fix mem leak * Address scan bild issue * Removed unused variable * Remove unused struc member * Address macOS-noopenssl build failures --- src/sig_stfl/lms/sig_stfl_lms.c | 65 +++-- src/sig_stfl/lms/sig_stfl_lms.h | 25 +- src/sig_stfl/lms/sig_stfl_lms_functions.c | 277 +++++++++++++++++++--- src/sig_stfl/lms/sig_stfl_lms_wrap.h | 26 -- src/sig_stfl/sig_stfl.h | 20 +- tests/kat_sig_stfl.c | 14 +- tests/test_sig_stfl.c | 102 +++++++- 7 files changed, 421 insertions(+), 108 deletions(-) diff --git a/src/sig_stfl/lms/sig_stfl_lms.c b/src/sig_stfl/lms/sig_stfl_lms.c index dde8dc586f..1a0831f39d 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.c +++ b/src/sig_stfl/lms/sig_stfl_lms.c @@ -10,7 +10,7 @@ // ======================== LMS-SHA256 H5/W1 ======================== // -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (secret_key == NULL || public_key == NULL) { return OQS_ERROR; } @@ -60,34 +60,55 @@ OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void) { // Initialize the key with length_secret_key amount of bytes. sk->length_secret_key = OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk; - if (sk->length_secret_key) { - sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); - if (sk->secret_key_data) { - memset(sk->secret_key_data, 0, sk->length_secret_key); - } else { - OQS_SECRET_KEY_LMS_free(sk); - OQS_MEM_insecure_free(sk); - sk = NULL; - return NULL; - } - } + /* Function that returns the total number of signatures for the secret key */ + sk->sigs_total = NULL; + + /* set Function to returns the number of signatures left for the secret key */ + sk->sigs_left = NULL; + + /* + * Secret Key retrieval Function + */ + sk->serialize_key = OQS_SECRET_KEY_LMS_serialize_key; + + /* + * set Secret Key to internal structure Function + */ + sk->deserialize_key = OQS_SECRET_KEY_LMS_deserialize_key; + + /* + * Set Secret Key Locking Function + */ + sk->lock_key = NULL; + + /* + * Set Secret Key Unlocking / Releasing Function + */ + sk->unlock_key = NULL; + /* + * Set Secret Key Saving Function + */ + sk->save_secret_key = NULL; + + /* + * Set Secret Key free function + */ sk->free_key = OQS_SECRET_KEY_LMS_free; return sk; } void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) { - if (sk == NULL) { - return; - } + oqs_secret_lms_key_free(sk); +} - //TODO: cleanup lock_key +/* Convert LMS secret key object to byte string */ +size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf) { + return oqs_serialize_lms_key(sk, sk_buf); +} - if (sk->sig) { - OQS_MEM_insecure_free(sk->sig); - sk->sig = NULL; - } - OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key); - sk->secret_key_data = NULL; +/* Insert lms byte string in an LMS secret key object */ +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { + return oqs_deserialize_lms_key(sk, key_len, sk_buf); } diff --git a/src/sig_stfl/lms/sig_stfl_lms.h b/src/sig_stfl/lms/sig_stfl_lms.h index 97104b47f8..ab32848ac8 100644 --- a/src/sig_stfl/lms/sig_stfl_lms.h +++ b/src/sig_stfl/lms/sig_stfl_lms.h @@ -10,32 +10,43 @@ #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_pk 60 #define OQS_SIG_STFL_alg_lms_sha256_h5_w1_length_sk 64 -OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key); OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_LMS_SHA256_H5_W1_new(void); + +/* Convert LMS secret key object to byte string */ +size_t OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); + +/* Insert lms byte string in an LMS secret key object */ +OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); + OQS_SIG_STFL *OQS_SIG_STFL_alg_lms_sha256_h5_w1_new(void); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key); -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const uint8_t *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key); +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key); void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk); // ----------------------------------- WRAPPER FUNCTIONS ------------------------------------------------ -int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid); +int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid); -int oqs_sig_stfl_lms_sign(uint8_t *sk, uint8_t *sm, size_t *smlen, +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); int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, size_t smlen, const uint8_t *pk); +void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk); + +size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key); +int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); + // ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT ----------------------------------------- -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, uint8_t *secret_key); +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_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); - // -------------------------------------------------------------------------------------------------------- #endif /* OQS_SIG_STFL_LMS_H */ diff --git a/src/sig_stfl/lms/sig_stfl_lms_functions.c b/src/sig_stfl/lms/sig_stfl_lms_functions.c index 8c17ddddd0..da7f865c07 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_functions.c +++ b/src/sig_stfl/lms/sig_stfl_lms_functions.c @@ -9,8 +9,40 @@ #include "sig_stfl_lms_wrap.h" #include +#define DEFAULT_AUX_DATA 10916 /* Use 10+k of aux data (which works well */ +/* with the above default parameter set) */ +/** + * @brief OQS_LMS_KEY object for HSS key pair + */ + +typedef struct OQS_LMS_KEY_DATA { + + /* Tree levels. */ + uint32_t levels; + + /* Array, 8 levels max, of LMS types */ + param_set_t lm_type[8]; + + /* Array, 8 levels max, of LM OTS types */ + param_set_t lm_ots_type[8]; + + /* LMS public key */ + uint8_t public_key[60]; + + /* Length of aux data */ + size_t len_aux_data; + /* internal nodes info of the Merkle tree */ + uint8_t *aux_data; + + /* Length of sec_key */ + size_t len_sec_key; + + /* secret key data */ + uint8_t *sec_key; +} oqs_lms_key_data; + 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, uint8_t *secret_key) { + size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key) { if (secret_key == NULL || message == NULL || signature == NULL) { return OQS_ERROR; @@ -45,7 +77,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t me return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (remain == NULL || secret_key == NULL) { return OQS_ERROR; @@ -55,7 +87,7 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const return OQS_SUCCESS; } -OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const uint8_t *secret_key) { +OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(uint64_t *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) { if (total == NULL || secret_key == NULL) { return OQS_ERROR; @@ -75,41 +107,78 @@ bool LMS_randombytes(void *buffer, size_t length) { return true; } -int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { +int oqs_sig_stfl_lms_keypair(uint8_t *pk, OQS_SIG_STFL_SECRET_KEY *sk, const uint32_t oid) { int ret = -1; bool b_ret; int parse_err = 0; - unsigned levels = 1; - unsigned char public_key[60]; size_t len_public_key = 60; - unsigned char *aux_data = NULL; - size_t max_aux_data = 10916; - int aux_len = 0; - oqs_lms_key_data *oqs_data = NULL; - - param_set_t lm_type[1]; - param_set_t lm_ots_type[1]; + oqs_lms_key_data *oqs_key_data = NULL; if (!pk || !sk || !oid) { return -1; } + if (sk->secret_key_data) { + //this means a key pair has already been recreated + //TODO log error. + return -1; + } + + oqs_key_data = malloc(sizeof(oqs_lms_key_data)); + if (oqs_key_data) { + oqs_key_data->levels = 1; + if (sk->length_secret_key) { + oqs_key_data->len_sec_key = sk->length_secret_key; + oqs_key_data->sec_key = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t)); + if (oqs_key_data->sec_key) { + memset(oqs_key_data->sec_key, 0, sk->length_secret_key); + } else { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; + } + } else { + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; + } + + //Aux Data + size_t len_aux_data = DEFAULT_AUX_DATA; + uint8_t *aux_data = malloc(sizeof(uint8_t) * len_aux_data); + if (aux_data) { + oqs_key_data->aux_data = aux_data; + oqs_key_data->len_aux_data = len_aux_data; + } else { + OQS_MEM_insecure_free( oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data); + return -1; + } + } else { + //TODO log error + return -1; + } + /* Set lms param set */ switch (oid) { case 0x1: - lm_type[0] = LMS_SHA256_N32_H5; - lm_ots_type[0] = LMOTS_SHA256_N32_W1; + oqs_key_data->lm_type[0] = LMS_SHA256_N32_H5; + oqs_key_data->lm_ots_type[0] = LMOTS_SHA256_N32_W1; break; default: - lm_type[0] = 0; - lm_ots_type[0] = 0; + oqs_key_data->lm_type[0] = 0; + oqs_key_data->lm_ots_type[0] = 0; parse_err = 1; break; } if (parse_err) { + OQS_MEM_insecure_free(oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data->aux_data); + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; return -1; } @@ -145,16 +214,23 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { */ b_ret = hss_generate_private_key( LMS_randombytes, - levels, - lm_type, - lm_ots_type, + oqs_key_data->levels, + oqs_key_data->lm_type, + oqs_key_data->lm_ots_type, NULL, //File handler function? - (void *)sk, - public_key, len_public_key, - aux_data, aux_len, + oqs_key_data->sec_key, + oqs_key_data->public_key, len_public_key, + oqs_key_data->aux_data, oqs_key_data->len_aux_data, NULL); if (b_ret) { - memcpy(pk, public_key, len_public_key); + memcpy(pk, oqs_key_data->public_key, len_public_key); + sk->secret_key_data = oqs_key_data; + } else { + OQS_MEM_insecure_free(oqs_key_data->sec_key); + OQS_MEM_insecure_free(oqs_key_data->aux_data); + OQS_MEM_insecure_free(oqs_key_data); + oqs_key_data = NULL; + return -1; } /* TODO: store key pair, file handler */ @@ -163,16 +239,24 @@ int oqs_sig_stfl_lms_keypair(uint8_t *pk, uint8_t *sk, const uint32_t oid) { return ret; } -int oqs_sig_stfl_lms_sign(uint8_t *sk, +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) { size_t sig_len; bool status; - unsigned char *sig = NULL; + uint8_t *sig = NULL; + uint8_t *priv_key = NULL; + oqs_lms_key_data *oqs_key_data = NULL; struct hss_working_key *w = NULL; struct hss_sign_inc ctx; - w = hss_load_private_key(NULL, sk, + if (sk) { + oqs_key_data = sk->secret_key_data; + priv_key = oqs_key_data->sec_key; + } else { + return -1; + } + w = hss_load_private_key(NULL, priv_key, 0, NULL, 0, @@ -205,7 +289,7 @@ int oqs_sig_stfl_lms_sign(uint8_t *sk, &ctx, /* Incremental signing context */ w, /* Working key */ NULL, /* Routine to update the */ - sk, /* private key */ + priv_key, /* private key */ sig, sig_len, /* Where to place the signature */ 0); @@ -264,3 +348,140 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, } } +void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) { + if (sk == NULL) { + return; + } + + //TODO: cleanup lock_key + + if (sk->sig) { + OQS_MEM_insecure_free(sk->sig); + sk->sig = NULL; + } + + if (sk->secret_key_data) { + oqs_lms_key_data *key_data = (oqs_lms_key_data *)sk->secret_key_data; + if (key_data) { + OQS_MEM_secure_free(key_data->sec_key, key_data->len_sec_key); + key_data->sec_key = NULL; + + OQS_MEM_secure_free(key_data->aux_data, key_data->len_aux_data); + } + + OQS_MEM_insecure_free(key_data); + sk->secret_key_data = NULL; + } +} + +/* + * Convert LMS secret key object to byte string + * Writes secret key + aux data if present + */ +size_t oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_key) { + + oqs_lms_key_data *lms_key_data = NULL; + size_t key_len = 0; + if (sk) { + uint8_t *sk_key_buf = NULL; + lms_key_data = sk->secret_key_data; + if (lms_key_data && lms_key_data->sec_key) { + size_t buf_size_needed = lms_key_data->len_aux_data + lms_key_data->len_sec_key; + key_len = buf_size_needed; + /* pass back serialized data */ + if (sk_key) { + if (buf_size_needed) { + sk_key_buf = malloc(buf_size_needed * sizeof(uint8_t)); + if (sk_key_buf) { + + /* + * Serialized data is sec_key followed by aux data + * So aux data begins after buffer top + sec_key length + */ + if (lms_key_data->len_sec_key) { + memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key); + } + + if (lms_key_data->len_aux_data) { + memcpy(sk_key_buf + lms_key_data->len_sec_key, lms_key_data->aux_data, lms_key_data->len_aux_data); + } + + *sk_key = sk_key_buf; + key_len = sk->length_secret_key + lms_key_data->len_aux_data; + } + } + } //sk_key + } + } //sk + return key_len; +} + +/* + * Convert LMS byte string to secret key object + * Writes secret key + aux data if present + * key_len is priv key length + aux length + */ +int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf) { + int oqs_status = -1; + oqs_lms_key_data *lms_key_data = NULL; + uint8_t priv_ky_len = hss_get_private_key_len((unsigned )(1), NULL, NULL); + + if ((!sk) || (key_len == 0) || (key_len < priv_ky_len) || (!sk_buf)) { + return oqs_status; + } + + if (sk->secret_key_data) { + //Key data already present + //We dont want to trample over data + return oqs_status; + } + + uint8_t *lms_sk = NULL; + uint8_t *lms_aux = NULL; + + unsigned levels = 0; + + int key_buf_left = key_len - priv_ky_len; + + param_set_t lm_type[ MAX_HSS_LEVELS ]; + param_set_t lm_ots_type[ MAX_HSS_LEVELS ]; + + // validate sk_buf for lms params + if (hss_get_parameter_set(&levels, + lm_type, + lm_ots_type, + NULL, + (void *)sk_buf)) { + return oqs_status; + } + + lms_key_data = malloc(sizeof(oqs_lms_key_data)); + if (lms_key_data) { + lms_sk = malloc(priv_ky_len * sizeof(uint8_t)); + if (lms_sk) { + memcpy(lms_sk, sk_buf, priv_ky_len); + lms_key_data->sec_key = lms_sk; + lms_key_data->len_sec_key = priv_ky_len; + } else { + OQS_MEM_insecure_free(lms_key_data); + return oqs_status; + } + + if (key_buf_left) { + lms_aux = malloc(key_buf_left * sizeof(uint8_t)); + if (lms_aux) { + memcpy(lms_aux, (sk_buf + priv_ky_len), key_buf_left); + lms_key_data->aux_data = lms_aux; + lms_key_data->len_aux_data = key_buf_left; + } else { + OQS_MEM_insecure_free(lms_key_data); + OQS_MEM_insecure_free(lms_sk); + return oqs_status; + } + } + + sk->secret_key_data = lms_key_data; + oqs_status = 0; + } + return oqs_status; +} diff --git a/src/sig_stfl/lms/sig_stfl_lms_wrap.h b/src/sig_stfl/lms/sig_stfl_lms_wrap.h index 043de2c461..1d5486d21a 100644 --- a/src/sig_stfl/lms/sig_stfl_lms_wrap.h +++ b/src/sig_stfl/lms/sig_stfl_lms_wrap.h @@ -13,32 +13,6 @@ */ typedef struct OQS_LMS_KEY_DATA oqs_lms_key_data; -typedef struct OQS_LMS_KEY_DATA { - - /* Tree levels. */ - unsigned levels; - - /* Array, 8 levels max, of LMS types */ - param_set_t lm_type[8]; - - /* Array, 8 levels max, of LM OTS types */ - param_set_t lm_ots_type[8]; - - /* LMS public key */ - unsigned char public_key[60]; - - /* internal nodes info of the Merkle tree */ - unsigned char *aux_data; - - /* Length of aux data */ - size_t len_aux_data; - - /* User defined data that may be used for the SAFETY functions */ - void *data; - -} oqs_lms_key_data; - - typedef struct OQS_LMS_SIG_DATA oqs_lms_sig_data; typedef struct OQS_LMS_SIG_DATA { diff --git a/src/sig_stfl/sig_stfl.h b/src/sig_stfl/sig_stfl.h index b795853c5c..a3423a667b 100644 --- a/src/sig_stfl/sig_stfl.h +++ b/src/sig_stfl/sig_stfl.h @@ -206,21 +206,23 @@ typedef struct OQS_SIG_STFL_SECRET_KEY { * Secret Key retrieval Function * * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] key_len length of the returned byte string - * @returns newly created pointer to ley byte string if none-zero length. Caller - * deletes the buffer. + * @param[out] sk_buf private key data as a byte stream + * @returns length of key material data available + * Caller deletes the buffer if memory was allocated. */ - uint8_t *(*serialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len); + size_t (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf); /** * set Secret Key to internal structure Function * - * @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object - * @param[out] key_len length of the returned byte string - * @returns newly created pointer to ley byte string if none-zero length. Caller - * deletes the buffer. + * @param[in] sk OQS_SIG_STFL_SECRET_KEY object + * @param[in] key_len length of the returned byte string + * @param[in] sk_key The secret key represented as OQS_SIG_STFL_SECRET_KEY object + * @param[in] key_len length of the returned byte string + * @returns status of the operation populated with key material none-zero length. Caller + * deletes the buffer. if sk_buf is NULL the function returns the length */ - uint8_t *(*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, uint8_t *sk_key); + OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf); /** * Secret Key Locking Function diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index ebb89c14e8..a65bc66a53 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -64,7 +64,8 @@ int FindMarker(FILE *infile, const char *marker) { // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { - int i, ch, started; + int ch, started; + unsigned long i; unsigned char ich; if (Length == 0) { @@ -121,19 +122,8 @@ void fprintBstr(FILE *fp, const char *S, const uint8_t *A, size_t L) { fprintf(fp, "\n"); } -static inline uint16_t UINT16_TO_BE(const uint16_t x) { - union { - uint16_t val; - uint8_t bytes[2]; - } y; - y.bytes[0] = (x >> 8) & 0xFF; - y.bytes[1] = x & 0xFF; - return y.val; -} - OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { - uint8_t entropy_input[48]; uint8_t seed[48]; FILE *fh = NULL; FILE *fp_rsp = NULL; diff --git a/tests/test_sig_stfl.c b/tests/test_sig_stfl.c index 770eb58f82..b496457b99 100644 --- a/tests/test_sig_stfl.c +++ b/tests/test_sig_stfl.c @@ -78,7 +78,8 @@ int FindMarker(FILE *infile, const char *marker) { // ALLOW TO READ HEXADECIMAL ENTRY (KEYS, DATA, TEXT, etc.) // int ReadHex(FILE *infile, unsigned char *a, unsigned long Length, char *str) { - int i, ch, started; + int ch, started; + unsigned long i; unsigned char ich; if (Length == 0) { @@ -178,7 +179,7 @@ OQS_STATUS sig_stfl_keypair_from_KATs(OQS_SIG_STFL *sig, uint8_t *public_key, OQ */ OQS_STATUS sig_stfl_KATs_keygen(OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key, const char *katfile) { - printf("%s", sig->method_name); + printf("%s ", sig->method_name); if (0) { #ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 @@ -379,6 +380,93 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { OQS_STATUS rc = OQS_SUCCESS; OQS_SIG_STFL_SECRET_KEY *sk = NULL; + OQS_SIG_STFL *sig_obj = NULL; + uint8_t *public_key = NULL; + + /* + * Temporarily skip algs with long key generation times. + */ + + if (0) { + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h16 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h16) == 0) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h20 + } else if (strcmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h20) == 0) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake128_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake128_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_sha512_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha512_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h16 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h16)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmss_shake256_h20 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_shake256_h20)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_sha256_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_sha256_h60_3)) { + goto skip_test; +#endif + +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h40_2 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h40_2)) { + goto skip_test; +#endif +#ifdef OQS_ENABLE_SIG_STFL_xmssmt_shake128_h60_3 + } else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmssmt_shake128_h60_3)) { + goto skip_test; +#endif + } else { + goto keep_going; + } +skip_test: + printf("Skip slow test %s.\n", method_name); + return rc; + +keep_going: + + printf("================================================================================\n"); + printf("Create stateful Signature %s\n", method_name); + printf("================================================================================\n"); + + sig_obj = OQS_SIG_STFL_new(method_name); + if (sig_obj == NULL) { + fprintf(stderr, "ERROR: OQS_SIG_STFL_new failed\n"); + goto err; + } + + public_key = malloc(sig_obj->length_public_key * sizeof(uint8_t)); + + printf("================================================================================\n"); + printf("Create stateful Secret Key %s\n", method_name); + printf("================================================================================\n"); + sk = OQS_SIG_STFL_SECRET_KEY_new(method_name); if (sk == NULL) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new failed\n"); @@ -386,21 +474,27 @@ static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) { } printf("================================================================================\n"); - printf("Create stateful Secret Key %s\n", method_name); + printf("Generate keypair %s\n", method_name); printf("================================================================================\n"); + rc = OQS_SIG_STFL_keypair(sig_obj, public_key, sk); + if (!sk->secret_key_data) { fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n"); + OQS_MEM_insecure_free(public_key); goto err; } - OQS_SIG_STFL_SECRET_KEY_free(sk); printf("Secret Key created as expected.\n"); goto end_it; err: rc = OQS_ERROR; end_it: + + OQS_SIG_STFL_SECRET_KEY_free(sk); + OQS_MEM_insecure_free(public_key); + OQS_SIG_STFL_free(sig_obj); return rc; }