Coverage Report

Created: 2026-07-12 07:21

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
17.3k
#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
21
{
106
21
    return type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448;
107
21
}
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
56.7k
{
143
56.7k
    const ECX_KEY *key = keydata;
144
56.7k
    int ok = 0;
145
146
56.7k
    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
28.5k
        ok = 1;
152
153
28.5k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
154
92
            ok = ok && key->haspubkey;
155
156
28.5k
        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
157
27
            ok = ok && key->privkey != NULL;
158
28.5k
    }
159
56.7k
    return ok;
160
56.7k
}
161
162
static int ecx_match(const void *keydata1, const void *keydata2, int selection)
163
46
{
164
46
    const ECX_KEY *key1 = keydata1;
165
46
    const ECX_KEY *key2 = keydata2;
166
46
    int ok = 1;
167
168
46
    if (!ossl_prov_is_running())
169
0
        return 0;
170
171
46
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
172
46
        ok = ok && key1->type == key2->type;
173
46
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
174
46
        int key_checked = 0;
175
176
46
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
177
46
            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
178
46
            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
179
46
            size_t pal = key1->keylen;
180
46
            size_t pbl = key2->keylen;
181
182
46
            if (pa != NULL && pb != NULL) {
183
46
                ok = ok
184
46
                    && key1->type == key2->type
185
46
                    && pal == pbl
186
46
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
187
46
                key_checked = 1;
188
46
            }
189
46
        }
190
46
        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
46
        ok = ok && key_checked;
206
46
    }
207
46
    return ok;
208
46
}
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
426k
{
296
426k
    if (key == NULL)
297
0
        return 0;
298
299
426k
    if (!ossl_param_build_set_octet_string(tmpl, pub,
300
426k
            OSSL_PKEY_PARAM_PUB_KEY,
301
426k
            key->pubkey, key->keylen))
302
0
        return 0;
303
304
426k
    if (include_private
305
378k
        && key->privkey != NULL
306
339k
        && !ossl_param_build_set_octet_string(tmpl, priv,
307
339k
            OSSL_PKEY_PARAM_PRIV_KEY,
308
339k
            key->privkey, key->keylen))
309
0
        return 0;
310
311
426k
    return 1;
312
426k
}
313
314
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
315
    void *cbarg)
316
47.4k
{
317
47.4k
    ECX_KEY *key = keydata;
318
47.4k
    OSSL_PARAM_BLD *tmpl;
319
47.4k
    OSSL_PARAM *params = NULL;
320
47.4k
    int ret = 0;
321
322
47.4k
    if (!ossl_prov_is_running() || key == NULL)
323
0
        return 0;
324
325
47.4k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
326
0
        return 0;
327
328
47.4k
    tmpl = OSSL_PARAM_BLD_new();
329
47.4k
    if (tmpl == NULL)
330
0
        return 0;
331
332
47.4k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
333
47.4k
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
334
335
47.4k
        if (!key_to_params(key, tmpl, NULL, NULL, include_private))
336
0
            goto err;
337
47.4k
    }
338
339
47.4k
    params = OSSL_PARAM_BLD_to_param(tmpl);
340
47.4k
    if (params == NULL)
341
0
        goto err;
342
343
47.4k
    ret = param_cb(params, cbarg);
344
47.4k
    OSSL_PARAM_free(params);
345
47.4k
err:
346
47.4k
    OSSL_PARAM_BLD_free(tmpl);
347
47.4k
    return ret;
348
47.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
146k
{
408
146k
    const char *s;
409
410
146k
    memset(r, 0, sizeof(*r));
411
146k
    if (p != NULL)
412
528k
        for (; (s = p->key) != NULL; p++)
413
382k
            switch(s[0]) {
414
0
            default:
415
0
                break;
416
78.6k
            case 'b':
417
78.6k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
418
                    /* OSSL_PKEY_PARAM_BITS */
419
78.6k
                    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
78.6k
                    r->bits = (OSSL_PARAM *)p;
425
78.6k
                }
426
78.6k
                break;
427
78.6k
            case 'e':
428
67.8k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
429
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
430
67.8k
                    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
67.8k
                    r->encpub = (OSSL_PARAM *)p;
436
67.8k
                }
437
67.8k
                break;
438
67.8k
            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
78.6k
            case 'm':
452
78.6k
                if (ossl_likely(strcmp("ax-size", s + 1) == 0)) {
453
                    /* OSSL_PKEY_PARAM_MAX_SIZE */
454
78.6k
                    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
78.6k
                    r->size = (OSSL_PARAM *)p;
460
78.6k
                }
461
78.6k
                break;
462
78.6k
            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
157k
            case 's':
490
157k
                switch(s[1]) {
491
0
                default:
492
0
                    break;
493
157k
                case 'e':
494
157k
                    switch(s[2]) {
495
0
                    default:
496
0
                        break;
497
157k
                    case 'c':
498
157k
                        switch(s[3]) {
499
0
                        default:
500
0
                            break;
501
157k
                        case 'u':
502
157k
                            switch(s[4]) {
503
0
                            default:
504
0
                                break;
505
157k
                            case 'r':
506
157k
                                switch(s[5]) {
507
0
                                default:
508
0
                                    break;
509
157k
                                case 'i':
510
157k
                                    switch(s[6]) {
511
0
                                    default:
512
0
                                        break;
513
157k
                                    case 't':
514
157k
                                        switch(s[7]) {
515
0
                                        default:
516
0
                                            break;
517
157k
                                        case 'y':
518
157k
                                            switch(s[8]) {
519
0
                                            default:
520
0
                                                break;
521
157k
                                            case '-':
522
157k
                                                switch(s[9]) {
523
0
                                                default:
524
0
                                                    break;
525
78.6k
                                                case 'b':
526
78.6k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
527
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
528
78.6k
                                                        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
78.6k
                                                        r->secbits = (OSSL_PARAM *)p;
534
78.6k
                                                    }
535
78.6k
                                                    break;
536
78.6k
                                                case 'c':
537
78.6k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
538
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
539
78.6k
                                                        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
78.6k
                                                        r->seccat = (OSSL_PARAM *)p;
545
78.6k
                                                    }
546
157k
                                                }
547
157k
                                            }
548
157k
                                        }
549
157k
                                    }
550
157k
                                }
551
157k
                            }
552
157k
                        }
553
157k
                    }
554
157k
                }
555
382k
            }
556
146k
    return 1;
557
146k
}
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.29k
{
595
1.29k
    const char *s;
596
597
1.29k
    memset(r, 0, sizeof(*r));
598
1.29k
    if (p != NULL)
599
6.49k
        for (; (s = p->key) != NULL; p++)
600
5.19k
            switch(s[0]) {
601
0
            default:
602
0
                break;
603
1.29k
            case 'b':
604
1.29k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
605
                    /* OSSL_PKEY_PARAM_BITS */
606
1.29k
                    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.29k
                    r->bits = (OSSL_PARAM *)p;
612
1.29k
                }
613
1.29k
                break;
614
1.29k
            case 'm':
615
1.29k
                switch(s[1]) {
616
0
                default:
617
0
                    break;
618
1.29k
                case 'a':
619
1.29k
                    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.29k
                    case 'x':
634
1.29k
                        if (ossl_likely(strcmp("-size", s + 3) == 0)) {
635
                            /* OSSL_PKEY_PARAM_MAX_SIZE */
636
1.29k
                            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.29k
                            r->size = (OSSL_PARAM *)p;
642
1.29k
                        }
643
1.29k
                    }
644
1.29k
                }
645
1.29k
                break;
646
1.29k
            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
2.59k
            case 's':
674
2.59k
                switch(s[1]) {
675
0
                default:
676
0
                    break;
677
2.59k
                case 'e':
678
2.59k
                    switch(s[2]) {
679
0
                    default:
680
0
                        break;
681
2.59k
                    case 'c':
682
2.59k
                        switch(s[3]) {
683
0
                        default:
684
0
                            break;
685
2.59k
                        case 'u':
686
2.59k
                            switch(s[4]) {
687
0
                            default:
688
0
                                break;
689
2.59k
                            case 'r':
690
2.59k
                                switch(s[5]) {
691
0
                                default:
692
0
                                    break;
693
2.59k
                                case 'i':
694
2.59k
                                    switch(s[6]) {
695
0
                                    default:
696
0
                                        break;
697
2.59k
                                    case 't':
698
2.59k
                                        switch(s[7]) {
699
0
                                        default:
700
0
                                            break;
701
2.59k
                                        case 'y':
702
2.59k
                                            switch(s[8]) {
703
0
                                            default:
704
0
                                                break;
705
2.59k
                                            case '-':
706
2.59k
                                                switch(s[9]) {
707
0
                                                default:
708
0
                                                    break;
709
1.29k
                                                case 'b':
710
1.29k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
711
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
712
1.29k
                                                        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.29k
                                                        r->secbits = (OSSL_PARAM *)p;
718
1.29k
                                                    }
719
1.29k
                                                    break;
720
1.29k
                                                case 'c':
721
1.29k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
722
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
723
1.29k
                                                        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.29k
                                                        r->seccat = (OSSL_PARAM *)p;
729
1.29k
                                                    }
730
2.59k
                                                }
731
2.59k
                                            }
732
2.59k
                                        }
733
2.59k
                                    }
734
2.59k
                                }
735
2.59k
                            }
736
2.59k
                        }
737
2.59k
                    }
738
2.59k
                }
739
5.19k
            }
740
1.29k
    return 1;
741
1.29k
}
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
147k
{
751
147k
    ECX_KEY *ecx = key;
752
753
147k
    if (p->bits != NULL && !OSSL_PARAM_set_int(p->bits, bits))
754
0
        return 0;
755
147k
    if (p->secbits != NULL && !OSSL_PARAM_set_int(p->secbits, secbits))
756
0
        return 0;
757
147k
    if (p->size != NULL && !OSSL_PARAM_set_int(p->size, size))
758
0
        return 0;
759
147k
    if (p->seccat != NULL && !OSSL_PARAM_set_int(p->seccat, 0))
760
0
        return 0;
761
147k
    return key_to_params(ecx, NULL, p->pub, p->priv, 1);
762
147k
}
763
764
/* X25519/X448 getter */
765
static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
766
    int size)
767
146k
{
768
146k
    ECX_KEY *ecx = key;
769
146k
    struct ecx_ed_common_get_params_st p;
770
771
146k
    if (key == NULL || !ecx_get_params_decoder(params, &p))
772
0
        return 0;
773
774
146k
    if (p.encpub != NULL
775
67.8k
        && !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
146k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
788
146k
}
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.29k
{
794
1.29k
    struct ecx_ed_common_get_params_st p;
795
796
1.29k
    if (key == NULL || !ed_get_params_decoder(params, &p))
797
0
        return 0;
798
1.29k
    if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, ""))
799
0
        return 0;
800
1.29k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
801
1.29k
}
802
803
static int x25519_get_params(void *key, OSSL_PARAM params[])
804
374k
{
805
374k
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
806
374k
        X25519_KEYLEN);
807
374k
}
808
809
static int x448_get_params(void *key, OSSL_PARAM params[])
810
2.01k
{
811
2.01k
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
812
2.01k
        X448_KEYLEN);
813
2.01k
}
814
815
static int ed25519_get_params(void *key, OSSL_PARAM params[])
816
250
{
817
250
    return ed_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
818
250
        ED25519_SIGSIZE);
819
250
}
820
static int ed448_get_params(void *key, OSSL_PARAM params[])
821
1.04k
{
822
1.04k
    return ed_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
823
1.04k
        ED448_SIGSIZE);
824
1.04k
}
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
12.3k
{
879
12.3k
    const char *s;
880
881
12.3k
    memset(r, 0, sizeof(*r));
882
12.3k
    if (p != NULL)
883
24.6k
        for (; (s = p->key) != NULL; p++)
884
12.3k
            switch(s[0]) {
885
0
            default:
886
0
                break;
887
12.3k
            case 'e':
888
12.3k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
889
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
890
12.3k
                    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
12.3k
                    r->pub = (OSSL_PARAM *)p;
896
12.3k
                }
897
12.3k
                break;
898
12.3k
            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
12.3k
            }
909
12.3k
    return 1;
910
12.3k
}
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
12.3k
{
917
12.3k
    ECX_KEY *ecxkey = key;
918
12.3k
    struct ecx_set_params_st p;
919
920
12.3k
    if (key == NULL || !ecx_set_params_decoder(params, &p))
921
0
        return 0;
922
923
12.3k
    if (p.pub != NULL) {
924
12.3k
        void *buf = ecxkey->pubkey;
925
926
12.3k
        if (p.pub->data_size != ecxkey->keylen
927
12.2k
            || !OSSL_PARAM_get_octet_string(p.pub, &buf, sizeof(ecxkey->pubkey),
928
12.2k
                NULL))
929
35
            return 0;
930
12.2k
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
931
12.2k
        ecxkey->privkey = NULL;
932
12.2k
        ecxkey->haspubkey = 1;
933
12.2k
    }
934
935
12.2k
    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
12.2k
    return 1;
942
12.2k
}
943
944
static int x25519_set_params(void *key, const OSSL_PARAM params[])
945
34.1k
{
946
34.1k
    return ecx_set_params(key, params);
947
34.1k
}
948
949
static int x448_set_params(void *key, const OSSL_PARAM params[])
950
68
{
951
68
    return ecx_set_params(key, params);
952
68
}
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
150k
{
992
150k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
993
150k
    struct ecx_gen_ctx *gctx = NULL;
994
995
150k
    if (!ossl_prov_is_running())
996
0
        return NULL;
997
998
150k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
999
150k
        gctx->libctx = libctx;
1000
150k
        gctx->type = type;
1001
150k
        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
150k
    } else {
1011
0
        return NULL;
1012
0
    }
1013
150k
    if (!ecx_gen_set_params(gctx, params)) {
1014
0
        ecx_gen_cleanup(gctx);
1015
0
        gctx = NULL;
1016
0
    }
1017
150k
    return gctx;
1018
150k
}
1019
1020
static void *x25519_gen_init(void *provctx, int selection,
1021
    const OSSL_PARAM params[])
1022
150k
{
1023
150k
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519");
1024
150k
}
1025
1026
static void *x448_gen_init(void *provctx, int selection,
1027
    const OSSL_PARAM params[])
1028
318
{
1029
318
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448");
1030
318
}
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
132k
{
1067
132k
    const char *s;
1068
1069
132k
    memset(r, 0, sizeof(*r));
1070
132k
    if (p != NULL)
1071
100k
        for (; (s = p->key) != NULL; p++)
1072
34.6k
            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
34.6k
            case 'g':
1087
34.6k
                if (ossl_likely(strcmp("roup", s + 1) == 0)) {
1088
                    /* OSSL_PKEY_PARAM_GROUP_NAME */
1089
34.6k
                    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
34.6k
                    r->group = (OSSL_PARAM *)p;
1095
34.6k
                }
1096
34.6k
                break;
1097
34.6k
            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
34.6k
            }
1108
132k
    return 1;
1109
132k
}
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
132k
{
1116
132k
    struct ecx_gen_ctx *gctx = genctx;
1117
132k
    struct ecx_gen_set_params_st p;
1118
1119
132k
    if (gctx == NULL || !ecx_gen_set_params_decoder(params, &p))
1120
0
        return 0;
1121
1122
132k
    if (p.group != NULL) {
1123
34.6k
        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
34.6k
        switch (gctx->type) {
1131
34.5k
        case ECX_KEY_TYPE_X25519:
1132
34.5k
            groupname = "x25519";
1133
34.5k
            break;
1134
94
        case ECX_KEY_TYPE_X448:
1135
94
            groupname = "x448";
1136
94
            break;
1137
0
        default:
1138
            /* We only support this for key exchange at the moment */
1139
0
            break;
1140
34.6k
        }
1141
34.6k
        if (p.group->data_type != OSSL_PARAM_UTF8_STRING
1142
34.6k
            || groupname == NULL
1143
34.6k
            || 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
34.6k
    }
1148
1149
132k
    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
132k
    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
132k
    return 1;
1169
132k
}
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
102k
{
1247
102k
    ECX_KEY *key;
1248
102k
    unsigned char *privkey;
1249
1250
102k
    if (gctx == NULL)
1251
0
        return NULL;
1252
102k
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
1253
102k
             gctx->propq))
1254
102k
        == 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
102k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1261
3.05k
        return key;
1262
1263
98.9k
    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
98.9k
#ifndef FIPS_MODULE
1268
98.9k
    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
98.9k
#endif
1276
98.9k
    {
1277
98.9k
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
1278
0
            goto err;
1279
98.9k
    }
1280
1281
98.9k
    switch (gctx->type) {
1282
98.8k
    case ECX_KEY_TYPE_X25519:
1283
98.8k
        privkey[0] &= 248;
1284
98.8k
        privkey[X25519_KEYLEN - 1] &= 127;
1285
98.8k
        privkey[X25519_KEYLEN - 1] |= 64;
1286
98.8k
        ossl_x25519_public_from_private(key->pubkey, privkey);
1287
98.8k
        break;
1288
111
    case ECX_KEY_TYPE_X448:
1289
111
        privkey[0] &= 252;
1290
111
        privkey[X448_KEYLEN - 1] |= 128;
1291
111
        ossl_x448_public_from_private(key->pubkey, privkey);
1292
111
        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
98.9k
    }
1304
98.9k
    key->haspubkey = 1;
1305
98.9k
    return key;
1306
0
err:
1307
0
    ossl_ecx_key_free(key);
1308
0
    return NULL;
1309
98.9k
}
1310
1311
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1312
150k
{
1313
150k
    struct ecx_gen_ctx *gctx = genctx;
1314
1315
150k
    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
150k
    return ecx_gen(gctx);
1323
150k
}
1324
1325
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1326
318
{
1327
318
    struct ecx_gen_ctx *gctx = genctx;
1328
1329
318
    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
318
    return ecx_gen(gctx);
1337
318
}
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_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
1365
        ossl_ecx_key_free(key);
1366
        return NULL;
1367
    }
1368
#endif
1369
1370
0
    return key;
1371
0
}
1372
1373
static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1374
0
{
1375
0
    ECX_KEY *key = NULL;
1376
0
    struct ecx_gen_ctx *gctx = genctx;
1377
1378
0
    if (!ossl_prov_is_running())
1379
0
        return 0;
1380
1381
#ifdef S390X_EC_ASM
1382
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1383
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1384
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)) {
1385
        key = s390x_ecd_keygen448(gctx);
1386
    } else
1387
#endif
1388
0
    {
1389
0
        key = ecx_gen(gctx);
1390
0
    }
1391
1392
#ifdef FIPS_MODULE
1393
    /* Exit if keygen failed OR we are doing parameter generation (blank key) */
1394
    if (!key || ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0))
1395
        return key;
1396
    if (ecd_fips140_pairwise_test(key, ECX_KEY_TYPE_ED448, 1) != 1) {
1397
        ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
1398
        ossl_ecx_key_free(key);
1399
        return NULL;
1400
    }
1401
#endif
1402
1403
0
    return key;
1404
0
}
1405
1406
static void ecx_gen_cleanup(void *genctx)
1407
150k
{
1408
150k
    struct ecx_gen_ctx *gctx = genctx;
1409
1410
150k
    if (gctx == NULL)
1411
0
        return;
1412
1413
150k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1414
150k
    OPENSSL_free(gctx->propq);
1415
150k
    OPENSSL_free(gctx);
1416
150k
}
1417
1418
void *ecx_load(const void *reference, size_t reference_sz)
1419
5.16k
{
1420
5.16k
    ECX_KEY *key = NULL;
1421
1422
5.16k
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
1423
        /* The contents of the reference is the address to our object */
1424
5.16k
        key = *(ECX_KEY **)reference;
1425
        /* We grabbed, so we detach it */
1426
5.16k
        *(ECX_KEY **)reference = NULL;
1427
5.16k
        return key;
1428
5.16k
    }
1429
0
    return NULL;
1430
5.16k
}
1431
1432
static void *ecx_dup(const void *keydata_from, int selection)
1433
28.2k
{
1434
28.2k
    if (ossl_prov_is_running())
1435
28.2k
        return ossl_ecx_key_dup(keydata_from, selection);
1436
0
    return NULL;
1437
28.2k
}
1438
1439
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
1440
12
{
1441
12
    uint8_t pub[64];
1442
1443
12
    switch (type) {
1444
6
    case ECX_KEY_TYPE_X25519:
1445
6
        ossl_x25519_public_from_private(pub, ecx->privkey);
1446
6
        break;
1447
6
    case ECX_KEY_TYPE_X448:
1448
6
        ossl_x448_public_from_private(pub, ecx->privkey);
1449
6
        break;
1450
0
    default:
1451
0
        return 0;
1452
12
    }
1453
12
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1454
12
}
1455
1456
#ifdef FIPS_MODULE
1457
/*
1458
 * FIPS ACVP testing requires the ability to check if the public key is valid
1459
 * This is not required normally since the ED signature verify does the test
1460
 * internally.
1461
 */
1462
static int ecd_key_pub_check(const ECX_KEY *ecx, int type)
1463
{
1464
    switch (type) {
1465
    case ECX_KEY_TYPE_ED25519:
1466
        return ossl_ed25519_pubkey_verify(ecx->pubkey, ecx->keylen);
1467
    case ECX_KEY_TYPE_ED448:
1468
        return ossl_ed448_pubkey_verify(ecx->pubkey, ecx->keylen);
1469
    default:
1470
        return 1;
1471
    }
1472
}
1473
#endif
1474
1475
#ifdef FIPS_MODULE
1476
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
1477
{
1478
    return ecd_fips140_pairwise_test(ecx, type, 0);
1479
}
1480
#else
1481
static int ecd_key_pairwise_check(const ECX_KEY *ecx, int type)
1482
14
{
1483
14
    uint8_t pub[64];
1484
1485
14
    switch (type) {
1486
7
    case ECX_KEY_TYPE_ED25519:
1487
7
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
1488
7
                ecx->propq))
1489
0
            return 0;
1490
7
        break;
1491
7
    case ECX_KEY_TYPE_ED448:
1492
7
        if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
1493
7
                ecx->propq))
1494
0
            return 0;
1495
7
        break;
1496
7
    default:
1497
0
        return 0;
1498
14
    }
1499
14
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1500
14
}
1501
#endif
1502
1503
static int ecx_validate(const void *keydata, int selection, int type,
1504
    size_t keylen)
1505
17.3k
{
1506
17.3k
    const ECX_KEY *ecx = keydata;
1507
17.3k
    int ok = keylen == ecx->keylen;
1508
1509
17.3k
    if (!ossl_prov_is_running())
1510
0
        return 0;
1511
1512
17.3k
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
1513
21
        return 1; /* nothing to validate */
1514
1515
17.3k
    if (!ok) {
1516
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
1517
0
        return 0;
1518
0
    }
1519
1520
17.3k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
1521
17.3k
        ok = ok && ecx->haspubkey;
1522
#ifdef FIPS_MODULE
1523
        ok = ok && ecd_key_pub_check(ecx, type);
1524
#endif
1525
17.3k
    }
1526
1527
17.3k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
1528
42
        ok = ok && ecx->privkey != NULL;
1529
1530
17.3k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
1531
17.3k
        return ok;
1532
1533
21
    if (ecx_key_type_is_ed(type))
1534
10
        ok = ok && ecd_key_pairwise_check(ecx, type);
1535
11
    else
1536
11
        ok = ok && ecx_key_pairwise_check(ecx, type);
1537
1538
21
    return ok;
1539
17.3k
}
1540
1541
static int x25519_validate(const void *keydata, int selection, int checktype)
1542
32.0k
{
1543
32.0k
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
1544
32.0k
}
1545
1546
static int x448_validate(const void *keydata, int selection, int checktype)
1547
79
{
1548
79
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
1549
79
}
1550
1551
static int ed25519_validate(const void *keydata, int selection, int checktype)
1552
48
{
1553
48
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
1554
48
}
1555
1556
static int ed448_validate(const void *keydata, int selection, int checktype)
1557
48
{
1558
48
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
1559
48
}
1560
1561
static void ecx_free_key(void *keydata)
1562
120k
{
1563
120k
    ossl_ecx_key_free((ECX_KEY *)keydata);
1564
120k
}
1565
1566
#define MAKE_KEYMGMT_FUNCTIONS(alg)                                                   \
1567
    const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = {                          \
1568
        { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key },                     \
1569
        { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_free_key },                     \
1570
        { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))alg##_get_params },           \
1571
        { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))alg##_gettable_params }, \
1572
        { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))alg##_set_params },           \
1573
        { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))alg##_settable_params }, \
1574
        { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has },                           \
1575
        { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match },                       \
1576
        { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate },               \
1577
        { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import },                     \
1578
        { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types },       \
1579
        { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export },                     \
1580
        { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types },       \
1581
        { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init },               \
1582
        { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params },     \
1583
        { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,                                      \
1584
            (void (*)(void))ecx_gen_settable_params },                                \
1585
        { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen },                         \
1586
        { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup },           \
1587
        { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load },                         \
1588
        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup },                           \
1589
        OSSL_DISPATCH_END                                                             \
1590
    };
1591
1592
MAKE_KEYMGMT_FUNCTIONS(x25519)
1593
MAKE_KEYMGMT_FUNCTIONS(x448)
1594
MAKE_KEYMGMT_FUNCTIONS(ed25519)
1595
MAKE_KEYMGMT_FUNCTIONS(ed448)
1596
1597
#ifdef S390X_EC_ASM
1598
#include "s390x_arch.h"
1599
1600
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
1601
{
1602
    static const unsigned char generator[] = {
1603
        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1604
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1605
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1606
    };
1607
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
1608
        gctx->propq);
1609
    unsigned char *privkey = NULL, *pubkey;
1610
1611
    if (key == NULL) {
1612
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1613
        goto err;
1614
    }
1615
1616
    /* If we're doing parameter generation then we just return a blank key */
1617
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1618
        return key;
1619
1620
    pubkey = key->pubkey;
1621
1622
    privkey = ossl_ecx_key_allocate_privkey(key);
1623
    if (privkey == NULL) {
1624
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1625
        goto err;
1626
    }
1627
1628
#ifndef FIPS_MODULE
1629
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1630
        if (gctx->type != ECX_KEY_TYPE_X25519)
1631
            goto err;
1632
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
1633
                gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1634
            goto err;
1635
    } else
1636
#endif
1637
    {
1638
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
1639
            goto err;
1640
    }
1641
1642
    privkey[0] &= 248;
1643
    privkey[31] &= 127;
1644
    privkey[31] |= 64;
1645
1646
    if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1647
        goto err;
1648
    key->haspubkey = 1;
1649
    return key;
1650
err:
1651
    ossl_ecx_key_free(key);
1652
    return NULL;
1653
}
1654
1655
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
1656
{
1657
    static const unsigned char generator[] = {
1658
        0x05, 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, 0x00, 0x00, 0x00, 0x00,
1661
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1663
    };
1664
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
1665
        gctx->propq);
1666
    unsigned char *privkey = NULL, *pubkey;
1667
1668
    if (key == NULL) {
1669
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1670
        goto err;
1671
    }
1672
1673
    /* If we're doing parameter generation then we just return a blank key */
1674
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1675
        return key;
1676
1677
    pubkey = key->pubkey;
1678
1679
    privkey = ossl_ecx_key_allocate_privkey(key);
1680
    if (privkey == NULL) {
1681
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1682
        goto err;
1683
    }
1684
1685
#ifndef FIPS_MODULE
1686
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
1687
        if (gctx->type != ECX_KEY_TYPE_X448)
1688
            goto err;
1689
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
1690
                gctx->dhkem_ikm, gctx->dhkem_ikmlen))
1691
            goto err;
1692
    } else
1693
#endif
1694
    {
1695
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
1696
            goto err;
1697
    }
1698
1699
    privkey[0] &= 252;
1700
    privkey[55] |= 128;
1701
1702
    if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1703
        goto err;
1704
    key->haspubkey = 1;
1705
    return key;
1706
err:
1707
    ossl_ecx_key_free(key);
1708
    return NULL;
1709
}
1710
1711
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
1712
{
1713
    static const unsigned char generator_x[] = {
1714
        0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1715
        0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1716
        0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1717
    };
1718
    static const unsigned char generator_y[] = {
1719
        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1720
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1721
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1722
        0x66, 0x66
1723
    };
1724
    unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1725
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1726
        gctx->propq);
1727
    unsigned char *privkey = NULL, *pubkey;
1728
    unsigned int sz;
1729
    EVP_MD *sha = NULL;
1730
    int j;
1731
1732
    if (key == NULL) {
1733
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1734
        goto err;
1735
    }
1736
1737
    /* If we're doing parameter generation then we just return a blank key */
1738
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1739
        return key;
1740
1741
    pubkey = key->pubkey;
1742
1743
    privkey = ossl_ecx_key_allocate_privkey(key);
1744
    if (privkey == NULL) {
1745
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1746
        goto err;
1747
    }
1748
1749
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1750
        goto err;
1751
1752
    sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1753
    if (sha == NULL)
1754
        goto err;
1755
    j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1756
    EVP_MD_free(sha);
1757
    if (!j)
1758
        goto err;
1759
1760
    buff[0] &= 248;
1761
    buff[31] &= 63;
1762
    buff[31] |= 64;
1763
1764
    if (s390x_ed25519_mul(x_dst, pubkey,
1765
            generator_x, generator_y, buff)
1766
        != 1)
1767
        goto err;
1768
1769
    pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1770
    key->haspubkey = 1;
1771
    return key;
1772
err:
1773
    ossl_ecx_key_free(key);
1774
    return NULL;
1775
}
1776
1777
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1778
{
1779
    static const unsigned char generator_x[] = {
1780
        0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1781
        0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1782
        0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1783
        0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1784
        0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1785
    };
1786
    static const unsigned char generator_y[] = {
1787
        0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1788
        0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1789
        0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1790
        0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1791
        0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1792
    };
1793
    unsigned char x_dst[57], buff[114];
1794
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1795
        gctx->propq);
1796
    unsigned char *privkey = NULL, *pubkey;
1797
    EVP_MD_CTX *hashctx = NULL;
1798
    EVP_MD *shake = NULL;
1799
1800
    if (key == NULL) {
1801
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1802
        goto err;
1803
    }
1804
1805
    /* If we're doing parameter generation then we just return a blank key */
1806
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1807
        return key;
1808
1809
    pubkey = key->pubkey;
1810
1811
    privkey = ossl_ecx_key_allocate_privkey(key);
1812
    if (privkey == NULL) {
1813
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1814
        goto err;
1815
    }
1816
1817
    shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1818
    if (shake == NULL)
1819
        goto err;
1820
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1821
        goto err;
1822
1823
    hashctx = EVP_MD_CTX_new();
1824
    if (hashctx == NULL)
1825
        goto err;
1826
    if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1827
        goto err;
1828
    if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1829
        goto err;
1830
    if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1831
        goto err;
1832
1833
    buff[0] &= -4;
1834
    buff[55] |= 0x80;
1835
    buff[56] = 0;
1836
1837
    if (s390x_ed448_mul(x_dst, pubkey,
1838
            generator_x, generator_y, buff)
1839
        != 1)
1840
        goto err;
1841
1842
    pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1843
    EVP_MD_CTX_free(hashctx);
1844
    EVP_MD_free(shake);
1845
    key->haspubkey = 1;
1846
    return key;
1847
err:
1848
    ossl_ecx_key_free(key);
1849
    EVP_MD_CTX_free(hashctx);
1850
    EVP_MD_free(shake);
1851
    return NULL;
1852
}
1853
#endif