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

Add XMSS Serialize/Deserialize #1542

Merged
merged 13 commits into from
Sep 9, 2023
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
Loading