Coverage Report

Created: 2026-05-24 07:14

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_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
18.2k
#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
22
{
106
22
    return type == ECX_KEY_TYPE_ED25519 || type == ECX_KEY_TYPE_ED448;
107
22
}
108
109
static void *x25519_new_key(void *provctx)
110
26
{
111
26
    if (!ossl_prov_is_running())
112
0
        return 0;
113
26
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
114
26
        NULL);
115
26
}
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
59.4k
{
143
59.4k
    const ECX_KEY *key = keydata;
144
59.4k
    int ok = 0;
145
146
59.4k
    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
29.9k
        ok = 1;
152
153
29.9k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
154
96
            ok = ok && key->haspubkey;
155
156
29.9k
        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
157
28
            ok = ok && key->privkey != NULL;
158
29.9k
    }
159
59.4k
    return ok;
160
59.4k
}
161
162
static int ecx_match(const void *keydata1, const void *keydata2, int selection)
163
48
{
164
48
    const ECX_KEY *key1 = keydata1;
165
48
    const ECX_KEY *key2 = keydata2;
166
48
    int ok = 1;
167
168
48
    if (!ossl_prov_is_running())
169
0
        return 0;
170
171
48
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
172
48
        ok = ok && key1->type == key2->type;
173
48
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
174
48
        int key_checked = 0;
175
176
48
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
177
48
            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
178
48
            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
179
48
            size_t pal = key1->keylen;
180
48
            size_t pbl = key2->keylen;
181
182
48
            if (pa != NULL && pb != NULL) {
183
48
                ok = ok
184
48
                    && key1->type == key2->type
185
48
                    && pal == pbl
186
48
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
187
48
                key_checked = 1;
188
48
            }
189
48
        }
190
48
        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
48
        ok = ok && key_checked;
206
48
    }
207
48
    return ok;
208
48
}
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
26
{
231
26
    const char *s;
232
233
26
    memset(r, 0, sizeof(*r));
234
26
    if (p != NULL)
235
52
        for (; (s = p->key) != NULL; p++)
236
26
            switch(s[0]) {
237
0
            default:
238
0
                break;
239
26
            case 'p':
240
26
                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
26
                case 'u':
255
26
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
256
                        /* OSSL_PKEY_PARAM_PUB_KEY */
257
26
                        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
26
                        r->pub = (OSSL_PARAM *)p;
263
26
                    }
264
26
                }
265
26
            }
266
26
    return 1;
267
26
}
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
26
{
274
26
    ECX_KEY *key = keydata;
275
26
    int ok = 1;
276
26
    int include_private;
277
26
    struct ecx_imexport_types_st p;
278
279
26
    if (!ossl_prov_is_running()
280
26
        || key == NULL
281
26
        || !ecx_imexport_types_decoder(params, &p))
282
0
        return 0;
283
284
26
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
285
0
        return 0;
286
287
26
    include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
288
26
    ok = ok && ossl_ecx_key_fromdata(key, p.pub, p.priv, include_private);
289
290
26
    return ok;
291
26
}
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
451k
{
296
451k
    if (key == NULL)
297
0
        return 0;
298
299
451k
    if (!ossl_param_build_set_octet_string(tmpl, pub,
300
451k
            OSSL_PKEY_PARAM_PUB_KEY,
301
451k
            key->pubkey, key->keylen))
302
0
        return 0;
303
304
451k
    if (include_private
305
400k
        && key->privkey != NULL
306
358k
        && !ossl_param_build_set_octet_string(tmpl, priv,
307
358k
            OSSL_PKEY_PARAM_PRIV_KEY,
308
358k
            key->privkey, key->keylen))
309
0
        return 0;
310
311
451k
    return 1;
312
451k
}
313
314
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
315
    void *cbarg)
316
50.6k
{
317
50.6k
    ECX_KEY *key = keydata;
318
50.6k
    OSSL_PARAM_BLD *tmpl;
319
50.6k
    OSSL_PARAM *params = NULL;
320
50.6k
    int ret = 0;
321
322
50.6k
    if (!ossl_prov_is_running() || key == NULL)
323
0
        return 0;
324
325
50.6k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
326
0
        return 0;
327
328
50.6k
    tmpl = OSSL_PARAM_BLD_new();
329
50.6k
    if (tmpl == NULL)
330
0
        return 0;
331
332
50.6k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
333
50.6k
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
334
335
50.6k
        if (!key_to_params(key, tmpl, NULL, NULL, include_private))
336
0
            goto err;
337
50.6k
    }
338
339
50.6k
    params = OSSL_PARAM_BLD_to_param(tmpl);
340
50.6k
    if (params == NULL)
341
0
        goto err;
342
343
50.6k
    ret = param_cb(params, cbarg);
344
50.6k
    OSSL_PARAM_free(params);
345
50.6k
err:
346
50.6k
    OSSL_PARAM_BLD_free(tmpl);
347
50.6k
    return ret;
348
50.6k
}
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
158k
{
408
158k
    const char *s;
409
410
158k
    memset(r, 0, sizeof(*r));
411
158k
    if (p != NULL)
412
570k
        for (; (s = p->key) != NULL; p++)
413
412k
            switch(s[0]) {
414
0
            default:
415
0
                break;
416
84.8k
            case 'b':
417
84.8k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
418
                    /* OSSL_PKEY_PARAM_BITS */
419
84.8k
                    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
84.8k
                    r->bits = (OSSL_PARAM *)p;
425
84.8k
                }
426
84.8k
                break;
427
84.8k
            case 'e':
428
73.2k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
429
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
430
73.2k
                    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
73.2k
                    r->encpub = (OSSL_PARAM *)p;
436
73.2k
                }
437
73.2k
                break;
438
73.2k
            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
84.8k
            case 'm':
452
84.8k
                if (ossl_likely(strcmp("ax-size", s + 1) == 0)) {
453
                    /* OSSL_PKEY_PARAM_MAX_SIZE */
454
84.8k
                    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
84.8k
                    r->size = (OSSL_PARAM *)p;
460
84.8k
                }
461
84.8k
                break;
462
84.8k
            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
169k
            case 's':
490
169k
                switch(s[1]) {
491
0
                default:
492
0
                    break;
493
169k
                case 'e':
494
169k
                    switch(s[2]) {
495
0
                    default:
496
0
                        break;
497
169k
                    case 'c':
498
169k
                        switch(s[3]) {
499
0
                        default:
500
0
                            break;
501
169k
                        case 'u':
502
169k
                            switch(s[4]) {
503
0
                            default:
504
0
                                break;
505
169k
                            case 'r':
506
169k
                                switch(s[5]) {
507
0
                                default:
508
0
                                    break;
509
169k
                                case 'i':
510
169k
                                    switch(s[6]) {
511
0
                                    default:
512
0
                                        break;
513
169k
                                    case 't':
514
169k
                                        switch(s[7]) {
515
0
                                        default:
516
0
                                            break;
517
169k
                                        case 'y':
518
169k
                                            switch(s[8]) {
519
0
                                            default:
520
0
                                                break;
521
169k
                                            case '-':
522
169k
                                                switch(s[9]) {
523
0
                                                default:
524
0
                                                    break;
525
84.8k
                                                case 'b':
526
84.8k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
527
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
528
84.8k
                                                        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
84.8k
                                                        r->secbits = (OSSL_PARAM *)p;
534
84.8k
                                                    }
535
84.8k
                                                    break;
536
84.8k
                                                case 'c':
537
84.8k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
538
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
539
84.8k
                                                        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
84.8k
                                                        r->seccat = (OSSL_PARAM *)p;
545
84.8k
                                                    }
546
169k
                                                }
547
169k
                                            }
548
169k
                                        }
549
169k
                                    }
550
169k
                                }
551
169k
                            }
552
169k
                        }
553
169k
                    }
554
169k
                }
555
412k
            }
556
158k
    return 1;
557
158k
}
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.32k
{
595
1.32k
    const char *s;
596
597
1.32k
    memset(r, 0, sizeof(*r));
598
1.32k
    if (p != NULL)
599
6.62k
        for (; (s = p->key) != NULL; p++)
600
5.30k
            switch(s[0]) {
601
0
            default:
602
0
                break;
603
1.32k
            case 'b':
604
1.32k
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
605
                    /* OSSL_PKEY_PARAM_BITS */
606
1.32k
                    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.32k
                    r->bits = (OSSL_PARAM *)p;
612
1.32k
                }
613
1.32k
                break;
614
1.32k
            case 'm':
615
1.32k
                switch(s[1]) {
616
0
                default:
617
0
                    break;
618
1.32k
                case 'a':
619
1.32k
                    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.32k
                    case 'x':
634
1.32k
                        if (ossl_likely(strcmp("-size", s + 3) == 0)) {
635
                            /* OSSL_PKEY_PARAM_MAX_SIZE */
636
1.32k
                            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.32k
                            r->size = (OSSL_PARAM *)p;
642
1.32k
                        }
643
1.32k
                    }
644
1.32k
                }
645
1.32k
                break;
646
1.32k
            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.65k
            case 's':
674
2.65k
                switch(s[1]) {
675
0
                default:
676
0
                    break;
677
2.65k
                case 'e':
678
2.65k
                    switch(s[2]) {
679
0
                    default:
680
0
                        break;
681
2.65k
                    case 'c':
682
2.65k
                        switch(s[3]) {
683
0
                        default:
684
0
                            break;
685
2.65k
                        case 'u':
686
2.65k
                            switch(s[4]) {
687
0
                            default:
688
0
                                break;
689
2.65k
                            case 'r':
690
2.65k
                                switch(s[5]) {
691
0
                                default:
692
0
                                    break;
693
2.65k
                                case 'i':
694
2.65k
                                    switch(s[6]) {
695
0
                                    default:
696
0
                                        break;
697
2.65k
                                    case 't':
698
2.65k
                                        switch(s[7]) {
699
0
                                        default:
700
0
                                            break;
701
2.65k
                                        case 'y':
702
2.65k
                                            switch(s[8]) {
703
0
                                            default:
704
0
                                                break;
705
2.65k
                                            case '-':
706
2.65k
                                                switch(s[9]) {
707
0
                                                default:
708
0
                                                    break;
709
1.32k
                                                case 'b':
710
1.32k
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
711
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
712
1.32k
                                                        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.32k
                                                        r->secbits = (OSSL_PARAM *)p;
718
1.32k
                                                    }
719
1.32k
                                                    break;
720
1.32k
                                                case 'c':
721
1.32k
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
722
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
723
1.32k
                                                        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.32k
                                                        r->seccat = (OSSL_PARAM *)p;
729
1.32k
                                                    }
730
2.65k
                                                }
731
2.65k
                                            }
732
2.65k
                                        }
733
2.65k
                                    }
734
2.65k
                                }
735
2.65k
                            }
736
2.65k
                        }
737
2.65k
                    }
738
2.65k
                }
739
5.30k
            }
740
1.32k
    return 1;
741
1.32k
}
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
159k
{
751
159k
    ECX_KEY *ecx = key;
752
753
159k
    if (p->bits != NULL && !OSSL_PARAM_set_int(p->bits, bits))
754
0
        return 0;
755
159k
    if (p->secbits != NULL && !OSSL_PARAM_set_int(p->secbits, secbits))
756
0
        return 0;
757
159k
    if (p->size != NULL && !OSSL_PARAM_set_int(p->size, size))
758
0
        return 0;
759
159k
    if (p->seccat != NULL && !OSSL_PARAM_set_int(p->seccat, 0))
760
0
        return 0;
761
159k
    return key_to_params(ecx, NULL, p->pub, p->priv, 1);
762
159k
}
763
764
/* X25519/X448 getter */
765
static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
766
    int size)
767
158k
{
768
158k
    ECX_KEY *ecx = key;
769
158k
    struct ecx_ed_common_get_params_st p;
770
771
158k
    if (key == NULL || !ecx_get_params_decoder(params, &p))
772
0
        return 0;
773
774
158k
    if (p.encpub != NULL
775
73.2k
        && !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
158k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
788
158k
}
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.32k
{
794
1.32k
    struct ecx_ed_common_get_params_st p;
795
796
1.32k
    if (key == NULL || !ed_get_params_decoder(params, &p))
797
0
        return 0;
798
1.32k
    if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, ""))
799
0
        return 0;
800
1.32k
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
801
1.32k
}
802
803
static int x25519_get_params(void *key, OSSL_PARAM params[])
804
396k
{
805
396k
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
806
396k
        X25519_KEYLEN);
807
396k
}
808
809
static int x448_get_params(void *key, OSSL_PARAM params[])
810
2.11k
{
811
2.11k
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
812
2.11k
        X448_KEYLEN);
813
2.11k
}
814
815
static int ed25519_get_params(void *key, OSSL_PARAM params[])
816
182
{
817
182
    return ed_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
818
182
        ED25519_SIGSIZE);
819
182
}
820
static int ed448_get_params(void *key, OSSL_PARAM params[])
821
1.14k
{
822
1.14k
    return ed_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
823
1.14k
        ED448_SIGSIZE);
824
1.14k
}
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.9k
{
879
12.9k
    const char *s;
880
881
12.9k
    memset(r, 0, sizeof(*r));
882
12.9k
    if (p != NULL)
883
25.8k
        for (; (s = p->key) != NULL; p++)
884
12.9k
            switch(s[0]) {
885
0
            default:
886
0
                break;
887
12.9k
            case 'e':
888
12.9k
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
889
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
890
12.9k
                    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.9k
                    r->pub = (OSSL_PARAM *)p;
896
12.9k
                }
897
12.9k
                break;
898
12.9k
            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.9k
            }
909
12.9k
    return 1;
910
12.9k
}
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.9k
{
917
12.9k
    ECX_KEY *ecxkey = key;
918
12.9k
    struct ecx_set_params_st p;
919
920
12.9k
    if (key == NULL || !ecx_set_params_decoder(params, &p))
921
0
        return 0;
922
923
12.9k
    if (p.pub != NULL) {
924
12.9k
        void *buf = ecxkey->pubkey;
925
926
12.9k
        if (p.pub->data_size != ecxkey->keylen
927
12.9k
            || !OSSL_PARAM_get_octet_string(p.pub, &buf, sizeof(ecxkey->pubkey),
928
12.9k
                NULL))
929
34
            return 0;
930
12.9k
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
931
12.9k
        ecxkey->privkey = NULL;
932
12.9k
        ecxkey->haspubkey = 1;
933
12.9k
    }
934
935
12.9k
    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.9k
    return 1;
942
12.9k
}
943
944
static int x25519_set_params(void *key, const OSSL_PARAM params[])
945
35.5k
{
946
35.5k
    return ecx_set_params(key, params);
947
35.5k
}
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
159k
{
992
159k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
993
159k
    struct ecx_gen_ctx *gctx = NULL;
994
995
159k
    if (!ossl_prov_is_running())
996
0
        return NULL;
997
998
159k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
999
159k
        gctx->libctx = libctx;
1000
159k
        gctx->type = type;
1001
159k
        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
159k
    } else {
1011
0
        return NULL;
1012
0
    }
1013
159k
    if (!ecx_gen_set_params(gctx, params)) {
1014
0
        ecx_gen_cleanup(gctx);
1015
0
        gctx = NULL;
1016
0
    }
1017
159k
    return gctx;
1018
159k
}
1019
1020
static void *x25519_gen_init(void *provctx, int selection,
1021
    const OSSL_PARAM params[])
1022
159k
{
1023
159k
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519");
1024
159k
}
1025
1026
static void *x448_gen_init(void *provctx, int selection,
1027
    const OSSL_PARAM params[])
1028
351
{
1029
351
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448");
1030
351
}
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
142k
{
1067
142k
    const char *s;
1068
1069
142k
    memset(r, 0, sizeof(*r));
1070
142k
    if (p != NULL)
1071
108k
        for (; (s = p->key) != NULL; p++)
1072
37.2k
            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
37.2k
            case 'g':
1087
37.2k
                if (ossl_likely(strcmp("roup", s + 1) == 0)) {
1088
                    /* OSSL_PKEY_PARAM_GROUP_NAME */
1089
37.2k
                    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
37.2k
                    r->group = (OSSL_PARAM *)p;
1095
37.2k
                }
1096
37.2k
                break;
1097
37.2k
            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
37.2k
            }
1108
142k
    return 1;
1109
142k
}
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
142k
{
1116
142k
    struct ecx_gen_ctx *gctx = genctx;
1117
142k
    struct ecx_gen_set_params_st p;
1118
1119
142k
    if (gctx == NULL || !ecx_gen_set_params_decoder(params, &p))
1120
0
        return 0;
1121
1122
142k
    if (p.group != NULL) {
1123
37.2k
        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
37.2k
        switch (gctx->type) {
1131
37.1k
        case ECX_KEY_TYPE_X25519:
1132
37.1k
            groupname = "x25519";
1133
37.1k
            break;
1134
104
        case ECX_KEY_TYPE_X448:
1135
104
            groupname = "x448";
1136
104
            break;
1137
0
        default:
1138
            /* We only support this for key exchange at the moment */
1139
0
            break;
1140
37.2k
        }
1141
37.2k
        if (p.group->data_type != OSSL_PARAM_UTF8_STRING
1142
37.2k
            || groupname == NULL
1143
37.2k
            || 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
37.2k
    }
1148
1149
142k
    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
142k
    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
142k
    return 1;
1169
142k
}
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
108k
{
1247
108k
    ECX_KEY *key;
1248
108k
    unsigned char *privkey;
1249
1250
108k
    if (gctx == NULL)
1251
0
        return NULL;
1252
108k
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
1253
108k
             gctx->propq))
1254
108k
        == 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
108k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1261
3.10k
        return key;
1262
1263
105k
    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
105k
#ifndef FIPS_MODULE
1268
105k
    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
105k
#endif
1276
105k
    {
1277
105k
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
1278
0
            goto err;
1279
105k
    }
1280
1281
105k
    switch (gctx->type) {
1282
105k
    case ECX_KEY_TYPE_X25519:
1283
105k
        privkey[0] &= 248;
1284
105k
        privkey[X25519_KEYLEN - 1] &= 127;
1285
105k
        privkey[X25519_KEYLEN - 1] |= 64;
1286
105k
        ossl_x25519_public_from_private(key->pubkey, privkey);
1287
105k
        break;
1288
125
    case ECX_KEY_TYPE_X448:
1289
125
        privkey[0] &= 252;
1290
125
        privkey[X448_KEYLEN - 1] |= 128;
1291
125
        ossl_x448_public_from_private(key->pubkey, privkey);
1292
125
        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
105k
    }
1304
105k
    key->haspubkey = 1;
1305
105k
    return key;
1306
0
err:
1307
0
    ossl_ecx_key_free(key);
1308
0
    return NULL;
1309
105k
}
1310
1311
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1312
159k
{
1313
159k
    struct ecx_gen_ctx *gctx = genctx;
1314
1315
159k
    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
159k
    return ecx_gen(gctx);
1323
159k
}
1324
1325
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1326
351
{
1327
351
    struct ecx_gen_ctx *gctx = genctx;
1328
1329
351
    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
351
    return ecx_gen(gctx);
1337
351
}
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
159k
{
1408
159k
    struct ecx_gen_ctx *gctx = genctx;
1409
1410
159k
    if (gctx == NULL)
1411
0
        return;
1412
1413
159k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1414
159k
    OPENSSL_free(gctx->propq);
1415
159k
    OPENSSL_free(gctx);
1416
159k
}
1417
1418
void *ecx_load(const void *reference, size_t reference_sz)
1419
5.94k
{
1420
5.94k
    ECX_KEY *key = NULL;
1421
1422
5.94k
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
1423
        /* The contents of the reference is the address to our object */
1424
5.94k
        key = *(ECX_KEY **)reference;
1425
        /* We grabbed, so we detach it */
1426
5.94k
        *(ECX_KEY **)reference = NULL;
1427
5.94k
        return key;
1428
5.94k
    }
1429
0
    return NULL;
1430
5.94k
}
1431
1432
static void *ecx_dup(const void *keydata_from, int selection)
1433
29.5k
{
1434
29.5k
    if (ossl_prov_is_running())
1435
29.5k
        return ossl_ecx_key_dup(keydata_from, selection);
1436
0
    return NULL;
1437
29.5k
}
1438
1439
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
1440
11
{
1441
11
    uint8_t pub[64];
1442
1443
11
    switch (type) {
1444
6
    case ECX_KEY_TYPE_X25519:
1445
6
        ossl_x25519_public_from_private(pub, ecx->privkey);
1446
6
        break;
1447
5
    case ECX_KEY_TYPE_X448:
1448
5
        ossl_x448_public_from_private(pub, ecx->privkey);
1449
5
        break;
1450
0
    default:
1451
0
        return 0;
1452
11
    }
1453
11
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1454
11
}
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
16
{
1483
16
    uint8_t pub[64];
1484
1485
16
    switch (type) {
1486
9
    case ECX_KEY_TYPE_ED25519:
1487
9
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
1488
9
                ecx->propq))
1489
0
            return 0;
1490
9
        break;
1491
9
    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
16
    }
1499
16
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1500
16
}
1501
#endif
1502
1503
static int ecx_validate(const void *keydata, int selection, int type,
1504
    size_t keylen)
1505
18.2k
{
1506
18.2k
    const ECX_KEY *ecx = keydata;
1507
18.2k
    int ok = keylen == ecx->keylen;
1508
1509
18.2k
    if (!ossl_prov_is_running())
1510
0
        return 0;
1511
1512
18.2k
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
1513
22
        return 1; /* nothing to validate */
1514
1515
18.2k
    if (!ok) {
1516
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
1517
0
        return 0;
1518
0
    }
1519
1520
18.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
1521
18.2k
        ok = ok && ecx->haspubkey;
1522
#ifdef FIPS_MODULE
1523
        ok = ok && ecd_key_pub_check(ecx, type);
1524
#endif
1525
18.2k
    }
1526
1527
18.2k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
1528
44
        ok = ok && ecx->privkey != NULL;
1529
1530
18.2k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
1531
18.2k
        return ok;
1532
1533
22
    if (ecx_key_type_is_ed(type))
1534
10
        ok = ok && ecd_key_pairwise_check(ecx, type);
1535
12
    else
1536
12
        ok = ok && ecx_key_pairwise_check(ecx, type);
1537
1538
22
    return ok;
1539
18.2k
}
1540
1541
static int x25519_validate(const void *keydata, int selection, int checktype)
1542
33.4k
{
1543
33.4k
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
1544
33.4k
}
1545
1546
static int x448_validate(const void *keydata, int selection, int checktype)
1547
82
{
1548
82
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
1549
82
}
1550
1551
static int ed25519_validate(const void *keydata, int selection, int checktype)
1552
56
{
1553
56
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
1554
56
}
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
128k
{
1563
128k
    ossl_ecx_key_free((ECX_KEY *)keydata);
1564
128k
}
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,
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
        0x66,
1746
        0x66,
1747
        0x66,
1748
        0x66,
1749
        0x66,
1750
        0x66,
1751
    };
1752
    unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1753
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1754
        gctx->propq);
1755
    unsigned char *privkey = NULL, *pubkey;
1756
    unsigned int sz;
1757
    EVP_MD *sha = NULL;
1758
    int j;
1759
1760
    if (key == NULL) {
1761
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1762
        goto err;
1763
    }
1764
1765
    /* If we're doing parameter generation then we just return a blank key */
1766
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1767
        return key;
1768
1769
    pubkey = key->pubkey;
1770
1771
    privkey = ossl_ecx_key_allocate_privkey(key);
1772
    if (privkey == NULL) {
1773
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1774
        goto err;
1775
    }
1776
1777
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1778
        goto err;
1779
1780
    sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1781
    if (sha == NULL)
1782
        goto err;
1783
    j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1784
    EVP_MD_free(sha);
1785
    if (!j)
1786
        goto err;
1787
1788
    buff[0] &= 248;
1789
    buff[31] &= 63;
1790
    buff[31] |= 64;
1791
1792
    if (s390x_ed25519_mul(x_dst, pubkey,
1793
            generator_x, generator_y, buff)
1794
        != 1)
1795
        goto err;
1796
1797
    pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1798
    key->haspubkey = 1;
1799
    return key;
1800
err:
1801
    ossl_ecx_key_free(key);
1802
    return NULL;
1803
}
1804
1805
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1806
{
1807
    static const unsigned char generator_x[] = {
1808
        0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1809
        0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1810
        0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1811
        0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1812
        0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1813
    };
1814
    static const unsigned char generator_y[] = {
1815
        0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1816
        0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1817
        0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1818
        0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1819
        0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1820
    };
1821
    unsigned char x_dst[57], buff[114];
1822
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1823
        gctx->propq);
1824
    unsigned char *privkey = NULL, *pubkey;
1825
    EVP_MD_CTX *hashctx = NULL;
1826
    EVP_MD *shake = NULL;
1827
1828
    if (key == NULL) {
1829
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1830
        goto err;
1831
    }
1832
1833
    /* If we're doing parameter generation then we just return a blank key */
1834
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1835
        return key;
1836
1837
    pubkey = key->pubkey;
1838
1839
    privkey = ossl_ecx_key_allocate_privkey(key);
1840
    if (privkey == NULL) {
1841
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1842
        goto err;
1843
    }
1844
1845
    shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1846
    if (shake == NULL)
1847
        goto err;
1848
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1849
        goto err;
1850
1851
    hashctx = EVP_MD_CTX_new();
1852
    if (hashctx == NULL)
1853
        goto err;
1854
    if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1855
        goto err;
1856
    if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1857
        goto err;
1858
    if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1859
        goto err;
1860
1861
    buff[0] &= -4;
1862
    buff[55] |= 0x80;
1863
    buff[56] = 0;
1864
1865
    if (s390x_ed448_mul(x_dst, pubkey,
1866
            generator_x, generator_y, buff)
1867
        != 1)
1868
        goto err;
1869
1870
    pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1871
    EVP_MD_CTX_free(hashctx);
1872
    EVP_MD_free(shake);
1873
    key->haspubkey = 1;
1874
    return key;
1875
err:
1876
    ossl_ecx_key_free(key);
1877
    EVP_MD_CTX_free(hashctx);
1878
    EVP_MD_free(shake);
1879
    return NULL;
1880
}
1881
#endif