Coverage Report

Created: 2025-08-25 06:30

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