Coverage Report

Created: 2025-06-13 06:58

/src/openssl32/providers/implementations/keymgmt/ecx_kmgmt.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2020-2023 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
#include <assert.h>
11
#include <string.h>
12
#include <openssl/core_dispatch.h>
13
#include <openssl/core_names.h>
14
#include <openssl/params.h>
15
#include <openssl/err.h>
16
#include <openssl/proverr.h>
17
#include <openssl/evp.h>
18
#include <openssl/rand.h>
19
#include "internal/param_build_set.h"
20
#include <openssl/param_build.h>
21
#include "crypto/ecx.h"
22
#include "prov/implementations.h"
23
#include "prov/providercommon.h"
24
#include "prov/provider_ctx.h"
25
#include "prov/ecx.h"
26
#ifdef S390X_EC_ASM
27
# include "s390x_arch.h"
28
# include <openssl/sha.h>   /* For SHA512_DIGEST_LENGTH */
29
#endif
30
31
static OSSL_FUNC_keymgmt_new_fn x25519_new_key;
32
static OSSL_FUNC_keymgmt_new_fn x448_new_key;
33
static OSSL_FUNC_keymgmt_new_fn ed25519_new_key;
34
static OSSL_FUNC_keymgmt_new_fn ed448_new_key;
35
static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init;
36
static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init;
37
static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init;
38
static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init;
39
static OSSL_FUNC_keymgmt_gen_fn x25519_gen;
40
static OSSL_FUNC_keymgmt_gen_fn x448_gen;
41
static OSSL_FUNC_keymgmt_gen_fn ed25519_gen;
42
static OSSL_FUNC_keymgmt_gen_fn ed448_gen;
43
static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
44
static OSSL_FUNC_keymgmt_gen_set_params_fn ecx_gen_set_params;
45
static OSSL_FUNC_keymgmt_gen_settable_params_fn ecx_gen_settable_params;
46
static OSSL_FUNC_keymgmt_load_fn ecx_load;
47
static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params;
48
static OSSL_FUNC_keymgmt_get_params_fn x448_get_params;
49
static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params;
50
static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params;
51
static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params;
52
static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params;
53
static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params;
54
static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params;
55
static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params;
56
static OSSL_FUNC_keymgmt_set_params_fn x448_set_params;
57
static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params;
58
static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params;
59
static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params;
60
static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params;
61
static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params;
62
static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params;
63
static OSSL_FUNC_keymgmt_has_fn ecx_has;
64
static OSSL_FUNC_keymgmt_match_fn ecx_match;
65
static OSSL_FUNC_keymgmt_validate_fn x25519_validate;
66
static OSSL_FUNC_keymgmt_validate_fn x448_validate;
67
static OSSL_FUNC_keymgmt_validate_fn ed25519_validate;
68
static OSSL_FUNC_keymgmt_validate_fn ed448_validate;
69
static OSSL_FUNC_keymgmt_import_fn ecx_import;
70
static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
71
static OSSL_FUNC_keymgmt_export_fn ecx_export;
72
static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
73
static OSSL_FUNC_keymgmt_dup_fn ecx_dup;
74
75
8.91k
#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
76
77
struct ecx_gen_ctx {
78
    OSSL_LIB_CTX *libctx;
79
    char *propq;
80
    ECX_KEY_TYPE type;
81
    int selection;
82
    unsigned char *dhkem_ikm;
83
    size_t dhkem_ikmlen;
84
};
85
86
#ifdef S390X_EC_ASM
87
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
88
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
89
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
90
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
91
#endif
92
93
static void *x25519_new_key(void *provctx)
94
28
{
95
28
    if (!ossl_prov_is_running())
96
0
        return 0;
97
28
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
98
28
                            NULL);
99
28
}
100
101
static void *x448_new_key(void *provctx)
102
0
{
103
0
    if (!ossl_prov_is_running())
104
0
        return 0;
105
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0,
106
0
                            NULL);
107
0
}
108
109
static void *ed25519_new_key(void *provctx)
110
0
{
111
0
    if (!ossl_prov_is_running())
112
0
        return 0;
113
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0,
114
0
                            NULL);
115
0
}
116
117
static void *ed448_new_key(void *provctx)
118
0
{
119
0
    if (!ossl_prov_is_running())
120
0
        return 0;
121
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0,
122
0
                            NULL);
123
0
}
124
125
static int ecx_has(const void *keydata, int selection)
126
26.1k
{
127
26.1k
    const ECX_KEY *key = keydata;
128
26.1k
    int ok = 0;
129
130
26.1k
    if (ossl_prov_is_running() && key != NULL) {
131
        /*
132
         * ECX keys always have all the parameters they need (i.e. none).
133
         * Therefore we always return with 1, if asked about parameters.
134
         */
135
13.2k
        ok = 1;
136
137
13.2k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
138
44
            ok = ok && key->haspubkey;
139
140
13.2k
        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
141
26
            ok = ok && key->privkey != NULL;
142
13.2k
    }
143
26.1k
    return ok;
144
26.1k
}
145
146
static int ecx_match(const void *keydata1, const void *keydata2, int selection)
147
22
{
148
22
    const ECX_KEY *key1 = keydata1;
149
22
    const ECX_KEY *key2 = keydata2;
150
22
    int ok = 1;
151
152
22
    if (!ossl_prov_is_running())
153
0
        return 0;
154
155
22
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
156
22
        ok = ok && key1->type == key2->type;
157
22
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
158
22
        int key_checked = 0;
159
160
22
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
161
22
            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
162
22
            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
163
22
            size_t pal = key1->keylen;
164
22
            size_t pbl = key2->keylen;
165
166
22
            if (pa != NULL && pb != NULL) {
167
22
                ok = ok
168
22
                    && key1->type == key2->type
169
22
                    && pal == pbl
170
22
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
171
22
                key_checked = 1;
172
22
            }
173
22
        }
174
22
        if (!key_checked
175
22
            && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
176
0
            const unsigned char *pa = key1->privkey;
177
0
            const unsigned char *pb = key2->privkey;
178
0
            size_t pal = key1->keylen;
179
0
            size_t pbl = key2->keylen;
180
181
0
            if (pa != NULL && pb != NULL) {
182
0
                ok = ok
183
0
                    && key1->type == key2->type
184
0
                    && pal == pbl
185
0
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
186
0
                key_checked = 1;
187
0
            }
188
0
        }
189
22
        ok = ok && key_checked;
190
22
    }
191
22
    return ok;
192
22
}
193
194
static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
195
28
{
196
28
    ECX_KEY *key = keydata;
197
28
    int ok = 1;
198
28
    int include_private;
199
200
28
    if (!ossl_prov_is_running() || key == NULL)
201
0
        return 0;
202
203
28
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
204
0
        return 0;
205
206
28
    include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
207
28
    ok = ok && ossl_ecx_key_fromdata(key, params, include_private);
208
209
28
    return ok;
210
28
}
211
212
static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
213
                         OSSL_PARAM params[], int include_private)
214
227k
{
215
227k
    if (key == NULL)
216
0
        return 0;
217
218
227k
    if (!ossl_param_build_set_octet_string(tmpl, params,
219
227k
                                           OSSL_PKEY_PARAM_PUB_KEY,
220
227k
                                           key->pubkey, key->keylen))
221
0
        return 0;
222
223
227k
    if (include_private
224
227k
        && key->privkey != NULL
225
227k
        && !ossl_param_build_set_octet_string(tmpl, params,
226
186k
                                              OSSL_PKEY_PARAM_PRIV_KEY,
227
186k
                                              key->privkey, key->keylen))
228
0
        return 0;
229
230
227k
    return 1;
231
227k
}
232
233
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
234
                      void *cbarg)
235
18.1k
{
236
18.1k
    ECX_KEY *key = keydata;
237
18.1k
    OSSL_PARAM_BLD *tmpl;
238
18.1k
    OSSL_PARAM *params = NULL;
239
18.1k
    int ret = 0;
240
241
18.1k
    if (!ossl_prov_is_running() || key == NULL)
242
0
        return 0;
243
244
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
245
0
        return 0;
246
247
18.1k
    tmpl = OSSL_PARAM_BLD_new();
248
18.1k
    if (tmpl == NULL)
249
0
        return 0;
250
251
18.1k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
252
18.1k
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
253
254
18.1k
        if (!key_to_params(key, tmpl, NULL, include_private))
255
0
            goto err;
256
18.1k
    }
257
258
18.1k
    params = OSSL_PARAM_BLD_to_param(tmpl);
259
18.1k
    if (params == NULL)
260
0
        goto err;
261
262
18.1k
    ret = param_cb(params, cbarg);
263
18.1k
    OSSL_PARAM_free(params);
264
18.1k
err:
265
18.1k
    OSSL_PARAM_BLD_free(tmpl);
266
18.1k
    return ret;
267
18.1k
}
268
269
#define ECX_KEY_TYPES()                                                        \
270
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),                     \
271
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
272
273
static const OSSL_PARAM ecx_key_types[] = {
274
    ECX_KEY_TYPES(),
275
    OSSL_PARAM_END
276
};
277
static const OSSL_PARAM *ecx_imexport_types(int selection)
278
0
{
279
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
280
0
        return ecx_key_types;
281
0
    return NULL;
282
0
}
283
284
static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
285
                          int size)
286
122k
{
287
122k
    ECX_KEY *ecx = key;
288
122k
    OSSL_PARAM *p;
289
290
122k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
291
122k
        && !OSSL_PARAM_set_int(p, bits))
292
0
        return 0;
293
122k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
294
122k
        && !OSSL_PARAM_set_int(p, secbits))
295
0
        return 0;
296
122k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
297
122k
        && !OSSL_PARAM_set_int(p, size))
298
0
        return 0;
299
122k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL
300
122k
            && (ecx->type == ECX_KEY_TYPE_X25519
301
71.9k
                || ecx->type == ECX_KEY_TYPE_X448)) {
302
71.9k
        if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
303
0
            return 0;
304
71.9k
    }
305
306
122k
    return key_to_params(ecx, NULL, params, 1);
307
122k
}
308
309
static int ed_get_params(void *key, OSSL_PARAM params[])
310
1.03k
{
311
1.03k
    OSSL_PARAM *p;
312
313
1.03k
    if ((p = OSSL_PARAM_locate(params,
314
1.03k
                               OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
315
1.03k
        && !OSSL_PARAM_set_utf8_string(p, ""))
316
0
        return 0;
317
1.03k
    return 1;
318
1.03k
}
319
320
static int x25519_get_params(void *key, OSSL_PARAM params[])
321
205k
{
322
205k
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
323
205k
                          X25519_KEYLEN);
324
205k
}
325
326
static int x448_get_params(void *key, OSSL_PARAM params[])
327
2.90k
{
328
2.90k
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
329
2.90k
                          X448_KEYLEN);
330
2.90k
}
331
332
static int ed25519_get_params(void *key, OSSL_PARAM params[])
333
430
{
334
430
    return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
335
430
                          ED25519_SIGSIZE)
336
430
        && ed_get_params(key, params);
337
430
}
338
339
static int ed448_get_params(void *key, OSSL_PARAM params[])
340
602
{
341
602
    return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
342
602
                          ED448_SIGSIZE)
343
602
        && ed_get_params(key, params);
344
602
}
345
346
static const OSSL_PARAM ecx_gettable_params[] = {
347
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
348
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
349
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
350
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
351
    ECX_KEY_TYPES(),
352
    OSSL_PARAM_END
353
};
354
355
static const OSSL_PARAM ed_gettable_params[] = {
356
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
357
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
358
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
359
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
360
    ECX_KEY_TYPES(),
361
    OSSL_PARAM_END
362
};
363
364
static const OSSL_PARAM *x25519_gettable_params(void *provctx)
365
0
{
366
0
    return ecx_gettable_params;
367
0
}
368
369
static const OSSL_PARAM *x448_gettable_params(void *provctx)
370
0
{
371
0
    return ecx_gettable_params;
372
0
}
373
374
static const OSSL_PARAM *ed25519_gettable_params(void *provctx)
375
0
{
376
0
    return ed_gettable_params;
377
0
}
378
379
static const OSSL_PARAM *ed448_gettable_params(void *provctx)
380
0
{
381
0
    return ed_gettable_params;
382
0
}
383
384
static int set_property_query(ECX_KEY *ecxkey, const char *propq)
385
0
{
386
0
    OPENSSL_free(ecxkey->propq);
387
0
    ecxkey->propq = NULL;
388
0
    if (propq != NULL) {
389
0
        ecxkey->propq = OPENSSL_strdup(propq);
390
0
        if (ecxkey->propq == NULL)
391
0
            return 0;
392
0
    }
393
0
    return 1;
394
0
}
395
396
static int ecx_set_params(void *key, const OSSL_PARAM params[])
397
11.1k
{
398
11.1k
    ECX_KEY *ecxkey = key;
399
11.1k
    const OSSL_PARAM *p;
400
401
11.1k
    if (params == NULL)
402
0
        return 1;
403
404
11.1k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
405
11.1k
    if (p != NULL) {
406
11.1k
        void *buf = ecxkey->pubkey;
407
408
11.1k
        if (p->data_size != ecxkey->keylen
409
11.1k
                || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
410
11.1k
                                                NULL))
411
48
            return 0;
412
11.1k
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
413
11.1k
        ecxkey->privkey = NULL;
414
11.1k
        ecxkey->haspubkey = 1;
415
11.1k
    }
416
11.1k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
417
11.1k
    if (p != NULL) {
418
0
        if (p->data_type != OSSL_PARAM_UTF8_STRING
419
0
            || !set_property_query(ecxkey, p->data))
420
0
            return 0;
421
0
    }
422
423
11.1k
    return 1;
424
11.1k
}
425
426
static int x25519_set_params(void *key, const OSSL_PARAM params[])
427
19.0k
{
428
19.0k
    return ecx_set_params(key, params);
429
19.0k
}
430
431
static int x448_set_params(void *key, const OSSL_PARAM params[])
432
29
{
433
29
    return ecx_set_params(key, params);
434
29
}
435
436
static int ed25519_set_params(void *key, const OSSL_PARAM params[])
437
0
{
438
0
    return 1;
439
0
}
440
441
static int ed448_set_params(void *key, const OSSL_PARAM params[])
442
0
{
443
0
    return 1;
444
0
}
445
446
static const OSSL_PARAM ecx_settable_params[] = {
447
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
448
    OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
449
    OSSL_PARAM_END
450
};
451
452
static const OSSL_PARAM ed_settable_params[] = {
453
    OSSL_PARAM_END
454
};
455
456
static const OSSL_PARAM *x25519_settable_params(void *provctx)
457
0
{
458
0
    return ecx_settable_params;
459
0
}
460
461
static const OSSL_PARAM *x448_settable_params(void *provctx)
462
0
{
463
0
    return ecx_settable_params;
464
0
}
465
466
static const OSSL_PARAM *ed25519_settable_params(void *provctx)
467
0
{
468
0
    return ed_settable_params;
469
0
}
470
471
static const OSSL_PARAM *ed448_settable_params(void *provctx)
472
0
{
473
0
    return ed_settable_params;
474
0
}
475
476
static void *ecx_gen_init(void *provctx, int selection,
477
                          const OSSL_PARAM params[], ECX_KEY_TYPE type)
478
70.3k
{
479
70.3k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
480
70.3k
    struct ecx_gen_ctx *gctx = NULL;
481
482
70.3k
    if (!ossl_prov_is_running())
483
0
        return NULL;
484
485
70.3k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
486
70.3k
        gctx->libctx = libctx;
487
70.3k
        gctx->type = type;
488
70.3k
        gctx->selection = selection;
489
70.3k
    } else {
490
0
        return NULL;
491
0
    }
492
70.3k
    if (!ecx_gen_set_params(gctx, params)) {
493
0
        ecx_gen_cleanup(gctx);
494
0
        gctx = NULL;
495
0
    }
496
70.3k
    return gctx;
497
70.3k
}
498
499
static void *x25519_gen_init(void *provctx, int selection,
500
                             const OSSL_PARAM params[])
501
80.3k
{
502
80.3k
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519);
503
80.3k
}
504
505
static void *x448_gen_init(void *provctx, int selection,
506
                           const OSSL_PARAM params[])
507
78
{
508
78
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448);
509
78
}
510
511
static void *ed25519_gen_init(void *provctx, int selection,
512
                              const OSSL_PARAM params[])
513
0
{
514
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519);
515
0
}
516
517
static void *ed448_gen_init(void *provctx, int selection,
518
                            const OSSL_PARAM params[])
519
0
{
520
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448);
521
0
}
522
523
static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
524
120k
{
525
120k
    struct ecx_gen_ctx *gctx = genctx;
526
120k
    const OSSL_PARAM *p;
527
528
120k
    if (gctx == NULL)
529
0
        return 0;
530
531
120k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
532
120k
    if (p != NULL) {
533
41.0k
        const char *groupname = NULL;
534
535
        /*
536
         * We optionally allow setting a group name - but each algorithm only
537
         * support one such name, so all we do is verify that it is the one we
538
         * expected.
539
         */
540
41.0k
        switch (gctx->type) {
541
41.0k
            case ECX_KEY_TYPE_X25519:
542
41.0k
                groupname = "x25519";
543
41.0k
                break;
544
49
            case ECX_KEY_TYPE_X448:
545
49
                groupname = "x448";
546
49
                break;
547
0
            default:
548
                /* We only support this for key exchange at the moment */
549
0
                break;
550
41.0k
        }
551
41.0k
        if (p->data_type != OSSL_PARAM_UTF8_STRING
552
41.0k
                || groupname == NULL
553
41.0k
                || OPENSSL_strcasecmp(p->data, groupname) != 0) {
554
0
            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
555
0
            return 0;
556
0
        }
557
41.0k
    }
558
120k
    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
559
120k
    if (p != NULL) {
560
0
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
561
0
            return 0;
562
0
        OPENSSL_free(gctx->propq);
563
0
        gctx->propq = OPENSSL_strdup(p->data);
564
0
        if (gctx->propq == NULL)
565
0
            return 0;
566
0
    }
567
120k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM);
568
120k
    if (p != NULL) {
569
0
        if (p->data_size != 0 && p->data != NULL) {
570
0
            OPENSSL_free(gctx->dhkem_ikm);
571
0
            gctx->dhkem_ikm = NULL;
572
0
            if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0,
573
0
                                             &gctx->dhkem_ikmlen))
574
0
                return 0;
575
0
        }
576
0
    }
577
578
120k
    return 1;
579
120k
}
580
581
static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx,
582
                                                 ossl_unused void *provctx)
583
0
{
584
0
    static OSSL_PARAM settable[] = {
585
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
586
0
        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
587
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0),
588
0
        OSSL_PARAM_END
589
0
    };
590
0
    return settable;
591
0
}
592
593
static void *ecx_gen(struct ecx_gen_ctx *gctx)
594
61.2k
{
595
61.2k
    ECX_KEY *key;
596
61.2k
    unsigned char *privkey;
597
598
61.2k
    if (gctx == NULL)
599
0
        return NULL;
600
61.2k
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
601
61.2k
                                gctx->propq)) == NULL) {
602
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
603
0
        return NULL;
604
0
    }
605
606
    /* If we're doing parameter generation then we just return a blank key */
607
61.2k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
608
3.16k
        return key;
609
610
58.0k
    if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) {
611
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
612
0
        goto err;
613
0
    }
614
58.0k
#ifndef FIPS_MODULE
615
58.0k
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
616
0
        if (gctx->type == ECX_KEY_TYPE_ED25519
617
0
                || gctx->type == ECX_KEY_TYPE_ED448)
618
0
            goto err;
619
0
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
620
0
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
621
0
            goto err;
622
0
    } else
623
58.0k
#endif
624
58.0k
    {
625
58.0k
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
626
0
            goto err;
627
58.0k
    }
628
629
58.0k
    switch (gctx->type) {
630
58.0k
    case ECX_KEY_TYPE_X25519:
631
58.0k
        privkey[0] &= 248;
632
58.0k
        privkey[X25519_KEYLEN - 1] &= 127;
633
58.0k
        privkey[X25519_KEYLEN - 1] |= 64;
634
58.0k
        ossl_x25519_public_from_private(key->pubkey, privkey);
635
58.0k
        break;
636
43
    case ECX_KEY_TYPE_X448:
637
43
        privkey[0] &= 252;
638
43
        privkey[X448_KEYLEN - 1] |= 128;
639
43
        ossl_x448_public_from_private(key->pubkey, privkey);
640
43
        break;
641
0
    case ECX_KEY_TYPE_ED25519:
642
0
        if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey,
643
0
                                              gctx->propq))
644
0
            goto err;
645
0
        break;
646
0
    case ECX_KEY_TYPE_ED448:
647
0
        if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey,
648
0
                                            gctx->propq))
649
0
            goto err;
650
0
        break;
651
58.0k
    }
652
58.0k
    key->haspubkey = 1;
653
58.0k
    return key;
654
0
err:
655
0
    ossl_ecx_key_free(key);
656
0
    return NULL;
657
58.0k
}
658
659
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
660
80.3k
{
661
80.3k
    struct ecx_gen_ctx *gctx = genctx;
662
663
80.3k
    if (!ossl_prov_is_running())
664
0
        return 0;
665
666
#ifdef S390X_EC_ASM
667
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
668
        return s390x_ecx_keygen25519(gctx);
669
#endif
670
80.3k
    return ecx_gen(gctx);
671
80.3k
}
672
673
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
674
78
{
675
78
    struct ecx_gen_ctx *gctx = genctx;
676
677
78
    if (!ossl_prov_is_running())
678
0
        return 0;
679
680
#ifdef S390X_EC_ASM
681
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
682
        return s390x_ecx_keygen448(gctx);
683
#endif
684
78
    return ecx_gen(gctx);
685
78
}
686
687
static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
688
0
{
689
0
    struct ecx_gen_ctx *gctx = genctx;
690
691
0
    if (!ossl_prov_is_running())
692
0
        return 0;
693
694
#ifdef S390X_EC_ASM
695
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
696
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
697
        && OPENSSL_s390xcap_P.kdsa[0]
698
            & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
699
        return s390x_ecd_keygen25519(gctx);
700
#endif
701
0
    return ecx_gen(gctx);
702
0
}
703
704
static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
705
0
{
706
0
    struct ecx_gen_ctx *gctx = genctx;
707
708
0
    if (!ossl_prov_is_running())
709
0
        return 0;
710
711
#ifdef S390X_EC_ASM
712
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
713
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
714
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
715
        return s390x_ecd_keygen448(gctx);
716
#endif
717
0
    return ecx_gen(gctx);
718
0
}
719
720
static void ecx_gen_cleanup(void *genctx)
721
40.6k
{
722
40.6k
    struct ecx_gen_ctx *gctx = genctx;
723
724
40.6k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
725
40.6k
    OPENSSL_free(gctx->propq);
726
40.6k
    OPENSSL_free(gctx);
727
40.6k
}
728
729
void *ecx_load(const void *reference, size_t reference_sz)
730
3.74k
{
731
3.74k
    ECX_KEY *key = NULL;
732
733
3.74k
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
734
        /* The contents of the reference is the address to our object */
735
3.74k
        key = *(ECX_KEY **)reference;
736
        /* We grabbed, so we detach it */
737
3.74k
        *(ECX_KEY **)reference = NULL;
738
3.74k
        return key;
739
3.74k
    }
740
0
    return NULL;
741
3.74k
}
742
743
static void *ecx_dup(const void *keydata_from, int selection)
744
12.8k
{
745
12.8k
    if (ossl_prov_is_running())
746
12.8k
        return ossl_ecx_key_dup(keydata_from, selection);
747
0
    return NULL;
748
12.8k
}
749
750
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
751
10
{
752
10
    uint8_t pub[64];
753
754
10
    switch (type) {
755
1
    case ECX_KEY_TYPE_X25519:
756
1
        ossl_x25519_public_from_private(pub, ecx->privkey);
757
1
        break;
758
1
    case ECX_KEY_TYPE_X448:
759
1
        ossl_x448_public_from_private(pub, ecx->privkey);
760
1
        break;
761
3
    case ECX_KEY_TYPE_ED25519:
762
3
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
763
3
                                              ecx->propq))
764
0
            return 0;
765
3
        break;
766
5
    case ECX_KEY_TYPE_ED448:
767
5
        if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
768
5
                                            ecx->propq))
769
0
            return 0;
770
5
        break;
771
5
    default:
772
0
        return 0;
773
10
    }
774
10
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
775
10
}
776
777
static int ecx_validate(const void *keydata, int selection, int type, size_t keylen)
778
8.91k
{
779
8.91k
    const ECX_KEY *ecx = keydata;
780
8.91k
    int ok = keylen == ecx->keylen;
781
782
8.91k
    if (!ossl_prov_is_running())
783
0
        return 0;
784
785
8.91k
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
786
14
        return 1; /* nothing to validate */
787
788
8.90k
    if (!ok) {
789
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
790
0
        return 0;
791
0
    }
792
793
8.90k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
794
8.88k
        ok = ok && ecx->haspubkey;
795
796
8.90k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
797
28
        ok = ok && ecx->privkey != NULL;
798
799
8.90k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
800
14
        ok = ok && ecx_key_pairwise_check(ecx, type);
801
802
8.90k
    return ok;
803
8.90k
}
804
805
static int x25519_validate(const void *keydata, int selection, int checktype)
806
16.2k
{
807
16.2k
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
808
16.2k
}
809
810
static int x448_validate(const void *keydata, int selection, int checktype)
811
29
{
812
29
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
813
29
}
814
815
static int ed25519_validate(const void *keydata, int selection, int checktype)
816
24
{
817
24
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
818
24
}
819
820
static int ed448_validate(const void *keydata, int selection, int checktype)
821
32
{
822
32
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
823
32
}
824
825
#define MAKE_KEYMGMT_FUNCTIONS(alg) \
826
    const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
827
        { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
828
        { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
829
        { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
830
        { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
831
        { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
832
        { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
833
        { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
834
        { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
835
        { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
836
        { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
837
        { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
838
        { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
839
        { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
840
        { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
841
        { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
842
        { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
843
          (void (*)(void))ecx_gen_settable_params }, \
844
        { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
845
        { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
846
        { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
847
        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
848
        OSSL_DISPATCH_END \
849
    };
850
851
MAKE_KEYMGMT_FUNCTIONS(x25519)
852
MAKE_KEYMGMT_FUNCTIONS(x448)
853
MAKE_KEYMGMT_FUNCTIONS(ed25519)
854
MAKE_KEYMGMT_FUNCTIONS(ed448)
855
856
#ifdef S390X_EC_ASM
857
# include "s390x_arch.h"
858
859
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
860
{
861
    static const unsigned char generator[] = {
862
        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
865
    };
866
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
867
                                    gctx->propq);
868
    unsigned char *privkey = NULL, *pubkey;
869
870
    if (key == NULL) {
871
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
872
        goto err;
873
    }
874
875
    /* If we're doing parameter generation then we just return a blank key */
876
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
877
        return key;
878
879
    pubkey = key->pubkey;
880
881
    privkey = ossl_ecx_key_allocate_privkey(key);
882
    if (privkey == NULL) {
883
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
884
        goto err;
885
    }
886
887
#ifndef FIPS_MODULE
888
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
889
        if (gctx->type != ECX_KEY_TYPE_X25519)
890
            goto err;
891
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
892
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
893
            goto err;
894
    } else
895
#endif
896
    {
897
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
898
            goto err;
899
    }
900
901
    privkey[0] &= 248;
902
    privkey[31] &= 127;
903
    privkey[31] |= 64;
904
905
    if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
906
        goto err;
907
    key->haspubkey = 1;
908
    return key;
909
 err:
910
    ossl_ecx_key_free(key);
911
    return NULL;
912
}
913
914
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
915
{
916
    static const unsigned char generator[] = {
917
        0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
918
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
919
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
922
    };
923
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
924
                                    gctx->propq);
925
    unsigned char *privkey = NULL, *pubkey;
926
927
    if (key == NULL) {
928
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
929
        goto err;
930
    }
931
932
    /* If we're doing parameter generation then we just return a blank key */
933
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
934
        return key;
935
936
    pubkey = key->pubkey;
937
938
    privkey = ossl_ecx_key_allocate_privkey(key);
939
    if (privkey == NULL) {
940
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
941
        goto err;
942
    }
943
944
#ifndef FIPS_MODULE
945
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
946
        if (gctx->type != ECX_KEY_TYPE_X448)
947
            goto err;
948
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
949
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
950
            goto err;
951
    } else
952
#endif
953
    {
954
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
955
            goto err;
956
    }
957
958
    privkey[0] &= 252;
959
    privkey[55] |= 128;
960
961
    if (s390x_x448_mul(pubkey, generator, privkey) != 1)
962
        goto err;
963
    key->haspubkey = 1;
964
    return key;
965
 err:
966
    ossl_ecx_key_free(key);
967
    return NULL;
968
}
969
970
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
971
{
972
    static const unsigned char generator_x[] = {
973
        0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
974
        0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
975
        0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
976
    };
977
    static const unsigned char generator_y[] = {
978
        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
979
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
980
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
981
    };
982
    unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
983
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
984
                                    gctx->propq);
985
    unsigned char *privkey = NULL, *pubkey;
986
    unsigned int sz;
987
    EVP_MD *sha = NULL;
988
    int j;
989
990
    if (key == NULL) {
991
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
992
        goto err;
993
    }
994
995
    /* If we're doing parameter generation then we just return a blank key */
996
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
997
        return key;
998
999
    pubkey = key->pubkey;
1000
1001
    privkey = ossl_ecx_key_allocate_privkey(key);
1002
    if (privkey == NULL) {
1003
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1004
        goto err;
1005
    }
1006
1007
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1008
        goto err;
1009
1010
    sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1011
    if (sha == NULL)
1012
        goto err;
1013
    j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1014
    EVP_MD_free(sha);
1015
    if (!j)
1016
        goto err;
1017
1018
    buff[0] &= 248;
1019
    buff[31] &= 63;
1020
    buff[31] |= 64;
1021
1022
    if (s390x_ed25519_mul(x_dst, pubkey,
1023
                          generator_x, generator_y, buff) != 1)
1024
        goto err;
1025
1026
    pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1027
    key->haspubkey = 1;
1028
    return key;
1029
 err:
1030
    ossl_ecx_key_free(key);
1031
    return NULL;
1032
}
1033
1034
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1035
{
1036
    static const unsigned char generator_x[] = {
1037
        0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1038
        0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1039
        0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1040
        0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1041
        0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1042
    };
1043
    static const unsigned char generator_y[] = {
1044
        0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1045
        0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1046
        0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1047
        0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1048
        0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1049
    };
1050
    unsigned char x_dst[57], buff[114];
1051
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1052
                                    gctx->propq);
1053
    unsigned char *privkey = NULL, *pubkey;
1054
    EVP_MD_CTX *hashctx = NULL;
1055
    EVP_MD *shake = NULL;
1056
1057
    if (key == NULL) {
1058
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1059
        goto err;
1060
    }
1061
1062
    /* If we're doing parameter generation then we just return a blank key */
1063
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1064
        return key;
1065
1066
    pubkey = key->pubkey;
1067
1068
    privkey = ossl_ecx_key_allocate_privkey(key);
1069
    if (privkey == NULL) {
1070
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1071
        goto err;
1072
    }
1073
1074
    shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1075
    if (shake == NULL)
1076
        goto err;
1077
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1078
        goto err;
1079
1080
    hashctx = EVP_MD_CTX_new();
1081
    if (hashctx == NULL)
1082
        goto err;
1083
    if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1084
        goto err;
1085
    if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1086
        goto err;
1087
    if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1088
        goto err;
1089
1090
    buff[0] &= -4;
1091
    buff[55] |= 0x80;
1092
    buff[56] = 0;
1093
1094
    if (s390x_ed448_mul(x_dst, pubkey,
1095
                        generator_x, generator_y, buff) != 1)
1096
        goto err;
1097
1098
    pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1099
    EVP_MD_CTX_free(hashctx);
1100
    EVP_MD_free(shake);
1101
    key->haspubkey = 1;
1102
    return key;
1103
 err:
1104
    ossl_ecx_key_free(key);
1105
    EVP_MD_CTX_free(hashctx);
1106
    EVP_MD_free(shake);
1107
    return NULL;
1108
}
1109
#endif