Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/keymgmt/slh_dsa_kmgmt.c
Line
Count
Source
1
/*
2
 * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
/* clang-format off */
10
11
/* clang-format on */
12
13
#include <openssl/core_dispatch.h>
14
#include <openssl/core_names.h>
15
#include <openssl/param_build.h>
16
#include <openssl/proverr.h>
17
#include <openssl/self_test.h>
18
#include <openssl/proverr.h>
19
#include "crypto/slh_dsa.h"
20
#include "internal/fips.h"
21
#include "internal/param_build_set.h"
22
#include "prov/implementations.h"
23
#include "prov/providercommon.h"
24
#include "prov/provider_ctx.h"
25
#include "providers/implementations/keymgmt/keymgmtcommon.inc"
26
27
#ifdef FIPS_MODULE
28
static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key,
29
    SLH_DSA_HASH_CTX *ctx);
30
#endif /* FIPS_MODULE */
31
32
static OSSL_FUNC_keymgmt_free_fn slh_dsa_free_key;
33
static OSSL_FUNC_keymgmt_has_fn slh_dsa_has;
34
static OSSL_FUNC_keymgmt_match_fn slh_dsa_match;
35
static OSSL_FUNC_keymgmt_import_fn slh_dsa_import;
36
static OSSL_FUNC_keymgmt_export_fn slh_dsa_export;
37
static OSSL_FUNC_keymgmt_import_types_fn slh_dsa_imexport_types;
38
static OSSL_FUNC_keymgmt_export_types_fn slh_dsa_imexport_types;
39
static OSSL_FUNC_keymgmt_load_fn slh_dsa_load;
40
static OSSL_FUNC_keymgmt_get_params_fn slh_dsa_get_params;
41
static OSSL_FUNC_keymgmt_gettable_params_fn slh_dsa_gettable_params;
42
static OSSL_FUNC_keymgmt_validate_fn slh_dsa_validate;
43
static OSSL_FUNC_keymgmt_gen_init_fn slh_dsa_gen_init;
44
static OSSL_FUNC_keymgmt_gen_cleanup_fn slh_dsa_gen_cleanup;
45
static OSSL_FUNC_keymgmt_gen_set_params_fn slh_dsa_gen_set_params;
46
static OSSL_FUNC_keymgmt_gen_settable_params_fn slh_dsa_gen_settable_params;
47
static OSSL_FUNC_keymgmt_dup_fn slh_dsa_dup_key;
48
49
2.36k
#define SLH_DSA_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
50
51
struct slh_dsa_gen_ctx {
52
    SLH_DSA_HASH_CTX *ctx;
53
    OSSL_LIB_CTX *libctx;
54
    char *propq;
55
    uint8_t entropy[SLH_DSA_MAX_N * 3];
56
    size_t entropy_len;
57
};
58
59
static void *slh_dsa_new_key(void *provctx, const char *alg)
60
727
{
61
727
    if (!ossl_prov_is_running())
62
0
        return 0;
63
64
727
    return ossl_slh_dsa_key_new(PROV_LIBCTX_OF(provctx), NULL, alg);
65
727
}
66
67
static void slh_dsa_free_key(void *keydata)
68
2.89k
{
69
2.89k
    ossl_slh_dsa_key_free((SLH_DSA_KEY *)keydata);
70
2.89k
}
71
72
static void *slh_dsa_dup_key(const void *keydata_from, int selection)
73
24
{
74
24
    if (ossl_prov_is_running())
75
24
        return ossl_slh_dsa_key_dup(keydata_from, selection);
76
0
    return NULL;
77
24
}
78
79
static int slh_dsa_has(const void *keydata, int selection)
80
1.78k
{
81
1.78k
    const SLH_DSA_KEY *key = keydata;
82
83
1.78k
    if (!ossl_prov_is_running() || key == NULL)
84
0
        return 0;
85
1.78k
    if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
86
24
        return 1; /* the selection is not missing */
87
88
1.75k
    return ossl_slh_dsa_key_has(key, selection);
89
1.78k
}
90
91
static int slh_dsa_match(const void *keydata1, const void *keydata2, int selection)
92
723
{
93
723
    const SLH_DSA_KEY *key1 = keydata1;
94
723
    const SLH_DSA_KEY *key2 = keydata2;
95
96
723
    if (!ossl_prov_is_running())
97
0
        return 0;
98
723
    if (key1 == NULL || key2 == NULL)
99
0
        return 0;
100
723
    return ossl_slh_dsa_key_equal(key1, key2, selection);
101
723
}
102
103
static int slh_dsa_validate(const void *key_data, int selection, int check_type)
104
96
{
105
96
    const SLH_DSA_KEY *key = key_data;
106
107
96
    if (!slh_dsa_has(key, selection))
108
0
        return 0;
109
110
96
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
111
24
        return ossl_slh_dsa_key_pairwise_check(key);
112
72
    return 1;
113
96
}
114
115
/* clang-format off */
116
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
117
#ifndef slh_dsa_import_list
118
static ossl_unused const OSSL_PARAM slh_dsa_import_list[] = {
119
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
120
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
121
    OSSL_PARAM_END
122
};
123
#endif
124
125
#ifndef slh_dsa_import_st
126
struct slh_dsa_import_st {
127
    OSSL_PARAM *priv;
128
    OSSL_PARAM *pub;
129
};
130
#endif
131
132
#ifndef slh_dsa_import_decoder
133
static ossl_unused int slh_dsa_import_decoder
134
    (const OSSL_PARAM *p, struct slh_dsa_import_st *r)
135
582
{
136
582
    const char *s;
137
138
582
    memset(r, 0, sizeof(*r));
139
582
    if (p != NULL)
140
1.74k
        for (; (s = p->key) != NULL; p++)
141
1.16k
            switch(s[0]) {
142
0
            default:
143
0
                break;
144
1.16k
            case 'p':
145
1.16k
                switch(s[1]) {
146
0
                default:
147
0
                    break;
148
582
                case 'r':
149
582
                    if (ossl_likely(strcmp("iv", s + 2) == 0)) {
150
                        /* OSSL_PKEY_PARAM_PRIV_KEY */
151
582
                        if (ossl_unlikely(r->priv != NULL)) {
152
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
153
0
                                           "param %s is repeated", s);
154
0
                            return 0;
155
0
                        }
156
582
                        r->priv = (OSSL_PARAM *)p;
157
582
                    }
158
582
                    break;
159
582
                case 'u':
160
582
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
161
                        /* OSSL_PKEY_PARAM_PUB_KEY */
162
582
                        if (ossl_unlikely(r->pub != NULL)) {
163
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
164
0
                                           "param %s is repeated", s);
165
0
                            return 0;
166
0
                        }
167
582
                        r->pub = (OSSL_PARAM *)p;
168
582
                    }
169
1.16k
                }
170
1.16k
            }
171
582
    return 1;
172
582
}
173
#endif
174
/* End of machine generated */
175
/* clang-format on */
176
177
static int slh_dsa_import(void *keydata, int selection, const OSSL_PARAM params[])
178
582
{
179
582
    SLH_DSA_KEY *key = keydata;
180
582
    int include_priv;
181
582
    struct slh_dsa_import_st p;
182
183
582
    if (!ossl_prov_is_running()
184
582
        || key == NULL
185
582
        || !slh_dsa_import_decoder(params, &p))
186
0
        return 0;
187
188
582
    if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
189
0
        return 0;
190
191
582
    include_priv = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
192
582
    return ossl_slh_dsa_key_fromdata(key, p.pub, p.priv, include_priv);
193
582
}
194
195
static const OSSL_PARAM *slh_dsa_imexport_types(int selection)
196
0
{
197
0
    if ((selection & SLH_DSA_POSSIBLE_SELECTIONS) == 0)
198
0
        return NULL;
199
0
    return slh_dsa_import_list;
200
0
}
201
202
/* clang-format off */
203
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
204
#ifndef slh_dsa_get_params_list
205
static ossl_unused const OSSL_PARAM slh_dsa_get_params_list[] = {
206
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
207
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
208
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
209
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
210
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
211
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
212
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
213
    OSSL_PARAM_END
214
};
215
#endif
216
217
#ifndef slh_dsa_get_params_st
218
struct slh_dsa_get_params_st {
219
    OSSL_PARAM *bits;
220
    OSSL_PARAM *mandgst;
221
    OSSL_PARAM *maxsize;
222
    OSSL_PARAM *priv;
223
    OSSL_PARAM *pub;
224
    OSSL_PARAM *secbits;
225
    OSSL_PARAM *seccat;
226
};
227
#endif
228
229
#ifndef slh_dsa_get_params_decoder
230
static ossl_unused int slh_dsa_get_params_decoder
231
    (const OSSL_PARAM *p, struct slh_dsa_get_params_st *r)
232
2.07k
{
233
2.07k
    const char *s;
234
235
2.07k
    memset(r, 0, sizeof(*r));
236
2.07k
    if (p != NULL)
237
10.3k
        for (; (s = p->key) != NULL; p++)
238
8.27k
            switch(s[0]) {
239
12
            default:
240
12
                break;
241
2.06k
            case 'b':
242
2.06k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
243
                    /* OSSL_PKEY_PARAM_BITS */
244
2.06k
                    if (ossl_unlikely(r->bits != NULL)) {
245
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
246
0
                                       "param %s is repeated", s);
247
0
                        return 0;
248
0
                    }
249
2.06k
                    r->bits = (OSSL_PARAM *)p;
250
2.06k
                }
251
2.06k
                break;
252
2.07k
            case 'm':
253
2.07k
                switch(s[1]) {
254
0
                default:
255
0
                    break;
256
2.07k
                case 'a':
257
2.07k
                    switch(s[2]) {
258
0
                    default:
259
0
                        break;
260
12
                    case 'n':
261
12
                        if (ossl_likely(strcmp("datory-digest", s + 3) == 0)) {
262
                            /* OSSL_PKEY_PARAM_MANDATORY_DIGEST */
263
12
                            if (ossl_unlikely(r->mandgst != NULL)) {
264
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
265
0
                                               "param %s is repeated", s);
266
0
                                return 0;
267
0
                            }
268
12
                            r->mandgst = (OSSL_PARAM *)p;
269
12
                        }
270
12
                        break;
271
2.06k
                    case 'x':
272
2.06k
                        if (ossl_likely(strcmp("-size", s + 3) == 0)) {
273
                            /* OSSL_PKEY_PARAM_MAX_SIZE */
274
2.06k
                            if (ossl_unlikely(r->maxsize != NULL)) {
275
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
276
0
                                               "param %s is repeated", s);
277
0
                                return 0;
278
0
                            }
279
2.06k
                            r->maxsize = (OSSL_PARAM *)p;
280
2.06k
                        }
281
2.07k
                    }
282
2.07k
                }
283
2.07k
                break;
284
2.07k
            case 'p':
285
0
                switch(s[1]) {
286
0
                default:
287
0
                    break;
288
0
                case 'r':
289
0
                    if (ossl_likely(strcmp("iv", s + 2) == 0)) {
290
                        /* OSSL_PKEY_PARAM_PRIV_KEY */
291
0
                        if (ossl_unlikely(r->priv != NULL)) {
292
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
293
0
                                           "param %s is repeated", s);
294
0
                            return 0;
295
0
                        }
296
0
                        r->priv = (OSSL_PARAM *)p;
297
0
                    }
298
0
                    break;
299
0
                case 'u':
300
0
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
301
                        /* OSSL_PKEY_PARAM_PUB_KEY */
302
0
                        if (ossl_unlikely(r->pub != NULL)) {
303
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
304
0
                                           "param %s is repeated", s);
305
0
                            return 0;
306
0
                        }
307
0
                        r->pub = (OSSL_PARAM *)p;
308
0
                    }
309
0
                }
310
0
                break;
311
4.12k
            case 's':
312
4.12k
                switch(s[1]) {
313
0
                default:
314
0
                    break;
315
4.12k
                case 'e':
316
4.12k
                    switch(s[2]) {
317
0
                    default:
318
0
                        break;
319
4.12k
                    case 'c':
320
4.12k
                        switch(s[3]) {
321
0
                        default:
322
0
                            break;
323
4.12k
                        case 'u':
324
4.12k
                            switch(s[4]) {
325
0
                            default:
326
0
                                break;
327
4.12k
                            case 'r':
328
4.12k
                                switch(s[5]) {
329
0
                                default:
330
0
                                    break;
331
4.12k
                                case 'i':
332
4.12k
                                    switch(s[6]) {
333
0
                                    default:
334
0
                                        break;
335
4.12k
                                    case 't':
336
4.12k
                                        switch(s[7]) {
337
0
                                        default:
338
0
                                            break;
339
4.12k
                                        case 'y':
340
4.12k
                                            switch(s[8]) {
341
0
                                            default:
342
0
                                                break;
343
4.12k
                                            case '-':
344
4.12k
                                                switch(s[9]) {
345
0
                                                default:
346
0
                                                    break;
347
2.06k
                                                case 'b':
348
2.06k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
349
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
350
2.06k
                                                        if (ossl_unlikely(r->secbits != NULL)) {
351
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
352
0
                                                                           "param %s is repeated", s);
353
0
                                                            return 0;
354
0
                                                        }
355
2.06k
                                                        r->secbits = (OSSL_PARAM *)p;
356
2.06k
                                                    }
357
2.06k
                                                    break;
358
2.06k
                                                case 'c':
359
2.06k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
360
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
361
2.06k
                                                        if (ossl_unlikely(r->seccat != NULL)) {
362
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
363
0
                                                                           "param %s is repeated", s);
364
0
                                                            return 0;
365
0
                                                        }
366
2.06k
                                                        r->seccat = (OSSL_PARAM *)p;
367
2.06k
                                                    }
368
4.12k
                                                }
369
4.12k
                                            }
370
4.12k
                                        }
371
4.12k
                                    }
372
4.12k
                                }
373
4.12k
                            }
374
4.12k
                        }
375
4.12k
                    }
376
4.12k
                }
377
8.27k
            }
378
2.07k
    return 1;
379
2.07k
}
380
#endif
381
/* End of machine generated */
382
/* clang-format on */
383
384
static const OSSL_PARAM *slh_dsa_gettable_params(void *provctx)
385
0
{
386
0
    return slh_dsa_get_params_list;
387
0
}
388
389
static int key_to_params(SLH_DSA_KEY *key, OSSL_PARAM_BLD *tmpl,
390
    int selection)
391
538
{
392
    /* Error if there is no key or public key */
393
538
    if (key == NULL || ossl_slh_dsa_key_get_pub(key) == NULL)
394
0
        return 0;
395
396
538
    if (((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
397
538
        && ossl_slh_dsa_key_get_priv(key) != NULL)
398
538
        if (ossl_param_build_set_octet_string(tmpl, NULL,
399
538
                OSSL_PKEY_PARAM_PRIV_KEY,
400
538
                ossl_slh_dsa_key_get_priv(key),
401
538
                ossl_slh_dsa_key_get_priv_len(key))
402
538
            != 1)
403
0
            return 0;
404
405
538
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
406
0
        return 1;
407
408
538
    return ossl_param_build_set_octet_string(tmpl, NULL,
409
538
        OSSL_PKEY_PARAM_PUB_KEY,
410
538
        ossl_slh_dsa_key_get_pub(key),
411
538
        ossl_slh_dsa_key_get_pub_len(key));
412
538
}
413
414
static int slh_dsa_get_params(void *keydata, OSSL_PARAM params[])
415
2.07k
{
416
2.07k
    SLH_DSA_KEY *key = keydata;
417
2.07k
    struct slh_dsa_get_params_st p;
418
2.07k
    const uint8_t *pub, *priv;
419
420
2.07k
    if (key == NULL || !slh_dsa_get_params_decoder(params, &p))
421
0
        return 0;
422
423
2.07k
    if (p.bits != NULL
424
2.06k
        && !OSSL_PARAM_set_size_t(p.bits, 8 * ossl_slh_dsa_key_get_pub_len(key)))
425
0
        return 0;
426
2.07k
    if (p.secbits != NULL
427
2.06k
        && !OSSL_PARAM_set_size_t(p.secbits, 8 * ossl_slh_dsa_key_get_n(key)))
428
0
        return 0;
429
2.07k
    if (p.maxsize != NULL
430
2.06k
        && !OSSL_PARAM_set_size_t(p.maxsize, ossl_slh_dsa_key_get_sig_len(key)))
431
0
        return 0;
432
2.07k
    if (p.seccat != NULL
433
2.06k
        && !OSSL_PARAM_set_int(p.seccat, ossl_slh_dsa_key_get_security_category(key)))
434
0
        return 0;
435
436
2.07k
    priv = ossl_slh_dsa_key_get_priv(key);
437
2.07k
    if (priv != NULL) {
438
        /* Note: ossl_slh_dsa_key_get_priv_len() includes the public key */
439
1.92k
        if (p.priv != NULL
440
0
            && !OSSL_PARAM_set_octet_string(p.priv, priv,
441
0
                ossl_slh_dsa_key_get_priv_len(key)))
442
0
            return 0;
443
1.92k
    }
444
2.07k
    pub = ossl_slh_dsa_key_get_pub(key);
445
2.07k
    if (pub != NULL) {
446
2.07k
        if (p.pub != NULL
447
0
            && !OSSL_PARAM_set_octet_string(p.pub, pub,
448
0
                ossl_slh_dsa_key_get_pub_len(key)))
449
0
            return 0;
450
2.07k
    }
451
    /*
452
     * This allows apps to use an empty digest, so that the old API
453
     * for digest signing can be used.
454
     */
455
2.07k
    if (p.mandgst != NULL && !OSSL_PARAM_set_utf8_string(p.mandgst, ""))
456
0
        return 0;
457
2.07k
    return 1;
458
2.07k
}
459
460
static int slh_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
461
    void *cbarg)
462
198
{
463
198
    SLH_DSA_KEY *key = keydata;
464
198
    OSSL_PARAM_BLD *tmpl;
465
198
    OSSL_PARAM *params = NULL, *p;
466
198
    int ret = 0;
467
468
198
    if (!ossl_prov_is_running() || key == NULL)
469
0
        return 0;
470
471
198
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
472
0
        return 0;
473
474
198
    tmpl = OSSL_PARAM_BLD_new();
475
198
    if (tmpl == NULL)
476
0
        return 0;
477
478
198
    if (!key_to_params(key, tmpl, selection))
479
0
        goto err;
480
481
198
    params = OSSL_PARAM_BLD_to_param(tmpl);
482
198
    if (params == NULL)
483
0
        goto err;
484
485
198
    ret = param_cb(params, cbarg);
486
    /*
487
     * OSSL_PARAM_free() only wipes the secure-heap data block,
488
     * so wipe the key material copies held in the params first.
489
     */
490
594
    for (p = params; p->key != NULL; p++)
491
396
        OPENSSL_cleanse(p->data, p->data_size);
492
198
    OSSL_PARAM_free(params);
493
198
err:
494
198
    OSSL_PARAM_BLD_free(tmpl);
495
198
    return ret;
496
198
}
497
498
static void *slh_dsa_load(const void *reference, size_t reference_sz)
499
191
{
500
191
    SLH_DSA_KEY *key = NULL;
501
502
191
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
503
        /* The contents of the reference is the address to our object */
504
191
        key = *(SLH_DSA_KEY **)reference;
505
        /* We grabbed, so we detach it */
506
191
        *(SLH_DSA_KEY **)reference = NULL;
507
191
        return key;
508
191
    }
509
0
    return NULL;
510
191
}
511
512
static void *slh_dsa_gen_init(void *provctx, int selection,
513
    const OSSL_PARAM params[])
514
1.95k
{
515
1.95k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
516
1.95k
    struct slh_dsa_gen_ctx *gctx = NULL;
517
518
1.95k
    if (!ossl_prov_is_running())
519
0
        return NULL;
520
521
1.95k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
522
1.95k
        gctx->libctx = libctx;
523
1.95k
        if (!slh_dsa_gen_set_params(gctx, params)) {
524
0
            OPENSSL_free(gctx);
525
0
            gctx = NULL;
526
0
        }
527
1.95k
    }
528
1.95k
    return gctx;
529
1.95k
}
530
531
#ifdef FIPS_MODULE
532
/*
533
 * Refer to FIPS 140-3 IG 10.3.A Additional Comment 1
534
 * Perform a pairwise test for SLH_DSA by signing and verifying a signature.
535
 */
536
static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key,
537
    SLH_DSA_HASH_CTX *ctx)
538
{
539
    int ret = 0;
540
    OSSL_SELF_TEST *st = NULL;
541
    OSSL_CALLBACK *cb = NULL;
542
    void *cb_arg = NULL;
543
    uint8_t msg[16] = { 0 };
544
    size_t msg_len = sizeof(msg);
545
    uint8_t *sig = NULL;
546
    size_t sig_len = 0;
547
    OSSL_LIB_CTX *lib_ctx;
548
    int alloc_ctx = 0;
549
550
    /* During self test, it is a waste to do this test */
551
    if (ossl_fips_self_testing())
552
        return 1;
553
554
    if (ctx == NULL) {
555
        ctx = ossl_slh_dsa_hash_ctx_new(key);
556
        if (ctx == NULL)
557
            return 0;
558
        alloc_ctx = 1;
559
    }
560
    lib_ctx = ossl_slh_dsa_key_get0_libctx(key);
561
562
    OSSL_SELF_TEST_get_callback(lib_ctx, &cb, &cb_arg);
563
    st = OSSL_SELF_TEST_new(cb, cb_arg);
564
    if (st == NULL)
565
        goto err;
566
567
    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
568
        OSSL_SELF_TEST_DESC_PCT_SLH_DSA);
569
570
    sig_len = ossl_slh_dsa_key_get_sig_len(key);
571
    sig = OPENSSL_malloc(sig_len);
572
    if (sig == NULL)
573
        goto err;
574
575
    if (ossl_slh_dsa_sign(ctx, msg, msg_len, NULL, 0, NULL, 0,
576
            sig, &sig_len, sig_len)
577
        != 1)
578
        goto err;
579
580
    OSSL_SELF_TEST_oncorrupt_byte(st, sig);
581
582
    if (ossl_slh_dsa_verify(ctx, msg, msg_len, NULL, 0, 0, sig, sig_len) != 1)
583
        goto err;
584
585
    ret = 1;
586
err:
587
    if (alloc_ctx)
588
        ossl_slh_dsa_hash_ctx_free(ctx);
589
    OPENSSL_clear_free(sig, sig_len);
590
    OSSL_SELF_TEST_onend(st, ret);
591
    OSSL_SELF_TEST_free(st);
592
    return ret;
593
}
594
#endif /* FIPS_MODULE */
595
596
static void *slh_dsa_gen(void *genctx, const char *alg)
597
1.95k
{
598
1.95k
    struct slh_dsa_gen_ctx *gctx = genctx;
599
1.95k
    SLH_DSA_KEY *key = NULL;
600
1.95k
    SLH_DSA_HASH_CTX *ctx = NULL;
601
602
1.95k
    if (!ossl_prov_is_running())
603
0
        return NULL;
604
1.95k
    key = ossl_slh_dsa_key_new(gctx->libctx, gctx->propq, alg);
605
1.95k
    if (key == NULL)
606
0
        return NULL;
607
1.95k
    ctx = ossl_slh_dsa_hash_ctx_new(key);
608
1.95k
    if (ctx == NULL)
609
0
        goto err;
610
1.95k
    if (!ossl_slh_dsa_generate_key(ctx, key, gctx->libctx,
611
1.95k
            gctx->entropy, gctx->entropy_len))
612
0
        goto err;
613
#ifdef FIPS_MODULE
614
    if (!slh_dsa_fips140_pairwise_test(key, ctx))
615
        goto err;
616
#endif /* FIPS_MODULE */
617
1.95k
    ossl_slh_dsa_hash_ctx_free(ctx);
618
1.95k
    return key;
619
0
err:
620
0
    ossl_slh_dsa_hash_ctx_free(ctx);
621
0
    ossl_slh_dsa_key_free(key);
622
0
    return NULL;
623
1.95k
}
624
625
/* clang-format off */
626
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
627
#ifndef slh_dsa_gen_set_params_list
628
static ossl_unused const OSSL_PARAM slh_dsa_gen_set_params_list[] = {
629
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
630
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_SLH_DSA_SEED, NULL, 0),
631
    OSSL_PARAM_END
632
};
633
#endif
634
635
#ifndef slh_dsa_gen_set_params_st
636
struct slh_dsa_gen_set_params_st {
637
    OSSL_PARAM *propq;
638
    OSSL_PARAM *seed;
639
};
640
#endif
641
642
#ifndef slh_dsa_gen_set_params_decoder
643
static ossl_unused int slh_dsa_gen_set_params_decoder
644
    (const OSSL_PARAM *p, struct slh_dsa_gen_set_params_st *r)
645
1.44k
{
646
1.44k
    const char *s;
647
648
1.44k
    memset(r, 0, sizeof(*r));
649
1.44k
    if (p != NULL)
650
0
        for (; (s = p->key) != NULL; p++)
651
0
            switch(s[0]) {
652
0
            default:
653
0
                break;
654
0
            case 'p':
655
0
                if (ossl_likely(strcmp("roperties", s + 1) == 0)) {
656
                    /* OSSL_PKEY_PARAM_PROPERTIES */
657
0
                    if (ossl_unlikely(r->propq != NULL)) {
658
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
659
0
                                       "param %s is repeated", s);
660
0
                        return 0;
661
0
                    }
662
0
                    r->propq = (OSSL_PARAM *)p;
663
0
                }
664
0
                break;
665
0
            case 's':
666
0
                if (ossl_likely(strcmp("eed", s + 1) == 0)) {
667
                    /* OSSL_PKEY_PARAM_SLH_DSA_SEED */
668
0
                    if (ossl_unlikely(r->seed != NULL)) {
669
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
670
0
                                       "param %s is repeated", s);
671
0
                        return 0;
672
0
                    }
673
0
                    r->seed = (OSSL_PARAM *)p;
674
0
                }
675
0
            }
676
1.44k
    return 1;
677
1.44k
}
678
#endif
679
/* End of machine generated */
680
/* clang-format on */
681
682
static int slh_dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
683
1.44k
{
684
1.44k
    struct slh_dsa_gen_ctx *gctx = genctx;
685
1.44k
    struct slh_dsa_gen_set_params_st p;
686
687
1.44k
    if (gctx == NULL || !slh_dsa_gen_set_params_decoder(params, &p))
688
0
        return 0;
689
690
1.44k
    if (p.seed != NULL) {
691
0
        void *vp = gctx->entropy;
692
0
        size_t len = sizeof(gctx->entropy);
693
694
0
        if (!OSSL_PARAM_get_octet_string(p.seed, &vp, len, &(gctx->entropy_len))) {
695
0
            gctx->entropy_len = 0;
696
0
            return 0;
697
0
        }
698
0
    }
699
700
1.44k
    if (p.propq != NULL) {
701
0
        if (p.propq->data_type != OSSL_PARAM_UTF8_STRING)
702
0
            return 0;
703
0
        OPENSSL_free(gctx->propq);
704
0
        gctx->propq = OPENSSL_strdup(p.propq->data);
705
0
        if (gctx->propq == NULL)
706
0
            return 0;
707
0
    }
708
1.44k
    return 1;
709
1.44k
}
710
711
static const OSSL_PARAM *slh_dsa_gen_settable_params(ossl_unused void *genctx,
712
    ossl_unused void *provctx)
713
0
{
714
0
    return slh_dsa_gen_set_params_list;
715
0
}
716
717
static void slh_dsa_gen_cleanup(void *genctx)
718
1.95k
{
719
1.95k
    struct slh_dsa_gen_ctx *gctx = genctx;
720
721
1.95k
    if (gctx == NULL)
722
0
        return;
723
724
1.95k
    OPENSSL_cleanse(gctx->entropy, sizeof(gctx->entropy));
725
1.95k
    OPENSSL_free(gctx->propq);
726
1.95k
    OPENSSL_free(gctx);
727
1.95k
}
728
729
#define MAKE_KEYMGMT_FUNCTIONS(alg, fn)                                                 \
730
    static OSSL_FUNC_keymgmt_new_fn slh_dsa_##fn##_new_key;                             \
731
    static OSSL_FUNC_keymgmt_gen_fn slh_dsa_##fn##_gen;                                 \
732
    static void *slh_dsa_##fn##_new_key(void *provctx)                                  \
733
727
    {                                                                                   \
734
727
        return slh_dsa_new_key(provctx, alg);                                           \
735
727
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_128s_new_key
Line
Count
Source
733
129
    {                                                                                   \
734
129
        return slh_dsa_new_key(provctx, alg);                                           \
735
129
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_128f_new_key
Line
Count
Source
733
56
    {                                                                                   \
734
56
        return slh_dsa_new_key(provctx, alg);                                           \
735
56
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_192s_new_key
Line
Count
Source
733
53
    {                                                                                   \
734
53
        return slh_dsa_new_key(provctx, alg);                                           \
735
53
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_192f_new_key
Line
Count
Source
733
107
    {                                                                                   \
734
107
        return slh_dsa_new_key(provctx, alg);                                           \
735
107
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_256s_new_key
Line
Count
Source
733
36
    {                                                                                   \
734
36
        return slh_dsa_new_key(provctx, alg);                                           \
735
36
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_256f_new_key
Line
Count
Source
733
44
    {                                                                                   \
734
44
        return slh_dsa_new_key(provctx, alg);                                           \
735
44
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_128s_new_key
Line
Count
Source
733
54
    {                                                                                   \
734
54
        return slh_dsa_new_key(provctx, alg);                                           \
735
54
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_128f_new_key
Line
Count
Source
733
44
    {                                                                                   \
734
44
        return slh_dsa_new_key(provctx, alg);                                           \
735
44
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_192s_new_key
Line
Count
Source
733
66
    {                                                                                   \
734
66
        return slh_dsa_new_key(provctx, alg);                                           \
735
66
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_192f_new_key
Line
Count
Source
733
37
    {                                                                                   \
734
37
        return slh_dsa_new_key(provctx, alg);                                           \
735
37
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_256s_new_key
Line
Count
Source
733
60
    {                                                                                   \
734
60
        return slh_dsa_new_key(provctx, alg);                                           \
735
60
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_256f_new_key
Line
Count
Source
733
41
    {                                                                                   \
734
41
        return slh_dsa_new_key(provctx, alg);                                           \
735
41
    }                                                                                   \
736
    static void *slh_dsa_##fn##_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)   \
737
1.95k
    {                                                                                   \
738
1.95k
        return slh_dsa_gen(genctx, alg);                                                \
739
1.95k
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_128s_gen
Line
Count
Source
737
299
    {                                                                                   \
738
299
        return slh_dsa_gen(genctx, alg);                                                \
739
299
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_128f_gen
Line
Count
Source
737
265
    {                                                                                   \
738
265
        return slh_dsa_gen(genctx, alg);                                                \
739
265
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_192s_gen
Line
Count
Source
737
93
    {                                                                                   \
738
93
        return slh_dsa_gen(genctx, alg);                                                \
739
93
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_192f_gen
Line
Count
Source
737
346
    {                                                                                   \
738
346
        return slh_dsa_gen(genctx, alg);                                                \
739
346
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_256s_gen
Line
Count
Source
737
125
    {                                                                                   \
738
125
        return slh_dsa_gen(genctx, alg);                                                \
739
125
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_sha2_256f_gen
Line
Count
Source
737
147
    {                                                                                   \
738
147
        return slh_dsa_gen(genctx, alg);                                                \
739
147
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_128s_gen
Line
Count
Source
737
75
    {                                                                                   \
738
75
        return slh_dsa_gen(genctx, alg);                                                \
739
75
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_128f_gen
Line
Count
Source
737
52
    {                                                                                   \
738
52
        return slh_dsa_gen(genctx, alg);                                                \
739
52
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_192s_gen
Line
Count
Source
737
136
    {                                                                                   \
738
136
        return slh_dsa_gen(genctx, alg);                                                \
739
136
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_192f_gen
Line
Count
Source
737
175
    {                                                                                   \
738
175
        return slh_dsa_gen(genctx, alg);                                                \
739
175
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_256s_gen
Line
Count
Source
737
139
    {                                                                                   \
738
139
        return slh_dsa_gen(genctx, alg);                                                \
739
139
    }                                                                                   \
slh_dsa_kmgmt.c:slh_dsa_shake_256f_gen
Line
Count
Source
737
98
    {                                                                                   \
738
98
        return slh_dsa_gen(genctx, alg);                                                \
739
98
    }                                                                                   \
740
    const OSSL_DISPATCH ossl_slh_dsa_##fn##_keymgmt_functions[] = {                     \
741
        { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))slh_dsa_##fn##_new_key },              \
742
        { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))slh_dsa_free_key },                   \
743
        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))slh_dsa_dup_key },                     \
744
        { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))slh_dsa_has },                         \
745
        { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))slh_dsa_match },                     \
746
        { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))slh_dsa_import },                   \
747
        { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))slh_dsa_imexport_types },     \
748
        { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))slh_dsa_export },                   \
749
        { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))slh_dsa_imexport_types },     \
750
        { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))slh_dsa_load },                       \
751
        { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))slh_dsa_get_params },           \
752
        { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))slh_dsa_gettable_params }, \
753
        { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))slh_dsa_validate },               \
754
        { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))slh_dsa_gen_init },               \
755
        { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))slh_dsa_##fn##_gen },                  \
756
        { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))slh_dsa_gen_cleanup },         \
757
        { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS,                                             \
758
            (void (*)(void))slh_dsa_gen_set_params },                                   \
759
        { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,                                        \
760
            (void (*)(void))slh_dsa_gen_settable_params },                              \
761
        OSSL_KEYMGMT_FIPS_APPROVED_GEN_DISPATCH_END                                     \
762
    }
763
764
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-128s", sha2_128s);
765
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-128f", sha2_128f);
766
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-192s", sha2_192s);
767
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-192f", sha2_192f);
768
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-256s", sha2_256s);
769
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHA2-256f", sha2_256f);
770
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-128s", shake_128s);
771
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-128f", shake_128f);
772
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-192s", shake_192s);
773
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-192f", shake_192f);
774
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-256s", shake_256s);
775
MAKE_KEYMGMT_FUNCTIONS("SLH-DSA-SHAKE-256f", shake_256f);