montana/macOS/MontanaPresence/Crypto/build-macos/include/oqs/sig_stfl.h

741 lines
34 KiB
C

/**
* \file sig_stfl.h
* \brief Stateful Signature schemes
*
* The file `tests/example_sig_stfl.c` contains an example on using the OQS_SIG_STFL API.
*
* SPDX-License-Identifier: MIT
*/
#ifndef OQS_SIG_STATEFUL_H
#define OQS_SIG_STATEFUL_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <oqs/oqs.h>
/*
* Developer's Notes:
* Stateful signatures are based on the one-time use of a secret key. A pool of secret keys is created for this purpose.
* The state of these keys is 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 stored securely.
* The key index/counter must be updated after each signature generation.
* The secret key must be protected in a thread-safe manner.
*
* Applications 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
/** Algorithm identifier for XMSS-SHA2_10_256 */
#define OQS_SIG_STFL_alg_xmss_sha256_h10 "XMSS-SHA2_10_256"
/** Algorithm identifier for XMSS-SHA2_16_256 */
#define OQS_SIG_STFL_alg_xmss_sha256_h16 "XMSS-SHA2_16_256"
/** Algorithm identifier for XMSS-SHA2_20_256 */
#define OQS_SIG_STFL_alg_xmss_sha256_h20 "XMSS-SHA2_20_256"
/** Algorithm identifier for XMSS-SHAKE_10_256 */
#define OQS_SIG_STFL_alg_xmss_shake128_h10 "XMSS-SHAKE_10_256"
/** Algorithm identifier for XMSS-SHAKE_16_256 */
#define OQS_SIG_STFL_alg_xmss_shake128_h16 "XMSS-SHAKE_16_256"
/** Algorithm identifier for XMSS-SHAKE_20_256 */
#define OQS_SIG_STFL_alg_xmss_shake128_h20 "XMSS-SHAKE_20_256"
/** Algorithm identifier for XMSS-SHA2_10_512 */
#define OQS_SIG_STFL_alg_xmss_sha512_h10 "XMSS-SHA2_10_512"
/** Algorithm identifier for XMSS-SHA2_16_512 */
#define OQS_SIG_STFL_alg_xmss_sha512_h16 "XMSS-SHA2_16_512"
/** Algorithm identifier for XMSS-SHA2_20_512 */
#define OQS_SIG_STFL_alg_xmss_sha512_h20 "XMSS-SHA2_20_512"
/** Algorithm identifier for XMSS-SHAKE_10_512 */
#define OQS_SIG_STFL_alg_xmss_shake256_h10 "XMSS-SHAKE_10_512"
/** Algorithm identifier for XMSS-SHAKE_16_512 */
#define OQS_SIG_STFL_alg_xmss_shake256_h16 "XMSS-SHAKE_16_512"
/** Algorithm identifier for XMSS-SHAKE_20_512 */
#define OQS_SIG_STFL_alg_xmss_shake256_h20 "XMSS-SHAKE_20_512"
/** Algorithm identifier for XMSS-SHA2_10_192 */
#define OQS_SIG_STFL_alg_xmss_sha256_h10_192 "XMSS-SHA2_10_192"
/** Algorithm identifier for XMSS-SHA2_16_192 */
#define OQS_SIG_STFL_alg_xmss_sha256_h16_192 "XMSS-SHA2_16_192"
/** Algorithm identifier for XMSS-SHA2_20_192 */
#define OQS_SIG_STFL_alg_xmss_sha256_h20_192 "XMSS-SHA2_20_192"
/** Algorithm identifier for XMSS-SHAKE256_10_192 */
#define OQS_SIG_STFL_alg_xmss_shake256_h10_192 "XMSS-SHAKE256_10_192"
/** Algorithm identifier for XMSS-SHAKE256_16_192 */
#define OQS_SIG_STFL_alg_xmss_shake256_h16_192 "XMSS-SHAKE256_16_192"
/** Algorithm identifier for XMSS-SHAKE256_20_192 */
#define OQS_SIG_STFL_alg_xmss_shake256_h20_192 "XMSS-SHAKE256_20_192"
/** Algorithm identifier for XMSS-SHAKE256_10_256 */
#define OQS_SIG_STFL_alg_xmss_shake256_h10_256 "XMSS-SHAKE256_10_256"
/** Algorithm identifier for XMSS-SHAKE256_16_256 */
#define OQS_SIG_STFL_alg_xmss_shake256_h16_256 "XMSS-SHAKE256_16_256"
/** Algorithm identifier for XMSS-SHAKE256_20_256 */
#define OQS_SIG_STFL_alg_xmss_shake256_h20_256 "XMSS-SHAKE256_20_256"
/** Algorithm identifier for XMSSMT-SHA2_20/2_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2 "XMSSMT-SHA2_20/2_256"
/** Algorithm identifier for XMSSMT-SHA2_20/4_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4 "XMSSMT-SHA2_20/4_256"
/** Algorithm identifier for XMSSMT-SHA2_40/2_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2 "XMSSMT-SHA2_40/2_256"
/** Algorithm identifier for XMSSMT-SHA2_40/4_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4 "XMSSMT-SHA2_40/4_256"
/** Algorithm identifier for XMSSMT-SHA2_40/8_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8 "XMSSMT-SHA2_40/8_256"
/** Algorithm identifier for XMSSMT-SHA2_60/3_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3 "XMSSMT-SHA2_60/3_256"
/** Algorithm identifier for XMSSMT-SHA2_60/6_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6 "XMSSMT-SHA2_60/6_256"
/** Algorithm identifier for XMSSMT-SHA2_60/12_256 */
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12 "XMSSMT-SHA2_60/12_256"
/** Algorithm identifier for XMSSMT-SHAKE_20/2_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2 "XMSSMT-SHAKE_20/2_256"
/** Algorithm identifier for XMSSMT-SHAKE_20/4_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4 "XMSSMT-SHAKE_20/4_256"
/** Algorithm identifier for XMSSMT-SHAKE_40/2_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2 "XMSSMT-SHAKE_40/2_256"
/** Algorithm identifier for XMSSMT-SHAKE_40/4_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4 "XMSSMT-SHAKE_40/4_256"
/** Algorithm identifier for XMSSMT-SHAKE_40/8_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8 "XMSSMT-SHAKE_40/8_256"
/** Algorithm identifier for XMSSMT-SHAKE_60/3_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3 "XMSSMT-SHAKE_60/3_256"
/** Algorithm identifier for XMSSMT-SHAKE_60/6_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6 "XMSSMT-SHAKE_60/6_256"
/** Algorithm identifier for XMSSMT-SHAKE_60/12_256 */
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12 "XMSSMT-SHAKE_60/12_256"
/* Defined LMS parameter identifiers */
/** Algorithm identifier for LMS-SHA256_H5_W1 */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w1 "LMS_SHA256_H5_W1" //"5/1"
/** Algorithm identifier for LMS-SHA256_H5_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w2 "LMS_SHA256_H5_W2" //"5/2"
/** Algorithm identifier for LMS-SHA256_H5_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w4 "LMS_SHA256_H5_W4" //"5/4"
/** Algorithm identifier for LMS-SHA256_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w8 "LMS_SHA256_H5_W8" //"5/8"
/** Algorithm identifier for LMS-SHA256_H10_W1 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w1 "LMS_SHA256_H10_W1" //"10/1"
/** Algorithm identifier for LMS-SHA256_H10_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w2 "LMS_SHA256_H10_W2" //"10/2"
/** Algorithm identifier for LMS-SHA256_H10_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4 "LMS_SHA256_H10_W4" //"10/4"
/** Algorithm identifier for LMS-SHA256_H10_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8 "LMS_SHA256_H10_W8" //"10/8"
/** Algorithm identifier for LMS-SHA256_H15_W1 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w1 "LMS_SHA256_H15_W1" //"15/1"
/** Algorithm identifier for LMS-SHA256_H15_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w2 "LMS_SHA256_H15_W2" //"15/2"
/** Algorithm identifier for LMS-SHA256_H15_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w4 "LMS_SHA256_H15_W4" //"15/4"
/** Algorithm identifier for LMS-SHA256_H15_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8 "LMS_SHA256_H15_W8" //"15/8"
/** Algorithm identifier for LMS-SHA256_H20_W1 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w1 "LMS_SHA256_H20_W1" //"20/1"
/** Algorithm identifier for LMS-SHA256_H20_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w2 "LMS_SHA256_H20_W2" //"20/2"
/** Algorithm identifier for LMS-SHA256_H20_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w4 "LMS_SHA256_H20_W4" //"20/4"
/** Algorithm identifier for LMS-SHA256_H20_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8 "LMS_SHA256_H20_W8" //"20/8"
/** Algorithm identifier for LMS-SHA256_H25_W1 */
#define OQS_SIG_STFL_alg_lms_sha256_h25_w1 "LMS_SHA256_H25_W1" //"25/1"
/** Algorithm identifier for LMS-SHA256_H25_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h25_w2 "LMS_SHA256_H25_W2" //"25/2"
/** Algorithm identifier for LMS-SHA256_H25_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h25_w4 "LMS_SHA256_H25_W4" //"25/4"
/** Algorithm identifier for LMS-SHA256_H25_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h25_w8 "LMS_SHA256_H25_W8" //"25/8"
// 2-Level LMS
/** Algorithm identifier for LMS-SHA256_H5_W8_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8 "LMS_SHA256_H5_W8_H5_W8" //"5/8, 5/8"
// RFC 6554
/** Algorithm identifier for LMS-SHA256_H10_W4_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8 "LMS_SHA256_H10_W4_H5_W8" //"10/4, 5/8"
/** Algorithm identifier for LMS-SHA256_H10_W8_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8 "LMS_SHA256_H10_W8_H5_W8" //"10/8, 5/8"
/** Algorithm identifier for LMS-SHA256_H10_W2_H10_W2 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2 "LMS_SHA256_H10_W2_H10_W2" //"10/2, 10/2"
/** Algorithm identifier for LMS-SHA256_H10_W4_H10_W4 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4 "LMS_SHA256_H10_W4_H10_W4" //"10/4, 10/4"
/** Algorithm identifier for LMS-SHA256_H10_W8_H10_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8 "LMS_SHA256_H10_W8_H10_W8" //"10/8, 10/8"
/** Algorithm identifier for LMS-SHA256_H15_W8_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8 "LMS_SHA256_H15_W8_H5_W8" //"15/8, 5/8"
/** Algorithm identifier for LMS-SHA256_H15_W8_H10_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8 "LMS_SHA256_H15_W8_H10_W8" //"15/8, 10/8"
/** Algorithm identifier for LMS-SHA256_H15_W8_H15_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8 "LMS_SHA256_H15_W8_H15_W8" //"15/8, 15/8"
/** Algorithm identifier for LMS-SHA256_H20_W8_H5_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8 "LMS_SHA256_H20_W8_H5_W8" //"20/8, 5/8"
/** Algorithm identifier for LMS-SHA256_H20_W8_H10_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8 "LMS_SHA256_H20_W8_H10_W8" //"20/8, 10/8"
/** Algorithm identifier for LMS-SHA256_H20_W8_H15_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8 "LMS_SHA256_H20_W8_H15_W8" //"20/8, 15/8"
/** Algorithm identifier for LMS-SHA256_H20_W8_H20_W8 */
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h20_w8 "LMS_SHA256_H20_W8_H20_W8" //"20/8, 20/8"
/** Total number of stateful variants defined above, used to create the tracking array */
#define OQS_SIG_STFL_algs_length 70
typedef struct OQS_SIG_STFL_SECRET_KEY OQS_SIG_STFL_SECRET_KEY;
/**
* Application provided function to securely store data
* @param[in] sk_buf pointer to the data to be saved
* @param[in] buf_len length of the data to be stored
* @param[out] context pass back application data related to secret key data storage.
* 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] 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] mutex pointer to mutex struct
* return OQS_SUCCESS if successful, otherwise OQS_ERROR
*/
typedef OQS_STATUS (*unlock_key)(void *mutex);
/**
* Returns identifiers for available signature schemes in liboqs. Used with `OQS_SIG_STFL_new`.
*
* Note that algorithm identifiers are present in this list even when the algorithm is disabled
* at compile time.
*
* @param[in] i Index of the algorithm identifier to return, 0 <= i < OQS_SIG_algs_length
* @return Algorithm identifier as a string, or NULL.
*/
OQS_API const char *OQS_SIG_STFL_alg_identifier(size_t i);
/**
* Returns the number of stateful signature mechanisms in liboqs. They can be enumerated with
* OQS_SIG_STFL_alg_identifier.
*
* Note that some mechanisms may be disabled at compile time.
*
* @return The number of stateful signature mechanisms.
*/
OQS_API int OQS_SIG_STFL_alg_count(void);
/**
* Indicates whether the specified algorithm was enabled at compile-time or not.
*
* @param[in] method_name Name of the desired algorithm; one of the names in `OQS_SIG_STFL_algs`.
* @return 1 if enabled, 0 if disabled or not found
*/
OQS_API int OQS_SIG_STFL_alg_is_enabled(const char *method_name);
#ifndef OQS_ALLOW_STFL_KEY_AND_SIG_GEN
/** Signature schemes object */
typedef struct OQS_SIG OQS_SIG;
/** Stateful signature scheme object */
#define OQS_SIG_STFL OQS_SIG
#else
/** Stateful signature scheme object */
typedef struct OQS_SIG_STFL {
/**
* A local ordinal representing the LMS/XMSS OID parameter of the signature scheme.
* This OID is unrelated to ASN.1 OID, it's only for LMS/XMSS internal usage.
*/
uint32_t oid;
/** Printable string representing the name of the signature scheme. */
const char *method_name;
/**
* Printable string representing the version of the cryptographic algorithm.
*
* Implementations with the same method_name and same alg_version will be interoperable.
* See README.md for information about algorithm compatibility.
*/
const char *alg_version;
/** Whether the signature offers EUF-CMA security (TRUE) or not (FALSE). */
bool euf_cma;
/** Whether the signature offers SUF-CMA security (TRUE) or not (FALSE). */
bool suf_cma;
/** The (maximum) length, in bytes, of public keys for this signature scheme. */
size_t length_public_key;
/** The (maximum) length, in bytes, of secret keys for this signature scheme. */
size_t length_secret_key;
/** The (maximum) length, in bytes, of signatures for this signature scheme. */
size_t length_signature;
/**
* Keypair generation algorithm.
*
* 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_*`.
*
* @param[out] public_key The public key is represented as a byte string.
* @param[out] secret_key The secret key object
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*keypair)(uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Signature generation algorithm.
*
* For stateful signatures, there is always a limited number of signatures that can be used,
* The private key signature counter is increased by one once a signature is successfully generated,
* When the signature counter reaches the maximum number of available signatures, the signature generation always fails.
*
* Caller is responsible for allocating sufficient memory for `signature`,
* based on the `length_*` members in this object or the per-scheme
* compile-time macros `OQS_SIG_STFL_*_length_*`.
*
* @param[out] signature The signature on the message is represented as a byte string.
* @param[out] signature_len The length of the signature.
* @param[in] message The message to sign is represented as a byte string.
* @param[in] message_len The length of the message to sign.
* @param[in] secret_key The secret key object pointer.
* @return OQS_SUCCESS or OQS_ERROR
*
* @note Internally, if `lock/unlock` functions and `mutex` are set, it will attempt to lock the private key and unlock
* the private key after the Signing operation is completed.
*/
OQS_STATUS (*sign)(uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Signature verification algorithm.
*
* @param[in] message The message is represented as a byte string.
* @param[in] message_len The length of the message.
* @param[in] signature The signature on the message is represented as a byte string.
* @param[in] signature_len The length of the signature.
* @param[in] public_key The public key is represented as a byte string.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*verify)(const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key);
/**
* Query the number of remaining signatures.
*
* The remaining signatures are the number of signatures available before the private key runs out of its total signature and expires.
*
* @param[out] remain The number of remaining signatures
* @param[in] secret_key The secret key object pointer.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*sigs_remaining)(unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Query the total number of signatures.
*
* The total number of signatures is the constant number present in how many signatures can be generated from a private key.
*
* @param[out] total The total number of signatures
* @param[in] secret_key The secret key key object pointer.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*sigs_total)(unsigned long long *total, const OQS_SIG_STFL_SECRET_KEY *secret_key);
} OQS_SIG_STFL;
#endif //OQS_ALLOW_STFL_KEY_AND_SIG_GEN
/**
* @brief OQS_SIG_STFL_SECRET_KEY object for stateful signature schemes
*/
typedef struct OQS_SIG_STFL_SECRET_KEY {
/** The (maximum) length, in bytes, of secret keys for this signature scheme. */
size_t length_secret_key;
/** The variant-specific secret key data must be allocated at the initialization. */
void *secret_key_data;
/** The mutual exclusion struct */
void *mutex;
/** Application-managed data related to secure storage of secret key data */
void *context;
/**
* Serialize the stateful secret key.
*
* This function encodes the stateful secret key represented by `sk` into a byte stream
* for storage or transfer. The `sk_buf_ptr` will point to the allocated memory containing
* the byte stream. Users must free the `sk_buf_ptr` using `OQS_MEM_secure_free` after use.
* The `sk_len` will contain the length of the byte stream.
*
* @param[out] sk_buf_ptr Pointer to the byte stream representing the serialized secret key.
* @param[out] sk_buf_len Pointer to the length of the serialized byte stream.
* @param[in] sk Pointer to the `OQS_SIG_STFL_SECRET_KEY` object to serialize.
* @return The number of bytes in the serialized byte stream upon success, or an OQS error code on failure.
*
* @attention The caller is responsible for ensuring that `sk` is a valid object before calling this function.
*/
OQS_STATUS (*serialize_key)(uint8_t **sk_buf_ptr, size_t *sk_buf_len, const OQS_SIG_STFL_SECRET_KEY *sk);
/**
* Deserialize a byte stream into the internal representation of a stateful secret key.
*
* This function takes a series of bytes representing a stateful secret key and initializes
* the internal `OQS_SIG_STFL_SECRET_KEY` object with the key material. This is particularly
* useful for reconstructing key objects from persisted or transmitted state.
*
* @param[out] sk Pointer to an uninitialized `OQS_SIG_STFL_SECRET_KEY` object to hold the secret key.
* @param[in] sk_buf Pointer to the byte stream containing the serialized secret key data.
* @param[in] sk_buf_len The length of the secret key byte stream.
* @param[in] context Pointer to application-specific data, handled externally, associated with the key.
* @returns OQS_SUCCESS if the deserialization succeeds, with the `sk` object populated with the key material.
*
* @attention The caller is responsible for ensuring that `sk_buf` is securely deallocated when it's no longer needed.
*/
OQS_STATUS (*deserialize_key)(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, const size_t sk_buf_len, void *context);
/**
* Secret Key Locking Function
*
* @param[in] mutex application defined mutex
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*lock_key)(void *mutex);
/**
* Secret Key Unlocking / Releasing Function
*
* @param[in] mutex application defined mutex
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_STATUS (*unlock_key)(void *mutex);
/**
* Store Secret Key Function
*
* Callback function used to securely store key data after a signature generation.
* When populated, this pointer points to the application-supplied secure storage function.
* @param[in] sk_buf The serialized secret key data to secure store
* @param[in] sk_buf_len length of data to secure
* @param[in] context application supplied data used to locate where this secret key
* is stored (passed in at the time the function pointer was set).
*
* @return OQS_SUCCESS or OQS_ERROR
* Ideally written to a secure device.
*/
OQS_STATUS (*secure_store_scrt_key)(uint8_t *sk_buf, size_t sk_buf_len, void *context);
/**
* 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);
/**
* Set Secret Key Store Callback Function
*
* This function is used to establish a callback mechanism for secure storage
* of private keys involved in stateful signature Signing operation. The secure storage
* and the management of private keys is the responsibility of the adopting application.
* Therefore, before invoking stateful signature generation, a callback function and
* associated context data must be provided by the application to manage the storage.
*
* The `context` argument is designed to hold information requisite for private key storage,
* such as a hardware security module (HSM) context, a file path, or other relevant data.
* This context is passed to the libOQS when the callback function is registered.
*
* @param[in] sk A pointer to the secret key object that requires secure storage management
* after signature Signing operations.
* @param[in] store_cb A pointer to the callback function provided by the application
* for storing and updating the private key securely.
* @param[in] context Application-specific context information for the private key storage,
* furnished when setting the callback function via
* OQS_SIG_STFL_SECRET_KEY_set_store_cb().
* @return None.
*/
void (*set_scrt_key_store_cb)(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context);
} OQS_SIG_STFL_SECRET_KEY;
/**
* Constructs an OQS_SIG_STFL 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 for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
*/
OQS_API OQS_SIG_STFL *OQS_SIG_STFL_new(const char *method_name);
/**
* Keypair generation algorithm.
*
* 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_*`. The caller is also responsible for initializing
* `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 is represented as a byte string.
* @param[out] secret_key The secret key object pointer.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_API OQS_STATUS OQS_SIG_STFL_keypair(const OQS_SIG_STFL *sig, uint8_t *public_key, OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Signature generation algorithm.
*
* For stateful signatures, there is always a limited number of signatures that can be used,
* The private key signature counter is increased by one once a signature is successfully generated,
* When the signature counter reaches the maximum number of available signatures, the signature generation always fails.
*
* Caller is responsible for allocating sufficient memory for `signature`,
* based on the `length_*` members in this object or the per-scheme
* compile-time macros `OQS_SIG_STFL_*_length_*`.
*
* @param[in] sig The OQS_SIG_STFL object representing the signature scheme.
* @param[out] signature The signature on the message is represented as a byte string.
* @param[out] signature_len The length of the signature.
* @param[in] message The message to sign is represented as a byte string.
* @param[in] message_len The length of the message to sign.
* @param[in] secret_key The secret key object pointer.
* @return OQS_SUCCESS or OQS_ERROR
*
* @note Internally, if `lock/unlock` functions and `mutex` are set, it will attempt to lock the private key and unlock
* the private key after the Signing operation is completed.
*/
OQS_API OQS_STATUS OQS_SIG_STFL_sign(const OQS_SIG_STFL *sig, uint8_t *signature, size_t *signature_len, const uint8_t *message, size_t message_len, OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Signature verification algorithm.
*
* @param[in] sig The OQS_SIG_STFL object representing the signature scheme.
* @param[in] message The message is represented as a byte string.
* @param[in] message_len The length of the message.
* @param[in] signature The signature on the message is represented as a byte string.
* @param[in] signature_len The length of the signature.
* @param[in] public_key The public key is represented as a byte string.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_API OQS_STATUS OQS_SIG_STFL_verify(const OQS_SIG_STFL *sig, const uint8_t *message, size_t message_len, const uint8_t *signature, size_t signature_len, const uint8_t *public_key);
/**
* Query the number of remaining signatures.
*
* The remaining signatures are the number of signatures available before the private key runs out of its total signature and expires.
*
* @param[in] sig The OQS_SIG_STFL object representing the signature scheme.
* @param[in] remain The number of remaining signatures.
* @param[in] secret_key The secret key object.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_API OQS_STATUS OQS_SIG_STFL_sigs_remaining(const OQS_SIG_STFL *sig, unsigned long long *remain, const OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Query the total number of signatures.
*
* The total number of signatures is the constant number present in how many signatures can be generated from a private key.
*
* @param[in] sig The OQS_SIG_STFL object representing the signature scheme.
* @param[out] max The number of remaining signatures
* @param[in] secret_key The secret key object.
* @return OQS_SUCCESS or OQS_ERROR
*/
OQS_API OQS_STATUS OQS_SIG_STFL_sigs_total(const OQS_SIG_STFL *sig, unsigned long long *max, const OQS_SIG_STFL_SECRET_KEY *secret_key);
/**
* Free an OQS_SIG_STFL object that was constructed by OQS_SIG_STFL_new.
*
*/
OQS_API void OQS_SIG_STFL_free(OQS_SIG_STFL *sig);
/**
* Construct 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);
/**
* Free an OQS_SIG_STFL_SECRET_KEY object that was constructed by OQS_SECRET_KEY_new.
*
* @param[in] sk The OQS_SIG_STFL_SECRET_KEY object to free.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_free(OQS_SIG_STFL_SECRET_KEY *sk);
/**
* Attach a locking mechanism to a secret key object.
*
* This allows for proper synchronization in a multi-threaded or multi-process environment,
* by ensuring that a secret key is not used concurrently by multiple entities, which could otherwise lead to security issues.
*
* @param[in] sk Pointer to the secret key object whose lock function is to be set.
* @param[in] lock Function pointer to the locking routine provided by the application.
*
* @note It's not required to set the lock and unlock functions in a single-threaded environment.
*
* @note Once the `lock` function is set, users must also set the `mutex` and `unlock` functions.
*
* @note By default, the internal value of `sk->lock` is NULL, which does nothing to lock the private key.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_lock(OQS_SIG_STFL_SECRET_KEY *sk, lock_key lock);
/**
* Attach an unlock mechanism to a secret key object.
*
* This allows for proper synchronization in a multi-threaded or multi-process environment,
* by ensuring that a secret key is not used concurrently by multiple entities, which could otherwise lead to security issues.
*
* @param[in] sk Pointer to the secret key object whose unlock function is to be set.
* @param[in] unlock Function pointer to the unlock routine provided by the application.
*
* @note It's not required to set the lock and unlock functions in a single-threaded environment.
*
* @note Once the `unlock` function is set, users must also set the `mutex` and `lock` functions.
*
* @note By default, the internal value of `sk->unlock` is NULL, which does nothing to unlock the private key.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_unlock(OQS_SIG_STFL_SECRET_KEY *sk, unlock_key unlock);
/**
* Assign a mutex function to handle concurrency control over the secret key.
*
* This is to ensure that only one process can access or modify the key at any given time.
*
* @param[in] sk A pointer to the secret key that the mutex functionality will protect.
* @param[in] mutex A function pointer to the desired concurrency control mechanism.
*
* @note It's not required to set the lock and unlock functions in a single-threaded environment.
*
* @note By default, the internal value of `sk->mutex` is NULL, it must be set to be used in `lock` or `unlock` the private key.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_mutex(OQS_SIG_STFL_SECRET_KEY *sk, void *mutex);
/**
* Lock the secret key to ensure exclusive access in a concurrent environment.
*
* If the `mutex` is not set, this lock operation will fail.
* This lock operation is essential in multi-threaded or multi-process contexts
* to prevent simultaneous Signing operations that could compromise the stateful signature security.
*
* @warning If the `lock` function is set and `mutex` is not set, this lock operation will fail.
*
* @param[in] sk Pointer to the secret key to be locked.
* @return OQS_SUCCESS if the lock is successfully applied; OQS_ERROR otherwise.
*
* @note It's not necessary to use this function in either Keygen or Verifying operations.
* In a concurrent environment, the user is responsible for locking and unlocking the private key,
* to make sure that only one thread can access the private key during a Signing operation.
*
* @note If the `lock` function and `mutex` are both set, proceed to lock the private key.
*/
OQS_STATUS OQS_SIG_STFL_SECRET_KEY_lock(OQS_SIG_STFL_SECRET_KEY *sk);
/**
* Unlock the secret key, making it accessible to other processes.
*
* This function is crucial in environments where multiple processes need to coordinate access to
* the secret key, as it allows a process to signal that it has finished using the key, so
* others can safely use it.
*
* @warning If the `unlock` function is set and `mutex` is not set, this unlock operation will fail.
*
* @param[in] sk Pointer to the secret key whose lock should be released.
* @return OQS_SUCCESS if the lock was successfully released; otherwise, OQS_ERROR.
*
* @note It's not necessary to use this function in either Keygen or Verifying operations.
* In a concurrent environment, the user is responsible for locking and unlocking the private key,
* to make sure that only one thread can access the private key during a Signing operation.
*
* @note If the `unlock` function and `mutex` are both set, proceed to unlock the private key.
*/
OQS_STATUS OQS_SIG_STFL_SECRET_KEY_unlock(OQS_SIG_STFL_SECRET_KEY *sk);
/**
* Set the callback and context for securely storing a stateful secret key.
*
* This function is designed to be called after a new stateful secret key
* has been generated. It enables the library to securely store secret key
* and update it every time a Signing operation occurs.
* Without properly setting this callback and context, signature generation
* will not succeed as the updated state of the secret key cannot be preserved.
*
* @param[in] sk Pointer to the stateful secret key to be managed.
* @param[in] store_cb Callback function that handles the secure storage of the key.
* @param[in] context Application-specific context that assists in the storage of secret key data.
* This context is managed by the application, which allocates it, keeps track of it,
* and deallocates it as necessary.
*/
OQS_API void OQS_SIG_STFL_SECRET_KEY_SET_store_cb(OQS_SIG_STFL_SECRET_KEY *sk, secure_store_sk store_cb, void *context);
/**
* Serialize the stateful secret key data into a byte array.
*
* Converts an OQS_SIG_STFL_SECRET_KEY object into a byte array for storage or transmission.
*
* @param[out] sk_buf_ptr Pointer to the allocated byte array containing the serialized key.
* @param[out] sk_buf_len Length of the serialized key byte array.
* @param[in] sk Pointer to the OQS_SIG_STFL_SECRET_KEY object to be serialized.
* @return OQS_SUCCESS on success, or an OQS error code on failure.
*
* @note The function allocates memory for the byte array, and it is the caller's responsibility to free this memory after use.
*/
OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_serialize(uint8_t **sk_buf_ptr, size_t *sk_buf_len, const OQS_SIG_STFL_SECRET_KEY *sk);
/**
* Deserialize a byte array into an OQS_SIG_STFL_SECRET_KEY object.
*
* Transforms a binary representation of a secret key into an OQS_SIG_STFL_SECRET_KEY structure.
* After deserialization, the secret key object can be used for subsequent cryptographic operations.
*
* @param[out] sk A pointer to the secret key object that will be populated from the binary data.
* @param[in] sk_buf The buffer containing the serialized secret key data.
* @param[in] sk_buf_len The length of the binary secret key data in bytes.
* @param[in] context Application-specific data used to maintain context about the secret key.
* @return OQS_SUCCESS if deserialization was successful; otherwise, OQS_ERROR.
*
* @attention The caller is responsible for freeing the `sk_buf` memory when it is no longer needed.
*/
OQS_API OQS_STATUS OQS_SIG_STFL_SECRET_KEY_deserialize(OQS_SIG_STFL_SECRET_KEY *sk, const uint8_t *sk_buf, size_t sk_buf_len, void *context);
#if defined(__cplusplus)
// extern "C"
}
#endif
#endif /* OQS_SIG_STATEFUL_H */