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
12 /* For strcasecmp on Windows */
14 #include <openssl/core_numbers.h>
15 #include <openssl/core_names.h>
16 #include <openssl/params.h>
17 #include <openssl/err.h>
18 #include <openssl/evp.h>
19 #include <openssl/rand.h>
20 #include "internal/param_build_set.h"
21 #include "openssl/param_build.h"
22 #include "crypto/ecx.h"
23 #include "prov/implementations.h"
24 #include "prov/providercommon.h"
25 #include "prov/provider_ctx.h"
27 # include "s390x_arch.h"
28 # include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
31 static OSSL_OP_keymgmt_new_fn x25519_new_key;
32 static OSSL_OP_keymgmt_new_fn x448_new_key;
33 static OSSL_OP_keymgmt_new_fn ed25519_new_key;
34 static OSSL_OP_keymgmt_new_fn ed448_new_key;
35 static OSSL_OP_keymgmt_gen_init_fn x25519_gen_init;
36 static OSSL_OP_keymgmt_gen_init_fn x448_gen_init;
37 static OSSL_OP_keymgmt_gen_init_fn ed25519_gen_init;
38 static OSSL_OP_keymgmt_gen_init_fn ed448_gen_init;
39 static OSSL_OP_keymgmt_gen_fn x25519_gen;
40 static OSSL_OP_keymgmt_gen_fn x448_gen;
41 static OSSL_OP_keymgmt_gen_fn ed25519_gen;
42 static OSSL_OP_keymgmt_gen_fn ed448_gen;
43 static OSSL_OP_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
44 static OSSL_OP_keymgmt_get_params_fn x25519_get_params;
45 static OSSL_OP_keymgmt_get_params_fn x448_get_params;
46 static OSSL_OP_keymgmt_get_params_fn ed25519_get_params;
47 static OSSL_OP_keymgmt_get_params_fn ed448_get_params;
48 static OSSL_OP_keymgmt_gettable_params_fn x25519_gettable_params;
49 static OSSL_OP_keymgmt_gettable_params_fn x448_gettable_params;
50 static OSSL_OP_keymgmt_gettable_params_fn ed25519_gettable_params;
51 static OSSL_OP_keymgmt_gettable_params_fn ed448_gettable_params;
52 static OSSL_OP_keymgmt_set_params_fn x25519_set_params;
53 static OSSL_OP_keymgmt_set_params_fn x448_set_params;
54 static OSSL_OP_keymgmt_set_params_fn ed25519_set_params;
55 static OSSL_OP_keymgmt_set_params_fn ed448_set_params;
56 static OSSL_OP_keymgmt_settable_params_fn x25519_settable_params;
57 static OSSL_OP_keymgmt_settable_params_fn x448_settable_params;
58 static OSSL_OP_keymgmt_settable_params_fn ed25519_settable_params;
59 static OSSL_OP_keymgmt_settable_params_fn ed448_settable_params;
60 static OSSL_OP_keymgmt_has_fn ecx_has;
61 static OSSL_OP_keymgmt_match_fn ecx_match;
62 static OSSL_OP_keymgmt_import_fn ecx_import;
63 static OSSL_OP_keymgmt_import_types_fn ecx_imexport_types;
64 static OSSL_OP_keymgmt_export_fn ecx_export;
65 static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types;
67 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
76 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
77 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
78 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
79 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
82 static void *x25519_new_key(void *provctx)
84 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X25519, 0);
87 static void *x448_new_key(void *provctx)
89 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_X448, 0);
92 static void *ed25519_new_key(void *provctx)
94 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED25519, 0);
97 static void *ed448_new_key(void *provctx)
99 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx), ECX_KEY_TYPE_ED448, 0);
102 static int ecx_has(void *keydata, int selection)
104 ECX_KEY *key = keydata;
109 * ECX keys always have all the parameters they need (i.e. none).
110 * Therefore we always return with 1, if asked about parameters.
114 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
115 ok = ok && key->haspubkey;
117 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
118 ok = ok && key->privkey != NULL;
123 static int ecx_match(const void *keydata1, const void *keydata2, int selection)
125 const ECX_KEY *key1 = keydata1;
126 const ECX_KEY *key2 = keydata2;
129 if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
130 ok = ok && key1->type == key2->type;
131 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
132 if ((key1->privkey == NULL && key2->privkey != NULL)
133 || (key1->privkey != NULL && key2->privkey == NULL)
134 || key1->type != key2->type)
137 ok = ok && (key1->privkey == NULL /* implies key2->privkey == NULL */
138 || CRYPTO_memcmp(key1->privkey, key2->privkey,
141 if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
142 if (key1->haspubkey != key2->haspubkey
143 || key1->type != key2->type)
146 ok = ok && (key1->haspubkey == 0 /* implies key2->haspubkey == 0 */
147 || CRYPTO_memcmp(key1->pubkey, key2->pubkey,
153 static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
155 ECX_KEY *key = keydata;
157 int include_private = 0;
162 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
165 include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
166 ok = ok && ecx_key_fromdata(key, params, include_private);
171 static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
177 if (!ossl_param_build_set_octet_string(tmpl, params,
178 OSSL_PKEY_PARAM_PUB_KEY,
179 key->pubkey, key->keylen))
182 if (key->privkey != NULL
183 && !ossl_param_build_set_octet_string(tmpl, params,
184 OSSL_PKEY_PARAM_PRIV_KEY,
185 key->privkey, key->keylen))
191 static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
194 ECX_KEY *key = keydata;
195 OSSL_PARAM_BLD *tmpl;
196 OSSL_PARAM *params = NULL;
202 tmpl = OSSL_PARAM_BLD_new();
206 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
207 && !key_to_params(key, tmpl, NULL))
210 params = OSSL_PARAM_BLD_to_param(tmpl);
214 ret = param_cb(params, cbarg);
215 OSSL_PARAM_BLD_free_params(params);
217 OSSL_PARAM_BLD_free(tmpl);
221 #define ECX_KEY_TYPES() \
222 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
223 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
225 static const OSSL_PARAM ecx_key_types[] = {
229 static const OSSL_PARAM *ecx_imexport_types(int selection)
231 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
232 return ecx_key_types;
236 static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
242 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
243 && !OSSL_PARAM_set_int(p, bits))
245 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
246 && !OSSL_PARAM_set_int(p, secbits))
248 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
249 && !OSSL_PARAM_set_int(p, size))
251 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT)) != NULL
252 && (ecx->type == ECX_KEY_TYPE_X25519
253 || ecx->type == ECX_KEY_TYPE_X448)) {
254 if (!OSSL_PARAM_set_octet_string(p, ecx->pubkey, ecx->keylen))
258 return key_to_params(ecx, NULL, params);
261 static int ed_get_params(void *key, OSSL_PARAM params[])
265 if ((p = OSSL_PARAM_locate(params,
266 OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
267 && !OSSL_PARAM_set_utf8_string(p, ""))
272 static int x25519_get_params(void *key, OSSL_PARAM params[])
274 return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
278 static int x448_get_params(void *key, OSSL_PARAM params[])
280 return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
284 static int ed25519_get_params(void *key, OSSL_PARAM params[])
286 return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
288 && ed_get_params(key, params);
291 static int ed448_get_params(void *key, OSSL_PARAM params[])
293 return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
295 && ed_get_params(key, params);
298 static const OSSL_PARAM ecx_gettable_params[] = {
299 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
300 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
301 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
302 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST, NULL, 0),
303 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
308 static const OSSL_PARAM ed_gettable_params[] = {
309 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
310 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
311 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
316 static const OSSL_PARAM *x25519_gettable_params(void)
318 return ecx_gettable_params;
321 static const OSSL_PARAM *x448_gettable_params(void)
323 return ecx_gettable_params;
326 static const OSSL_PARAM *ed25519_gettable_params(void)
328 return ed_gettable_params;
331 static const OSSL_PARAM *ed448_gettable_params(void)
333 return ed_gettable_params;
336 static int ecx_set_params(void *key, const OSSL_PARAM params[])
338 ECX_KEY *ecxkey = key;
341 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_TLS_ENCODED_PT);
343 void *buf = ecxkey->pubkey;
345 if (p->data_size != ecxkey->keylen
346 || !OSSL_PARAM_get_octet_string(p, &buf, sizeof(ecxkey->pubkey),
349 OPENSSL_clear_free(ecxkey->privkey, ecxkey->keylen);
350 ecxkey->privkey = NULL;
351 ecxkey->haspubkey = 1;
357 static int x25519_set_params(void *key, const OSSL_PARAM params[])
359 return ecx_set_params(key, params);
362 static int x448_set_params(void *key, const OSSL_PARAM params[])
364 return ecx_set_params(key, params);
367 static int ed25519_set_params(void *key, const OSSL_PARAM params[])
372 static int ed448_set_params(void *key, const OSSL_PARAM params[])
377 static const OSSL_PARAM ecx_settable_params[] = {
378 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
382 static const OSSL_PARAM ed_settable_params[] = {
386 static const OSSL_PARAM *x25519_settable_params(void)
388 return ecx_settable_params;
391 static const OSSL_PARAM *x448_settable_params(void)
393 return ecx_settable_params;
396 static const OSSL_PARAM *ed25519_settable_params(void)
398 return ed_settable_params;
401 static const OSSL_PARAM *ed448_settable_params(void)
403 return ed_settable_params;
406 static void *ecx_gen_init(void *provctx, int selection, ECX_KEY_TYPE type)
408 OPENSSL_CTX *libctx = PROV_LIBRARY_CONTEXT_OF(provctx);
409 struct ecx_gen_ctx *gctx = NULL;
411 if ((gctx = OPENSSL_malloc(sizeof(*gctx))) != NULL) {
412 gctx->libctx = libctx;
414 gctx->selection = selection;
419 static void *x25519_gen_init(void *provctx, int selection)
421 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X25519);
424 static void *x448_gen_init(void *provctx, int selection)
426 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_X448);
429 static void *ed25519_gen_init(void *provctx, int selection)
431 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED25519);
434 static void *ed448_gen_init(void *provctx, int selection)
436 return ecx_gen_init(provctx, selection, ECX_KEY_TYPE_ED448);
439 static int ecx_gen_set_params(void *genctx, const OSSL_PARAM params[])
441 struct ecx_gen_ctx *gctx = genctx;
447 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
449 const char *groupname = NULL;
452 * We optionally allow setting a group name - but each algorithm only
453 * support one such name, so all we do is verify that it is the one we
456 switch (gctx->type) {
457 case ECX_KEY_TYPE_X25519:
458 groupname = "x25519";
460 case ECX_KEY_TYPE_X448:
464 /* We only support this for key exchange at the moment */
467 if (p->data_type != OSSL_PARAM_UTF8_STRING
469 || strcasecmp(p->data, groupname) != 0) {
470 ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
478 static const OSSL_PARAM *ecx_gen_settable_params(void *provctx)
480 static OSSL_PARAM settable[] = {
481 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
487 static void *ecx_gen(struct ecx_gen_ctx *gctx)
490 unsigned char *privkey;
494 if ((key = ecx_key_new(gctx->libctx, gctx->type, 0)) == NULL) {
495 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
499 /* If we're doing parameter generation then we just return a blank key */
500 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
503 if ((privkey = ecx_key_allocate_privkey(key)) == NULL) {
504 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
507 if (RAND_priv_bytes_ex(gctx->libctx, privkey, key->keylen) <= 0)
509 switch (gctx->type) {
510 case ECX_KEY_TYPE_X25519:
512 privkey[X25519_KEYLEN - 1] &= 127;
513 privkey[X25519_KEYLEN - 1] |= 64;
514 X25519_public_from_private(key->pubkey, privkey);
516 case ECX_KEY_TYPE_X448:
518 privkey[X448_KEYLEN - 1] |= 128;
519 X448_public_from_private(key->pubkey, privkey);
521 case ECX_KEY_TYPE_ED25519:
522 if (!ED25519_public_from_private(gctx->libctx, key->pubkey, privkey))
525 case ECX_KEY_TYPE_ED448:
526 if (!ED448_public_from_private(gctx->libctx, key->pubkey, privkey))
537 static void *x25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
539 struct ecx_gen_ctx *gctx = genctx;
542 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
543 return s390x_ecx_keygen25519(gctx);
545 return ecx_gen(gctx);
548 static void *x448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
550 struct ecx_gen_ctx *gctx = genctx;
553 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
554 return s390x_ecx_keygen448(gctx);
556 return ecx_gen(gctx);
559 static void *ed25519_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
561 struct ecx_gen_ctx *gctx = genctx;
563 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
564 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
565 && OPENSSL_s390xcap_P.kdsa[0]
566 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
567 return s390x_ecd_keygen25519(gctx);
569 return ecx_gen(gctx);
572 static void *ed448_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
574 struct ecx_gen_ctx *gctx = genctx;
577 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
578 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
579 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
580 return s390x_ecd_keygen448(gctx);
582 return ecx_gen(gctx);
585 static void ecx_gen_cleanup(void *genctx)
587 struct ecx_gen_ctx *gctx = genctx;
592 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
593 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
594 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
595 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
596 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
597 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
598 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
599 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
600 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
601 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
602 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
603 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
604 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
605 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
606 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
607 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
608 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
609 (void (*)(void))ecx_gen_settable_params }, \
610 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
611 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
615 MAKE_KEYMGMT_FUNCTIONS(x25519)
616 MAKE_KEYMGMT_FUNCTIONS(x448)
617 MAKE_KEYMGMT_FUNCTIONS(ed25519)
618 MAKE_KEYMGMT_FUNCTIONS(ed448)
621 # include "s390x_arch.h"
623 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx)
625 static const unsigned char generator[] = {
626 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
630 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X25519, 1);
631 unsigned char *privkey = NULL, *pubkey;
634 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
638 /* If we're doing parameter generation then we just return a blank key */
639 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
642 pubkey = key->pubkey;
644 privkey = ecx_key_allocate_privkey(key);
645 if (privkey == NULL) {
646 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
650 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X25519_KEYLEN) <= 0)
657 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
666 static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx)
668 static const unsigned char generator[] = {
669 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
675 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_X448, 1);
676 unsigned char *privkey = NULL, *pubkey;
679 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
683 /* If we're doing parameter generation then we just return a blank key */
684 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
687 pubkey = key->pubkey;
689 privkey = ecx_key_allocate_privkey(key);
690 if (privkey == NULL) {
691 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
695 if (RAND_priv_bytes_ex(gctx->libctx, privkey, X448_KEYLEN) <= 0)
701 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
710 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx)
712 static const unsigned char generator_x[] = {
713 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
714 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
715 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
717 static const unsigned char generator_y[] = {
718 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
719 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
720 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
722 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
723 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED25519, 1);
724 unsigned char *privkey = NULL, *pubkey;
730 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
734 /* If we're doing parameter generation then we just return a blank key */
735 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
738 pubkey = key->pubkey;
740 privkey = ecx_key_allocate_privkey(key);
741 if (privkey == NULL) {
742 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
746 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED25519_KEYLEN) <= 0)
749 sha = EVP_MD_fetch(gctx->libctx, "SHA512", NULL);
752 j = EVP_Digest(privkey, 32, buff, &sz, sha, NULL);
761 if (s390x_ed25519_mul(x_dst, pubkey,
762 generator_x, generator_y, buff) != 1)
765 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
773 static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx)
775 static const unsigned char generator_x[] = {
776 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
777 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
778 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
779 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
780 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
782 static const unsigned char generator_y[] = {
783 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
784 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
785 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
786 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
787 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
789 unsigned char x_dst[57], buff[114];
790 ECX_KEY *key = ecx_key_new(gctx->libctx, ECX_KEY_TYPE_ED448, 1);
791 unsigned char *privkey = NULL, *pubkey;
792 EVP_MD_CTX *hashctx = NULL;
793 EVP_MD *shake = NULL;
796 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
800 /* If we're doing parameter generation then we just return a blank key */
801 if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
804 pubkey = key->pubkey;
806 privkey = ecx_key_allocate_privkey(key);
807 if (privkey == NULL) {
808 ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
812 shake = EVP_MD_fetch(gctx->libctx, "SHAKE256", NULL);
815 if (RAND_priv_bytes_ex(gctx->libctx, privkey, ED448_KEYLEN) <= 0)
818 hashctx = EVP_MD_CTX_new();
821 if (EVP_DigestInit_ex(hashctx, shake, NULL) != 1)
823 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
825 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
832 if (s390x_ed448_mul(x_dst, pubkey,
833 generator_x, generator_y, buff) != 1)
836 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
837 EVP_MD_CTX_free(hashctx);
843 EVP_MD_CTX_free(hashctx);