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