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/ecx_kmgmt.c
Line
Count
Source
1
/*
2
 * Copyright 2020-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 <assert.h>
14
#include <string.h>
15
#include <openssl/core_dispatch.h>
16
#include <openssl/core_names.h>
17
#include <openssl/params.h>
18
#include <openssl/err.h>
19
#include <openssl/proverr.h>
20
#include <openssl/evp.h>
21
#include <openssl/rand.h>
22
#include <openssl/self_test.h>
23
#include "internal/fips.h"
24
#include "internal/param_build_set.h"
25
#include <openssl/param_build.h>
26
#include "crypto/ecx.h"
27
#include "prov/implementations.h"
28
#include "prov/providercommon.h"
29
#include "prov/provider_ctx.h"
30
#include "prov/ecx.h"
31
#include "prov/securitycheck.h"
32
#include "providers/implementations/keymgmt/keymgmtcommon.inc"
33
#ifdef S390X_EC_ASM
34
#include "s390x_arch.h"
35
#include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
36
#endif
37
38
static OSSL_FUNC_keymgmt_new_fn x25519_new_key;
39
static OSSL_FUNC_keymgmt_new_fn x448_new_key;
40
static OSSL_FUNC_keymgmt_new_fn ed25519_new_key;
41
static OSSL_FUNC_keymgmt_new_fn ed448_new_key;
42
static OSSL_FUNC_keymgmt_free_fn ecx_free_key;
43
static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init;
44
static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init;
45
static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init;
46
static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init;
47
static OSSL_FUNC_keymgmt_gen_fn x25519_gen;
48
static OSSL_FUNC_keymgmt_gen_fn x448_gen;
49
static OSSL_FUNC_keymgmt_gen_fn ed25519_gen;
50
static OSSL_FUNC_keymgmt_gen_fn ed448_gen;
51
static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
52
static OSSL_FUNC_keymgmt_gen_set_params_fn ecx_gen_set_params;
53
static OSSL_FUNC_keymgmt_gen_settable_params_fn ecx_gen_settable_params;
54
static OSSL_FUNC_keymgmt_load_fn ecx_load;
55
static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params;
56
static OSSL_FUNC_keymgmt_get_params_fn x448_get_params;
57
static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params;
58
static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params;
59
static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params;
60
static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params;
61
static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params;
62
static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params;
63
static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params;
64
static OSSL_FUNC_keymgmt_set_params_fn x448_set_params;
65
static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params;
66
static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params;
67
static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params;
68
static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params;
69
static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params;
70
static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params;
71
static OSSL_FUNC_keymgmt_has_fn ecx_has;
72
static OSSL_FUNC_keymgmt_match_fn ecx_match;
73
static OSSL_FUNC_keymgmt_validate_fn x25519_validate;
74
static OSSL_FUNC_keymgmt_validate_fn x448_validate;
75
static OSSL_FUNC_keymgmt_validate_fn ed25519_validate;
76
static OSSL_FUNC_keymgmt_validate_fn ed448_validate;
77
static OSSL_FUNC_keymgmt_import_fn ecx_import;
78
static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
79
static OSSL_FUNC_keymgmt_export_fn ecx_export;
80
static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
81
static OSSL_FUNC_keymgmt_dup_fn ecx_dup;
82
83
27.3k
#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
84
85
struct ecx_gen_ctx {
86
    OSSL_LIB_CTX *libctx;
87
    char *propq;
88
    ECX_KEY_TYPE type;
89
    int selection;
90
    unsigned char *dhkem_ikm;
91
    size_t dhkem_ikmlen;
92
};
93
94
#ifdef S390X_EC_ASM
95
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
96
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
97
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
98
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
99
#endif
100
101
#ifdef FIPS_MODULE
102
static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test);
103
#endif /* FIPS_MODULE */
104
105
static ossl_inline int ecx_key_type_is_ed(ECX_KEY_TYPE type)
106
30
{
107
30
    return type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448;
108
30
}
109
110
#ifdef FIPS_MODULE
111
static int ecx_gen_get_params(void *genctx, OSSL_PARAM params[])
112
{
113
    struct ecx_gen_ctx *gctx = genctx;
114
    struct keymgmt_fips_gen_get_params_st p;
115
116
    if (gctx == NULL || !keymgmt_fips_gen_get_params_decoder(params, &p))
117
        return 0;
118
    if (p.ind != NULL
119
        && !OSSL_PARAM_set_int(p.ind, ecx_key_type_is_ed(gctx->type)))
120
        return 0;
121
    return 1;
122
}
123
#endif
124
125
static void *x25519_new_key(void *provctx)
126
19
{
127
19
    if (!ossl_prov_is_running())
128
0
        return 0;
129
19
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
130
19
        NULL);
131
19
}
132
133
static void *x448_new_key(void *provctx)
134
0
{
135
0
    if (!ossl_prov_is_running())
136
0
        return 0;
137
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0,
138
0
        NULL);
139
0
}
140
141
static void *ed25519_new_key(void *provctx)
142
0
{
143
0
    if (!ossl_prov_is_running())
144
0
        return 0;
145
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0,
146
0
        NULL);
147
0
}
148
149
static void *ed448_new_key(void *provctx)
150
0
{
151
0
    if (!ossl_prov_is_running())
152
0
        return 0;
153
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0,
154
0
        NULL);
155
0
}
156
157
static int ecx_has(const void *keydata, int selection)
158
60.6k
{
159
60.6k
    const ECX_KEY *key = keydata;
160
60.6k
    int ok = 0;
161
162
60.6k
    if (ossl_prov_is_running() && key != NULL) {
163
        /*
164
         * ECX keys always have all the parameters they need (i.e. none).
165
         * Therefore we always return with 1, if asked about parameters.
166
         */
167
30.4k
        ok = 1;
168
169
30.4k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
170
88
            ok = ok && key->haspubkey;
171
172
30.4k
        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
173
19
            ok = ok && key->privkey != NULL;
174
30.4k
    }
175
60.6k
    return ok;
176
60.6k
}
177
178
static int ecx_match(const void *keydata1, const void *keydata2, int selection)
179
44
{
180
44
    const ECX_KEY *key1 = keydata1;
181
44
    const ECX_KEY *key2 = keydata2;
182
44
    int ok = 1;
183
184
44
    if (!ossl_prov_is_running())
185
0
        return 0;
186
187
44
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
188
44
        ok = ok && key1->type == key2->type;
189
44
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
190
44
        int key_checked = 0;
191
192
44
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
193
44
            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
194
44
            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
195
44
            size_t pal = key1->keylen;
196
44
            size_t pbl = key2->keylen;
197
198
44
            if (pa != NULL && pb != NULL) {
199
44
                ok = ok
200
44
                    && key1->type == key2->type
201
44
                    && pal == pbl
202
44
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
203
44
                key_checked = 1;
204
44
            }
205
44
        }
206
44
        if (!key_checked
207
0
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
208
0
            const unsigned char *pa = key1->privkey;
209
0
            const unsigned char *pb = key2->privkey;
210
0
            size_t pal = key1->keylen;
211
0
            size_t pbl = key2->keylen;
212
213
0
            if (pa != NULL && pb != NULL) {
214
0
                ok = ok
215
0
                    && key1->type == key2->type
216
0
                    && pal == pbl
217
0
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
218
0
                key_checked = 1;
219
0
            }
220
0
        }
221
44
        ok = ok && key_checked;
222
44
    }
223
44
    return ok;
224
44
}
225
226
/* clang-format off */
227
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
228
#ifndef ecx_imexport_types_list
229
static ossl_unused const OSSL_PARAM ecx_imexport_types_list[] = {
230
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
231
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
232
    OSSL_PARAM_END
233
};
234
#endif
235
236
#ifndef ecx_imexport_types_st
237
struct ecx_imexport_types_st {
238
    OSSL_PARAM *priv;
239
    OSSL_PARAM *pub;
240
};
241
#endif
242
243
#ifndef ecx_imexport_types_decoder
244
static ossl_unused int ecx_imexport_types_decoder
245
    (const OSSL_PARAM *p, struct ecx_imexport_types_st *r)
246
19
{
247
19
    const char *s;
248
249
19
    memset(r, 0, sizeof(*r));
250
19
    if (p != NULL)
251
38
        for (; (s = p->key) != NULL; p++)
252
19
            switch(s[0]) {
253
0
            default:
254
0
                break;
255
19
            case 'p':
256
19
                switch(s[1]) {
257
0
                default:
258
0
                    break;
259
0
                case 'r':
260
0
                    if (ossl_likely(strcmp("iv", s + 2) == 0)) {
261
                        /* OSSL_PKEY_PARAM_PRIV_KEY */
262
0
                        if (ossl_unlikely(r->priv != 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->priv = (OSSL_PARAM *)p;
268
0
                    }
269
0
                    break;
270
19
                case 'u':
271
19
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
272
                        /* OSSL_PKEY_PARAM_PUB_KEY */
273
19
                        if (ossl_unlikely(r->pub != 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
19
                        r->pub = (OSSL_PARAM *)p;
279
19
                    }
280
19
                }
281
19
            }
282
19
    return 1;
283
19
}
284
#endif
285
/* End of machine generated */
286
/* clang-format on */
287
288
static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
289
19
{
290
19
    ECX_KEY *key = keydata;
291
19
    int ok = 1;
292
19
    int include_private;
293
19
    struct ecx_imexport_types_st p;
294
295
19
    if (!ossl_prov_is_running()
296
19
        || key == NULL
297
19
        || !ecx_imexport_types_decoder(params, &p))
298
0
        return 0;
299
300
19
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
301
0
        return 0;
302
303
19
    include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
304
19
    ok = ok && ossl_ecx_key_fromdata(key, p.pub, p.priv, include_private);
305
306
19
    return ok;
307
19
}
308
309
static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
310
    OSSL_PARAM *pub, OSSL_PARAM *priv, int include_private)
311
548k
{
312
548k
    if (key == NULL)
313
0
        return 0;
314
315
548k
    if (!ossl_param_build_set_octet_string(tmpl, pub,
316
548k
            OSSL_PKEY_PARAM_PUB_KEY,
317
548k
            key->pubkey, key->keylen))
318
0
        return 0;
319
320
548k
    if (include_private
321
461k
        && key->privkey != NULL
322
420k
        && !ossl_param_build_set_octet_string(tmpl, priv,
323
420k
            OSSL_PKEY_PARAM_PRIV_KEY,
324
420k
            key->privkey, key->keylen))
325
0
        return 0;
326
327
548k
    return 1;
328
548k
}
329
330
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
331
    void *cbarg)
332
87.5k
{
333
87.5k
    ECX_KEY *key = keydata;
334
87.5k
    OSSL_PARAM_BLD *tmpl;
335
87.5k
    OSSL_PARAM *params = NULL;
336
87.5k
    int ret = 0;
337
338
87.5k
    if (!ossl_prov_is_running() || key == NULL)
339
0
        return 0;
340
341
87.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
342
0
        return 0;
343
344
87.5k
    tmpl = OSSL_PARAM_BLD_new();
345
87.5k
    if (tmpl == NULL)
346
0
        return 0;
347
348
87.5k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
349
87.5k
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
350
351
87.5k
        if (!key_to_params(key, tmpl, NULL, NULL, include_private))
352
0
            goto err;
353
87.5k
    }
354
355
87.5k
    params = OSSL_PARAM_BLD_to_param(tmpl);
356
87.5k
    if (params == NULL)
357
0
        goto err;
358
359
87.5k
    ret = param_cb(params, cbarg);
360
87.5k
    OSSL_PARAM_free(params);
361
87.5k
err:
362
87.5k
    OSSL_PARAM_BLD_free(tmpl);
363
87.5k
    return ret;
364
87.5k
}
365
366
static const OSSL_PARAM *ecx_imexport_types(int selection)
367
0
{
368
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
369
0
        return ecx_imexport_types_list;
370
0
    return NULL;
371
0
}
372
373
struct ecx_ed_common_get_params_st {
374
    OSSL_PARAM *bits;
375
    OSSL_PARAM *secbits;
376
    OSSL_PARAM *size;
377
    OSSL_PARAM *seccat;
378
    OSSL_PARAM *pub;
379
    OSSL_PARAM *priv;
380
    OSSL_PARAM *encpub; /* ECX only */
381
    OSSL_PARAM *ind; /* ECX only */
382
    OSSL_PARAM *digest; /* Ed only */
383
};
384
385
#define ecx_get_params_st ecx_ed_common_get_params_st
386
387
/* clang-format off */
388
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
389
#ifndef ecx_get_params_list
390
static ossl_unused const OSSL_PARAM ecx_get_params_list[] = {
391
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
392
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
393
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
394
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
395
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
396
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
397
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
398
# if defined(FIPS_MODULE)
399
    OSSL_PARAM_int(OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR, NULL),
400
# endif
401
    OSSL_PARAM_END
402
};
403
#endif
404
405
#ifndef ecx_get_params_st
406
struct ecx_get_params_st {
407
    OSSL_PARAM *bits;
408
    OSSL_PARAM *encpub;
409
# if defined(FIPS_MODULE)
410
    OSSL_PARAM *ind;
411
# endif
412
    OSSL_PARAM *priv;
413
    OSSL_PARAM *pub;
414
    OSSL_PARAM *secbits;
415
    OSSL_PARAM *seccat;
416
    OSSL_PARAM *size;
417
};
418
#endif
419
420
#ifndef ecx_get_params_decoder
421
static ossl_unused int ecx_get_params_decoder
422
    (const OSSL_PARAM *p, struct ecx_get_params_st *r)
423
327k
{
424
327k
    const char *s;
425
426
327k
    memset(r, 0, sizeof(*r));
427
327k
    if (p != NULL)
428
1.17M
        for (; (s = p->key) != NULL; p++)
429
843k
            switch(s[0]) {
430
2
            default:
431
2
                break;
432
172k
            case 'b':
433
172k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
434
                    /* OSSL_PKEY_PARAM_BITS */
435
172k
                    if (ossl_unlikely(r->bits != NULL)) {
436
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
437
0
                                       "param %s is repeated", s);
438
0
                        return 0;
439
0
                    }
440
172k
                    r->bits = (OSSL_PARAM *)p;
441
172k
                }
442
172k
                break;
443
172k
            case 'e':
444
155k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
445
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
446
155k
                    if (ossl_unlikely(r->encpub != NULL)) {
447
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
448
0
                                       "param %s is repeated", s);
449
0
                        return 0;
450
0
                    }
451
155k
                    r->encpub = (OSSL_PARAM *)p;
452
155k
                }
453
155k
                break;
454
155k
            case 'f':
455
# if defined(FIPS_MODULE)
456
                if (ossl_likely(strcmp("ips-indicator", s + 1) == 0)) {
457
                    /* OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR */
458
                    if (ossl_unlikely(r->ind != NULL)) {
459
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
460
                                       "param %s is repeated", s);
461
                        return 0;
462
                    }
463
                    r->ind = (OSSL_PARAM *)p;
464
                }
465
# endif
466
0
                break;
467
172k
            case 'm':
468
172k
                if (ossl_likely(strcmp("ax-size", s + 1) == 0)) {
469
                    /* OSSL_PKEY_PARAM_MAX_SIZE */
470
172k
                    if (ossl_unlikely(r->size != NULL)) {
471
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
472
0
                                       "param %s is repeated", s);
473
0
                        return 0;
474
0
                    }
475
172k
                    r->size = (OSSL_PARAM *)p;
476
172k
                }
477
172k
                break;
478
172k
            case 'p':
479
0
                switch(s[1]) {
480
0
                default:
481
0
                    break;
482
0
                case 'r':
483
0
                    if (ossl_likely(strcmp("iv", s + 2) == 0)) {
484
                        /* OSSL_PKEY_PARAM_PRIV_KEY */
485
0
                        if (ossl_unlikely(r->priv != NULL)) {
486
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
487
0
                                           "param %s is repeated", s);
488
0
                            return 0;
489
0
                        }
490
0
                        r->priv = (OSSL_PARAM *)p;
491
0
                    }
492
0
                    break;
493
0
                case 'u':
494
0
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
495
                        /* OSSL_PKEY_PARAM_PUB_KEY */
496
0
                        if (ossl_unlikely(r->pub != NULL)) {
497
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
498
0
                                           "param %s is repeated", s);
499
0
                            return 0;
500
0
                        }
501
0
                        r->pub = (OSSL_PARAM *)p;
502
0
                    }
503
0
                }
504
0
                break;
505
344k
            case 's':
506
344k
                switch(s[1]) {
507
0
                default:
508
0
                    break;
509
344k
                case 'e':
510
344k
                    switch(s[2]) {
511
0
                    default:
512
0
                        break;
513
344k
                    case 'c':
514
344k
                        switch(s[3]) {
515
0
                        default:
516
0
                            break;
517
344k
                        case 'u':
518
344k
                            switch(s[4]) {
519
0
                            default:
520
0
                                break;
521
344k
                            case 'r':
522
344k
                                switch(s[5]) {
523
0
                                default:
524
0
                                    break;
525
344k
                                case 'i':
526
344k
                                    switch(s[6]) {
527
0
                                    default:
528
0
                                        break;
529
344k
                                    case 't':
530
344k
                                        switch(s[7]) {
531
0
                                        default:
532
0
                                            break;
533
344k
                                        case 'y':
534
344k
                                            switch(s[8]) {
535
0
                                            default:
536
0
                                                break;
537
344k
                                            case '-':
538
344k
                                                switch(s[9]) {
539
0
                                                default:
540
0
                                                    break;
541
172k
                                                case 'b':
542
172k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
543
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
544
172k
                                                        if (ossl_unlikely(r->secbits != NULL)) {
545
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
546
0
                                                                           "param %s is repeated", s);
547
0
                                                            return 0;
548
0
                                                        }
549
172k
                                                        r->secbits = (OSSL_PARAM *)p;
550
172k
                                                    }
551
172k
                                                    break;
552
172k
                                                case 'c':
553
172k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
554
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
555
172k
                                                        if (ossl_unlikely(r->seccat != NULL)) {
556
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
557
0
                                                                           "param %s is repeated", s);
558
0
                                                            return 0;
559
0
                                                        }
560
172k
                                                        r->seccat = (OSSL_PARAM *)p;
561
172k
                                                    }
562
344k
                                                }
563
344k
                                            }
564
344k
                                        }
565
344k
                                    }
566
344k
                                }
567
344k
                            }
568
344k
                        }
569
344k
                    }
570
344k
                }
571
843k
            }
572
327k
    return 1;
573
327k
}
574
#endif
575
/* End of machine generated */
576
/* clang-format on */
577
578
#define ed_get_params_st ecx_ed_common_get_params_st
579
580
/* clang-format off */
581
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
582
#ifndef ed_get_params_list
583
static ossl_unused const OSSL_PARAM ed_get_params_list[] = {
584
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
585
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
586
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
587
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL),
588
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
589
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
590
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
591
    OSSL_PARAM_END
592
};
593
#endif
594
595
#ifndef ed_get_params_st
596
struct ed_get_params_st {
597
    OSSL_PARAM *bits;
598
    OSSL_PARAM *digest;
599
    OSSL_PARAM *priv;
600
    OSSL_PARAM *pub;
601
    OSSL_PARAM *secbits;
602
    OSSL_PARAM *seccat;
603
    OSSL_PARAM *size;
604
};
605
#endif
606
607
#ifndef ed_get_params_decoder
608
static ossl_unused int ed_get_params_decoder
609
    (const OSSL_PARAM *p, struct ed_get_params_st *r)
610
2.46k
{
611
2.46k
    const char *s;
612
613
2.46k
    memset(r, 0, sizeof(*r));
614
2.46k
    if (p != NULL)
615
12.2k
        for (; (s = p->key) != NULL; p++)
616
9.74k
            switch(s[0]) {
617
62
            default:
618
62
                break;
619
2.40k
            case 'b':
620
2.40k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
621
                    /* OSSL_PKEY_PARAM_BITS */
622
2.40k
                    if (ossl_unlikely(r->bits != NULL)) {
623
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
624
0
                                       "param %s is repeated", s);
625
0
                        return 0;
626
0
                    }
627
2.40k
                    r->bits = (OSSL_PARAM *)p;
628
2.40k
                }
629
2.40k
                break;
630
2.46k
            case 'm':
631
2.46k
                switch(s[1]) {
632
0
                default:
633
0
                    break;
634
2.46k
                case 'a':
635
2.46k
                    switch(s[2]) {
636
0
                    default:
637
0
                        break;
638
62
                    case 'n':
639
62
                        if (ossl_likely(strcmp("datory-digest", s + 3) == 0)) {
640
                            /* OSSL_PKEY_PARAM_MANDATORY_DIGEST */
641
62
                            if (ossl_unlikely(r->digest != NULL)) {
642
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
643
0
                                               "param %s is repeated", s);
644
0
                                return 0;
645
0
                            }
646
62
                            r->digest = (OSSL_PARAM *)p;
647
62
                        }
648
62
                        break;
649
2.40k
                    case 'x':
650
2.40k
                        if (ossl_likely(strcmp("-size", s + 3) == 0)) {
651
                            /* OSSL_PKEY_PARAM_MAX_SIZE */
652
2.40k
                            if (ossl_unlikely(r->size != NULL)) {
653
0
                                ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
654
0
                                               "param %s is repeated", s);
655
0
                                return 0;
656
0
                            }
657
2.40k
                            r->size = (OSSL_PARAM *)p;
658
2.40k
                        }
659
2.46k
                    }
660
2.46k
                }
661
2.46k
                break;
662
2.46k
            case 'p':
663
0
                switch(s[1]) {
664
0
                default:
665
0
                    break;
666
0
                case 'r':
667
0
                    if (ossl_likely(strcmp("iv", s + 2) == 0)) {
668
                        /* OSSL_PKEY_PARAM_PRIV_KEY */
669
0
                        if (ossl_unlikely(r->priv != NULL)) {
670
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
671
0
                                           "param %s is repeated", s);
672
0
                            return 0;
673
0
                        }
674
0
                        r->priv = (OSSL_PARAM *)p;
675
0
                    }
676
0
                    break;
677
0
                case 'u':
678
0
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
679
                        /* OSSL_PKEY_PARAM_PUB_KEY */
680
0
                        if (ossl_unlikely(r->pub != NULL)) {
681
0
                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
682
0
                                           "param %s is repeated", s);
683
0
                            return 0;
684
0
                        }
685
0
                        r->pub = (OSSL_PARAM *)p;
686
0
                    }
687
0
                }
688
0
                break;
689
4.80k
            case 's':
690
4.80k
                switch(s[1]) {
691
0
                default:
692
0
                    break;
693
4.80k
                case 'e':
694
4.80k
                    switch(s[2]) {
695
0
                    default:
696
0
                        break;
697
4.80k
                    case 'c':
698
4.80k
                        switch(s[3]) {
699
0
                        default:
700
0
                            break;
701
4.80k
                        case 'u':
702
4.80k
                            switch(s[4]) {
703
0
                            default:
704
0
                                break;
705
4.80k
                            case 'r':
706
4.80k
                                switch(s[5]) {
707
0
                                default:
708
0
                                    break;
709
4.80k
                                case 'i':
710
4.80k
                                    switch(s[6]) {
711
0
                                    default:
712
0
                                        break;
713
4.80k
                                    case 't':
714
4.80k
                                        switch(s[7]) {
715
0
                                        default:
716
0
                                            break;
717
4.80k
                                        case 'y':
718
4.80k
                                            switch(s[8]) {
719
0
                                            default:
720
0
                                                break;
721
4.80k
                                            case '-':
722
4.80k
                                                switch(s[9]) {
723
0
                                                default:
724
0
                                                    break;
725
2.40k
                                                case 'b':
726
2.40k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
727
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
728
2.40k
                                                        if (ossl_unlikely(r->secbits != NULL)) {
729
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
730
0
                                                                           "param %s is repeated", s);
731
0
                                                            return 0;
732
0
                                                        }
733
2.40k
                                                        r->secbits = (OSSL_PARAM *)p;
734
2.40k
                                                    }
735
2.40k
                                                    break;
736
2.40k
                                                case 'c':
737
2.40k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
738
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
739
2.40k
                                                        if (ossl_unlikely(r->seccat != NULL)) {
740
0
                                                            ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
741
0
                                                                           "param %s is repeated", s);
742
0
                                                            return 0;
743
0
                                                        }
744
2.40k
                                                        r->seccat = (OSSL_PARAM *)p;
745
2.40k
                                                    }
746
4.80k
                                                }
747
4.80k
                                            }
748
4.80k
                                        }
749
4.80k
                                    }
750
4.80k
                                }
751
4.80k
                            }
752
4.80k
                        }
753
4.80k
                    }
754
4.80k
                }
755
9.74k
            }
756
2.46k
    return 1;
757
2.46k
}
758
#endif
759
/* End of machine generated */
760
/* clang-format on */
761
762
/* This getter is shared by ED25519, ED448, X25519 and X448 */
763
static int ecx_ed_common_get_params(void *key,
764
    const struct ecx_ed_common_get_params_st *p,
765
    int bits, int secbits, int size)
766
330k
{
767
330k
    ECX_KEY *ecx = key;
768
769
330k
    if (p->bits != NULL && !OSSL_PARAM_set_int(p->bits, bits))
770
0
        return 0;
771
330k
    if (p->secbits != NULL && !OSSL_PARAM_set_int(p->secbits, secbits))
772
0
        return 0;
773
330k
    if (p->size != NULL && !OSSL_PARAM_set_int(p->size, size))
774
0
        return 0;
775
330k
    if (p->seccat != NULL && !OSSL_PARAM_set_int(p->seccat, 0))
776
0
        return 0;
777
330k
    return key_to_params(ecx, NULL, p->pub, p->priv, 1);
778
330k
}
779
780
/* X25519/X448 getter */
781
static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
782
    int size)
783
327k
{
784
327k
    ECX_KEY *ecx = key;
785
327k
    struct ecx_ed_common_get_params_st p;
786
787
327k
    if (key == NULL || !ecx_get_params_decoder(params, &p))
788
0
        return 0;
789
790
327k
    if (p.encpub != NULL
791
155k
        && !OSSL_PARAM_set_octet_string(p.encpub, ecx->pubkey, ecx->keylen))
792
0
        return 0;
793
#ifdef FIPS_MODULE
794
    {
795
        /* Currently X25519 and X448 are not approved */
796
        int approved = 0;
797
798
        if (p.ind != NULL && !OSSL_PARAM_set_int(p.ind, approved))
799
            return 0;
800
    }
801
#endif
802
803
327k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
804
327k
}
805
806
/* ED25519/ED448 getter */
807
static int ed_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
808
    int size)
809
2.46k
{
810
2.46k
    struct ecx_ed_common_get_params_st p;
811
812
2.46k
    if (key == NULL || !ed_get_params_decoder(params, &p))
813
0
        return 0;
814
2.46k
    if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, ""))
815
0
        return 0;
816
2.46k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
817
2.46k
}
818
819
static int x25519_get_params(void *key, OSSL_PARAM params[])
820
457k
{
821
457k
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
822
457k
        X25519_KEYLEN);
823
457k
}
824
825
static int x448_get_params(void *key, OSSL_PARAM params[])
826
1.02k
{
827
1.02k
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
828
1.02k
        X448_KEYLEN);
829
1.02k
}
830
831
static int ed25519_get_params(void *key, OSSL_PARAM params[])
832
1.04k
{
833
1.04k
    return ed_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
834
1.04k
        ED25519_SIGSIZE);
835
1.04k
}
836
static int ed448_get_params(void *key, OSSL_PARAM params[])
837
1.42k
{
838
1.42k
    return ed_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
839
1.42k
        ED448_SIGSIZE);
840
1.42k
}
841
842
static const OSSL_PARAM *x25519_gettable_params(void *provctx)
843
0
{
844
0
    return ecx_get_params_list;
845
0
}
846
847
static const OSSL_PARAM *x448_gettable_params(void *provctx)
848
0
{
849
0
    return ecx_get_params_list;
850
0
}
851
852
static const OSSL_PARAM *ed25519_gettable_params(void *provctx)
853
0
{
854
0
    return ed_get_params_list;
855
0
}
856
857
static const OSSL_PARAM *ed448_gettable_params(void *provctx)
858
0
{
859
0
    return ed_get_params_list;
860
0
}
861
862
static int set_property_query(ECX_KEY *ecxkey, const char *propq)
863
0
{
864
0
    OPENSSL_free(ecxkey->propq);
865
0
    ecxkey->propq = NULL;
866
0
    if (propq != NULL) {
867
0
        ecxkey->propq = OPENSSL_strdup(propq);
868
0
        if (ecxkey->propq == NULL)
869
0
            return 0;
870
0
    }
871
0
    return 1;
872
0
}
873
874
/* clang-format off */
875
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
876
#ifndef ecx_set_params_list
877
static ossl_unused const OSSL_PARAM ecx_set_params_list[] = {
878
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
879
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
880
    OSSL_PARAM_END
881
};
882
#endif
883
884
#ifndef ecx_set_params_st
885
struct ecx_set_params_st {
886
    OSSL_PARAM *propq;
887
    OSSL_PARAM *pub;
888
};
889
#endif
890
891
#ifndef ecx_set_params_decoder
892
static ossl_unused int ecx_set_params_decoder
893
    (const OSSL_PARAM *p, struct ecx_set_params_st *r)
894
23.1k
{
895
23.1k
    const char *s;
896
897
23.1k
    memset(r, 0, sizeof(*r));
898
23.1k
    if (p != NULL)
899
46.3k
        for (; (s = p->key) != NULL; p++)
900
23.1k
            switch(s[0]) {
901
0
            default:
902
0
                break;
903
23.1k
            case 'e':
904
23.1k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
905
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
906
23.1k
                    if (ossl_unlikely(r->pub != NULL)) {
907
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
908
0
                                       "param %s is repeated", s);
909
0
                        return 0;
910
0
                    }
911
23.1k
                    r->pub = (OSSL_PARAM *)p;
912
23.1k
                }
913
23.1k
                break;
914
23.1k
            case 'p':
915
0
                if (ossl_likely(strcmp("roperties", s + 1) == 0)) {
916
                    /* OSSL_PKEY_PARAM_PROPERTIES */
917
0
                    if (ossl_unlikely(r->propq != NULL)) {
918
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
919
0
                                       "param %s is repeated", s);
920
0
                        return 0;
921
0
                    }
922
0
                    r->propq = (OSSL_PARAM *)p;
923
0
                }
924
23.1k
            }
925
23.1k
    return 1;
926
23.1k
}
927
#endif
928
/* End of machine generated */
929
/* clang-format on */
930
931
static int ecx_set_params(void *key, const OSSL_PARAM params[])
932
23.1k
{
933
23.1k
    ECX_KEY *ecxkey = key;
934
23.1k
    struct ecx_set_params_st p;
935
936
23.1k
    if (key == NULL || !ecx_set_params_decoder(params, &p))
937
0
        return 0;
938
939
23.1k
    if (p.pub != NULL) {
940
23.1k
        void *buf = ecxkey->pubkey;
941
942
23.1k
        if (p.pub->data_size != ecxkey->keylen
943
23.1k
            || !OSSL_PARAM_get_octet_string(p.pub, &buf, sizeof(ecxkey->pubkey),
944
23.1k
                NULL))
945
55
            return 0;
946
23.1k
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
947
23.1k
        ecxkey->privkey = NULL;
948
23.1k
        ecxkey->haspubkey = 1;
949
23.1k
    }
950
951
23.1k
    if (p.propq != NULL) {
952
0
        if (p.propq->data_type != OSSL_PARAM_UTF8_STRING
953
0
            || !set_property_query(ecxkey, p.propq->data))
954
0
            return 0;
955
0
    }
956
957
23.1k
    return 1;
958
23.1k
}
959
960
static int x25519_set_params(void *key, const OSSL_PARAM params[])
961
35.7k
{
962
35.7k
    return ecx_set_params(key, params);
963
35.7k
}
964
965
static int x448_set_params(void *key, const OSSL_PARAM params[])
966
68
{
967
68
    return ecx_set_params(key, params);
968
68
}
969
970
static int ed25519_set_params(void *key, const OSSL_PARAM params[])
971
0
{
972
0
    return 1;
973
0
}
974
975
static int ed448_set_params(void *key, const OSSL_PARAM params[])
976
0
{
977
0
    return 1;
978
0
}
979
980
static const OSSL_PARAM ed_settable_params[] = {
981
    OSSL_PARAM_END
982
};
983
984
static const OSSL_PARAM *x25519_settable_params(void *provctx)
985
0
{
986
0
    return ecx_set_params_list;
987
0
}
988
989
static const OSSL_PARAM *x448_settable_params(void *provctx)
990
0
{
991
0
    return ecx_set_params_list;
992
0
}
993
994
static const OSSL_PARAM *ed25519_settable_params(void *provctx)
995
0
{
996
0
    return ed_settable_params;
997
0
}
998
999
static const OSSL_PARAM *ed448_settable_params(void *provctx)
1000
0
{
1001
0
    return ed_settable_params;
1002
0
}
1003
1004
static void *ecx_gen_init(void *provctx, int selection,
1005
    const OSSL_PARAM params[], ECX_KEY_TYPE type,
1006
    const char *algdesc)
1007
202k
{
1008
202k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
1009
202k
    struct ecx_gen_ctx *gctx = NULL;
1010
1011
202k
    if (!ossl_prov_is_running())
1012
0
        return NULL;
1013
1014
202k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
1015
202k
        gctx->libctx = libctx;
1016
202k
        gctx->type = type;
1017
202k
        gctx->selection = selection;
1018
#ifdef FIPS_MODULE
1019
        /* X25519/X448 are not FIPS approved, (ED25519/ED448 are approved) */
1020
        if (algdesc != NULL
1021
            && !ossl_FIPS_IND_callback(libctx, algdesc, "KeyGen Init")) {
1022
            OPENSSL_free(gctx);
1023
            return NULL;
1024
        }
1025
#endif
1026
202k
    } else {
1027
0
        return NULL;
1028
0
    }
1029
202k
    if (!ecx_gen_set_params(gctx, params)) {
1030
0
        ecx_gen_cleanup(gctx);
1031
0
        gctx = NULL;
1032
0
    }
1033
202k
    return gctx;
1034
202k
}
1035
1036
static void *x25519_gen_init(void *provctx, int selection,
1037
    const OSSL_PARAM params[])
1038
201k
{
1039
201k
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519");
1040
201k
}
1041
1042
static void *x448_gen_init(void *provctx, int selection,
1043
    const OSSL_PARAM params[])
1044
306
{
1045
306
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448");
1046
306
}
1047
1048
static void *ed25519_gen_init(void *provctx, int selection,
1049
    const OSSL_PARAM params[])
1050
0
{
1051
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519, NULL);
1052
0
}
1053
1054
static void *ed448_gen_init(void *provctx, int selection,
1055
    const OSSL_PARAM params[])
1056
0
{
1057
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448, NULL);
1058
0
}
1059
1060
/* clang-format off */
1061
/* Machine generated by util/perl/OpenSSL/paramnames.pm */
1062
#ifndef ecx_gen_set_params_list
1063
static ossl_unused const OSSL_PARAM ecx_gen_set_params_list[] = {
1064
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
1065
    OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
1066
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0),
1067
    OSSL_PARAM_END
1068
};
1069
#endif
1070
1071
#ifndef ecx_gen_set_params_st
1072
struct ecx_gen_set_params_st {
1073
    OSSL_PARAM *group;
1074
    OSSL_PARAM *ikm;
1075
    OSSL_PARAM *kdfpropq;
1076
};
1077
#endif
1078
1079
#ifndef ecx_gen_set_params_decoder
1080
static ossl_unused int ecx_gen_set_params_decoder
1081
    (const OSSL_PARAM *p, struct ecx_gen_set_params_st *r)
1082
299k
{
1083
299k
    const char *s;
1084
1085
299k
    memset(r, 0, sizeof(*r));
1086
299k
    if (p != NULL)
1087
226k
        for (; (s = p->key) != NULL; p++)
1088
77.6k
            switch(s[0]) {
1089
0
            default:
1090
0
                break;
1091
0
            case 'd':
1092
0
                if (ossl_likely(strcmp("hkem-ikm", s + 1) == 0)) {
1093
                    /* OSSL_PKEY_PARAM_DHKEM_IKM */
1094
0
                    if (ossl_unlikely(r->ikm != NULL)) {
1095
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1096
0
                                       "param %s is repeated", s);
1097
0
                        return 0;
1098
0
                    }
1099
0
                    r->ikm = (OSSL_PARAM *)p;
1100
0
                }
1101
0
                break;
1102
77.6k
            case 'g':
1103
77.6k
                if (ossl_likely(strcmp("roup", s + 1) == 0)) {
1104
                    /* OSSL_PKEY_PARAM_GROUP_NAME */
1105
77.6k
                    if (ossl_unlikely(r->group != NULL)) {
1106
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1107
0
                                       "param %s is repeated", s);
1108
0
                        return 0;
1109
0
                    }
1110
77.6k
                    r->group = (OSSL_PARAM *)p;
1111
77.6k
                }
1112
77.6k
                break;
1113
77.6k
            case 'p':
1114
0
                if (ossl_likely(strcmp("roperties", s + 1) == 0)) {
1115
                    /* OSSL_KDF_PARAM_PROPERTIES */
1116
0
                    if (ossl_unlikely(r->kdfpropq != NULL)) {
1117
0
                        ERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,
1118
0
                                       "param %s is repeated", s);
1119
0
                        return 0;
1120
0
                    }
1121
0
                    r->kdfpropq = (OSSL_PARAM *)p;
1122
0
                }
1123
77.6k
            }
1124
299k
    return 1;
1125
299k
}
1126
#endif
1127
/* End of machine generated */
1128
/* clang-format on */
1129
1130
static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
1131
299k
{
1132
299k
    struct ecx_gen_ctx *gctx = genctx;
1133
299k
    struct ecx_gen_set_params_st p;
1134
1135
299k
    if (gctx == NULL || !ecx_gen_set_params_decoder(params, &p))
1136
0
        return 0;
1137
1138
299k
    if (p.group != NULL) {
1139
77.6k
        const char *groupname = NULL;
1140
1141
        /*
1142
         * We optionally allow setting a group name - but each algorithm only
1143
         * support one such name, so all we do is verify that it is the one we
1144
         * expected.
1145
         */
1146
77.6k
        switch (gctx->type) {
1147
77.4k
        case ECX_KEY_TYPE_X25519:
1148
77.4k
            groupname = "x25519";
1149
77.4k
            break;
1150
224
        case ECX_KEY_TYPE_X448:
1151
224
            groupname = "x448";
1152
224
            break;
1153
0
        default:
1154
            /* We only support this for key exchange at the moment */
1155
0
            break;
1156
77.6k
        }
1157
77.6k
        if (p.group->data_type != OSSL_PARAM_UTF8_STRING
1158
77.6k
            || groupname == NULL
1159
77.6k
            || OPENSSL_strcasecmp(p.group->data, groupname) != 0) {
1160
0
            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
1161
0
            return 0;
1162
0
        }
1163
77.6k
    }
1164
1165
299k
    if (p.kdfpropq != NULL) {
1166
0
        if (p.kdfpropq->data_type != OSSL_PARAM_UTF8_STRING)
1167
0
            return 0;
1168
0
        OPENSSL_free(gctx->propq);
1169
0
        gctx->propq = OPENSSL_strdup(p.kdfpropq->data);
1170
0
        if (gctx->propq == NULL)
1171
0
            return 0;
1172
0
    }
1173
1174
299k
    if (p.ikm != NULL) {
1175
0
        if (p.ikm->data_size != 0 && p.ikm->data != NULL) {
1176
0
            OPENSSL_free(gctx->dhkem_ikm);
1177
0
            gctx->dhkem_ikm = NULL;
1178
0
            if (!OSSL_PARAM_get_octet_string(p.ikm, (void **)&gctx->dhkem_ikm, 0,
1179
0
                    &gctx->dhkem_ikmlen))
1180
0
                return 0;
1181
0
        }
1182
0
    }
1183
1184
299k
    return 1;
1185
299k
}
1186
1187
static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx,
1188
    ossl_unused void *provctx)
1189
0
{
1190
0
    return ecx_gen_set_params_list;
1191
0
}
1192
1193
#ifdef FIPS_MODULE
1194
/*
1195
 * Refer: FIPS 140-3 IG 10.3.A Additional Comment 1
1196
 * Perform a pairwise test for EDDSA by signing and verifying signature.
1197
 *
1198
 * The parameter `self_test` is used to indicate whether to create OSSL_SELF_TEST
1199
 * instance.
1200
 */
1201
static int ecd_fips140_pairwise_test(const ECX_KEY *ecx, int type, int self_test)
1202
{
1203
    int ret = 0;
1204
    OSSL_SELF_TEST *st = NULL;
1205
    OSSL_CALLBACK *cb = NULL;
1206
    void *cbarg = NULL;
1207
1208
    unsigned char msg[16] = { 0 };
1209
    size_t msg_len = sizeof(msg);
1210
    unsigned char sig[ED448_SIGSIZE] = { 0 };
1211
1212
    int is_ed25519 = (type == ECX_KEY_TYPE_ED25519) ? 1 : 0;
1213
    int operation_result = 0;
1214
1215
    /*
1216
     * The functions `OSSL_SELF_TEST_*` will return directly if parameter `st`
1217
     * is NULL.
1218
     */
1219
    if (self_test) {
1220
        OSSL_SELF_TEST_get_callback(ecx->libctx, &cb, &cbarg);
1221
1222
        st = OSSL_SELF_TEST_new(cb, cbarg);
1223
        if (st == NULL)
1224
            return 0;
1225
    }
1226
1227
    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
1228
        OSSL_SELF_TEST_DESC_PCT_EDDSA);
1229
1230
    if (is_ed25519)
1231
        operation_result = ossl_ed25519_sign(sig, msg, msg_len, ecx->pubkey,
1232
            ecx->privkey, 0, 0, 0, NULL, 0,
1233
            ecx->libctx, ecx->propq);
1234
    else
1235
        operation_result = ossl_ed448_sign(ecx->libctx, sig, msg, msg_len,
1236
            ecx->pubkey, ecx->privkey, NULL, 0,
1237
            0, ecx->propq);
1238
    if (operation_result != 1)
1239
        goto err;
1240
1241
    OSSL_SELF_TEST_oncorrupt_byte(st, sig);
1242
1243
    if (is_ed25519)
1244
        operation_result = ossl_ed25519_verify(msg, msg_len, sig, ecx->pubkey,
1245
            0, 0, 0, NULL, 0, ecx->libctx,
1246
            ecx->propq);
1247
    else
1248
        operation_result = ossl_ed448_verify(ecx->libctx, msg, msg_len, sig,
1249
            ecx->pubkey, NULL, 0, 0, ecx->propq);
1250
    if (operation_result != 1)
1251
        goto err;
1252
1253
    ret = 1;
1254
err:
1255
    OSSL_SELF_TEST_onend(st, ret);
1256
    OSSL_SELF_TEST_free(st);
1257
    return ret;
1258
}
1259
#endif
1260
1261
static void *ecx_gen(struct ecx_gen_ctx *gctx)
1262
183k
{
1263
183k
    ECX_KEY *key;
1264
183k
    unsigned char *privkey;
1265
1266
183k
    if (gctx == NULL)
1267
0
        return NULL;
1268
183k
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
1269
183k
             gctx->propq))
1270
183k
        == NULL) {
1271
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1272
0
        return NULL;
1273
0
    }
1274
1275
    /* If we're doing parameter generation then we just return a blank key */
1276
183k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1277
4.69k
        return key;
1278
1279
178k
    if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) {
1280
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1281
0
        goto err;
1282
0
    }
1283
178k
#ifndef FIPS_MODULE
1284
178k
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1285
0
        if (ecx_key_type_is_ed(gctx->type))
1286
0
            goto err;
1287
0
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
1288
0
                gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1289
0
            goto err;
1290
0
    } else
1291
178k
#endif
1292
178k
    {
1293
178k
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
1294
0
            goto err;
1295
178k
    }
1296
1297
178k
    switch (gctx->type) {
1298
178k
    case ECX_KEY_TYPE_X25519:
1299
178k
        privkey[0] &= 248;
1300
178k
        privkey[X25519_KEYLEN - 1] &= 127;
1301
178k
        privkey[X25519_KEYLEN - 1] |= 64;
1302
178k
        ossl_x25519_public_from_private(key->pubkey, privkey);
1303
178k
        break;
1304
232
    case ECX_KEY_TYPE_X448:
1305
232
        privkey[0] &= 252;
1306
232
        privkey[X448_KEYLEN - 1] |= 128;
1307
232
        ossl_x448_public_from_private(key->pubkey, privkey);
1308
232
        break;
1309
0
    case ECX_KEY_TYPE_ED25519:
1310
0
        if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey,
1311
0
                gctx->propq))
1312
0
            goto err;
1313
0
        break;
1314
0
    case ECX_KEY_TYPE_ED448:
1315
0
        if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey,
1316
0
                gctx->propq))
1317
0
            goto err;
1318
0
        break;
1319
178k
    }
1320
178k
    key->haspubkey = 1;
1321
178k
    return key;
1322
0
err:
1323
0
    ossl_ecx_key_free(key);
1324
0
    return NULL;
1325
178k
}
1326
1327
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1328
201k
{
1329
201k
    struct ecx_gen_ctx *gctx = genctx;
1330
1331
201k
    if (!ossl_prov_is_running())
1332
0
        return 0;
1333
1334
#ifdef S390X_EC_ASM
1335
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1336
        return s390x_ecx_keygen25519(gctx);
1337
#endif
1338
201k
    return ecx_gen(gctx);
1339
201k
}
1340
1341
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1342
306
{
1343
306
    struct ecx_gen_ctx *gctx = genctx;
1344
1345
306
    if (!ossl_prov_is_running())
1346
0
        return 0;
1347
1348
#ifdef S390X_EC_ASM
1349
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1350
        return s390x_ecx_keygen448(gctx);
1351
#endif
1352
306
    return ecx_gen(gctx);
1353
306
}
1354
1355
static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1356
0
{
1357
0
    ECX_KEY *key = NULL;
1358
0
    struct ecx_gen_ctx *gctx = genctx;
1359
1360
0
    if (!ossl_prov_is_running())
1361
0
        return 0;
1362
1363
#ifdef S390X_EC_ASM
1364
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1365
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1366
        && OPENSSL_s390xcap_P.kdsa[0]
1367
            & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)) {
1368
        key = s390x_ecd_keygen25519(gctx);
1369
    } else
1370
#endif
1371
0
    {
1372
0
        key = ecx_gen(gctx);
1373
0
    }
1374
1375
#ifdef FIPS_MODULE
1376
    /* Exit if keygen failed OR we are doing parameter generation (blank key) */
1377
    if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
1378
        return key;
1379
    if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED25519, 1) != 1) {
1380
        ossl_ecx_key_free(key);
1381
        return NULL;
1382
    }
1383
#endif
1384
1385
0
    return key;
1386
0
}
1387
1388
static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1389
0
{
1390
0
    ECX_KEY *key = NULL;
1391
0
    struct ecx_gen_ctx *gctx = genctx;
1392
1393
0
    if (!ossl_prov_is_running())
1394
0
        return 0;
1395
1396
#ifdef S390X_EC_ASM
1397
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1398
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1399
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) {
1400
        key = s390x_ecd_keygen448(gctx);
1401
    } else
1402
#endif
1403
0
    {
1404
0
        key = ecx_gen(gctx);
1405
0
    }
1406
1407
#ifdef FIPS_MODULE
1408
    /* Exit if keygen failed OR we are doing parameter generation (blank key) */
1409
    if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
1410
        return key;
1411
    if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED448, 1) != 1) {
1412
        ossl_ecx_key_free(key);
1413
        return NULL;
1414
    }
1415
#endif
1416
1417
0
    return key;
1418
0
}
1419
1420
static void ecx_gen_cleanup(void *genctx)
1421
202k
{
1422
202k
    struct ecx_gen_ctx *gctx = genctx;
1423
1424
202k
    if (gctx == NULL)
1425
0
        return;
1426
1427
202k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1428
202k
    OPENSSL_free(gctx->propq);
1429
202k
    OPENSSL_free(gctx);
1430
202k
}
1431
1432
void *ecx_load(const void *reference, size_t reference_sz)
1433
4.84k
{
1434
4.84k
    ECX_KEY *key = NULL;
1435
1436
4.84k
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
1437
        /* The contents of the reference is the address to our object */
1438
4.84k
        key = *(ECX_KEY **)reference;
1439
        /* We grabbed, so we detach it */
1440
4.84k
        *(ECX_KEY **)reference = NULL;
1441
4.84k
        return key;
1442
4.84k
    }
1443
0
    return NULL;
1444
4.84k
}
1445
1446
static void *ecx_dup(const void *keydata_from, int selection)
1447
30.2k
{
1448
30.2k
    if (ossl_prov_is_running())
1449
30.2k
        return ossl_ecx_key_dup(keydata_from, selection);
1450
0
    return NULL;
1451
30.2k
}
1452
1453
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
1454
9
{
1455
9
    uint8_t pub[64];
1456
1457
9
    switch (type) {
1458
6
    case ECX_KEY_TYPE_X25519:
1459
6
        ossl_x25519_public_from_private(pub, ecx->privkey);
1460
6
        break;
1461
3
    case ECX_KEY_TYPE_X448:
1462
3
        ossl_x448_public_from_private(pub, ecx->privkey);
1463
3
        break;
1464
0
    default:
1465
0
        return 0;
1466
9
    }
1467
9
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1468
9
}
1469
1470
#ifdef FIPS_MODULE
1471
/*
1472
 * FIPS ACVP testing requires the ability to check if the public key is valid
1473
 * This is not required normally since the ED signature verify does the test
1474
 * internally.
1475
 */
1476
static int ecd_key_pub_check(const ECX_KEY *ecx, int type)
1477
{
1478
    switch (type) {
1479
    case ECX_KEY_TYPE_ED25519:
1480
        return ossl_ed25519_pubkey_verify(ecx->pubkey, ecx->keylen);
1481
    case ECX_KEY_TYPE_ED448:
1482
        return ossl_ed448_pubkey_verify(ecx->pubkey, ecx->keylen);
1483
    default:
1484
        return 1;
1485
    }
1486
}
1487
#endif
1488
1489
#ifdef FIPS_MODULE
1490
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
1491
{
1492
    return ecd_fips140_pairwise_test(ecx, type, 0);
1493
}
1494
#else
1495
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
1496
11
{
1497
11
    uint8_t pub[64];
1498
1499
11
    switch (type) {
1500
5
    case ECX_KEY_TYPE_ED25519:
1501
5
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
1502
5
                ecx->propq))
1503
0
            return 0;
1504
5
        break;
1505
6
    case ECX_KEY_TYPE_ED448:
1506
6
        if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
1507
6
                ecx->propq))
1508
0
            return 0;
1509
6
        break;
1510
6
    default:
1511
0
        return 0;
1512
11
    }
1513
11
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1514
11
}
1515
#endif
1516
1517
static int ecx_validate(const void *keydata, int selection, int type,
1518
    size_t keylen)
1519
27.3k
{
1520
27.3k
    const ECX_KEY *ecx = keydata;
1521
27.3k
    int ok = keylen == ecx->keylen;
1522
1523
27.3k
    if (!ossl_prov_is_running())
1524
0
        return 0;
1525
1526
27.3k
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
1527
30
        return 1; /* nothing to validate */
1528
1529
27.3k
    if (!ok) {
1530
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
1531
0
        return 0;
1532
0
    }
1533
1534
27.3k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
1535
27.3k
        ok = ok && ecx->haspubkey;
1536
#ifdef FIPS_MODULE
1537
        ok = ok && ecd_key_pub_check(ecx, type);
1538
#endif
1539
27.3k
    }
1540
1541
27.3k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
1542
60
        ok = ok && ecx->privkey != NULL;
1543
1544
27.3k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
1545
27.3k
        return ok;
1546
1547
30
    if (ecx_key_type_is_ed(type))
1548
13
        ok = ok && ecd_key_pairwise_check(ecx, type);
1549
17
    else
1550
17
        ok = ok && ecx_key_pairwise_check(ecx, type);
1551
1552
30
    return ok;
1553
27.3k
}
1554
1555
static int x25519_validate(const void *keydata, int selection, int checktype)
1556
33.8k
{
1557
33.8k
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
1558
33.8k
}
1559
1560
static int x448_validate(const void *keydata, int selection, int checktype)
1561
68
{
1562
68
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
1563
68
}
1564
1565
static int ed25519_validate(const void *keydata, int selection, int checktype)
1566
44
{
1567
44
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
1568
44
}
1569
1570
static int ed448_validate(const void *keydata, int selection, int checktype)
1571
48
{
1572
48
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
1573
48
}
1574
1575
static void ecx_free_key(void *keydata)
1576
211k
{
1577
211k
    ossl_ecx_key_free((ECX_KEY *)keydata);
1578
211k
}
1579
1580
#define MAKE_KEYMGMT_FUNCTIONS(alg)                                                   \
1581
    const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = {                          \
1582
        { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key },                     \
1583
        { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_free_key },                     \
1584
        { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))alg##_get_params },           \
1585
        { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))alg##_gettable_params }, \
1586
        { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))alg##_set_params },           \
1587
        { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))alg##_settable_params }, \
1588
        { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has },                           \
1589
        { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match },                       \
1590
        { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate },               \
1591
        { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import },                     \
1592
        { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types },       \
1593
        { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export },                     \
1594
        { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types },       \
1595
        { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init },               \
1596
        { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params },     \
1597
        { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,                                      \
1598
            (void (*)(void))ecx_gen_settable_params },                                \
1599
        { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen },                         \
1600
        { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup },           \
1601
        { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load },                         \
1602
        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup },                           \
1603
        OSSL_KEYMGMT_FIPS_GEN_DISPATCH_END(ecx_gen_get_params)                        \
1604
    };
1605
1606
MAKE_KEYMGMT_FUNCTIONS(x25519)
1607
MAKE_KEYMGMT_FUNCTIONS(x448)
1608
MAKE_KEYMGMT_FUNCTIONS(ed25519)
1609
MAKE_KEYMGMT_FUNCTIONS(ed448)
1610
1611
#ifdef S390X_EC_ASM
1612
#include "s390x_arch.h"
1613
1614
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
1615
{
1616
    static const unsigned char generator[] = {
1617
        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1618
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1619
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1620
    };
1621
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
1622
        gctx->propq);
1623
    unsigned char *privkey = NULL, *pubkey;
1624
1625
    if (key == NULL) {
1626
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1627
        goto err;
1628
    }
1629
1630
    /* If we're doing parameter generation then we just return a blank key */
1631
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1632
        return key;
1633
1634
    pubkey = key->pubkey;
1635
1636
    privkey = ossl_ecx_key_allocate_privkey(key);
1637
    if (privkey == NULL) {
1638
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1639
        goto err;
1640
    }
1641
1642
#ifndef FIPS_MODULE
1643
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1644
        if (gctx->type != ECX_KEY_TYPE_X25519)
1645
            goto err;
1646
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
1647
                gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1648
            goto err;
1649
    } else
1650
#endif
1651
    {
1652
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
1653
            goto err;
1654
    }
1655
1656
    privkey[0] &= 248;
1657
    privkey[31] &= 127;
1658
    privkey[31] |= 64;
1659
1660
    if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1661
        goto err;
1662
    key->haspubkey = 1;
1663
    return key;
1664
err:
1665
    ossl_ecx_key_free(key);
1666
    return NULL;
1667
}
1668
1669
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
1670
{
1671
    static const unsigned char generator[] = {
1672
        0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1677
    };
1678
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
1679
        gctx->propq);
1680
    unsigned char *privkey = NULL, *pubkey;
1681
1682
    if (key == NULL) {
1683
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1684
        goto err;
1685
    }
1686
1687
    /* If we're doing parameter generation then we just return a blank key */
1688
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1689
        return key;
1690
1691
    pubkey = key->pubkey;
1692
1693
    privkey = ossl_ecx_key_allocate_privkey(key);
1694
    if (privkey == NULL) {
1695
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1696
        goto err;
1697
    }
1698
1699
#ifndef FIPS_MODULE
1700
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1701
        if (gctx->type != ECX_KEY_TYPE_X448)
1702
            goto err;
1703
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
1704
                gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1705
            goto err;
1706
    } else
1707
#endif
1708
    {
1709
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
1710
            goto err;
1711
    }
1712
1713
    privkey[0] &= 252;
1714
    privkey[55] |= 128;
1715
1716
    if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1717
        goto err;
1718
    key->haspubkey = 1;
1719
    return key;
1720
err:
1721
    ossl_ecx_key_free(key);
1722
    return NULL;
1723
}
1724
1725
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
1726
{
1727
    static const unsigned char generator_x[] = {
1728
        0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1729
        0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1730
        0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1731
    };
1732
    static const unsigned char generator_y[] = {
1733
        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1734
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1735
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1736
        0x66, 0x66
1737
    };
1738
    unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1739
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1740
        gctx->propq);
1741
    unsigned char *privkey = NULL, *pubkey;
1742
    unsigned int sz;
1743
    EVP_MD *sha = NULL;
1744
    int j;
1745
1746
    if (key == NULL) {
1747
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1748
        goto err;
1749
    }
1750
1751
    /* If we're doing parameter generation then we just return a blank key */
1752
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1753
        return key;
1754
1755
    pubkey = key->pubkey;
1756
1757
    privkey = ossl_ecx_key_allocate_privkey(key);
1758
    if (privkey == NULL) {
1759
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1760
        goto err;
1761
    }
1762
1763
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1764
        goto err;
1765
1766
    sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1767
    if (sha == NULL)
1768
        goto err;
1769
    j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1770
    EVP_MD_free(sha);
1771
    if (!j)
1772
        goto err;
1773
1774
    buff[0] &= 248;
1775
    buff[31] &= 63;
1776
    buff[31] |= 64;
1777
1778
    if (s390x_ed25519_mul(x_dst, pubkey,
1779
            generator_x, generator_y, buff)
1780
        != 1)
1781
        goto err;
1782
1783
    pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1784
    key->haspubkey = 1;
1785
    return key;
1786
err:
1787
    ossl_ecx_key_free(key);
1788
    return NULL;
1789
}
1790
1791
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1792
{
1793
    static const unsigned char generator_x[] = {
1794
        0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1795
        0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1796
        0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1797
        0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1798
        0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1799
    };
1800
    static const unsigned char generator_y[] = {
1801
        0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1802
        0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1803
        0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1804
        0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1805
        0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1806
    };
1807
    unsigned char x_dst[57], buff[114];
1808
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1809
        gctx->propq);
1810
    unsigned char *privkey = NULL, *pubkey;
1811
    EVP_MD_CTX *hashctx = NULL;
1812
    EVP_MD *shake = NULL;
1813
1814
    if (key == NULL) {
1815
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1816
        goto err;
1817
    }
1818
1819
    /* If we're doing parameter generation then we just return a blank key */
1820
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1821
        return key;
1822
1823
    pubkey = key->pubkey;
1824
1825
    privkey = ossl_ecx_key_allocate_privkey(key);
1826
    if (privkey == NULL) {
1827
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1828
        goto err;
1829
    }
1830
1831
    shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1832
    if (shake == NULL)
1833
        goto err;
1834
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1835
        goto err;
1836
1837
    hashctx = EVP_MD_CTX_new();
1838
    if (hashctx == NULL)
1839
        goto err;
1840
    if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1841
        goto err;
1842
    if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1843
        goto err;
1844
    if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1845
        goto err;
1846
1847
    buff[0] &= -4;
1848
    buff[55] |= 0x80;
1849
    buff[56] = 0;
1850
1851
    if (s390x_ed448_mul(x_dst, pubkey,
1852
            generator_x, generator_y, buff)
1853
        != 1)
1854
        goto err;
1855
1856
    pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1857
    EVP_MD_CTX_free(hashctx);
1858
    EVP_MD_free(shake);
1859
    key->haspubkey = 1;
1860
    return key;
1861
err:
1862
    ossl_ecx_key_free(key);
1863
    EVP_MD_CTX_free(hashctx);
1864
    EVP_MD_free(shake);
1865
    return NULL;
1866
}
1867
#endif