Coverage Report

Created: 2025-12-04 06:33

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