-
Notifications
You must be signed in to change notification settings - Fork 462
/
sig_stfl.h
671 lines (602 loc) · 30.3 KB
/
sig_stfl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
/**
* \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"
#define OQS_SIG_STFL_alg_xmss_sha256_h16 "XMSS-SHA2_16_256"
#define OQS_SIG_STFL_alg_xmss_sha256_h20 "XMSS-SHA2_20_256"
#define OQS_SIG_STFL_alg_xmss_shake128_h10 "XMSS-SHAKE_10_256"
#define OQS_SIG_STFL_alg_xmss_shake128_h16 "XMSS-SHAKE_16_256"
#define OQS_SIG_STFL_alg_xmss_shake128_h20 "XMSS-SHAKE_20_256"
#define OQS_SIG_STFL_alg_xmss_sha512_h10 "XMSS-SHA2_10_512"
#define OQS_SIG_STFL_alg_xmss_sha512_h16 "XMSS-SHA2_16_512"
#define OQS_SIG_STFL_alg_xmss_sha512_h20 "XMSS-SHA2_20_512"
#define OQS_SIG_STFL_alg_xmss_shake256_h10 "XMSS-SHAKE_10_512"
#define OQS_SIG_STFL_alg_xmss_shake256_h16 "XMSS-SHAKE_16_512"
#define OQS_SIG_STFL_alg_xmss_shake256_h20 "XMSS-SHAKE_20_512"
#define OQS_SIG_STFL_alg_xmss_sha256_h10_192 "XMSS-SHA2_10_192"
#define OQS_SIG_STFL_alg_xmss_sha256_h16_192 "XMSS-SHA2_16_192"
#define OQS_SIG_STFL_alg_xmss_sha256_h20_192 "XMSS-SHA2_20_192"
#define OQS_SIG_STFL_alg_xmss_shake256_h10_192 "XMSS-SHAKE256_10_192"
#define OQS_SIG_STFL_alg_xmss_shake256_h16_192 "XMSS-SHAKE256_16_192"
#define OQS_SIG_STFL_alg_xmss_shake256_h20_192 "XMSS-SHAKE256_20_192"
#define OQS_SIG_STFL_alg_xmss_shake256_h10_256 "XMSS-SHAKE256_10_256"
#define OQS_SIG_STFL_alg_xmss_shake256_h16_256 "XMSS-SHAKE256_16_256"
#define OQS_SIG_STFL_alg_xmss_shake256_h20_256 "XMSS-SHAKE256_20_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_2 "XMSSMT-SHA2_20/2_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h20_4 "XMSSMT-SHA2_20/4_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_2 "XMSSMT-SHA2_40/2_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_4 "XMSSMT-SHA2_40/4_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h40_8 "XMSSMT-SHA2_40/8_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_3 "XMSSMT-SHA2_60/3_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_6 "XMSSMT-SHA2_60/6_256"
#define OQS_SIG_STFL_alg_xmssmt_sha256_h60_12 "XMSSMT-SHA2_60/12_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_2 "XMSSMT-SHAKE_20/2_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h20_4 "XMSSMT-SHAKE_20/4_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_2 "XMSSMT-SHAKE_40/2_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_4 "XMSSMT-SHAKE_40/4_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h40_8 "XMSSMT-SHAKE_40/8_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_3 "XMSSMT-SHAKE_60/3_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_6 "XMSSMT-SHAKE_60/6_256"
#define OQS_SIG_STFL_alg_xmssmt_shake128_h60_12 "XMSSMT-SHAKE_60/12_256"
/* Defined LMS parameter identifiers */
#define OQS_SIG_STFL_alg_lms_sha256_h5_w1 "LMS_SHA256_H5_W1" //"5/1"
#define OQS_SIG_STFL_alg_lms_sha256_h5_w2 "LMS_SHA256_H5_W2" //"5/2"
#define OQS_SIG_STFL_alg_lms_sha256_h5_w4 "LMS_SHA256_H5_W4" //"5/4"
#define OQS_SIG_STFL_alg_lms_sha256_h5_w8 "LMS_SHA256_H5_W8" //"5/8"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w1 "LMS_SHA256_H10_W1" //"10/1"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w2 "LMS_SHA256_H10_W2" //"10/2"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4 "LMS_SHA256_H10_W4" //"10/4"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8 "LMS_SHA256_H10_W8" //"10/8"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w1 "LMS_SHA256_H15_W1" //"15/1"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w2 "LMS_SHA256_H15_W2" //"15/2"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w4 "LMS_SHA256_H15_W4" //"15/4"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8 "LMS_SHA256_H15_W8" //"15/8"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w1 "LMS_SHA256_H20_W1" //"20/1"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w2 "LMS_SHA256_H20_W2" //"20/2"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w4 "LMS_SHA256_H20_W4" //"20/4"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8 "LMS_SHA256_H20_W8" //"20/8"
#define OQS_SIG_STFL_alg_lms_sha256_h25_w1 "LMS_SHA256_H25_W1" //"25/1"
#define OQS_SIG_STFL_alg_lms_sha256_h25_w2 "LMS_SHA256_H25_W2" //"25/2"
#define OQS_SIG_STFL_alg_lms_sha256_h25_w4 "LMS_SHA256_H25_W4" //"25/4"
#define OQS_SIG_STFL_alg_lms_sha256_h25_w8 "LMS_SHA256_H25_W8" //"25/8"
// 2-Level LMS
#define OQS_SIG_STFL_alg_lms_sha256_h5_w8_h5_w8 "LMS_SHA256_H5_W8_H5_W8" //"5/8, 5/8"
// RFC 6554
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h5_w8 "LMS_SHA256_H10_W4_H5_W8" //"10/4, 5/8"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h5_w8 "LMS_SHA256_H10_W8_H5_W8" //"10/8, 5/8"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w2_h10_w2 "LMS_SHA256_H10_W2_H10_W2" //"10/2, 10/2"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w4_h10_w4 "LMS_SHA256_H10_W4_H10_W4" //"10/4, 10/4"
#define OQS_SIG_STFL_alg_lms_sha256_h10_w8_h10_w8 "LMS_SHA256_H10_W8_H10_W8" //"10/8, 10/8"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h5_w8 "LMS_SHA256_H15_W8_H5_W8" //"15/8, 5/8"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h10_w8 "LMS_SHA256_H15_W8_H10_W8" //"15/8, 10/8"
#define OQS_SIG_STFL_alg_lms_sha256_h15_w8_h15_w8 "LMS_SHA256_H15_W8_H15_W8" //"15/8, 15/8"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h5_w8 "LMS_SHA256_H20_W8_H5_W8" //"20/8, 5/8"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h10_w8 "LMS_SHA256_H20_W8_H10_W8" //"20/8, 10/8"
#define OQS_SIG_STFL_alg_lms_sha256_h20_w8_h15_w8 "LMS_SHA256_H20_W8_H15_W8" //"20/8, 15/8"
#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
typedef struct OQS_SIG OQS_SIG;
#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;
/** 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] 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] sig The OQS_SIG_STFL_SECRET_KEY object to free.
* @return OQS_SUCCESS if successful, or OQS_ERROR if the object cannot be freed.
*/
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.
* @return None.
*
* @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.
* @return None.
*
* @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.
* @return None.
*
* @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.
* @return None.
*/
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 */