Skip to content

Commit

Permalink
Add XMSS Serialize/Deserialize (#1542)
Browse files Browse the repository at this point in the history
* Add serialize and deserialize to XMSS
---------

Co-authored-by: Norman Ashley <[email protected]>
  • Loading branch information
2 people authored and SWilson4 committed May 14, 2024
1 parent 245aede commit 99067be
Show file tree
Hide file tree
Showing 36 changed files with 412 additions and 233 deletions.
9 changes: 4 additions & 5 deletions src/sig_stfl/lms/sig_stfl_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "sig_stfl_lms_wrap.h"
#include "sig_stfl_lms.h"


// ======================== LMS-SHA256 H5/W1 ======================== //

OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key) {
Expand Down Expand Up @@ -104,11 +103,11 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) {
}

/* 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);
OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr) {
return oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr);
}

/* 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);
OQS_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) {
return oqs_deserialize_lms_key(sk, sk_len, sk_buf);
}
10 changes: 5 additions & 5 deletions src/sig_stfl/lms/sig_stfl_lms.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sha256_h5_w1_keypair(uint8_t *public_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);
OQS_STATUS OQS_SECRET_KEY_LMS_serialize_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr);

/* 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_STATUS OQS_SECRET_KEY_LMS_deserialize_key(OQS_SIG_STFL_SECRET_KEY *sk, const 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 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);
OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *totaln, const OQS_SIG_STFL_SECRET_KEY *secret_key);

void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk);

Expand All @@ -38,8 +38,8 @@ int oqs_sig_stfl_lms_verify(const uint8_t *m, size_t mlen, const uint8_t *sm, si

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);
OQS_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_key);
OQS_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf);

// ---------------------------- FUNCTIONS INDEPENDENT OF VARIANT -----------------------------------------

Expand Down
157 changes: 83 additions & 74 deletions src/sig_stfl/lms/sig_stfl_lms_functions.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT

#include <string.h>
#include <oqs/oqs.h>
#include "sig_stfl_lms.h"
#include "external/config.h"
#include "external/hss_verify_inc.h"
Expand Down Expand Up @@ -87,7 +88,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 OQS_SIG_STFL_SECRET_KEY *secret_key) {
OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_total(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key) {

if (total == NULL || secret_key == NULL) {
return OQS_ERROR;
Expand Down Expand Up @@ -378,71 +379,74 @@ void oqs_secret_lms_key_free(OQS_SIG_STFL_SECRET_KEY *sk) {
* 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_STATUS oqs_serialize_lms_key(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, 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;
if (sk == NULL || sk_len == NULL || sk_key == NULL) {
return OQS_ERROR;
}

oqs_lms_key_data *lms_key_data = sk->secret_key_data;

if (lms_key_data == NULL || lms_key_data->sec_key == NULL) {
return OQS_ERROR;
}

size_t key_len = lms_key_data->len_aux_data + lms_key_data->len_sec_key;

if (key_len == 0) {
return OQS_ERROR;
}

uint8_t *sk_key_buf = malloc(key_len * sizeof(uint8_t));

if (sk_key_buf == NULL) {
return OQS_ERROR;
}
/* pass back serialized data */
/*
* 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 != 0) {
memcpy(sk_key_buf, lms_key_data->sec_key, lms_key_data->len_sec_key);
}

if (lms_key_data->len_aux_data != 0) {
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;
*sk_len = sk->length_secret_key + lms_key_data->len_aux_data;

return OQS_SUCCESS;
}

/*
* 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_STATUS oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf) {

oqs_lms_key_data *lms_key_data = NULL;
uint8_t priv_ky_len = hss_get_private_key_len((unsigned )(1), NULL, NULL);
uint8_t *lms_sk = NULL;
uint8_t *lms_aux = NULL;
int aux_buf_len = 0;
uint8_t lms_sk_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 == NULL || sk_buf == NULL || (sk_len == 0) || (sk_len < lms_sk_len )) {
return OQS_ERROR;
}

aux_buf_len = sk_len - lms_sk_len;
if (sk->secret_key_data) {
//Key data already present
//We dont want to trample over data
return oqs_status;
// Key data already present
// We dont want to trample over data
return OQS_ERROR;
}

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 ];

Expand All @@ -452,36 +456,41 @@ int oqs_deserialize_lms_key(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const u
lm_ots_type,
NULL,
(void *)sk_buf)) {
return oqs_status;
return OQS_ERROR;
}

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;
}
lms_sk = malloc(lms_sk_len * sizeof(uint8_t));

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;
}
if (lms_key_data == NULL || lms_sk == NULL) {
goto err;
}

memcpy(lms_sk, sk_buf, lms_sk_len);
lms_key_data->sec_key = lms_sk;
lms_key_data->len_sec_key = lms_sk_len;

if (aux_buf_len) {
lms_aux = malloc(aux_buf_len * sizeof(uint8_t));

if (lms_aux == NULL) {
goto err;
}

sk->secret_key_data = lms_key_data;
oqs_status = 0;
memcpy(lms_aux, sk_buf + lms_sk_len, aux_buf_len);
lms_key_data->aux_data = lms_aux;
lms_key_data->len_aux_data = aux_buf_len;
}
return oqs_status;

sk->secret_key_data = lms_key_data;
goto success;

err:
OQS_MEM_secure_free(lms_key_data, sizeof(oqs_lms_key_data));
OQS_MEM_secure_free(lms_sk, lms_sk_len);
OQS_MEM_secure_free(lms_aux, aux_buf_len);
return OQS_ERROR;

success:
return OQS_SUCCESS;
}
14 changes: 7 additions & 7 deletions src/sig_stfl/sig_stfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,23 +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] sk_buf private key data as a byte stream
* @param[out] sk_len length of private key as a byte stream
* @param[out] sk_buf_ptr pointer to private key data as a byte stream
* @returns length of key material data available
* Caller deletes the buffer if memory was allocated.
*/
size_t (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, uint8_t **sk_buf);
OQS_STATUS (*serialize_key)(const OQS_SIG_STFL_SECRET_KEY *sk, size_t *sk_len, uint8_t **sk_buf_ptr);

/**
* set Secret Key to internal structure Function
*
* @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
* @param[out] sk OQS_SIG_STFL_SECRET_KEY object
* @param[in] sk_len length of the returned byte string
* @param[in] sk_buf The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @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
*/
OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, const uint8_t *sk_buf);
OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const size_t sk_len, const uint8_t *sk_buf);

/**
* Secret Key Locking Function
Expand Down
3 changes: 3 additions & 0 deletions src/sig_stfl/xmss/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ set(SRCS external/core_hash.c
external/xmss_core_fast.c
)

add_library(sig_stfl_xmss_secret_key_functions OBJECT sig_stfl_xmss_secret_key_functions.c)
set(_XMSS_OBJS ${_XMSS_OBJS} $<TARGET_OBJECTS:sig_stfl_xmss_secret_key_functions>)

if (OQS_ENABLE_SIG_STFL_xmss_sha256_h10)
add_library(xmss_sha256_h10 OBJECT sig_stfl_xmss_sha256_h10.c ${SRCS})
target_compile_options(xmss_sha256_h10 PRIVATE -DXMSS_PARAMS_NAMESPACE=xmss_sha256_h10 -DHASH=3)
Expand Down
Loading

0 comments on commit 99067be

Please sign in to comment.