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_dispatch.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_FUNC_keymgmt_new_fn x25519_new_key
;
32 static OSSL_FUNC_keymgmt_new_fn x448_new_key
;
33 static OSSL_FUNC_keymgmt_new_fn ed25519_new_key
;
34 static OSSL_FUNC_keymgmt_new_fn ed448_new_key
;
35 static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init
;
36 static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init
;
37 static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init
;
38 static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init
;
39 static OSSL_FUNC_keymgmt_gen_fn x25519_gen
;
40 static OSSL_FUNC_keymgmt_gen_fn x448_gen
;
41 static OSSL_FUNC_keymgmt_gen_fn ed25519_gen
;
42 static OSSL_FUNC_keymgmt_gen_fn ed448_gen
;
43 static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup
;
44 static OSSL_FUNC_keymgmt_load_fn ecx_load
;
45 static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params
;
46 static OSSL_FUNC_keymgmt_get_params_fn x448_get_params
;
47 static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params
;
48 static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params
;
49 static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params
;
50 static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params
;
51 static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params
;
52 static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params
;
53 static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params
;
54 static OSSL_FUNC_keymgmt_set_params_fn x448_set_params
;
55 static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params
;
56 static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params
;
57 static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params
;
58 static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params
;
59 static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params
;
60 static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params
;
61 static OSSL_FUNC_keymgmt_has_fn ecx_has
;
62 static OSSL_FUNC_keymgmt_match_fn ecx_match
;
63 static OSSL_FUNC_keymgmt_import_fn ecx_import
;
64 static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types
;
65 static OSSL_FUNC_keymgmt_export_fn ecx_export
;
66 static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types
;
68 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
77 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
);
78 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
);
79 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
);
80 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
);
83 static void *x25519_new_key(void *provctx
)
85 if (!ossl_prov_is_running())
87 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_X25519
, 0);
90 static void *x448_new_key(void *provctx
)
92 if (!ossl_prov_is_running())
94 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_X448
, 0);
97 static void *ed25519_new_key(void *provctx
)
99 if (!ossl_prov_is_running())
101 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_ED25519
, 0);
104 static void *ed448_new_key(void *provctx
)
106 if (!ossl_prov_is_running())
108 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_ED448
, 0);
111 static int ecx_has(void *keydata
, int selection
)
113 ECX_KEY
*key
= keydata
;
116 if (ossl_prov_is_running() && key
!= NULL
) {
118 * ECX keys always have all the parameters they need (i.e. none).
119 * Therefore we always return with 1, if asked about parameters.
123 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
124 ok
= ok
&& key
->haspubkey
;
126 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
127 ok
= ok
&& key
->privkey
!= NULL
;
132 static int ecx_match(const void *keydata1
, const void *keydata2
, int selection
)
134 const ECX_KEY
*key1
= keydata1
;
135 const ECX_KEY
*key2
= keydata2
;
138 if (!ossl_prov_is_running())
141 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
142 ok
= ok
&& key1
->type
== key2
->type
;
143 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0) {
144 if ((key1
->privkey
== NULL
&& key2
->privkey
!= NULL
)
145 || (key1
->privkey
!= NULL
&& key2
->privkey
== NULL
)
146 || key1
->type
!= key2
->type
)
149 ok
= ok
&& (key1
->privkey
== NULL
/* implies key2->privkey == NULL */
150 || CRYPTO_memcmp(key1
->privkey
, key2
->privkey
,
153 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0) {
154 if (key1
->haspubkey
!= key2
->haspubkey
155 || key1
->type
!= key2
->type
)
158 ok
= ok
&& (key1
->haspubkey
== 0 /* implies key2->haspubkey == 0 */
159 || CRYPTO_memcmp(key1
->pubkey
, key2
->pubkey
,
165 static int ecx_import(void *keydata
, int selection
, const OSSL_PARAM params
[])
167 ECX_KEY
*key
= keydata
;
169 int include_private
= 0;
171 if (!ossl_prov_is_running() || key
== NULL
)
174 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
177 include_private
= ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0);
178 ok
= ok
&& ecx_key_fromdata(key
, params
, include_private
);
183 static int key_to_params(ECX_KEY
*key
, OSSL_PARAM_BLD
*tmpl
,
189 if (!ossl_param_build_set_octet_string(tmpl
, params
,
190 OSSL_PKEY_PARAM_PUB_KEY
,
191 key
->pubkey
, key
->keylen
))
194 if (key
->privkey
!= NULL
195 && !ossl_param_build_set_octet_string(tmpl
, params
,
196 OSSL_PKEY_PARAM_PRIV_KEY
,
197 key
->privkey
, key
->keylen
))
203 static int ecx_export(void *keydata
, int selection
, OSSL_CALLBACK
*param_cb
,
206 ECX_KEY
*key
= keydata
;
207 OSSL_PARAM_BLD
*tmpl
;
208 OSSL_PARAM
*params
= NULL
;
211 if (!ossl_prov_is_running() || key
== NULL
)
214 tmpl
= OSSL_PARAM_BLD_new();
218 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0
219 && !key_to_params(key
, tmpl
, NULL
))
222 params
= OSSL_PARAM_BLD_to_param(tmpl
);
226 ret
= param_cb(params
, cbarg
);
227 OSSL_PARAM_BLD_free_params(params
);
229 OSSL_PARAM_BLD_free(tmpl
);
233 #define ECX_KEY_TYPES() \
234 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
235 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
237 static const OSSL_PARAM ecx_key_types
[] = {
241 static const OSSL_PARAM
*ecx_imexport_types(int selection
)
243 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
244 return ecx_key_types
;
248 static int ecx_get_params(void *key
, OSSL_PARAM params
[], int bits
, int secbits
,
254 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_BITS
)) != NULL
255 && !OSSL_PARAM_set_int(p
, bits
))
257 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_SECURITY_BITS
)) != NULL
258 && !OSSL_PARAM_set_int(p
, secbits
))
260 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_MAX_SIZE
)) != NULL
261 && !OSSL_PARAM_set_int(p
, size
))
263 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_TLS_ENCODED_PT
)) != NULL
264 && (ecx
->type
== ECX_KEY_TYPE_X25519
265 || ecx
->type
== ECX_KEY_TYPE_X448
)) {
266 if (!OSSL_PARAM_set_octet_string(p
, ecx
->pubkey
, ecx
->keylen
))
270 return key_to_params(ecx
, NULL
, params
);
273 static int ed_get_params(void *key
, OSSL_PARAM params
[])
277 if ((p
= OSSL_PARAM_locate(params
,
278 OSSL_PKEY_PARAM_MANDATORY_DIGEST
)) != NULL
279 && !OSSL_PARAM_set_utf8_string(p
, ""))
284 static int x25519_get_params(void *key
, OSSL_PARAM params
[])
286 return ecx_get_params(key
, params
, X25519_BITS
, X25519_SECURITY_BITS
,
290 static int x448_get_params(void *key
, OSSL_PARAM params
[])
292 return ecx_get_params(key
, params
, X448_BITS
, X448_SECURITY_BITS
,
296 static int ed25519_get_params(void *key
, OSSL_PARAM params
[])
298 return ecx_get_params(key
, params
, ED25519_BITS
, ED25519_SECURITY_BITS
,
300 && ed_get_params(key
, params
);
303 static int ed448_get_params(void *key
, OSSL_PARAM params
[])
305 return ecx_get_params(key
, params
, ED448_BITS
, ED448_SECURITY_BITS
,
307 && ed_get_params(key
, params
);
310 static const OSSL_PARAM ecx_gettable_params
[] = {
311 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
312 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
313 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
314 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST
, NULL
, 0),
315 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT
, NULL
, 0),
320 static const OSSL_PARAM ed_gettable_params
[] = {
321 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
322 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
323 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
328 static const OSSL_PARAM
*x25519_gettable_params(void *provctx
)
330 return ecx_gettable_params
;
333 static const OSSL_PARAM
*x448_gettable_params(void *provctx
)
335 return ecx_gettable_params
;
338 static const OSSL_PARAM
*ed25519_gettable_params(void *provctx
)
340 return ed_gettable_params
;
343 static const OSSL_PARAM
*ed448_gettable_params(void *provctx
)
345 return ed_gettable_params
;
348 static int ecx_set_params(void *key
, const OSSL_PARAM params
[])
350 ECX_KEY
*ecxkey
= key
;
353 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_TLS_ENCODED_PT
);
355 void *buf
= ecxkey
->pubkey
;
357 if (p
->data_size
!= ecxkey
->keylen
358 || !OSSL_PARAM_get_octet_string(p
, &buf
, sizeof(ecxkey
->pubkey
),
361 OPENSSL_clear_free(ecxkey
->privkey
, ecxkey
->keylen
);
362 ecxkey
->privkey
= NULL
;
363 ecxkey
->haspubkey
= 1;
369 static int x25519_set_params(void *key
, const OSSL_PARAM params
[])
371 return ecx_set_params(key
, params
);
374 static int x448_set_params(void *key
, const OSSL_PARAM params
[])
376 return ecx_set_params(key
, params
);
379 static int ed25519_set_params(void *key
, const OSSL_PARAM params
[])
384 static int ed448_set_params(void *key
, const OSSL_PARAM params
[])
389 static const OSSL_PARAM ecx_settable_params
[] = {
390 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT
, NULL
, 0),
394 static const OSSL_PARAM ed_settable_params
[] = {
398 static const OSSL_PARAM
*x25519_settable_params(void *provctx
)
400 return ecx_settable_params
;
403 static const OSSL_PARAM
*x448_settable_params(void *provctx
)
405 return ecx_settable_params
;
408 static const OSSL_PARAM
*ed25519_settable_params(void *provctx
)
410 return ed_settable_params
;
413 static const OSSL_PARAM
*ed448_settable_params(void *provctx
)
415 return ed_settable_params
;
418 static void *ecx_gen_init(void *provctx
, int selection
, ECX_KEY_TYPE type
)
420 OPENSSL_CTX
*libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
);
421 struct ecx_gen_ctx
*gctx
= NULL
;
423 if (!ossl_prov_is_running())
426 if ((gctx
= OPENSSL_malloc(sizeof(*gctx
))) != NULL
) {
427 gctx
->libctx
= libctx
;
429 gctx
->selection
= selection
;
434 static void *x25519_gen_init(void *provctx
, int selection
)
436 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X25519
);
439 static void *x448_gen_init(void *provctx
, int selection
)
441 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X448
);
444 static void *ed25519_gen_init(void *provctx
, int selection
)
446 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED25519
);
449 static void *ed448_gen_init(void *provctx
, int selection
)
451 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED448
);
454 static int ecx_gen_set_params(void *genctx
, const OSSL_PARAM params
[])
456 struct ecx_gen_ctx
*gctx
= genctx
;
462 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_GROUP_NAME
);
464 const char *groupname
= NULL
;
467 * We optionally allow setting a group name - but each algorithm only
468 * support one such name, so all we do is verify that it is the one we
471 switch (gctx
->type
) {
472 case ECX_KEY_TYPE_X25519
:
473 groupname
= "x25519";
475 case ECX_KEY_TYPE_X448
:
479 /* We only support this for key exchange at the moment */
482 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
484 || strcasecmp(p
->data
, groupname
) != 0) {
485 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
493 static const OSSL_PARAM
*ecx_gen_settable_params(void *provctx
)
495 static OSSL_PARAM settable
[] = {
496 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
, NULL
, 0),
502 static void *ecx_gen(struct ecx_gen_ctx
*gctx
)
505 unsigned char *privkey
;
509 if ((key
= ecx_key_new(gctx
->libctx
, gctx
->type
, 0)) == NULL
) {
510 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
514 /* If we're doing parameter generation then we just return a blank key */
515 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
518 if ((privkey
= ecx_key_allocate_privkey(key
)) == NULL
) {
519 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
522 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, key
->keylen
) <= 0)
524 switch (gctx
->type
) {
525 case ECX_KEY_TYPE_X25519
:
527 privkey
[X25519_KEYLEN
- 1] &= 127;
528 privkey
[X25519_KEYLEN
- 1] |= 64;
529 X25519_public_from_private(key
->pubkey
, privkey
);
531 case ECX_KEY_TYPE_X448
:
533 privkey
[X448_KEYLEN
- 1] |= 128;
534 X448_public_from_private(key
->pubkey
, privkey
);
536 case ECX_KEY_TYPE_ED25519
:
537 if (!ED25519_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
))
540 case ECX_KEY_TYPE_ED448
:
541 if (!ED448_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
))
552 static void *x25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
554 struct ecx_gen_ctx
*gctx
= genctx
;
556 if (!ossl_prov_is_running())
560 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519
))
561 return s390x_ecx_keygen25519(gctx
);
563 return ecx_gen(gctx
);
566 static void *x448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
568 struct ecx_gen_ctx
*gctx
= genctx
;
570 if (!ossl_prov_is_running())
574 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448
))
575 return s390x_ecx_keygen448(gctx
);
577 return ecx_gen(gctx
);
580 static void *ed25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
582 struct ecx_gen_ctx
*gctx
= genctx
;
584 if (!ossl_prov_is_running())
588 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519
)
589 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519
)
590 && OPENSSL_s390xcap_P
.kdsa
[0]
591 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519
))
592 return s390x_ecd_keygen25519(gctx
);
594 return ecx_gen(gctx
);
597 static void *ed448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
599 struct ecx_gen_ctx
*gctx
= genctx
;
601 if (!ossl_prov_is_running())
605 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448
)
606 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448
)
607 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448
))
608 return s390x_ecd_keygen448(gctx
);
610 return ecx_gen(gctx
);
613 static void ecx_gen_cleanup(void *genctx
)
615 struct ecx_gen_ctx
*gctx
= genctx
;
620 void *ecx_load(const void *reference
, size_t reference_sz
)
624 if (ossl_prov_is_running() && reference_sz
== sizeof(key
)) {
625 /* The contents of the reference is the address to our object */
626 key
= *(ECX_KEY
**)reference
;
627 /* We grabbed, so we detach it */
628 *(ECX_KEY
**)reference
= NULL
;
634 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
635 const OSSL_DISPATCH alg##_keymgmt_functions[] = { \
636 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
637 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
638 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
639 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
640 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
641 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
642 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
643 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
644 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
645 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
646 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
647 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
648 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
649 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
650 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
651 (void (*)(void))ecx_gen_settable_params }, \
652 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
653 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
654 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
658 MAKE_KEYMGMT_FUNCTIONS(x25519
)
659 MAKE_KEYMGMT_FUNCTIONS(x448
)
660 MAKE_KEYMGMT_FUNCTIONS(ed25519
)
661 MAKE_KEYMGMT_FUNCTIONS(ed448
)
664 # include "s390x_arch.h"
666 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
)
668 static const unsigned char generator
[] = {
669 0x09, 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
673 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X25519
, 1);
674 unsigned char *privkey
= NULL
, *pubkey
;
677 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
681 /* If we're doing parameter generation then we just return a blank key */
682 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
685 pubkey
= key
->pubkey
;
687 privkey
= ecx_key_allocate_privkey(key
);
688 if (privkey
== NULL
) {
689 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
693 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X25519_KEYLEN
) <= 0)
700 if (s390x_x25519_mul(pubkey
, generator
, privkey
) != 1)
709 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
)
711 static const unsigned char generator
[] = {
712 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
718 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X448
, 1);
719 unsigned char *privkey
= NULL
, *pubkey
;
722 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
726 /* If we're doing parameter generation then we just return a blank key */
727 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
730 pubkey
= key
->pubkey
;
732 privkey
= ecx_key_allocate_privkey(key
);
733 if (privkey
== NULL
) {
734 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
738 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X448_KEYLEN
) <= 0)
744 if (s390x_x448_mul(pubkey
, generator
, privkey
) != 1)
753 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
)
755 static const unsigned char generator_x
[] = {
756 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
757 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
758 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
760 static const unsigned char generator_y
[] = {
761 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
762 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
763 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
765 unsigned char x_dst
[32], buff
[SHA512_DIGEST_LENGTH
];
766 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED25519
, 1);
767 unsigned char *privkey
= NULL
, *pubkey
;
773 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
777 /* If we're doing parameter generation then we just return a blank key */
778 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
781 pubkey
= key
->pubkey
;
783 privkey
= ecx_key_allocate_privkey(key
);
784 if (privkey
== NULL
) {
785 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
789 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED25519_KEYLEN
) <= 0)
792 sha
= EVP_MD_fetch(gctx
->libctx
, "SHA512", NULL
);
795 j
= EVP_Digest(privkey
, 32, buff
, &sz
, sha
, NULL
);
804 if (s390x_ed25519_mul(x_dst
, pubkey
,
805 generator_x
, generator_y
, buff
) != 1)
808 pubkey
[31] |= ((x_dst
[0] & 0x01) << 7);
816 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
)
818 static const unsigned char generator_x
[] = {
819 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
820 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
821 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
822 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
823 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
825 static const unsigned char generator_y
[] = {
826 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
827 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
828 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
829 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
830 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
832 unsigned char x_dst
[57], buff
[114];
833 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED448
, 1);
834 unsigned char *privkey
= NULL
, *pubkey
;
835 EVP_MD_CTX
*hashctx
= NULL
;
836 EVP_MD
*shake
= NULL
;
839 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
843 /* If we're doing parameter generation then we just return a blank key */
844 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
847 pubkey
= key
->pubkey
;
849 privkey
= ecx_key_allocate_privkey(key
);
850 if (privkey
== NULL
) {
851 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
855 shake
= EVP_MD_fetch(gctx
->libctx
, "SHAKE256", NULL
);
858 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED448_KEYLEN
) <= 0)
861 hashctx
= EVP_MD_CTX_new();
864 if (EVP_DigestInit_ex(hashctx
, shake
, NULL
) != 1)
866 if (EVP_DigestUpdate(hashctx
, privkey
, 57) != 1)
868 if (EVP_DigestFinalXOF(hashctx
, buff
, sizeof(buff
)) != 1)
875 if (s390x_ed448_mul(x_dst
, pubkey
,
876 generator_x
, generator_y
, buff
) != 1)
879 pubkey
[56] |= ((x_dst
[0] & 0x01) << 7);
880 EVP_MD_CTX_free(hashctx
);
886 EVP_MD_CTX_free(hashctx
);