Skip to content

Commit

Permalink
Re-add OQS_SECRET_KEY (#1493)
Browse files Browse the repository at this point in the history
* Re-add OQS_SECRET_KEY

* Updates per review and formating changes

* Set function callback for 'free'.

* Address escaped PR comment

* fix formatting

* Update src/sig_stfl/sig_stfl.h

Co-authored-by: Douglas Stebila <dstebila@users.noreply.github.com>

---------

Co-authored-by: Norman Ashley <nashley@cisco.com>
  • Loading branch information
dstebila and ashman-p committed Aug 18, 2023
1 parent 5566c9c commit 88602de
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 4 deletions.
33 changes: 33 additions & 0 deletions src/sig_stfl/sig_stfl.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,36 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max,
OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig) {
OQS_MEM_insecure_free(sig);
}



// ================================= OQS_SIG_STFL_SECRET_KEY FUNCTION ===============================================


OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name) {
assert(method_name != NULL);

if (0) {

} else if (0 == strcasecmp(method_name, OQS_SIG_STFL_alg_xmss_sha256_h10)) {
#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10
return OQS_SECRET_KEY_XMSS_SHA256_H10_new();
#else
return NULL;
#endif
} else {
return NULL;
}
}

OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk) {
if (sk == NULL) {
return;
}

/* Call object specif free */
if (sk->free_key) {
sk->free_key(sk);
}
OQS_MEM_secure_free(sk, sizeof(sk));
}
96 changes: 95 additions & 1 deletion src/sig_stfl/sig_stfl.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,81 @@ typedef struct OQS_SIG_STFL {

} OQS_SIG_STFL;

/**
* @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes
*/
typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY;

typedef struct OQS_SIG_STFL_SECRET_KEY {

/** Associated signature object */
OQS_SIG_STFL *sig;

/* The (maximum) length, in bytes, of secret keys for this signature scheme. */
size_t length_secret_key;

/* The variant specific secret key data */
void *secret_key_data;

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

/* Function that returns the number of signatures left for the secret key */
unsigned long long (*sigs_left)(const OQS_SIG_STFL_SECRET_KEY *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.
*/
uint8_t *(*serialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len);

/**
* 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.
*/
uint8_t *(*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, size_t key_len, uint8_t *sk_key);

/**
* Secret Key Locking Function
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*lock_key)(OQS_SIG_STFL_SECRET_KEY *sk);

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

/**
* Secret Key Saving Function
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*save_secret_key)(const OQS_SIG_STFL_SECRET_KEY *sk);

/**
* Secret Key free internal variant specific data
*
* @param[in] sk The secret key represented as OQS_SIG_STFL_SECRET_KEY object
* @return none
*/
void (*free_key)(OQS_SIG_STFL_SECRET_KEY *sk);
} OQS_SIG_STFL_SECRET_KEY;

/**
* Constructs an OQS_SIG_STFL object for a particular algorithm.
*
Expand All @@ -162,7 +237,7 @@ OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name);
* Caller is responsible for allocating sufficient memory for `public_key` based
* on the `length_*` members in this object or the per-scheme compile-time macros
* `OQS_SIG_STFL_*_length_*`. Caller is also responsible for initializing
* `secret_key` using the OQS_SECRET_KEY(*) function
* `secret_key` using the OQS_SIG_STFL_SECRET_KEY(*) function
*
* @param[in] sig The OQS_SIG_STFL object representing the signature scheme.
* @param[out] public_key The public key represented as a byte string.
Expand Down Expand Up @@ -228,6 +303,25 @@ OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, size_t *max,
*/
OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig);

/**
* Constructs an OQS_SIG_STFL_SECRET_KEY object for a particular algorithm.
*
* Callers should always check whether the return value is `NULL`, which indicates either than an
* invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time.
*
* @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_STFL_algs`.
* @return An OQS_SIG_STFL_SECRET_KEY for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
*/
OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SIG_STFL_SECRET_KEY_new(const char *method_name);

/**
* Frees an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new.
*
* @param[in] sig The OQS_SIG_STFL_SECRET_KEY object to free.
* @return OQS_SUCCESS if successful, or OQS_ERROR if the object could not be freed.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk);

#if defined(__cplusplus)
} // extern "C"
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/sig_stfl/xmss/sig_stfl_xmss.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <oqs/oqs.h>

#define XMSS_OID_LEN 4
void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk);

#ifdef OQS_ENABLE_SIG_STFL_xmss_sha256_h10

Expand All @@ -14,6 +15,7 @@
#define OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk (132 + XMSS_OID_LEN)

OQS_API OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void);
OQS_API OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void);
OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(uint8_t *public_key, uint8_t *secret_key);
OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sign(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, uint8_t *secret_key);
OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_verify(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key);
Expand Down
35 changes: 34 additions & 1 deletion src/sig_stfl/xmss/sig_stfl_xmss_sha256_h10.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,30 @@ OQS_SIG_STFL *OQS_SIG_STFL_alg_xmss_sha256_h10_new(void) {
return sig;
}

OQS_SIG_STFL_SECRET_KEY *OQS_SECRET_KEY_XMSS_SHA256_H10_new(void) {

// Initialize the secret key in the heap with adequate memory
OQS_SIG_STFL_SECRET_KEY *sk = malloc(sizeof(OQS_SIG_STFL_SECRET_KEY));
if (sk == NULL) {
return NULL;
}
memset(sk, 0, sizeof(OQS_SIG_STFL_SECRET_KEY));

sk->length_secret_key = OQS_SIG_STFL_alg_xmss_sha256_h10_length_sk;

// Assign the sigs_left and sigs_max functions
sk->sigs_left = NULL;
sk->sigs_total = NULL;

// Initialize the key with length_secret_key amount of bytes.
sk->secret_key_data = (uint8_t *)malloc(sk->length_secret_key * sizeof(uint8_t));
memset(sk->secret_key_data, 0, sk->length_secret_key);

sk->free_key = OQS_SECRET_KEY_XMSS_free;

return sk;
}

OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_keypair(XMSS_UNUSED_ATT uint8_t *public_key, XMSS_UNUSED_ATT uint8_t *secret_key) {

if (public_key == NULL || secret_key == NULL) {
Expand Down Expand Up @@ -109,4 +133,13 @@ OQS_API OQS_STATUS OQS_SIG_STFL_alg_xmss_sha256_h10_sigs_total(size_t *total, co
*total = (size_t) total_signatures;

return OQS_SUCCESS;
}
}

void OQS_SECRET_KEY_XMSS_free(OQS_SIG_STFL_SECRET_KEY *sk) {
if (sk == NULL) {
return;
}

OQS_MEM_secure_free(sk->secret_key_data, sk->length_secret_key);
sk->secret_key_data = NULL;
}
37 changes: 35 additions & 2 deletions tests/test_sig_stfl.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,35 @@ static OQS_STATUS sig_stfl_test_correctness(const char *method_name) {
return ret;
}

static OQS_STATUS sig_stfl_test_secret_key(const char *method_name) {
OQS_STATUS rc = OQS_SUCCESS;
OQS_SIG_STFL_SECRET_KEY *sk = NULL;

sk = OQS_SIG_STFL_SECRET_KEY_new(method_name);
if (sk == NULL) {
fprintf(stderr, "ERROR: OQS_SECRET_KEY_new failed\n");
goto err;
}

printf("================================================================================\n");
printf("Create for statefull Secret Key %s\n", method_name);
printf("================================================================================\n");

if (!sk->secret_key_data) {
fprintf(stderr, "ERROR: OQS_SECRET_KEY_new incomplete.\n");
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:
return rc;
}

#ifdef OQS_ENABLE_TEST_CONSTANT_TIME
static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_read) {
// We can't make direct calls to the system randombytes on some platforms,
Expand All @@ -178,11 +207,13 @@ static void TEST_SIG_STFL_randombytes(uint8_t *random_array, size_t bytes_to_rea
struct thread_data {
char *alg_name;
OQS_STATUS rc;
OQS_STATUS rc1;
};

void *test_wrapper(void *arg) {
struct thread_data *td = arg;
td->rc = sig_stfl_test_correctness(td->alg_name);
td->rc1 = sig_stfl_test_secret_key(td->alg_name);
return NULL;
}
#endif
Expand Down Expand Up @@ -221,7 +252,7 @@ int main(int argc, char **argv) {
OQS_randombytes_switch_algorithm("system");
#endif

OQS_STATUS rc;
OQS_STATUS rc, rc1;
#if OQS_USE_PTHREADS_IN_TESTS
#define MAX_LEN_SIG_NAME_ 64
pthread_t thread;
Expand All @@ -235,10 +266,12 @@ int main(int argc, char **argv) {
}
pthread_join(thread, NULL);
rc = td.rc;
rc1 = td.rc1;
#else
rc = sig_stfl_test_correctness(alg_name);
rc1 = sig_stfl_test_secret_key(alg_name);
#endif
if (rc != OQS_SUCCESS) {
if ((rc != OQS_SUCCESS) || (rc1 != OQS_SUCCESS)) {
OQS_destroy();
return EXIT_FAILURE;
}
Expand Down

0 comments on commit 88602de

Please sign in to comment.