Coverage Report

Created: 2026-09-12 06:55

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