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