2 * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/core_numbers.h>
12 #include <openssl/core_names.h>
13 #include <openssl/params.h>
14 #include <openssl/err.h>
15 #include <openssl/evp.h>
16 #include <openssl/rand.h>
17 #include "internal/param_build_set.h"
18 #include "openssl/param_build.h"
19 #include "crypto/ecx.h"
20 #include "prov/implementations.h"
21 #include "prov/providercommon.h"
22 #include "prov/provider_ctx.h"
24 # include "s390x_arch.h"
25 # include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
28 static OSSL_OP_keymgmt_new_fn x25519_new_key;
29 static OSSL_OP_keymgmt_new_fn x448_new_key;
30 static OSSL_OP_keymgmt_new_fn ed25519_new_key;
31 static OSSL_OP_keymgmt_new_fn ed448_new_key;
32 static OSSL_OP_keymgmt_gen_init_fn x25519_gen_init;
33 static OSSL_OP_keymgmt_gen_init_fn x448_gen_init;
34 static OSSL_OP_keymgmt_gen_init_fn ed25519_gen_init;
35 static OSSL_OP_keymgmt_gen_init_fn ed448_gen_init;
36 static OSSL_OP_keymgmt_gen_fn x25519_gen;
37 static OSSL_OP_keymgmt_gen_fn x448_gen;
38 static OSSL_OP_keymgmt_gen_fn ed25519_gen;
39 static OSSL_OP_keymgmt_gen_fn ed448_gen;
40 static OSSL_OP_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
41 static OSSL_OP_keymgmt_get_params_fn x25519_get_params;
42 static OSSL_OP_keymgmt_get_params_fn x448_get_params;
43 static OSSL_OP_keymgmt_get_params_fn ed25519_get_params;
44 static OSSL_OP_keymgmt_get_params_fn ed448_get_params;
45 static OSSL_OP_keymgmt_gettable_params_fn x25519_gettable_params;
46 static OSSL_OP_keymgmt_gettable_params_fn x448_gettable_params;
47 static OSSL_OP_keymgmt_gettable_params_fn ed25519_gettable_params;
48 static OSSL_OP_keymgmt_gettable_params_fn ed448_gettable_params;
49 static OSSL_OP_keymgmt_set_params_fn x25519_set_params;
50 static OSSL_OP_keymgmt_set_params_fn x448_set_params;
51 static OSSL_OP_keymgmt_set_params_fn ed25519_set_params;
52 static OSSL_OP_keymgmt_set_params_fn ed448_set_params;
53 static OSSL_OP_keymgmt_settable_params_fn x25519_settable_params;
54 static OSSL_OP_keymgmt_settable_params_fn x448_settable_params;
55 static OSSL_OP_keymgmt_settable_params_fn ed25519_settable_params;
56 static OSSL_OP_keymgmt_settable_params_fn ed448_settable_params;
57 static OSSL_OP_keymgmt_has_fn ecx_has;
58 static OSSL_OP_keymgmt_match_fn ecx_match;
59 static OSSL_OP_keymgmt_import_fn ecx_import;
60 static OSSL_OP_keymgmt_import_types_fn ecx_imexport_types;
61 static OSSL_OP_keymgmt_export_fn ecx_export;
62 static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types;
64 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
72 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
73 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
74 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
75 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
78 static void *x25519_new_key(void *provctx)
80 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0);
83 static void *x448_new_key(void *provctx)
85 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0);
88 static void *ed25519_new_key(void *provctx)
90 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0);
93 static void *ed448_new_key(void *provctx)
95 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0);
98 static int ecx_has(void *keydata, int selection)
100 ECX_KEY *key = keydata;
105 * ECX keys always have all the parameters they need (i.e. none).
106 * Therefore we always return with 1, if asked about parameters.
110 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
111 ok = ok && key->haspubkey;
113 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
114 ok = ok && key->privkey != NULL;
119 static int ecx_match(const void *keydata1, const void *keydata2, int selection)
121 const ECX_KEY *key1 = keydata1;
122 const ECX_KEY *key2 = keydata2;
125 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
126 ok = ok && key1->type == key2->type;
127 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
128 if ((key1->privkey == NULL && key2->privkey != NULL)
129 || (key1->privkey != NULL && key2->privkey == NULL)
130 || key1->type != key2->type)
133 ok = ok && (key1->privkey == NULL /* implies key2->privkey == NULL */
134 || CRYPTO_memcmp(key1->privkey, key2->privkey,
137 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
138 if (key1->haspubkey != key2->haspubkey
139 || key1->type != key2->type)
142 ok = ok && (key1->haspubkey == 0 /* implies key2->haspubkey == 0 */
143 || CRYPTO_memcmp(key1->pubkey, key2->pubkey,
149 static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
151 ECX_KEY *key = keydata;
153 int include_private = 0;
158 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
161 include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
162 ok = ok && ecx_key_fromdata(key, params, include_private);
167 static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
173 if (!ossl_param_build_set_octet_string(tmpl, params,
174 OSSL_PKEY_PARAM_PUB_KEY,
175 key->pubkey, key->keylen))
178 if (key->privkey != NULL
179 && !ossl_param_build_set_octet_string(tmpl, params,
180 OSSL_PKEY_PARAM_PRIV_KEY,
181 key->privkey, key->keylen))
187 static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
190 ECX_KEY *key = keydata;
191 OSSL_PARAM_BLD *tmpl;
192 OSSL_PARAM *params = NULL;
198 tmpl = OSSL_PARAM_BLD_new();
202 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
203 && !key_to_params(key, tmpl, NULL))
206 params = OSSL_PARAM_BLD_to_param(tmpl);
210 ret = param_cb(params, cbarg);
211 OSSL_PARAM_BLD_free_params(params);
213 OSSL_PARAM_BLD_free(tmpl);
217 #define ECX_KEY_TYPES() \
218 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
219 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
221 static const OSSL_PARAM ecx_key_types[] = {
225 static const OSSL_PARAM *ecx_imexport_types(int selection)
227 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
228 return ecx_key_types;
232 static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
238 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
239 && !OSSL_PARAM_set_int(p, bits))
241 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
242 && !OSSL_PARAM_set_int(p, secbits))
244 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
245 && !OSSL_PARAM_set_int(p, size))
247 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL
248 && (ecx->type == ECX_KEY_TYPE_X25519
249 || ecx->type == ECX_KEY_TYPE_X448)) {
250 if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
254 return key_to_params(ecx, NULL, params);
257 static int ed_get_params(void *key, OSSL_PARAM params[])
261 if ((p = OSSL_PARAM_locate(params,
262 OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
263 && !OSSL_PARAM_set_utf8_string(p, ""))
268 static int x25519_get_params(void *key, OSSL_PARAM params[])
270 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
274 static int x448_get_params(void *key, OSSL_PARAM params[])
276 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
280 static int ed25519_get_params(void *key, OSSL_PARAM params[])
282 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
284 && ed_get_params(key, params);
287 static int ed448_get_params(void *key, OSSL_PARAM params[])
289 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
291 && ed_get_params(key, params);
294 static const OSSL_PARAM ecx_gettable_params[] = {
295 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
296 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
297 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
298 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
299 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
304 static const OSSL_PARAM ed_gettable_params[] = {
305 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
306 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
307 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
312 static const OSSL_PARAM *x25519_gettable_params(void)
314 return ecx_gettable_params;
317 static const OSSL_PARAM *x448_gettable_params(void)
319 return ecx_gettable_params;
322 static const OSSL_PARAM *ed25519_gettable_params(void)
324 return ed_gettable_params;
327 static const OSSL_PARAM *ed448_gettable_params(void)
329 return ed_gettable_params;
332 static int ecx_set_params(void *key, const OSSL_PARAM params[])
334 ECX_KEY *ecxkey = key;
337 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
339 void *buf = ecxkey->pubkey;
341 if (p->data_size != ecxkey->keylen
342 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
345 OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
346 ecxkey->privkey = NULL;
347 ecxkey->haspubkey = 1;
353 static int x25519_set_params(void *key, const OSSL_PARAM params[])
355 return ecx_set_params(key, params);
358 static int x448_set_params(void *key, const OSSL_PARAM params[])
360 return ecx_set_params(key, params);
363 static int ed25519_set_params(void *key, const OSSL_PARAM params[])
368 static int ed448_set_params(void *key, const OSSL_PARAM params[])
373 static const OSSL_PARAM ecx_settable_params[] = {
374 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
378 static const OSSL_PARAM ed_settable_params[] = {
382 static const OSSL_PARAM *x25519_settable_params(void)
384 return ecx_settable_params;
387 static const OSSL_PARAM *x448_settable_params(void)
389 return ecx_settable_params;
392 static const OSSL_PARAM *ed25519_settable_params(void)
394 return ed_settable_params;
397 static const OSSL_PARAM *ed448_settable_params(void)
399 return ed_settable_params;
402 static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
404 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
405 struct ecx_gen_ctx *gctx = NULL;
407 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
410 if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
411 gctx->libctx = libctx;
417 static void *x25519_gen_init(void *provctx, int selection)
419 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X25519);
422 static void *x448_gen_init(void *provctx, int selection)
424 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X448);
427 static void *ed25519_gen_init(void *provctx, int selection)
429 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED25519);
432 static void *ed448_gen_init(void *provctx, int selection)
434 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED448);
437 static void *ecx_gen(struct ecx_gen_ctx *gctx)
440 unsigned char *privkey;
444 if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) {
445 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
448 if ((privkey = ecx_key_allocate_privkey(key)) == NULL) {
449 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
452 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen) <= 0)
454 switch (gctx->type) {
455 case ECX_KEY_TYPE_X25519:
457 privkey[X25519_KEYLEN - 1] &= 127;
458 privkey[X25519_KEYLEN - 1] |= 64;
459 X25519_public_from_private(key->pubkey, privkey);
461 case ECX_KEY_TYPE_X448:
463 privkey[X448_KEYLEN - 1] |= 128;
464 X448_public_from_private(key->pubkey, privkey);
466 case ECX_KEY_TYPE_ED25519:
467 if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey))
470 case ECX_KEY_TYPE_ED448:
471 if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey))
481 static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
483 struct ecx_gen_ctx *gctx = genctx;
486 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
487 return s390x_ecx_keygen25519(gctx);
489 return ecx_gen(gctx);
492 static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
494 struct ecx_gen_ctx *gctx = genctx;
497 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
498 return s390x_ecx_keygen448(gctx);
500 return ecx_gen(gctx);
503 static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
505 struct ecx_gen_ctx *gctx = genctx;
507 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
508 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
509 && OPENSSL_s390xcap_P.kdsa[0]
510 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
511 return s390x_ecd_keygen25519(gctx);
513 return ecx_gen(gctx);
516 static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
518 struct ecx_gen_ctx *gctx = genctx;
521 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
522 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
523 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
524 return s390x_ecd_keygen448(gctx);
526 return ecx_gen(gctx);
529 static void ecx_gen_cleanup(void *genctx)
531 struct ecx_gen_ctx *gctx = genctx;
536 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
537 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
538 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
539 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
540 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
541 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
542 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
543 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
544 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
545 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
546 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
547 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
548 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
549 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
550 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
551 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
552 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
556 MAKE_KEYMGMT_FUNCTIONS(x25519)
557 MAKE_KEYMGMT_FUNCTIONS(x448)
558 MAKE_KEYMGMT_FUNCTIONS(ed25519)
559 MAKE_KEYMGMT_FUNCTIONS(ed448)
562 # include "s390x_arch.h"
564 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
566 static const unsigned char generator[] = {
567 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
571 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1);
572 unsigned char *privkey = NULL, *pubkey;
575 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
579 pubkey = key->pubkey;
581 privkey = ecx_key_allocate_privkey(key);
582 if (privkey == NULL) {
583 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
587 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN) <= 0)
594 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
602 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
604 static const unsigned char generator[] = {
605 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
611 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1);
612 unsigned char *privkey = NULL, *pubkey;
615 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
619 pubkey = key->pubkey;
621 privkey = ecx_key_allocate_privkey(key);
622 if (privkey == NULL) {
623 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
627 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN) <= 0)
633 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
641 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
643 static const unsigned char generator_x[] = {
644 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
645 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
646 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
648 static const unsigned char generator_y[] = {
649 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
650 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
651 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
653 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
654 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1);
655 unsigned char *privkey = NULL, *pubkey;
661 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
665 pubkey = key->pubkey;
667 privkey = ecx_key_allocate_privkey(key);
668 if (privkey == NULL) {
669 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
673 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0)
676 sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL);
679 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
688 if (s390x_ed25519_mul(x_dst, pubkey,
689 generator_x, generator_y, buff) != 1)
692 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
699 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
701 static const unsigned char generator_x[] = {
702 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
703 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
704 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
705 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
706 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
708 static const unsigned char generator_y[] = {
709 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
710 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
711 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
712 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
713 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
715 unsigned char x_dst[57], buff[114];
716 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1);
717 unsigned char *privkey = NULL, *pubkey;
718 EVP_MD_CTX *hashctx = NULL;
719 EVP_MD *shake = NULL;
722 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
726 pubkey = key->pubkey;
728 privkey = ecx_key_allocate_privkey(key);
729 if (privkey == NULL) {
730 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
734 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL);
737 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0)
740 hashctx = EVP_MD_CTX_new();
743 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
745 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
747 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
754 if (s390x_ed448_mul(x_dst, pubkey,
755 generator_x, generator_y, buff) != 1)
758 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
759 EVP_MD_CTX_free(hashctx);
764 EVP_MD_CTX_free(hashctx);