Coverage Report

Created: 2025-10-10 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/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
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
                        /* 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
0
                case 'u':
251
0
                    if (ossl_likely(strcmp("b", s + 2) == 0)) {
252
                        /* OSSL_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
0
    return ok;
286
0
}
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
0
{
291
0
    if (key == NULL)
292
0
        return 0;
293
294
0
    if (!ossl_param_build_set_octet_string(tmpl, pub,
295
0
                                           OSSL_PKEY_PARAM_PUB_KEY,
296
0
                                           key->pubkey, key->keylen))
297
0
        return 0;
298
299
0
    if (include_private
300
0
        && key->privkey != NULL
301
0
        && !ossl_param_build_set_octet_string(tmpl, priv,
302
0
                                              OSSL_PKEY_PARAM_PRIV_KEY,
303
0
                                              key->privkey, key->keylen))
304
0
        return 0;
305
306
0
    return 1;
307
0
}
308
309
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
310
                      void *cbarg)
311
0
{
312
0
    ECX_KEY *key = keydata;
313
0
    OSSL_PARAM_BLD *tmpl;
314
0
    OSSL_PARAM *params = NULL;
315
0
    int ret = 0;
316
317
0
    if (!ossl_prov_is_running() || key == NULL)
318
0
        return 0;
319
320
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
321
0
        return 0;
322
323
0
    tmpl = OSSL_PARAM_BLD_new();
324
0
    if (tmpl == NULL)
325
0
        return 0;
326
327
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
328
0
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
329
330
0
        if (!key_to_params(key, tmpl, NULL, NULL, include_private))
331
0
            goto err;
332
0
    }
333
334
0
    params = OSSL_PARAM_BLD_to_param(tmpl);
335
0
    if (params == NULL)
336
0
        goto err;
337
338
0
    ret = param_cb(params, cbarg);
339
0
    OSSL_PARAM_free(params);
340
0
err:
341
0
    OSSL_PARAM_BLD_free(tmpl);
342
0
    return ret;
343
0
}
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
0
{
402
0
    const char *s;
403
404
0
    memset(r, 0, sizeof(*r));
405
0
    if (p != NULL)
406
0
        for (; (s = p->key) != NULL; p++)
407
0
            switch(s[0]) {
408
0
            default:
409
0
                break;
410
0
            case 'b':
411
0
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
412
                    /* OSSL_PKEY_PARAM_BITS */
413
0
                    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
0
                    r->bits = (OSSL_PARAM *)p;
419
0
                }
420
0
                break;
421
0
            case 'e':
422
0
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
423
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
424
0
                    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
0
                    r->encpub = (OSSL_PARAM *)p;
430
0
                }
431
0
                break;
432
0
            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
0
            case 'm':
446
0
                if (ossl_likely(strcmp("ax-size", s + 1) == 0)) {
447
                    /* OSSL_PKEY_PARAM_MAX_SIZE */
448
0
                    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
0
                    r->size = (OSSL_PARAM *)p;
454
0
                }
455
0
                break;
456
0
            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
0
            case 's':
484
0
                switch(s[1]) {
485
0
                default:
486
0
                    break;
487
0
                case 'e':
488
0
                    switch(s[2]) {
489
0
                    default:
490
0
                        break;
491
0
                    case 'c':
492
0
                        switch(s[3]) {
493
0
                        default:
494
0
                            break;
495
0
                        case 'u':
496
0
                            switch(s[4]) {
497
0
                            default:
498
0
                                break;
499
0
                            case 'r':
500
0
                                switch(s[5]) {
501
0
                                default:
502
0
                                    break;
503
0
                                case 'i':
504
0
                                    switch(s[6]) {
505
0
                                    default:
506
0
                                        break;
507
0
                                    case 't':
508
0
                                        switch(s[7]) {
509
0
                                        default:
510
0
                                            break;
511
0
                                        case 'y':
512
0
                                            switch(s[8]) {
513
0
                                            default:
514
0
                                                break;
515
0
                                            case '-':
516
0
                                                switch(s[9]) {
517
0
                                                default:
518
0
                                                    break;
519
0
                                                case 'b':
520
0
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
521
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
522
0
                                                        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
0
                                                        r->secbits = (OSSL_PARAM *)p;
528
0
                                                    }
529
0
                                                    break;
530
0
                                                case 'c':
531
0
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
532
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
533
0
                                                        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
0
                                                        r->seccat = (OSSL_PARAM *)p;
539
0
                                                    }
540
0
                                                }
541
0
                                            }
542
0
                                        }
543
0
                                    }
544
0
                                }
545
0
                            }
546
0
                        }
547
0
                    }
548
0
                }
549
0
            }
550
0
    return 1;
551
0
}
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
0
{
587
0
    const char *s;
588
589
0
    memset(r, 0, sizeof(*r));
590
0
    if (p != NULL)
591
0
        for (; (s = p->key) != NULL; p++)
592
0
            switch(s[0]) {
593
0
            default:
594
0
                break;
595
0
            case 'b':
596
0
                if (ossl_likely(strcmp("its", s + 1) == 0)) {
597
                    /* OSSL_PKEY_PARAM_BITS */
598
0
                    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
0
                    r->bits = (OSSL_PARAM *)p;
604
0
                }
605
0
                break;
606
0
            case 'm':
607
0
                switch(s[1]) {
608
0
                default:
609
0
                    break;
610
0
                case 'a':
611
0
                    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
0
                    case 'x':
626
0
                        if (ossl_likely(strcmp("-size", s + 3) == 0)) {
627
                            /* OSSL_PKEY_PARAM_MAX_SIZE */
628
0
                            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
0
                            r->size = (OSSL_PARAM *)p;
634
0
                        }
635
0
                    }
636
0
                }
637
0
                break;
638
0
            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
0
            case 's':
666
0
                switch(s[1]) {
667
0
                default:
668
0
                    break;
669
0
                case 'e':
670
0
                    switch(s[2]) {
671
0
                    default:
672
0
                        break;
673
0
                    case 'c':
674
0
                        switch(s[3]) {
675
0
                        default:
676
0
                            break;
677
0
                        case 'u':
678
0
                            switch(s[4]) {
679
0
                            default:
680
0
                                break;
681
0
                            case 'r':
682
0
                                switch(s[5]) {
683
0
                                default:
684
0
                                    break;
685
0
                                case 'i':
686
0
                                    switch(s[6]) {
687
0
                                    default:
688
0
                                        break;
689
0
                                    case 't':
690
0
                                        switch(s[7]) {
691
0
                                        default:
692
0
                                            break;
693
0
                                        case 'y':
694
0
                                            switch(s[8]) {
695
0
                                            default:
696
0
                                                break;
697
0
                                            case '-':
698
0
                                                switch(s[9]) {
699
0
                                                default:
700
0
                                                    break;
701
0
                                                case 'b':
702
0
                                                    if (ossl_likely(strcmp("its", s + 10) == 0)) {
703
                                                        /* OSSL_PKEY_PARAM_SECURITY_BITS */
704
0
                                                        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
0
                                                        r->secbits = (OSSL_PARAM *)p;
710
0
                                                    }
711
0
                                                    break;
712
0
                                                case 'c':
713
0
                                                    if (ossl_likely(strcmp("ategory", s + 10) == 0)) {
714
                                                        /* OSSL_PKEY_PARAM_SECURITY_CATEGORY */
715
0
                                                        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
0
                                                        r->seccat = (OSSL_PARAM *)p;
721
0
                                                    }
722
0
                                                }
723
0
                                            }
724
0
                                        }
725
0
                                    }
726
0
                                }
727
0
                            }
728
0
                        }
729
0
                    }
730
0
                }
731
0
            }
732
0
    return 1;
733
0
}
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
0
{
742
0
    ECX_KEY *ecx = key;
743
744
0
    if (p->bits != NULL && !OSSL_PARAM_set_int(p->bits, bits))
745
0
        return 0;
746
0
    if (p->secbits != NULL && !OSSL_PARAM_set_int(p->secbits, secbits))
747
0
        return 0;
748
0
    if (p->size != NULL && !OSSL_PARAM_set_int(p->size, size))
749
0
        return 0;
750
0
    if (p->seccat != NULL && !OSSL_PARAM_set_int(p->seccat, 0))
751
0
            return 0;
752
0
    return key_to_params(ecx, NULL, p->pub, p->priv, 1);
753
0
}
754
755
/* X25519/X448 getter */
756
static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
757
                          int size)
758
0
{
759
0
    ECX_KEY *ecx = key;
760
0
    struct ecx_ed_common_get_params_st p;
761
762
0
    if (key == NULL || !ecx_get_params_decoder(params, &p))
763
0
        return 0;
764
765
0
    if (p.encpub != NULL
766
0
        && !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
0
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
779
0
}
780
781
/* ED25519/ED448 getter */
782
static int ed_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
783
                         int size)
784
0
{
785
0
    struct ecx_ed_common_get_params_st p;
786
787
0
    if (key == NULL || !ed_get_params_decoder(params, &p))
788
0
        return 0;
789
0
    if (p.digest != NULL && !OSSL_PARAM_set_utf8_string(p.digest, ""))
790
0
        return 0;
791
0
    return ecx_ed_common_get_params(key, &p, bits, secbits, size);
792
0
}
793
794
static int x25519_get_params(void *key, OSSL_PARAM params[])
795
0
{
796
0
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
797
0
                          X25519_KEYLEN);
798
0
}
799
800
static int x448_get_params(void *key, OSSL_PARAM params[])
801
0
{
802
0
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
803
0
                          X448_KEYLEN);
804
0
}
805
806
static int ed25519_get_params(void *key, OSSL_PARAM params[])
807
0
{
808
0
    return ed_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
809
0
                         ED25519_SIGSIZE);
810
0
}
811
static int ed448_get_params(void *key, OSSL_PARAM params[])
812
0
{
813
0
    return ed_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
814
0
                         ED448_SIGSIZE);
815
0
}
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
0
{
869
0
    const char *s;
870
871
0
    memset(r, 0, sizeof(*r));
872
0
    if (p != NULL)
873
0
        for (; (s = p->key) != NULL; p++)
874
0
            switch(s[0]) {
875
0
            default:
876
0
                break;
877
0
            case 'e':
878
0
                if (ossl_likely(strcmp("ncoded-pub-key", s + 1) == 0)) {
879
                    /* OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY */
880
0
                    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
0
                    r->pub = (OSSL_PARAM *)p;
886
0
                }
887
0
                break;
888
0
            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
0
            }
899
0
    return 1;
900
0
}
901
#endif
902
/* End of machine generated */
903
904
static int ecx_set_params(void *key, const OSSL_PARAM params[])
905
0
{
906
0
    ECX_KEY *ecxkey = key;
907
0
    struct ecx_set_params_st p;
908
909
0
    if (key == NULL || !ecx_set_params_decoder(params, &p))
910
0
        return 0;
911
912
0
    if (p.pub != NULL) {
913
0
        void *buf = ecxkey->pubkey;
914
915
0
        if (p.pub->data_size != ecxkey->keylen
916
0
                || !OSSL_PARAM_get_octet_string(p.pub, &buf, sizeof(ecxkey->pubkey),
917
0
                                                NULL))
918
0
            return 0;
919
0
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
920
0
        ecxkey->privkey = NULL;
921
0
        ecxkey->haspubkey = 1;
922
0
    }
923
924
0
    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
0
    return 1;
931
0
}
932
933
static int x25519_set_params(void *key, const OSSL_PARAM params[])
934
0
{
935
0
    return ecx_set_params(key, params);
936
0
}
937
938
static int x448_set_params(void *key, const OSSL_PARAM params[])
939
0
{
940
0
    return ecx_set_params(key, params);
941
0
}
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
0
{
981
0
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
982
0
    struct ecx_gen_ctx *gctx = NULL;
983
984
0
    if (!ossl_prov_is_running())
985
0
        return NULL;
986
987
0
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
988
0
        gctx->libctx = libctx;
989
0
        gctx->type = type;
990
0
        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
0
    } else {
1000
0
        return NULL;
1001
0
    }
1002
0
    if (!ecx_gen_set_params(gctx, params)) {
1003
0
        ecx_gen_cleanup(gctx);
1004
0
        gctx = NULL;
1005
0
    }
1006
0
    return gctx;
1007
0
}
1008
1009
static void *x25519_gen_init(void *provctx, int selection,
1010
                             const OSSL_PARAM params[])
1011
0
{
1012
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519, "X25519");
1013
0
}
1014
1015
static void *x448_gen_init(void *provctx, int selection,
1016
                           const OSSL_PARAM params[])
1017
0
{
1018
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448, "X448");
1019
0
}
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
0
{
1055
0
    const char *s;
1056
1057
0
    memset(r, 0, sizeof(*r));
1058
0
    if (p != NULL)
1059
0
        for (; (s = p->key) != NULL; p++)
1060
0
            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
0
            case 'g':
1075
0
                if (ossl_likely(strcmp("roup", s + 1) == 0)) {
1076
                    /* OSSL_PKEY_PARAM_GROUP_NAME */
1077
0
                    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
0
                    r->group = (OSSL_PARAM *)p;
1083
0
                }
1084
0
                break;
1085
0
            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
0
            }
1096
0
    return 1;
1097
0
}
1098
#endif
1099
/* End of machine generated */
1100
1101
static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
1102
0
{
1103
0
    struct ecx_gen_ctx *gctx = genctx;
1104
0
    struct ecx_gen_set_params_st p;
1105
1106
0
    if (gctx == NULL || !ecx_gen_set_params_decoder(params, &p))
1107
0
        return 0;
1108
1109
0
    if (p.group != NULL) {
1110
0
        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
0
        switch (gctx->type) {
1118
0
            case ECX_KEY_TYPE_X25519:
1119
0
                groupname = "x25519";
1120
0
                break;
1121
0
            case ECX_KEY_TYPE_X448:
1122
0
                groupname = "x448";
1123
0
                break;
1124
0
            default:
1125
                /* We only support this for key exchange at the moment */
1126
0
                break;
1127
0
        }
1128
0
        if (p.group->data_type != OSSL_PARAM_UTF8_STRING
1129
0
                || groupname == NULL
1130
0
                || 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
0
    }
1135
1136
0
    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
0
    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
0
    return 1;
1156
0
}
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
0
{
1234
0
    ECX_KEY *key;
1235
0
    unsigned char *privkey;
1236
1237
0
    if (gctx == NULL)
1238
0
        return NULL;
1239
0
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
1240
0
                                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
0
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1247
0
        return key;
1248
1249
0
    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
0
#ifndef FIPS_MODULE
1254
0
    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
0
#endif
1262
0
    {
1263
0
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
1264
0
            goto err;
1265
0
    }
1266
1267
0
    switch (gctx->type) {
1268
0
    case ECX_KEY_TYPE_X25519:
1269
0
        privkey[0] &= 248;
1270
0
        privkey[X25519_KEYLEN - 1] &= 127;
1271
0
        privkey[X25519_KEYLEN - 1] |= 64;
1272
0
        ossl_x25519_public_from_private(key->pubkey, privkey);
1273
0
        break;
1274
0
    case ECX_KEY_TYPE_X448:
1275
0
        privkey[0] &= 252;
1276
0
        privkey[X448_KEYLEN - 1] |= 128;
1277
0
        ossl_x448_public_from_private(key->pubkey, privkey);
1278
0
        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
0
    }
1290
0
    key->haspubkey = 1;
1291
0
    return key;
1292
0
err:
1293
0
    ossl_ecx_key_free(key);
1294
0
    return NULL;
1295
0
}
1296
1297
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1298
0
{
1299
0
    struct ecx_gen_ctx *gctx = genctx;
1300
1301
0
    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
0
    return ecx_gen(gctx);
1309
0
}
1310
1311
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
1312
0
{
1313
0
    struct ecx_gen_ctx *gctx = genctx;
1314
1315
0
    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
0
    return ecx_gen(gctx);
1323
0
}
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
0
{
1394
0
    struct ecx_gen_ctx *gctx = genctx;
1395
1396
0
    if (gctx == NULL)
1397
0
        return;
1398
1399
0
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
1400
0
    OPENSSL_free(gctx->propq);
1401
0
    OPENSSL_free(gctx);
1402
0
}
1403
1404
void *ecx_load(const void *reference, size_t reference_sz)
1405
0
{
1406
0
    ECX_KEY *key = NULL;
1407
1408
0
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
1409
        /* The contents of the reference is the address to our object */
1410
0
        key = *(ECX_KEY **)reference;
1411
        /* We grabbed, so we detach it */
1412
0
        *(ECX_KEY **)reference = NULL;
1413
0
        return key;
1414
0
    }
1415
0
    return NULL;
1416
0
}
1417
1418
static void *ecx_dup(const void *keydata_from, int selection)
1419
0
{
1420
0
    if (ossl_prov_is_running())
1421
0
        return ossl_ecx_key_dup(keydata_from, selection);
1422
0
    return NULL;
1423
0
}
1424
1425
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
1426
0
{
1427
0
    uint8_t pub[64];
1428
1429
0
    switch (type) {
1430
0
    case ECX_KEY_TYPE_X25519:
1431
0
        ossl_x25519_public_from_private(pub, ecx->privkey);
1432
0
        break;
1433
0
    case ECX_KEY_TYPE_X448:
1434
0
        ossl_x448_public_from_private(pub, ecx->privkey);
1435
0
        break;
1436
0
    default:
1437
0
        return 0;
1438
0
    }
1439
0
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1440
0
}
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
0
{
1469
0
    uint8_t pub[64];
1470
1471
0
    switch (type) {
1472
0
    case ECX_KEY_TYPE_ED25519:
1473
0
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
1474
0
                                              ecx->propq))
1475
0
            return 0;
1476
0
        break;
1477
0
    case ECX_KEY_TYPE_ED448:
1478
0
        if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
1479
0
                                            ecx->propq))
1480
0
            return 0;
1481
0
        break;
1482
0
    default:
1483
0
        return 0;
1484
0
    }
1485
0
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
1486
0
}
1487
#endif
1488
1489
static int ecx_validate(const void *keydata, int selection, int type,
1490
                        size_t keylen)
1491
0
{
1492
0
    const ECX_KEY *ecx = keydata;
1493
0
    int ok = keylen == ecx->keylen;
1494
1495
0
    if (!ossl_prov_is_running())
1496
0
        return 0;
1497
1498
0
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
1499
0
        return 1; /* nothing to validate */
1500
1501
0
    if (!ok) {
1502
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
1503
0
        return 0;
1504
0
    }
1505
1506
0
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
1507
0
        ok = ok && ecx->haspubkey;
1508
#ifdef FIPS_MODULE
1509
        ok = ok && ecd_key_pub_check(ecx, type);
1510
#endif
1511
0
    }
1512
1513
0
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
1514
0
        ok = ok && ecx->privkey != NULL;
1515
1516
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != OSSL_KEYMGMT_SELECT_KEYPAIR)
1517
0
        return ok;
1518
1519
0
    if (ecx_key_type_is_ed(type))
1520
0
        ok = ok && ecd_key_pairwise_check(ecx, type);
1521
0
    else
1522
0
        ok = ok && ecx_key_pairwise_check(ecx, type);
1523
1524
0
    return ok;
1525
0
}
1526
1527
static int x25519_validate(const void *keydata, int selection, int checktype)
1528
0
{
1529
0
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
1530
0
}
1531
1532
static int x448_validate(const void *keydata, int selection, int checktype)
1533
0
{
1534
0
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
1535
0
}
1536
1537
static int ed25519_validate(const void *keydata, int selection, int checktype)
1538
0
{
1539
0
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
1540
0
}
1541
1542
static int ed448_validate(const void *keydata, int selection, int checktype)
1543
0
{
1544
0
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
1545
0
}
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