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

Na statful sig lock #1559

Merged
merged 6 commits into from
Sep 28, 2023
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
12 changes: 11 additions & 1 deletion src/sig_stfl/lms/sig_stfl_lms.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,17 @@ void OQS_SECRET_KEY_LMS_free(OQS_SIG_STFL_SECRET_KEY *sk) {

/* Convert LMS secret key object to byte string */
static 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);
OQS_STATUS status;
if (sk->lock_key && sk->mutex) {
sk->lock_key(sk->mutex);
}

status = oqs_serialize_lms_key(sk, sk_len, sk_buf_ptr);

if (sk->unlock_key && sk->mutex) {
sk->unlock_key(sk->mutex);
}
return status;
}

/* Insert lms byte string in an LMS secret key object */
Expand Down
31 changes: 26 additions & 5 deletions src/sig_stfl/lms/sig_stfl_lms_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ typedef struct 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, OQS_SIG_STFL_SECRET_KEY *secret_key) {

OQS_STATUS status = OQS_ERROR;
OQS_STATUS rc_keyupdate = OQS_ERROR;
oqs_lms_key_data *lms_key_data = NULL;
const OQS_SIG_STFL_SECRET_KEY *sk;
Expand All @@ -59,6 +59,11 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu
return OQS_ERROR;
}

/* Lock secret to ensure OTS use */
if ((secret_key->lock_key) && (secret_key->mutex)) {
secret_key->lock_key(secret_key->mutex);
}

/*
* Don't even attempt signing without a way to safe the updated private key
*/
Expand Down Expand Up @@ -94,16 +99,23 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_sign(uint8_t *signature, size_t *signatu
goto err;
}

OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len);
return OQS_SUCCESS;
status = OQS_SUCCESS;
goto passed;

err:
OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len);
if (*signature_length) {
memset(signature, 0, *signature_length);
}
*signature_length = 0;
return OQS_ERROR;

passed:
OQS_MEM_secure_free(sk_key_buf, sk_key_buf_len);

/* Unlock secret to ensure OTS use */
if ((secret_key->unlock_key) && (secret_key->mutex)) {
secret_key->unlock_key(secret_key->mutex);
}
return status;
}

OQS_API OQS_STATUS OQS_SIG_STFL_alg_lms_verify(const uint8_t *message, size_t message_len,
Expand All @@ -128,8 +140,17 @@ OQS_API OQS_STATUS OQS_SIG_STFL_lms_sigs_left(unsigned long long *remain, const
if (remain == NULL || secret_key == NULL) {
return OQS_ERROR;
}
/* Lock secret key to ensure data integrity use */
if ((secret_key->lock_key) && (secret_key->mutex)) {
secret_key->lock_key(secret_key->mutex);
}

remain = 0;

/* Unlock secret key */
if ((secret_key->unlock_key) && (secret_key->mutex)) {
secret_key->unlock_key(secret_key->mutex);
}
return OQS_SUCCESS;
}

Expand Down
49 changes: 49 additions & 0 deletions src/sig_stfl/sig_stfl.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,3 +716,52 @@ OQS_API OQS_STATUS OQS_SECRET_KEY_STFL_deserialize_key(OQS_SIG_STFL_SECRET_KEY *

return sk->deserialize_key(sk, key_len, sk_buf, context);
}



/* OQS_SIG_STFL_SECRET_KEY_SET_lock callback function*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock) {
if (sk == NULL) {
return;
}
sk->lock_key = lock;
}

/* OQS_SIG_STFL_SECRET_KEY_SET_unlock callback function */
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock) {
if (sk == NULL) {
return;
}
sk->unlock_key = unlock;
}

/* OQS_SIG_STFL_SECRET_KEY_SET_mutex */
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex) {
if (sk == NULL) {
return;
}
sk->mutex = mutex;
}

/* OQS_SIG_STFL_SECRET_KEY_lock */
OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk) {
if (sk == NULL) {
return OQS_ERROR;
}
if (sk->lock_key == NULL) {
return OQS_SUCCESS;
}

return (sk->lock_key(sk->mutex));
}

/* OQS_SIG_STFL_SECRET_KEY_unlock */
OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk) {
if (sk == NULL) {
return OQS_ERROR;
}
if (sk->unlock_key == NULL) {
return OQS_SUCCESS;
}
return (sk->unlock_key(sk->mutex));
}
110 changes: 103 additions & 7 deletions src/sig_stfl/sig_stfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@

#include <oqs/oqs.h>

/*
* Developer's Notes:
* Stateful signatures are based on one-time use of a secret key. A pool of secret keys are created for this purpose.
* The state of these keys are tracked to ensure that they are used only once to generate a signature.
*
* As such, product specific environments do play a role in ensuring the safety of the keys.
* Secret keys must be store securely.
* The key index/counter must be updated after each signature generation.
* Secret key must be protected in a thread-save manner.
*
* Application therefore are required to provide environment specific callback functions to
* - store private key
* - lock/unlock private key
*
* See below for details
* OQS_SIG_STFL_SECRET_KEY_SET_lock
* OQS_SIG_STFL_SECRET_KEY_SET_unlock
* OQS_SIG_STFL_SECRET_KEY_SET_mutex
* OQS_SIG_STFL_SECRET_KEY_SET_store_cb
*
*/


#if defined(__cplusplus)
extern "C" {
#endif
Expand Down Expand Up @@ -66,9 +89,25 @@ typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY;
* @param[in] sk_buf pointer to the data to be saved
* @param[in] buf_len length of the the data to be store
* @param[out] context pointer to application relevant data.
* @retrun OQS_SUCCESS if successful, otherwise OQS_ERROR
* return OQS_SUCCESS if successful, otherwise OQS_ERROR
*/
typedef OQS_STATUS (*secure_store_sk)(uint8_t *sk_buf, size_t buf_len, void *context);

/**
* Application provided function to lock secret key object serialize access
* @param[in] sk pointer to secret key object to lock
* @param[in] mutex pointer to mutex struct
* return OQS_SUCCESS if successful, otherwise OQS_ERROR
*/
typedef OQS_STATUS (*lock_key)(void *mutex);

/**
* Application provided function to unlock secret key object
* @param[in] sk pointer to secret key object to unlock
* @param[in] mutex pointer to mutex struct
* return OQS_SUCCESS if successful, otherwise OQS_ERROR
*/
typedef OQS_STATUS (*secure_store_sk)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context);
typedef OQS_STATUS (*unlock_key)(void *mutex);

/**
* Returns identifiers for available signature schemes in liboqs. Used with OQS_SIG_STFL_new.
Expand Down Expand Up @@ -205,6 +244,9 @@ typedef struct OQS_SIG_STFL_SECRET_KEY {
/* The variant specific secret key data */
void *secret_key_data;

/* mutual exclusion struct */
void *mutex;

/* Function that returns the total number of signatures for the secret key */
uint64_t (*sigs_total)(const OQS_SIG_STFL_SECRET_KEY *secret_key);

Expand Down Expand Up @@ -237,18 +279,18 @@ typedef struct OQS_SIG_STFL_SECRET_KEY {
/**
* Secret Key Locking Function
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @param[in] mutex application defined mutex
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*lock_key)(OQS_SIG_STFL_SECRET_KEY *sk);
OQS_STATUS (*lock_key)(void *mutex);

/**
* Secret Key Unlocking / Releasing Function
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @param[in] mutex application defined mutex
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*unlock_key)(OQS_SIG_STFL_SECRET_KEY *sk);
OQS_STATUS (*unlock_key)(void *mutex);

/**
* Store Secret Key Function
Expand All @@ -260,7 +302,7 @@ typedef struct OQS_SIG_STFL_SECRET_KEY {
* @return OQS_SUCCESS or OQS_ERROR
* Idealy written to secure device
*/
OQS_STATUS (*secure_store_scrt_key)(/*const*/ uint8_t *sk_buf, size_t buf_len, void *context);
OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t buf_len, void *context);

/**
* Secret Key free internal variant specific data
Expand Down Expand Up @@ -388,6 +430,60 @@ void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk);
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk);

/**
* OQS_SIG_STFL_SECRET_KEY_SET_lock .
*
* Sets function to prevent multiple processes from using the sk at the same time.
*
* @param[in] sk secret key pointer to be updated
* @param[in] lock function pointer
*
*/
void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock);

/**
* OQS_SIG_STFL_SECRET_KEY_SET_unlock .
*
* Sets function to prevent multiple processes from using the sk at the same time.
*
* @param[in] sk secret key pointer to be updated
* @param[in] unlock function pointer
*
*/
void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock);

/**
* OQS_SIG_STFL_SECRET_KEY_SET_mutex .
*
* Sets function to prevent multiple processes from using the sk at the same time.
*
* @param[in] sk secret key pointer to be updated
* @param[in] mutex function pointer
*
*/
void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex);

/**
* OQS_SIG_STFL_SECRET_KEY_lock .
*
* Locks sk so only one application that holds the lock can access it.
*
* @param[in] sk secret key pointer to be locked
* @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to apply the lock
*
*/
OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk);

/**
* OQS_SIG_STFL_SECRET_KEY_unlock .
*
* Unlocks the resouces so that th enext process can access it.
*
* @param[in] sk secret key pointer
* @return OQS_SUCCESS if successful, or OQS_ERROR if the object fails to release the lock
*
*/
OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk);

/**
* OQS_SIG_STFL_SECRET_KEY_SET_store_cb .
Expand Down
Loading
Loading