Coverage Report

Created: 2024-07-27 06:39

/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
9.01k
#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
0
{
95
0
    if (!ossl_prov_is_running())
96
0
        return 0;
97
0
    return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
98
0
                            NULL);
99
0
}
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
24.9k
{
127
24.9k
    const ECX_KEY *key = keydata;
128
24.9k
    int ok = 0;
129
130
24.9k
    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
12.5k
        ok = 1;
136
137
12.5k
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
138
66
            ok = ok && key->haspubkey;
139
140
12.5k
        if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
141
27
            ok = ok && key->privkey != NULL;
142
12.5k
    }
143
24.9k
    return ok;
144
24.9k
}
145
146
static int ecx_match(const void *keydata1, const void *keydata2, int selection)
147
33
{
148
33
    const ECX_KEY *key1 = keydata1;
149
33
    const ECX_KEY *key2 = keydata2;
150
33
    int ok = 1;
151
152
33
    if (!ossl_prov_is_running())
153
0
        return 0;
154
155
33
    if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
156
33
        ok = ok && key1->type == key2->type;
157
33
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
158
33
        int key_checked = 0;
159
160
33
        if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
161
33
            const unsigned char *pa = key1->haspubkey ? key1->pubkey : NULL;
162
33
            const unsigned char *pb = key2->haspubkey ? key2->pubkey : NULL;
163
33
            size_t pal = key1->keylen;
164
33
            size_t pbl = key2->keylen;
165
166
33
            if (pa != NULL && pb != NULL) {
167
33
                ok = ok
168
33
                    && key1->type == key2->type
169
33
                    && pal == pbl
170
33
                    && CRYPTO_memcmp(pa, pb, pal) == 0;
171
33
                key_checked = 1;
172
33
            }
173
33
        }
174
33
        if (!key_checked
175
33
            && (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
33
        ok = ok && key_checked;
190
33
    }
191
33
    return ok;
192
33
}
193
194
static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
195
0
{
196
0
    ECX_KEY *key = keydata;
197
0
    int ok = 1;
198
0
    int include_private;
199
200
0
    if (!ossl_prov_is_running() || key == NULL)
201
0
        return 0;
202
203
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
204
0
        return 0;
205
206
0
    include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
207
0
    ok = ok && ossl_ecx_key_fromdata(key, params, include_private);
208
209
0
    return ok;
210
0
}
211
212
static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
213
                         OSSL_PARAM params[], int include_private)
214
185k
{
215
185k
    if (key == NULL)
216
0
        return 0;
217
218
185k
    if (!ossl_param_build_set_octet_string(tmpl, params,
219
185k
                                           OSSL_PKEY_PARAM_PUB_KEY,
220
185k
                                           key->pubkey, key->keylen))
221
0
        return 0;
222
223
185k
    if (include_private
224
185k
        && key->privkey != NULL
225
185k
        && !ossl_param_build_set_octet_string(tmpl, params,
226
163k
                                              OSSL_PKEY_PARAM_PRIV_KEY,
227
163k
                                              key->privkey, key->keylen))
228
0
        return 0;
229
230
185k
    return 1;
231
185k
}
232
233
static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
234
                      void *cbarg)
235
0
{
236
0
    ECX_KEY *key = keydata;
237
0
    OSSL_PARAM_BLD *tmpl;
238
0
    OSSL_PARAM *params = NULL;
239
0
    int ret = 0;
240
241
0
    if (!ossl_prov_is_running() || key == NULL)
242
0
        return 0;
243
244
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
245
0
        return 0;
246
247
0
    tmpl = OSSL_PARAM_BLD_new();
248
0
    if (tmpl == NULL)
249
0
        return 0;
250
251
0
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
252
0
        int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
253
254
0
        if (!key_to_params(key, tmpl, NULL, include_private))
255
0
            goto err;
256
0
    }
257
258
0
    params = OSSL_PARAM_BLD_to_param(tmpl);
259
0
    if (params == NULL)
260
0
        goto err;
261
262
0
    ret = param_cb(params, cbarg);
263
0
    OSSL_PARAM_free(params);
264
0
err:
265
0
    OSSL_PARAM_BLD_free(tmpl);
266
0
    return ret;
267
0
}
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
185k
{
287
185k
    ECX_KEY *ecx = key;
288
185k
    OSSL_PARAM *p;
289
290
185k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
291
185k
        && !OSSL_PARAM_set_int(p, bits))
292
0
        return 0;
293
185k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
294
185k
        && !OSSL_PARAM_set_int(p, secbits))
295
0
        return 0;
296
185k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
297
185k
        && !OSSL_PARAM_set_int(p, size))
298
0
        return 0;
299
185k
    if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL
300
185k
            && (ecx->type == ECX_KEY_TYPE_X25519
301
109k
                || ecx->type == ECX_KEY_TYPE_X448)) {
302
109k
        if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
303
0
            return 0;
304
109k
    }
305
306
185k
    return key_to_params(ecx, NULL, params, 1);
307
185k
}
308
309
static int ed_get_params(void *key, OSSL_PARAM params[])
310
531
{
311
531
    OSSL_PARAM *p;
312
313
531
    if ((p = OSSL_PARAM_locate(params,
314
531
                               OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
315
531
        && !OSSL_PARAM_set_utf8_string(p, ""))
316
0
        return 0;
317
531
    return 1;
318
531
}
319
320
static int x25519_get_params(void *key, OSSL_PARAM params[])
321
181k
{
322
181k
    return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
323
181k
                          X25519_KEYLEN);
324
181k
}
325
326
static int x448_get_params(void *key, OSSL_PARAM params[])
327
3.34k
{
328
3.34k
    return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
329
3.34k
                          X448_KEYLEN);
330
3.34k
}
331
332
static int ed25519_get_params(void *key, OSSL_PARAM params[])
333
160
{
334
160
    return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
335
160
                          ED25519_SIGSIZE)
336
160
        && ed_get_params(key, params);
337
160
}
338
339
static int ed448_get_params(void *key, OSSL_PARAM params[])
340
371
{
341
371
    return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
342
371
                          ED448_SIGSIZE)
343
371
        && ed_get_params(key, params);
344
371
}
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_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
351
    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
352
    ECX_KEY_TYPES(),
353
    OSSL_PARAM_END
354
};
355
356
static const OSSL_PARAM ed_gettable_params[] = {
357
    OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
358
    OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
359
    OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
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
18.4k
{
398
18.4k
    ECX_KEY *ecxkey = key;
399
18.4k
    const OSSL_PARAM *p;
400
401
18.4k
    if (params == NULL)
402
0
        return 1;
403
404
18.4k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
405
18.4k
    if (p != NULL) {
406
18.4k
        void *buf = ecxkey->pubkey;
407
408
18.4k
        if (p->data_size != ecxkey->keylen
409
18.4k
                || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
410
18.3k
                                                NULL))
411
71
            return 0;
412
18.3k
        OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
413
18.3k
        ecxkey->privkey = NULL;
414
18.3k
        ecxkey->haspubkey = 1;
415
18.3k
    }
416
18.3k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
417
18.3k
    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
18.3k
    return 1;
424
18.3k
}
425
426
static int x25519_set_params(void *key, const OSSL_PARAM params[])
427
18.3k
{
428
18.3k
    return ecx_set_params(key, params);
429
18.3k
}
430
431
static int x448_set_params(void *key, const OSSL_PARAM params[])
432
31
{
433
31
    return ecx_set_params(key, params);
434
31
}
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
60.5k
{
479
60.5k
    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx);
480
60.5k
    struct ecx_gen_ctx *gctx = NULL;
481
482
60.5k
    if (!ossl_prov_is_running())
483
0
        return NULL;
484
485
60.5k
    if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
486
60.5k
        gctx->libctx = libctx;
487
60.5k
        gctx->type = type;
488
60.5k
        gctx->selection = selection;
489
60.5k
    }
490
60.5k
    if (!ecx_gen_set_params(gctx, params)) {
491
0
        OPENSSL_free(gctx);
492
0
        gctx = NULL;
493
0
    }
494
60.5k
    return gctx;
495
60.5k
}
496
497
static void *x25519_gen_init(void *provctx, int selection,
498
                             const OSSL_PARAM params[])
499
60.4k
{
500
60.4k
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X25519);
501
60.4k
}
502
503
static void *x448_gen_init(void *provctx, int selection,
504
                           const OSSL_PARAM params[])
505
95
{
506
95
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_X448);
507
95
}
508
509
static void *ed25519_gen_init(void *provctx, int selection,
510
                              const OSSL_PARAM params[])
511
0
{
512
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED25519);
513
0
}
514
515
static void *ed448_gen_init(void *provctx, int selection,
516
                            const OSSL_PARAM params[])
517
0
{
518
0
    return ecx_gen_init(provctx, selection, params, ECX_KEY_TYPE_ED448);
519
0
}
520
521
static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
522
81.7k
{
523
81.7k
    struct ecx_gen_ctx *gctx = genctx;
524
81.7k
    const OSSL_PARAM *p;
525
526
81.7k
    if (gctx == NULL)
527
0
        return 0;
528
529
81.7k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
530
81.7k
    if (p != NULL) {
531
39.9k
        const char *groupname = NULL;
532
533
        /*
534
         * We optionally allow setting a group name - but each algorithm only
535
         * support one such name, so all we do is verify that it is the one we
536
         * expected.
537
         */
538
39.9k
        switch (gctx->type) {
539
39.8k
            case ECX_KEY_TYPE_X25519:
540
39.8k
                groupname = "x25519";
541
39.8k
                break;
542
65
            case ECX_KEY_TYPE_X448:
543
65
                groupname = "x448";
544
65
                break;
545
0
            default:
546
                /* We only support this for key exchange at the moment */
547
0
                break;
548
39.9k
        }
549
39.9k
        if (p->data_type != OSSL_PARAM_UTF8_STRING
550
39.9k
                || groupname == NULL
551
39.9k
                || OPENSSL_strcasecmp(p->data, groupname) != 0) {
552
0
            ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
553
0
            return 0;
554
0
        }
555
39.9k
    }
556
81.7k
    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
557
81.7k
    if (p != NULL) {
558
0
        if (p->data_type != OSSL_PARAM_UTF8_STRING)
559
0
            return 0;
560
0
        OPENSSL_free(gctx->propq);
561
0
        gctx->propq = OPENSSL_strdup(p->data);
562
0
        if (gctx->propq == NULL)
563
0
            return 0;
564
0
    }
565
81.7k
    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DHKEM_IKM);
566
81.7k
    if (p != NULL) {
567
0
        if (p->data_size != 0 && p->data != NULL) {
568
0
            OPENSSL_free(gctx->dhkem_ikm);
569
0
            gctx->dhkem_ikm = NULL;
570
0
            if (!OSSL_PARAM_get_octet_string(p, (void **)&gctx->dhkem_ikm, 0,
571
0
                                             &gctx->dhkem_ikmlen))
572
0
                return 0;
573
0
        }
574
0
    }
575
576
81.7k
    return 1;
577
81.7k
}
578
579
static const OSSL_PARAM *ecx_gen_settable_params(ossl_unused void *genctx,
580
                                                 ossl_unused void *provctx)
581
0
{
582
0
    static OSSL_PARAM settable[] = {
583
0
        OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
584
0
        OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
585
0
        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0),
586
0
        OSSL_PARAM_END
587
0
    };
588
0
    return settable;
589
0
}
590
591
static void *ecx_gen(struct ecx_gen_ctx *gctx)
592
41.7k
{
593
41.7k
    ECX_KEY *key;
594
41.7k
    unsigned char *privkey;
595
596
41.7k
    if (gctx == NULL)
597
0
        return NULL;
598
41.7k
    if ((key = ossl_ecx_key_new(gctx->libctx, gctx->type, 0,
599
41.7k
                                gctx->propq)) == NULL) {
600
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
601
0
        return NULL;
602
0
    }
603
604
    /* If we're doing parameter generation then we just return a blank key */
605
41.7k
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
606
3.06k
        return key;
607
608
38.7k
    if ((privkey = ossl_ecx_key_allocate_privkey(key)) == NULL) {
609
0
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
610
0
        goto err;
611
0
    }
612
38.7k
#ifndef FIPS_MODULE
613
38.7k
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
614
0
        if (gctx->type == ECX_KEY_TYPE_ED25519
615
0
                || gctx->type == ECX_KEY_TYPE_ED448)
616
0
            goto err;
617
0
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
618
0
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
619
0
            goto err;
620
0
    } else
621
38.7k
#endif
622
38.7k
    {
623
38.7k
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen, 0) <= 0)
624
0
            goto err;
625
38.7k
    }
626
627
38.7k
    switch (gctx->type) {
628
38.6k
    case ECX_KEY_TYPE_X25519:
629
38.6k
        privkey[0] &= 248;
630
38.6k
        privkey[X25519_KEYLEN - 1] &= 127;
631
38.6k
        privkey[X25519_KEYLEN - 1] |= 64;
632
38.6k
        ossl_x25519_public_from_private(key->pubkey, privkey);
633
38.6k
        break;
634
58
    case ECX_KEY_TYPE_X448:
635
58
        privkey[0] &= 252;
636
58
        privkey[X448_KEYLEN - 1] |= 128;
637
58
        ossl_x448_public_from_private(key->pubkey, privkey);
638
58
        break;
639
0
    case ECX_KEY_TYPE_ED25519:
640
0
        if (!ossl_ed25519_public_from_private(gctx->libctx, key->pubkey, privkey,
641
0
                                              gctx->propq))
642
0
            goto err;
643
0
        break;
644
0
    case ECX_KEY_TYPE_ED448:
645
0
        if (!ossl_ed448_public_from_private(gctx->libctx, key->pubkey, privkey,
646
0
                                            gctx->propq))
647
0
            goto err;
648
0
        break;
649
38.7k
    }
650
38.7k
    key->haspubkey = 1;
651
38.7k
    return key;
652
0
err:
653
0
    ossl_ecx_key_free(key);
654
0
    return NULL;
655
38.7k
}
656
657
static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
658
60.4k
{
659
60.4k
    struct ecx_gen_ctx *gctx = genctx;
660
661
60.4k
    if (!ossl_prov_is_running())
662
0
        return 0;
663
664
#ifdef S390X_EC_ASM
665
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
666
        return s390x_ecx_keygen25519(gctx);
667
#endif
668
60.4k
    return ecx_gen(gctx);
669
60.4k
}
670
671
static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
672
95
{
673
95
    struct ecx_gen_ctx *gctx = genctx;
674
675
95
    if (!ossl_prov_is_running())
676
0
        return 0;
677
678
#ifdef S390X_EC_ASM
679
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
680
        return s390x_ecx_keygen448(gctx);
681
#endif
682
95
    return ecx_gen(gctx);
683
95
}
684
685
static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
686
0
{
687
0
    struct ecx_gen_ctx *gctx = genctx;
688
689
0
    if (!ossl_prov_is_running())
690
0
        return 0;
691
692
#ifdef S390X_EC_ASM
693
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
694
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
695
        && OPENSSL_s390xcap_P.kdsa[0]
696
            & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
697
        return s390x_ecd_keygen25519(gctx);
698
#endif
699
0
    return ecx_gen(gctx);
700
0
}
701
702
static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
703
0
{
704
0
    struct ecx_gen_ctx *gctx = genctx;
705
706
0
    if (!ossl_prov_is_running())
707
0
        return 0;
708
709
#ifdef S390X_EC_ASM
710
    if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
711
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
712
        && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
713
        return s390x_ecd_keygen448(gctx);
714
#endif
715
0
    return ecx_gen(gctx);
716
0
}
717
718
static void ecx_gen_cleanup(void *genctx)
719
60.5k
{
720
60.5k
    struct ecx_gen_ctx *gctx = genctx;
721
722
60.5k
    OPENSSL_clear_free(gctx->dhkem_ikm, gctx->dhkem_ikmlen);
723
60.5k
    OPENSSL_free(gctx->propq);
724
60.5k
    OPENSSL_free(gctx);
725
60.5k
}
726
727
void *ecx_load(const void *reference, size_t reference_sz)
728
3.72k
{
729
3.72k
    ECX_KEY *key = NULL;
730
731
3.72k
    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
732
        /* The contents of the reference is the address to our object */
733
3.72k
        key = *(ECX_KEY **)reference;
734
        /* We grabbed, so we detach it */
735
3.72k
        *(ECX_KEY **)reference = NULL;
736
3.72k
        return key;
737
3.72k
    }
738
0
    return NULL;
739
3.72k
}
740
741
static void *ecx_dup(const void *keydata_from, int selection)
742
12.4k
{
743
12.4k
    if (ossl_prov_is_running())
744
12.4k
        return ossl_ecx_key_dup(keydata_from, selection);
745
0
    return NULL;
746
12.4k
}
747
748
static int ecx_key_pairwise_check(const ECX_KEY *ecx, int type)
749
15
{
750
15
    uint8_t pub[64];
751
752
15
    switch (type) {
753
1
    case ECX_KEY_TYPE_X25519:
754
1
        ossl_x25519_public_from_private(pub, ecx->privkey);
755
1
        break;
756
1
    case ECX_KEY_TYPE_X448:
757
1
        ossl_x448_public_from_private(pub, ecx->privkey);
758
1
        break;
759
3
    case ECX_KEY_TYPE_ED25519:
760
3
        if (!ossl_ed25519_public_from_private(ecx->libctx, pub, ecx->privkey,
761
3
                                              ecx->propq))
762
0
            return 0;
763
3
        break;
764
10
    case ECX_KEY_TYPE_ED448:
765
10
        if (!ossl_ed448_public_from_private(ecx->libctx, pub, ecx->privkey,
766
10
                                            ecx->propq))
767
0
            return 0;
768
10
        break;
769
10
    default:
770
0
        return 0;
771
15
    }
772
15
    return CRYPTO_memcmp(ecx->pubkey, pub, ecx->keylen) == 0;
773
15
}
774
775
static int ecx_validate(const void *keydata, int selection, int type, size_t keylen)
776
9.01k
{
777
9.01k
    const ECX_KEY *ecx = keydata;
778
9.01k
    int ok = keylen == ecx->keylen;
779
780
9.01k
    if (!ossl_prov_is_running())
781
0
        return 0;
782
783
9.01k
    if ((selection & ECX_POSSIBLE_SELECTIONS) == 0)
784
19
        return 1; /* nothing to validate */
785
786
8.99k
    if (!ok) {
787
0
        ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH);
788
0
        return 0;
789
0
    }
790
791
8.99k
    if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
792
8.97k
        ok = ok && ecx->haspubkey;
793
794
8.99k
    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
795
38
        ok = ok && ecx->privkey != NULL;
796
797
8.99k
    if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR)
798
19
        ok = ok && ecx_key_pairwise_check(ecx, type);
799
800
8.99k
    return ok;
801
8.99k
}
802
803
static int x25519_validate(const void *keydata, int selection, int checktype)
804
15.5k
{
805
15.5k
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X25519, X25519_KEYLEN);
806
15.5k
}
807
808
static int x448_validate(const void *keydata, int selection, int checktype)
809
29
{
810
29
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_X448, X448_KEYLEN);
811
29
}
812
813
static int ed25519_validate(const void *keydata, int selection, int checktype)
814
28
{
815
28
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED25519, ED25519_KEYLEN);
816
28
}
817
818
static int ed448_validate(const void *keydata, int selection, int checktype)
819
64
{
820
64
    return ecx_validate(keydata, selection, ECX_KEY_TYPE_ED448, ED448_KEYLEN);
821
64
}
822
823
#define MAKE_KEYMGMT_FUNCTIONS(alg) \
824
    const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
825
        { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
826
        { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
827
        { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
828
        { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
829
        { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
830
        { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
831
        { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
832
        { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
833
        { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
834
        { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
835
        { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
836
        { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
837
        { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
838
        { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
839
        { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
840
        { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
841
          (void (*)(void))ecx_gen_settable_params }, \
842
        { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
843
        { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
844
        { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
845
        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ecx_dup }, \
846
        OSSL_DISPATCH_END \
847
    };
848
849
MAKE_KEYMGMT_FUNCTIONS(x25519)
850
MAKE_KEYMGMT_FUNCTIONS(x448)
851
MAKE_KEYMGMT_FUNCTIONS(ed25519)
852
MAKE_KEYMGMT_FUNCTIONS(ed448)
853
854
#ifdef S390X_EC_ASM
855
# include "s390x_arch.h"
856
857
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
858
{
859
    static const unsigned char generator[] = {
860
        0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
861
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
862
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
863
    };
864
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1,
865
                                    gctx->propq);
866
    unsigned char *privkey = NULL, *pubkey;
867
868
    if (key == NULL) {
869
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
870
        goto err;
871
    }
872
873
    /* If we're doing parameter generation then we just return a blank key */
874
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
875
        return key;
876
877
    pubkey = key->pubkey;
878
879
    privkey = ossl_ecx_key_allocate_privkey(key);
880
    if (privkey == NULL) {
881
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
882
        goto err;
883
    }
884
885
#ifndef FIPS_MODULE
886
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
887
        if (gctx->type != ECX_KEY_TYPE_X25519)
888
            goto err;
889
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
890
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
891
            goto err;
892
    } else
893
#endif
894
    {
895
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
896
            goto err;
897
    }
898
899
    privkey[0] &= 248;
900
    privkey[31] &= 127;
901
    privkey[31] |= 64;
902
903
    if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
904
        goto err;
905
    key->haspubkey = 1;
906
    return key;
907
 err:
908
    ossl_ecx_key_free(key);
909
    return NULL;
910
}
911
912
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
913
{
914
    static const unsigned char generator[] = {
915
        0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
916
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
917
        0x00, 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
920
    };
921
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1,
922
                                    gctx->propq);
923
    unsigned char *privkey = NULL, *pubkey;
924
925
    if (key == NULL) {
926
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
927
        goto err;
928
    }
929
930
    /* If we're doing parameter generation then we just return a blank key */
931
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
932
        return key;
933
934
    pubkey = key->pubkey;
935
936
    privkey = ossl_ecx_key_allocate_privkey(key);
937
    if (privkey == NULL) {
938
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
939
        goto err;
940
    }
941
942
#ifndef FIPS_MODULE
943
    if (gctx->dhkem_ikm != NULL && gctx->dhkem_ikmlen != 0) {
944
        if (gctx->type != ECX_KEY_TYPE_X448)
945
            goto err;
946
        if (!ossl_ecx_dhkem_derive_private(key, privkey,
947
                                           gctx->dhkem_ikm, gctx->dhkem_ikmlen))
948
            goto err;
949
    } else
950
#endif
951
    {
952
        if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
953
            goto err;
954
    }
955
956
    privkey[0] &= 252;
957
    privkey[55] |= 128;
958
959
    if (s390x_x448_mul(pubkey, generator, privkey) != 1)
960
        goto err;
961
    key->haspubkey = 1;
962
    return key;
963
 err:
964
    ossl_ecx_key_free(key);
965
    return NULL;
966
}
967
968
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
969
{
970
    static const unsigned char generator_x[] = {
971
        0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
972
        0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
973
        0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
974
    };
975
    static const unsigned char generator_y[] = {
976
        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
977
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
978
        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
979
    };
980
    unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
981
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1,
982
                                    gctx->propq);
983
    unsigned char *privkey = NULL, *pubkey;
984
    unsigned int sz;
985
    EVP_MD *sha = NULL;
986
    int j;
987
988
    if (key == NULL) {
989
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
990
        goto err;
991
    }
992
993
    /* If we're doing parameter generation then we just return a blank key */
994
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
995
        return key;
996
997
    pubkey = key->pubkey;
998
999
    privkey = ossl_ecx_key_allocate_privkey(key);
1000
    if (privkey == NULL) {
1001
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1002
        goto err;
1003
    }
1004
1005
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1006
        goto err;
1007
1008
    sha = EVP_MD_fetch(gctx->libctx, "SHA512", gctx->propq);
1009
    if (sha == NULL)
1010
        goto err;
1011
    j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
1012
    EVP_MD_free(sha);
1013
    if (!j)
1014
        goto err;
1015
1016
    buff[0] &= 248;
1017
    buff[31] &= 63;
1018
    buff[31] |= 64;
1019
1020
    if (s390x_ed25519_mul(x_dst, pubkey,
1021
                          generator_x, generator_y, buff) != 1)
1022
        goto err;
1023
1024
    pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1025
    key->haspubkey = 1;
1026
    return key;
1027
 err:
1028
    ossl_ecx_key_free(key);
1029
    return NULL;
1030
}
1031
1032
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
1033
{
1034
    static const unsigned char generator_x[] = {
1035
        0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1036
        0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1037
        0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1038
        0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1039
        0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1040
    };
1041
    static const unsigned char generator_y[] = {
1042
        0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1043
        0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1044
        0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1045
        0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1046
        0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1047
    };
1048
    unsigned char x_dst[57], buff[114];
1049
    ECX_KEY *key = ossl_ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1,
1050
                                    gctx->propq);
1051
    unsigned char *privkey = NULL, *pubkey;
1052
    EVP_MD_CTX *hashctx = NULL;
1053
    EVP_MD *shake = NULL;
1054
1055
    if (key == NULL) {
1056
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1057
        goto err;
1058
    }
1059
1060
    /* If we're doing parameter generation then we just return a blank key */
1061
    if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
1062
        return key;
1063
1064
    pubkey = key->pubkey;
1065
1066
    privkey = ossl_ecx_key_allocate_privkey(key);
1067
    if (privkey == NULL) {
1068
        ERR_raise(ERR_LIB_PROV, ERR_R_EC_LIB);
1069
        goto err;
1070
    }
1071
1072
    shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", gctx->propq);
1073
    if (shake == NULL)
1074
        goto err;
1075
    if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1076
        goto err;
1077
1078
    hashctx = EVP_MD_CTX_new();
1079
    if (hashctx == NULL)
1080
        goto err;
1081
    if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
1082
        goto err;
1083
    if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1084
        goto err;
1085
    if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1086
        goto err;
1087
1088
    buff[0] &= -4;
1089
    buff[55] |= 0x80;
1090
    buff[56] = 0;
1091
1092
    if (s390x_ed448_mul(x_dst, pubkey,
1093
                        generator_x, generator_y, buff) != 1)
1094
        goto err;
1095
1096
    pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1097
    EVP_MD_CTX_free(hashctx);
1098
    EVP_MD_free(shake);
1099
    key->haspubkey = 1;
1100
    return key;
1101
 err:
1102
    ossl_ecx_key_free(key);
1103
    EVP_MD_CTX_free(hashctx);
1104
    EVP_MD_free(shake);
1105
    return NULL;
1106
}
1107
#endif