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)
78 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
);
79 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
);
80 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
);
81 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
);
84 static void *x25519_new_key(void *provctx
)
86 if (!ossl_prov_is_running())
88 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_X25519
, 0,
92 static void *x448_new_key(void *provctx
)
94 if (!ossl_prov_is_running())
96 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_X448
, 0,
100 static void *ed25519_new_key(void *provctx
)
102 if (!ossl_prov_is_running())
104 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_ED25519
, 0,
108 static void *ed448_new_key(void *provctx
)
110 if (!ossl_prov_is_running())
112 return ecx_key_new(PROV_LIBRARY_CONTEXT_OF(provctx
), ECX_KEY_TYPE_ED448
, 0,
116 static int ecx_has(void *keydata
, int selection
)
118 ECX_KEY
*key
= keydata
;
121 if (ossl_prov_is_running() && key
!= NULL
) {
123 * ECX keys always have all the parameters they need (i.e. none).
124 * Therefore we always return with 1, if asked about parameters.
128 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
129 ok
= ok
&& key
->haspubkey
;
131 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
132 ok
= ok
&& key
->privkey
!= NULL
;
137 static int ecx_match(const void *keydata1
, const void *keydata2
, int selection
)
139 const ECX_KEY
*key1
= keydata1
;
140 const ECX_KEY
*key2
= keydata2
;
143 if (!ossl_prov_is_running())
146 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
147 ok
= ok
&& key1
->type
== key2
->type
;
148 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0) {
149 if ((key1
->privkey
== NULL
&& key2
->privkey
!= NULL
)
150 || (key1
->privkey
!= NULL
&& key2
->privkey
== NULL
)
151 || key1
->type
!= key2
->type
)
154 ok
= ok
&& (key1
->privkey
== NULL
/* implies key2->privkey == NULL */
155 || CRYPTO_memcmp(key1
->privkey
, key2
->privkey
,
158 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0) {
159 if (key1
->haspubkey
!= key2
->haspubkey
160 || key1
->type
!= key2
->type
)
163 ok
= ok
&& (key1
->haspubkey
== 0 /* implies key2->haspubkey == 0 */
164 || CRYPTO_memcmp(key1
->pubkey
, key2
->pubkey
,
170 static int ecx_import(void *keydata
, int selection
, const OSSL_PARAM params
[])
172 ECX_KEY
*key
= keydata
;
174 int include_private
= 0;
176 if (!ossl_prov_is_running() || key
== NULL
)
179 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
182 include_private
= ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0);
183 ok
= ok
&& ecx_key_fromdata(key
, params
, include_private
);
188 static int key_to_params(ECX_KEY
*key
, OSSL_PARAM_BLD
*tmpl
,
194 if (!ossl_param_build_set_octet_string(tmpl
, params
,
195 OSSL_PKEY_PARAM_PUB_KEY
,
196 key
->pubkey
, key
->keylen
))
199 if (key
->privkey
!= NULL
200 && !ossl_param_build_set_octet_string(tmpl
, params
,
201 OSSL_PKEY_PARAM_PRIV_KEY
,
202 key
->privkey
, key
->keylen
))
208 static int ecx_export(void *keydata
, int selection
, OSSL_CALLBACK
*param_cb
,
211 ECX_KEY
*key
= keydata
;
212 OSSL_PARAM_BLD
*tmpl
;
213 OSSL_PARAM
*params
= NULL
;
216 if (!ossl_prov_is_running() || key
== NULL
)
219 tmpl
= OSSL_PARAM_BLD_new();
223 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0
224 && !key_to_params(key
, tmpl
, NULL
))
227 params
= OSSL_PARAM_BLD_to_param(tmpl
);
231 ret
= param_cb(params
, cbarg
);
232 OSSL_PARAM_BLD_free_params(params
);
234 OSSL_PARAM_BLD_free(tmpl
);
238 #define ECX_KEY_TYPES() \
239 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
240 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
242 static const OSSL_PARAM ecx_key_types
[] = {
246 static const OSSL_PARAM
*ecx_imexport_types(int selection
)
248 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
249 return ecx_key_types
;
253 static int ecx_get_params(void *key
, OSSL_PARAM params
[], int bits
, int secbits
,
259 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_BITS
)) != NULL
260 && !OSSL_PARAM_set_int(p
, bits
))
262 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_SECURITY_BITS
)) != NULL
263 && !OSSL_PARAM_set_int(p
, secbits
))
265 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_MAX_SIZE
)) != NULL
266 && !OSSL_PARAM_set_int(p
, size
))
268 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_TLS_ENCODED_PT
)) != NULL
269 && (ecx
->type
== ECX_KEY_TYPE_X25519
270 || ecx
->type
== ECX_KEY_TYPE_X448
)) {
271 if (!OSSL_PARAM_set_octet_string(p
, ecx
->pubkey
, ecx
->keylen
))
275 return key_to_params(ecx
, NULL
, params
);
278 static int ed_get_params(void *key
, OSSL_PARAM params
[])
282 if ((p
= OSSL_PARAM_locate(params
,
283 OSSL_PKEY_PARAM_MANDATORY_DIGEST
)) != NULL
284 && !OSSL_PARAM_set_utf8_string(p
, ""))
289 static int x25519_get_params(void *key
, OSSL_PARAM params
[])
291 return ecx_get_params(key
, params
, X25519_BITS
, X25519_SECURITY_BITS
,
295 static int x448_get_params(void *key
, OSSL_PARAM params
[])
297 return ecx_get_params(key
, params
, X448_BITS
, X448_SECURITY_BITS
,
301 static int ed25519_get_params(void *key
, OSSL_PARAM params
[])
303 return ecx_get_params(key
, params
, ED25519_BITS
, ED25519_SECURITY_BITS
,
305 && ed_get_params(key
, params
);
308 static int ed448_get_params(void *key
, OSSL_PARAM params
[])
310 return ecx_get_params(key
, params
, ED448_BITS
, ED448_SECURITY_BITS
,
312 && ed_get_params(key
, params
);
315 static const OSSL_PARAM ecx_gettable_params
[] = {
316 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
317 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
318 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
319 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST
, NULL
, 0),
320 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT
, NULL
, 0),
325 static const OSSL_PARAM ed_gettable_params
[] = {
326 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
327 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
328 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
333 static const OSSL_PARAM
*x25519_gettable_params(void *provctx
)
335 return ecx_gettable_params
;
338 static const OSSL_PARAM
*x448_gettable_params(void *provctx
)
340 return ecx_gettable_params
;
343 static const OSSL_PARAM
*ed25519_gettable_params(void *provctx
)
345 return ed_gettable_params
;
348 static const OSSL_PARAM
*ed448_gettable_params(void *provctx
)
350 return ed_gettable_params
;
353 static int set_property_query(ECX_KEY
*ecxkey
, const char *propq
)
355 OPENSSL_free(ecxkey
->propq
);
356 ecxkey
->propq
= NULL
;
358 ecxkey
->propq
= OPENSSL_strdup(propq
);
359 if (ecxkey
->propq
== NULL
) {
360 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
367 static int ecx_set_params(void *key
, const OSSL_PARAM params
[])
369 ECX_KEY
*ecxkey
= key
;
372 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_TLS_ENCODED_PT
);
374 void *buf
= ecxkey
->pubkey
;
376 if (p
->data_size
!= ecxkey
->keylen
377 || !OSSL_PARAM_get_octet_string(p
, &buf
, sizeof(ecxkey
->pubkey
),
380 OPENSSL_clear_free(ecxkey
->privkey
, ecxkey
->keylen
);
381 ecxkey
->privkey
= NULL
;
382 ecxkey
->haspubkey
= 1;
384 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PROPERTIES
);
386 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
387 || !set_property_query(ecxkey
, p
->data
))
394 static int x25519_set_params(void *key
, const OSSL_PARAM params
[])
396 return ecx_set_params(key
, params
);
399 static int x448_set_params(void *key
, const OSSL_PARAM params
[])
401 return ecx_set_params(key
, params
);
404 static int ed25519_set_params(void *key
, const OSSL_PARAM params
[])
409 static int ed448_set_params(void *key
, const OSSL_PARAM params
[])
414 static const OSSL_PARAM ecx_settable_params
[] = {
415 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT
, NULL
, 0),
416 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES
, NULL
, 0),
420 static const OSSL_PARAM ed_settable_params
[] = {
424 static const OSSL_PARAM
*x25519_settable_params(void *provctx
)
426 return ecx_settable_params
;
429 static const OSSL_PARAM
*x448_settable_params(void *provctx
)
431 return ecx_settable_params
;
434 static const OSSL_PARAM
*ed25519_settable_params(void *provctx
)
436 return ed_settable_params
;
439 static const OSSL_PARAM
*ed448_settable_params(void *provctx
)
441 return ed_settable_params
;
444 static void *ecx_gen_init(void *provctx
, int selection
, ECX_KEY_TYPE type
)
446 OSSL_LIB_CTX
*libctx
= PROV_LIBRARY_CONTEXT_OF(provctx
);
447 struct ecx_gen_ctx
*gctx
= NULL
;
449 if (!ossl_prov_is_running())
452 if ((gctx
= OPENSSL_zalloc(sizeof(*gctx
))) != NULL
) {
453 gctx
->libctx
= libctx
;
455 gctx
->selection
= selection
;
460 static void *x25519_gen_init(void *provctx
, int selection
)
462 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X25519
);
465 static void *x448_gen_init(void *provctx
, int selection
)
467 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X448
);
470 static void *ed25519_gen_init(void *provctx
, int selection
)
472 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED25519
);
475 static void *ed448_gen_init(void *provctx
, int selection
)
477 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED448
);
480 static int ecx_gen_set_params(void *genctx
, const OSSL_PARAM params
[])
482 struct ecx_gen_ctx
*gctx
= genctx
;
488 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_GROUP_NAME
);
490 const char *groupname
= NULL
;
493 * We optionally allow setting a group name - but each algorithm only
494 * support one such name, so all we do is verify that it is the one we
497 switch (gctx
->type
) {
498 case ECX_KEY_TYPE_X25519
:
499 groupname
= "x25519";
501 case ECX_KEY_TYPE_X448
:
505 /* We only support this for key exchange at the moment */
508 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
510 || strcasecmp(p
->data
, groupname
) != 0) {
511 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
515 p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PROPERTIES
);
517 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
519 OPENSSL_free(gctx
->propq
);
520 gctx
->propq
= OPENSSL_strdup(p
->data
);
521 if (gctx
->propq
== NULL
)
528 static const OSSL_PARAM
*ecx_gen_settable_params(void *provctx
)
530 static OSSL_PARAM settable
[] = {
531 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
, NULL
, 0),
532 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
538 static void *ecx_gen(struct ecx_gen_ctx
*gctx
)
541 unsigned char *privkey
;
545 if ((key
= ecx_key_new(gctx
->libctx
, gctx
->type
, 0, gctx
->propq
)) == NULL
) {
546 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
550 /* If we're doing parameter generation then we just return a blank key */
551 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
554 if ((privkey
= ecx_key_allocate_privkey(key
)) == NULL
) {
555 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
558 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, key
->keylen
) <= 0)
560 switch (gctx
->type
) {
561 case ECX_KEY_TYPE_X25519
:
563 privkey
[X25519_KEYLEN
- 1] &= 127;
564 privkey
[X25519_KEYLEN
- 1] |= 64;
565 X25519_public_from_private(key
->pubkey
, privkey
);
567 case ECX_KEY_TYPE_X448
:
569 privkey
[X448_KEYLEN
- 1] |= 128;
570 X448_public_from_private(key
->pubkey
, privkey
);
572 case ECX_KEY_TYPE_ED25519
:
573 if (!ED25519_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
577 case ECX_KEY_TYPE_ED448
:
578 if (!ED448_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
590 static void *x25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
592 struct ecx_gen_ctx
*gctx
= genctx
;
594 if (!ossl_prov_is_running())
598 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519
))
599 return s390x_ecx_keygen25519(gctx
);
601 return ecx_gen(gctx
);
604 static void *x448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
606 struct ecx_gen_ctx
*gctx
= genctx
;
608 if (!ossl_prov_is_running())
612 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448
))
613 return s390x_ecx_keygen448(gctx
);
615 return ecx_gen(gctx
);
618 static void *ed25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
620 struct ecx_gen_ctx
*gctx
= genctx
;
622 if (!ossl_prov_is_running())
626 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519
)
627 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519
)
628 && OPENSSL_s390xcap_P
.kdsa
[0]
629 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519
))
630 return s390x_ecd_keygen25519(gctx
);
632 return ecx_gen(gctx
);
635 static void *ed448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
637 struct ecx_gen_ctx
*gctx
= genctx
;
639 if (!ossl_prov_is_running())
643 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448
)
644 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448
)
645 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448
))
646 return s390x_ecd_keygen448(gctx
);
648 return ecx_gen(gctx
);
651 static void ecx_gen_cleanup(void *genctx
)
653 struct ecx_gen_ctx
*gctx
= genctx
;
655 OPENSSL_free(gctx
->propq
);
659 void *ecx_load(const void *reference
, size_t reference_sz
)
663 if (ossl_prov_is_running() && reference_sz
== sizeof(key
)) {
664 /* The contents of the reference is the address to our object */
665 key
= *(ECX_KEY
**)reference
;
666 /* We grabbed, so we detach it */
667 *(ECX_KEY
**)reference
= NULL
;
673 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
674 const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
675 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
676 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
677 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
678 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
679 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
680 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
681 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
682 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
683 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
684 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
685 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
686 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
687 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
688 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
689 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
690 (void (*)(void))ecx_gen_settable_params }, \
691 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
692 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
693 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
697 MAKE_KEYMGMT_FUNCTIONS(x25519
)
698 MAKE_KEYMGMT_FUNCTIONS(x448
)
699 MAKE_KEYMGMT_FUNCTIONS(ed25519
)
700 MAKE_KEYMGMT_FUNCTIONS(ed448
)
703 # include "s390x_arch.h"
705 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
)
707 static const unsigned char generator
[] = {
708 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
712 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X25519
, 1, gctx
->propq
);
713 unsigned char *privkey
= NULL
, *pubkey
;
716 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
720 /* If we're doing parameter generation then we just return a blank key */
721 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
724 pubkey
= key
->pubkey
;
726 privkey
= ecx_key_allocate_privkey(key
);
727 if (privkey
== NULL
) {
728 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
732 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X25519_KEYLEN
) <= 0)
739 if (s390x_x25519_mul(pubkey
, generator
, privkey
) != 1)
748 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
)
750 static const unsigned char generator
[] = {
751 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
757 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X448
, 1, gctx
->propq
);
758 unsigned char *privkey
= NULL
, *pubkey
;
761 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
765 /* If we're doing parameter generation then we just return a blank key */
766 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
769 pubkey
= key
->pubkey
;
771 privkey
= ecx_key_allocate_privkey(key
);
772 if (privkey
== NULL
) {
773 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
777 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X448_KEYLEN
) <= 0)
783 if (s390x_x448_mul(pubkey
, generator
, privkey
) != 1)
792 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
)
794 static const unsigned char generator_x
[] = {
795 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
796 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
797 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
799 static const unsigned char generator_y
[] = {
800 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
801 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
802 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
804 unsigned char x_dst
[32], buff
[SHA512_DIGEST_LENGTH
];
805 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED25519
, 1, gctx
->propq
);
806 unsigned char *privkey
= NULL
, *pubkey
;
812 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
816 /* If we're doing parameter generation then we just return a blank key */
817 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
820 pubkey
= key
->pubkey
;
822 privkey
= ecx_key_allocate_privkey(key
);
823 if (privkey
== NULL
) {
824 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
828 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED25519_KEYLEN
) <= 0)
831 sha
= EVP_MD_fetch(gctx
->libctx
, "SHA512", gctx
->propq
);
834 j
= EVP_Digest(privkey
, 32, buff
, &sz
, sha
, NULL
);
843 if (s390x_ed25519_mul(x_dst
, pubkey
,
844 generator_x
, generator_y
, buff
) != 1)
847 pubkey
[31] |= ((x_dst
[0] & 0x01) << 7);
855 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
)
857 static const unsigned char generator_x
[] = {
858 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
859 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
860 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
861 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
862 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
864 static const unsigned char generator_y
[] = {
865 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
866 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
867 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
868 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
869 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
871 unsigned char x_dst
[57], buff
[114];
872 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED448
, 1, gctx
->propq
);
873 unsigned char *privkey
= NULL
, *pubkey
;
874 EVP_MD_CTX
*hashctx
= NULL
;
875 EVP_MD
*shake
= NULL
;
878 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
882 /* If we're doing parameter generation then we just return a blank key */
883 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
886 pubkey
= key
->pubkey
;
888 privkey
= ecx_key_allocate_privkey(key
);
889 if (privkey
== NULL
) {
890 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
894 shake
= EVP_MD_fetch(gctx
->libctx
, "SHAKE256", gctx
->propq
);
897 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED448_KEYLEN
) <= 0)
900 hashctx
= EVP_MD_CTX_new();
903 if (EVP_DigestInit_ex(hashctx
, shake
, NULL
) != 1)
905 if (EVP_DigestUpdate(hashctx
, privkey
, 57) != 1)
907 if (EVP_DigestFinalXOF(hashctx
, buff
, sizeof(buff
)) != 1)
914 if (s390x_ed448_mul(x_dst
, pubkey
,
915 generator_x
, generator_y
, buff
) != 1)
918 pubkey
[56] |= ((x_dst
[0] & 0x01) << 7);
919 EVP_MD_CTX_free(hashctx
);
925 EVP_MD_CTX_free(hashctx
);