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;
104 if ((selection & ECX_POSSIBLE_SELECTIONS) != 0)
107 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
108 ok = ok && key->haspubkey;
110 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
111 ok = ok && key->privkey != NULL;
116 static int ecx_match(const void *keydata1, const void *keydata2, int selection)
118 const ECX_KEY *key1 = keydata1;
119 const ECX_KEY *key2 = keydata2;
122 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
123 ok = ok && key1->type == key2->type;
124 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
125 if ((key1->privkey == NULL && key2->privkey != NULL)
126 || (key1->privkey != NULL && key2->privkey == NULL)
127 || key1->type != key2->type)
130 ok = ok && (key1->privkey == NULL /* implies key2->privkey == NULL */
131 || CRYPTO_memcmp(key1->privkey, key2->privkey,
134 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
135 if (key1->haspubkey != key2->haspubkey
136 || key1->type != key2->type)
139 ok = ok && (key1->haspubkey == 0 /* implies key2->haspubkey == 0 */
140 || CRYPTO_memcmp(key1->pubkey, key2->pubkey,
146 static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
148 ECX_KEY *key = keydata;
150 int include_private = 0;
155 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
158 include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
159 ok = ok && ecx_key_fromdata(key, params, include_private);
164 static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
170 if (!ossl_param_build_set_octet_string(tmpl, params,
171 OSSL_PKEY_PARAM_PUB_KEY,
172 key->pubkey, key->keylen))
175 if (key->privkey != NULL
176 && !ossl_param_build_set_octet_string(tmpl, params,
177 OSSL_PKEY_PARAM_PRIV_KEY,
178 key->privkey, key->keylen))
184 static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
187 ECX_KEY *key = keydata;
188 OSSL_PARAM_BLD *tmpl;
189 OSSL_PARAM *params = NULL;
195 tmpl = OSSL_PARAM_BLD_new();
199 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
200 && !key_to_params(key, tmpl, NULL))
203 params = OSSL_PARAM_BLD_to_param(tmpl);
207 ret = param_cb(params, cbarg);
208 OSSL_PARAM_BLD_free_params(params);
210 OSSL_PARAM_BLD_free(tmpl);
214 #define ECX_KEY_TYPES() \
215 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
216 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
218 static const OSSL_PARAM ecx_key_types[] = {
222 static const OSSL_PARAM *ecx_imexport_types(int selection)
224 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
225 return ecx_key_types;
229 static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
235 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
236 && !OSSL_PARAM_set_int(p, bits))
238 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
239 && !OSSL_PARAM_set_int(p, secbits))
241 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
242 && !OSSL_PARAM_set_int(p, size))
244 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL
245 && (ecx->type == ECX_KEY_TYPE_X25519
246 || ecx->type == ECX_KEY_TYPE_X448)) {
247 if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
251 return key_to_params(ecx, NULL, params);
254 static int ed_get_params(void *key, OSSL_PARAM params[])
258 if ((p = OSSL_PARAM_locate(params,
259 OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
260 && !OSSL_PARAM_set_utf8_string(p, ""))
265 static int x25519_get_params(void *key, OSSL_PARAM params[])
267 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
271 static int x448_get_params(void *key, OSSL_PARAM params[])
273 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
277 static int ed25519_get_params(void *key, OSSL_PARAM params[])
279 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
281 && ed_get_params(key, params);
284 static int ed448_get_params(void *key, OSSL_PARAM params[])
286 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
288 && ed_get_params(key, params);
291 static const OSSL_PARAM ecx_gettable_params[] = {
292 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
293 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
294 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
295 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
296 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
301 static const OSSL_PARAM ed_gettable_params[] = {
302 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
303 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
304 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
309 static const OSSL_PARAM *x25519_gettable_params(void)
311 return ecx_gettable_params;
314 static const OSSL_PARAM *x448_gettable_params(void)
316 return ecx_gettable_params;
319 static const OSSL_PARAM *ed25519_gettable_params(void)
321 return ed_gettable_params;
324 static const OSSL_PARAM *ed448_gettable_params(void)
326 return ed_gettable_params;
329 static int ecx_set_params(void *key, const OSSL_PARAM params[])
331 ECX_KEY *ecxkey = key;
334 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
336 void *buf = ecxkey->pubkey;
338 if (p->data_size != ecxkey->keylen
339 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
342 OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
343 ecxkey->privkey = NULL;
344 ecxkey->haspubkey = 1;
350 static int x25519_set_params(void *key, const OSSL_PARAM params[])
352 return ecx_set_params(key, params);
355 static int x448_set_params(void *key, const OSSL_PARAM params[])
357 return ecx_set_params(key, params);
360 static int ed25519_set_params(void *key, const OSSL_PARAM params[])
365 static int ed448_set_params(void *key, const OSSL_PARAM params[])
370 static const OSSL_PARAM ecx_settable_params[] = {
371 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
375 static const OSSL_PARAM ed_settable_params[] = {
379 static const OSSL_PARAM *x25519_settable_params(void)
381 return ecx_settable_params;
384 static const OSSL_PARAM *x448_settable_params(void)
386 return ecx_settable_params;
389 static const OSSL_PARAM *ed25519_settable_params(void)
391 return ed_settable_params;
394 static const OSSL_PARAM *ed448_settable_params(void)
396 return ed_settable_params;
399 static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
401 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
402 struct ecx_gen_ctx *gctx = NULL;
404 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
407 if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
408 gctx->libctx = libctx;
414 static void *x25519_gen_init(void *provctx, int selection)
416 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X25519);
419 static void *x448_gen_init(void *provctx, int selection)
421 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X448);
424 static void *ed25519_gen_init(void *provctx, int selection)
426 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED25519);
429 static void *ed448_gen_init(void *provctx, int selection)
431 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED448);
434 static void *ecx_gen(struct ecx_gen_ctx *gctx)
437 unsigned char *privkey;
441 if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) {
442 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
445 if ((privkey = ecx_key_allocate_privkey(key)) == NULL) {
446 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
449 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen) <= 0)
451 switch (gctx->type) {
452 case ECX_KEY_TYPE_X25519:
454 privkey[X25519_KEYLEN - 1] &= 127;
455 privkey[X25519_KEYLEN - 1] |= 64;
456 X25519_public_from_private(key->pubkey, privkey);
458 case ECX_KEY_TYPE_X448:
460 privkey[X448_KEYLEN - 1] |= 128;
461 X448_public_from_private(key->pubkey, privkey);
463 case ECX_KEY_TYPE_ED25519:
464 if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey))
467 case ECX_KEY_TYPE_ED448:
468 if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey))
478 static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
480 struct ecx_gen_ctx *gctx = genctx;
483 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
484 return s390x_ecx_keygen25519(gctx);
486 return ecx_gen(gctx);
489 static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
491 struct ecx_gen_ctx *gctx = genctx;
494 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
495 return s390x_ecx_keygen448(gctx);
497 return ecx_gen(gctx);
500 static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
502 struct ecx_gen_ctx *gctx = genctx;
504 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
505 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
506 && OPENSSL_s390xcap_P.kdsa[0]
507 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
508 return s390x_ecd_keygen25519(gctx);
510 return ecx_gen(gctx);
513 static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
515 struct ecx_gen_ctx *gctx = genctx;
518 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
519 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
520 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
521 return s390x_ecd_keygen448(gctx);
523 return ecx_gen(gctx);
526 static void ecx_gen_cleanup(void *genctx)
528 struct ecx_gen_ctx *gctx = genctx;
533 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
534 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
535 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
536 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
537 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
538 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
539 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
540 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
541 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
542 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
543 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
544 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
545 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
546 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
547 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
548 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
549 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
553 MAKE_KEYMGMT_FUNCTIONS(x25519)
554 MAKE_KEYMGMT_FUNCTIONS(x448)
555 MAKE_KEYMGMT_FUNCTIONS(ed25519)
556 MAKE_KEYMGMT_FUNCTIONS(ed448)
559 # include "s390x_arch.h"
561 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
563 static const unsigned char generator[] = {
564 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
568 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1);
569 unsigned char *privkey = NULL, *pubkey;
572 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
576 pubkey = key->pubkey;
578 privkey = ecx_key_allocate_privkey(key);
579 if (privkey == NULL) {
580 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
584 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN) <= 0)
591 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
599 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
601 static const unsigned char generator[] = {
602 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
608 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1);
609 unsigned char *privkey = NULL, *pubkey;
612 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
616 pubkey = key->pubkey;
618 privkey = ecx_key_allocate_privkey(key);
619 if (privkey == NULL) {
620 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
624 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN) <= 0)
630 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
638 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
640 static const unsigned char generator_x[] = {
641 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
642 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
643 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
645 static const unsigned char generator_y[] = {
646 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
647 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
648 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
650 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
651 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1);
652 unsigned char *privkey = NULL, *pubkey;
658 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
662 pubkey = key->pubkey;
664 privkey = ecx_key_allocate_privkey(key);
665 if (privkey == NULL) {
666 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
670 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0)
673 sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL);
676 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
685 if (s390x_ed25519_mul(x_dst, pubkey,
686 generator_x, generator_y, buff) != 1)
689 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
696 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
698 static const unsigned char generator_x[] = {
699 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
700 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
701 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
702 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
703 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
705 static const unsigned char generator_y[] = {
706 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
707 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
708 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
709 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
710 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
712 unsigned char x_dst[57], buff[114];
713 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1);
714 unsigned char *privkey = NULL, *pubkey;
715 EVP_MD_CTX *hashctx = NULL;
716 EVP_MD *shake = NULL;
719 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
723 pubkey = key->pubkey;
725 privkey = ecx_key_allocate_privkey(key);
726 if (privkey == NULL) {
727 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
731 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL);
734 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0)
737 hashctx = EVP_MD_CTX_new();
740 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
742 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
744 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
751 if (s390x_ed448_mul(x_dst, pubkey,
752 generator_x, generator_y, buff) != 1)
755 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
756 EVP_MD_CTX_free(hashctx);
761 EVP_MD_CTX_free(hashctx);