Coverage Report

Created: 2025-12-31 06:58

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