Coverage Report

Created: 2023-06-08 06:43

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