2 * Copyright 2020-2021 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_validate_fn x25519_validate
;
64 static OSSL_FUNC_keymgmt_validate_fn x448_validate
;
65 static OSSL_FUNC_keymgmt_validate_fn ed25519_validate
;
66 static OSSL_FUNC_keymgmt_validate_fn ed448_validate
;
67 static OSSL_FUNC_keymgmt_import_fn ecx_import
;
68 static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types
;
69 static OSSL_FUNC_keymgmt_export_fn ecx_export
;
70 static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types
;
72 #define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
82 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
);
83 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
);
84 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
);
85 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
);
88 static void *x25519_new_key(void *provctx
)
90 if (!ossl_prov_is_running())
92 return ecx_key_new(PROV_LIBCTX_OF(provctx
), ECX_KEY_TYPE_X25519
, 0,
96 static void *x448_new_key(void *provctx
)
98 if (!ossl_prov_is_running())
100 return ecx_key_new(PROV_LIBCTX_OF(provctx
), ECX_KEY_TYPE_X448
, 0,
104 static void *ed25519_new_key(void *provctx
)
106 if (!ossl_prov_is_running())
108 return ecx_key_new(PROV_LIBCTX_OF(provctx
), ECX_KEY_TYPE_ED25519
, 0,
112 static void *ed448_new_key(void *provctx
)
114 if (!ossl_prov_is_running())
116 return ecx_key_new(PROV_LIBCTX_OF(provctx
), ECX_KEY_TYPE_ED448
, 0,
120 static int ecx_has(const void *keydata
, int selection
)
122 const ECX_KEY
*key
= keydata
;
125 if (ossl_prov_is_running() && key
!= NULL
) {
127 * ECX keys always have all the parameters they need (i.e. none).
128 * Therefore we always return with 1, if asked about parameters.
132 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
133 ok
= ok
&& key
->haspubkey
;
135 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
136 ok
= ok
&& key
->privkey
!= NULL
;
141 static int ecx_match(const void *keydata1
, const void *keydata2
, int selection
)
143 const ECX_KEY
*key1
= keydata1
;
144 const ECX_KEY
*key2
= keydata2
;
147 if (!ossl_prov_is_running())
150 if ((selection
& OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
) != 0)
151 ok
= ok
&& key1
->type
== key2
->type
;
152 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0) {
153 if ((key1
->privkey
== NULL
&& key2
->privkey
!= NULL
)
154 || (key1
->privkey
!= NULL
&& key2
->privkey
== NULL
)
155 || key1
->type
!= key2
->type
)
158 ok
= ok
&& (key1
->privkey
== NULL
/* implies key2->privkey == NULL */
159 || CRYPTO_memcmp(key1
->privkey
, key2
->privkey
,
162 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0) {
163 if (key1
->haspubkey
!= key2
->haspubkey
164 || key1
->type
!= key2
->type
)
167 ok
= ok
&& (key1
->haspubkey
== 0 /* implies key2->haspubkey == 0 */
168 || CRYPTO_memcmp(key1
->pubkey
, key2
->pubkey
,
174 static int ecx_import(void *keydata
, int selection
, const OSSL_PARAM params
[])
176 ECX_KEY
*key
= keydata
;
178 int include_private
= 0;
180 if (!ossl_prov_is_running() || key
== NULL
)
183 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
186 include_private
= ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0);
187 ok
= ok
&& ecx_key_fromdata(key
, params
, include_private
);
192 static int key_to_params(ECX_KEY
*key
, OSSL_PARAM_BLD
*tmpl
,
198 if (!ossl_param_build_set_octet_string(tmpl
, params
,
199 OSSL_PKEY_PARAM_PUB_KEY
,
200 key
->pubkey
, key
->keylen
))
203 if (key
->privkey
!= NULL
204 && !ossl_param_build_set_octet_string(tmpl
, params
,
205 OSSL_PKEY_PARAM_PRIV_KEY
,
206 key
->privkey
, key
->keylen
))
212 static int ecx_export(void *keydata
, int selection
, OSSL_CALLBACK
*param_cb
,
215 ECX_KEY
*key
= keydata
;
216 OSSL_PARAM_BLD
*tmpl
;
217 OSSL_PARAM
*params
= NULL
;
220 if (!ossl_prov_is_running() || key
== NULL
)
223 tmpl
= OSSL_PARAM_BLD_new();
227 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0
228 && !key_to_params(key
, tmpl
, NULL
))
231 params
= OSSL_PARAM_BLD_to_param(tmpl
);
235 ret
= param_cb(params
, cbarg
);
236 OSSL_PARAM_BLD_free_params(params
);
238 OSSL_PARAM_BLD_free(tmpl
);
242 #define ECX_KEY_TYPES() \
243 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
244 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
246 static const OSSL_PARAM ecx_key_types
[] = {
250 static const OSSL_PARAM
*ecx_imexport_types(int selection
)
252 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) != 0)
253 return ecx_key_types
;
257 static int ecx_get_params(void *key
, OSSL_PARAM params
[], int bits
, int secbits
,
263 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_BITS
)) != NULL
264 && !OSSL_PARAM_set_int(p
, bits
))
266 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_SECURITY_BITS
)) != NULL
267 && !OSSL_PARAM_set_int(p
, secbits
))
269 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_MAX_SIZE
)) != NULL
270 && !OSSL_PARAM_set_int(p
, size
))
272 if ((p
= OSSL_PARAM_locate(params
, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
)) != NULL
273 && (ecx
->type
== ECX_KEY_TYPE_X25519
274 || ecx
->type
== ECX_KEY_TYPE_X448
)) {
275 if (!OSSL_PARAM_set_octet_string(p
, ecx
->pubkey
, ecx
->keylen
))
279 return key_to_params(ecx
, NULL
, params
);
282 static int ed_get_params(void *key
, OSSL_PARAM params
[])
286 if ((p
= OSSL_PARAM_locate(params
,
287 OSSL_PKEY_PARAM_MANDATORY_DIGEST
)) != NULL
288 && !OSSL_PARAM_set_utf8_string(p
, ""))
293 static int x25519_get_params(void *key
, OSSL_PARAM params
[])
295 return ecx_get_params(key
, params
, X25519_BITS
, X25519_SECURITY_BITS
,
299 static int x448_get_params(void *key
, OSSL_PARAM params
[])
301 return ecx_get_params(key
, params
, X448_BITS
, X448_SECURITY_BITS
,
305 static int ed25519_get_params(void *key
, OSSL_PARAM params
[])
307 return ecx_get_params(key
, params
, ED25519_BITS
, ED25519_SECURITY_BITS
,
309 && ed_get_params(key
, params
);
312 static int ed448_get_params(void *key
, OSSL_PARAM params
[])
314 return ecx_get_params(key
, params
, ED448_BITS
, ED448_SECURITY_BITS
,
316 && ed_get_params(key
, params
);
319 static const OSSL_PARAM ecx_gettable_params
[] = {
320 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
321 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
322 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
323 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST
, NULL
, 0),
324 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
, NULL
, 0),
329 static const OSSL_PARAM ed_gettable_params
[] = {
330 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS
, NULL
),
331 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS
, NULL
),
332 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE
, NULL
),
337 static const OSSL_PARAM
*x25519_gettable_params(void *provctx
)
339 return ecx_gettable_params
;
342 static const OSSL_PARAM
*x448_gettable_params(void *provctx
)
344 return ecx_gettable_params
;
347 static const OSSL_PARAM
*ed25519_gettable_params(void *provctx
)
349 return ed_gettable_params
;
352 static const OSSL_PARAM
*ed448_gettable_params(void *provctx
)
354 return ed_gettable_params
;
357 static int set_property_query(ECX_KEY
*ecxkey
, const char *propq
)
359 OPENSSL_free(ecxkey
->propq
);
360 ecxkey
->propq
= NULL
;
362 ecxkey
->propq
= OPENSSL_strdup(propq
);
363 if (ecxkey
->propq
== NULL
) {
364 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
371 static int ecx_set_params(void *key
, const OSSL_PARAM params
[])
373 ECX_KEY
*ecxkey
= key
;
376 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
);
378 void *buf
= ecxkey
->pubkey
;
380 if (p
->data_size
!= ecxkey
->keylen
381 || !OSSL_PARAM_get_octet_string(p
, &buf
, sizeof(ecxkey
->pubkey
),
384 OPENSSL_clear_free(ecxkey
->privkey
, ecxkey
->keylen
);
385 ecxkey
->privkey
= NULL
;
386 ecxkey
->haspubkey
= 1;
388 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PROPERTIES
);
390 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
391 || !set_property_query(ecxkey
, p
->data
))
398 static int x25519_set_params(void *key
, const OSSL_PARAM params
[])
400 return ecx_set_params(key
, params
);
403 static int x448_set_params(void *key
, const OSSL_PARAM params
[])
405 return ecx_set_params(key
, params
);
408 static int ed25519_set_params(void *key
, const OSSL_PARAM params
[])
413 static int ed448_set_params(void *key
, const OSSL_PARAM params
[])
418 static const OSSL_PARAM ecx_settable_params
[] = {
419 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
, NULL
, 0),
420 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES
, NULL
, 0),
424 static const OSSL_PARAM ed_settable_params
[] = {
428 static const OSSL_PARAM
*x25519_settable_params(void *provctx
)
430 return ecx_settable_params
;
433 static const OSSL_PARAM
*x448_settable_params(void *provctx
)
435 return ecx_settable_params
;
438 static const OSSL_PARAM
*ed25519_settable_params(void *provctx
)
440 return ed_settable_params
;
443 static const OSSL_PARAM
*ed448_settable_params(void *provctx
)
445 return ed_settable_params
;
448 static void *ecx_gen_init(void *provctx
, int selection
, ECX_KEY_TYPE type
)
450 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(provctx
);
451 struct ecx_gen_ctx
*gctx
= NULL
;
453 if (!ossl_prov_is_running())
456 if ((gctx
= OPENSSL_zalloc(sizeof(*gctx
))) != NULL
) {
457 gctx
->libctx
= libctx
;
459 gctx
->selection
= selection
;
464 static void *x25519_gen_init(void *provctx
, int selection
)
466 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X25519
);
469 static void *x448_gen_init(void *provctx
, int selection
)
471 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_X448
);
474 static void *ed25519_gen_init(void *provctx
, int selection
)
476 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED25519
);
479 static void *ed448_gen_init(void *provctx
, int selection
)
481 return ecx_gen_init(provctx
, selection
, ECX_KEY_TYPE_ED448
);
484 static int ecx_gen_set_params(void *genctx
, const OSSL_PARAM params
[])
486 struct ecx_gen_ctx
*gctx
= genctx
;
492 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_GROUP_NAME
);
494 const char *groupname
= NULL
;
497 * We optionally allow setting a group name - but each algorithm only
498 * support one such name, so all we do is verify that it is the one we
501 switch (gctx
->type
) {
502 case ECX_KEY_TYPE_X25519
:
503 groupname
= "x25519";
505 case ECX_KEY_TYPE_X448
:
509 /* We only support this for key exchange at the moment */
512 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
514 || strcasecmp(p
->data
, groupname
) != 0) {
515 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
519 p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PROPERTIES
);
521 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
523 OPENSSL_free(gctx
->propq
);
524 gctx
->propq
= OPENSSL_strdup(p
->data
);
525 if (gctx
->propq
== NULL
)
532 static const OSSL_PARAM
*ecx_gen_settable_params(void *provctx
)
534 static OSSL_PARAM settable
[] = {
535 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
, NULL
, 0),
536 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
542 static void *ecx_gen(struct ecx_gen_ctx
*gctx
)
545 unsigned char *privkey
;
549 if ((key
= ecx_key_new(gctx
->libctx
, gctx
->type
, 0, gctx
->propq
)) == NULL
) {
550 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
554 /* If we're doing parameter generation then we just return a blank key */
555 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
558 if ((privkey
= ecx_key_allocate_privkey(key
)) == NULL
) {
559 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
562 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, key
->keylen
) <= 0)
564 switch (gctx
->type
) {
565 case ECX_KEY_TYPE_X25519
:
567 privkey
[X25519_KEYLEN
- 1] &= 127;
568 privkey
[X25519_KEYLEN
- 1] |= 64;
569 X25519_public_from_private(key
->pubkey
, privkey
);
571 case ECX_KEY_TYPE_X448
:
573 privkey
[X448_KEYLEN
- 1] |= 128;
574 X448_public_from_private(key
->pubkey
, privkey
);
576 case ECX_KEY_TYPE_ED25519
:
577 if (!ED25519_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
581 case ECX_KEY_TYPE_ED448
:
582 if (!ED448_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
594 static void *x25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
596 struct ecx_gen_ctx
*gctx
= genctx
;
598 if (!ossl_prov_is_running())
602 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519
))
603 return s390x_ecx_keygen25519(gctx
);
605 return ecx_gen(gctx
);
608 static void *x448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
610 struct ecx_gen_ctx
*gctx
= genctx
;
612 if (!ossl_prov_is_running())
616 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448
))
617 return s390x_ecx_keygen448(gctx
);
619 return ecx_gen(gctx
);
622 static void *ed25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
624 struct ecx_gen_ctx
*gctx
= genctx
;
626 if (!ossl_prov_is_running())
630 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519
)
631 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519
)
632 && OPENSSL_s390xcap_P
.kdsa
[0]
633 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519
))
634 return s390x_ecd_keygen25519(gctx
);
636 return ecx_gen(gctx
);
639 static void *ed448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
641 struct ecx_gen_ctx
*gctx
= genctx
;
643 if (!ossl_prov_is_running())
647 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448
)
648 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448
)
649 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448
))
650 return s390x_ecd_keygen448(gctx
);
652 return ecx_gen(gctx
);
655 static void ecx_gen_cleanup(void *genctx
)
657 struct ecx_gen_ctx
*gctx
= genctx
;
659 OPENSSL_free(gctx
->propq
);
663 void *ecx_load(const void *reference
, size_t reference_sz
)
667 if (ossl_prov_is_running() && reference_sz
== sizeof(key
)) {
668 /* The contents of the reference is the address to our object */
669 key
= *(ECX_KEY
**)reference
;
670 /* We grabbed, so we detach it */
671 *(ECX_KEY
**)reference
= NULL
;
677 static int ecx_key_pairwise_check(const ECX_KEY
*ecx
, int type
)
682 case ECX_KEY_TYPE_X25519
:
683 X25519_public_from_private(pub
, ecx
->privkey
);
685 case ECX_KEY_TYPE_X448
:
686 X448_public_from_private(pub
, ecx
->privkey
);
688 case ECX_KEY_TYPE_ED25519
:
689 if (!ED25519_public_from_private(ecx
->libctx
, pub
, ecx
->privkey
,
693 case ECX_KEY_TYPE_ED448
:
694 if (!ED448_public_from_private(ecx
->libctx
, pub
, ecx
->privkey
,
701 return CRYPTO_memcmp(ecx
->pubkey
, pub
, ecx
->keylen
) == 0;
704 static int ecx_validate(const void *keydata
, int selection
, int type
, size_t keylen
)
706 const ECX_KEY
*ecx
= keydata
;
709 if (!ossl_prov_is_running())
712 assert(keylen
== ecx
->keylen
);
714 if ((selection
& ECX_POSSIBLE_SELECTIONS
) != 0)
717 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
718 ok
= ok
&& ecx
->haspubkey
;
720 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
721 ok
= ok
&& ecx
->privkey
!= NULL
;
723 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == OSSL_KEYMGMT_SELECT_KEYPAIR
)
724 ok
= ok
&& ecx_key_pairwise_check(ecx
, type
);
729 static int x25519_validate(const void *keydata
, int selection
, int checktype
)
731 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_X25519
, X25519_KEYLEN
);
734 static int x448_validate(const void *keydata
, int selection
, int checktype
)
736 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_X448
, X448_KEYLEN
);
739 static int ed25519_validate(const void *keydata
, int selection
, int checktype
)
741 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_ED25519
, ED25519_KEYLEN
);
744 static int ed448_validate(const void *keydata
, int selection
, int checktype
)
746 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_ED448
, ED448_KEYLEN
);
749 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
750 const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
751 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
752 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ecx_key_free }, \
753 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
754 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
755 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
756 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
757 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
758 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
759 { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
760 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
761 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
762 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
763 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
764 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
765 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
766 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
767 (void (*)(void))ecx_gen_settable_params }, \
768 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
769 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
770 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
774 MAKE_KEYMGMT_FUNCTIONS(x25519
)
775 MAKE_KEYMGMT_FUNCTIONS(x448
)
776 MAKE_KEYMGMT_FUNCTIONS(ed25519
)
777 MAKE_KEYMGMT_FUNCTIONS(ed448
)
780 # include "s390x_arch.h"
782 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
)
784 static const unsigned char generator
[] = {
785 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
789 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X25519
, 1, gctx
->propq
);
790 unsigned char *privkey
= NULL
, *pubkey
;
793 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
797 /* If we're doing parameter generation then we just return a blank key */
798 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
801 pubkey
= key
->pubkey
;
803 privkey
= ecx_key_allocate_privkey(key
);
804 if (privkey
== NULL
) {
805 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
809 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X25519_KEYLEN
) <= 0)
816 if (s390x_x25519_mul(pubkey
, generator
, privkey
) != 1)
825 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
)
827 static const unsigned char generator
[] = {
828 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
834 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X448
, 1, gctx
->propq
);
835 unsigned char *privkey
= NULL
, *pubkey
;
838 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
842 /* If we're doing parameter generation then we just return a blank key */
843 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
846 pubkey
= key
->pubkey
;
848 privkey
= ecx_key_allocate_privkey(key
);
849 if (privkey
== NULL
) {
850 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
854 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X448_KEYLEN
) <= 0)
860 if (s390x_x448_mul(pubkey
, generator
, privkey
) != 1)
869 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
)
871 static const unsigned char generator_x
[] = {
872 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
873 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
874 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
876 static const unsigned char generator_y
[] = {
877 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
878 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
879 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
881 unsigned char x_dst
[32], buff
[SHA512_DIGEST_LENGTH
];
882 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED25519
, 1, gctx
->propq
);
883 unsigned char *privkey
= NULL
, *pubkey
;
889 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
893 /* If we're doing parameter generation then we just return a blank key */
894 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
897 pubkey
= key
->pubkey
;
899 privkey
= ecx_key_allocate_privkey(key
);
900 if (privkey
== NULL
) {
901 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
905 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED25519_KEYLEN
) <= 0)
908 sha
= EVP_MD_fetch(gctx
->libctx
, "SHA512", gctx
->propq
);
911 j
= EVP_Digest(privkey
, 32, buff
, &sz
, sha
, NULL
);
920 if (s390x_ed25519_mul(x_dst
, pubkey
,
921 generator_x
, generator_y
, buff
) != 1)
924 pubkey
[31] |= ((x_dst
[0] & 0x01) << 7);
932 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
)
934 static const unsigned char generator_x
[] = {
935 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
936 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
937 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
938 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
939 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
941 static const unsigned char generator_y
[] = {
942 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
943 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
944 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
945 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
946 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
948 unsigned char x_dst
[57], buff
[114];
949 ECX_KEY
*key
= ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED448
, 1, gctx
->propq
);
950 unsigned char *privkey
= NULL
, *pubkey
;
951 EVP_MD_CTX
*hashctx
= NULL
;
952 EVP_MD
*shake
= NULL
;
955 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
959 /* If we're doing parameter generation then we just return a blank key */
960 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
963 pubkey
= key
->pubkey
;
965 privkey
= ecx_key_allocate_privkey(key
);
966 if (privkey
== NULL
) {
967 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
971 shake
= EVP_MD_fetch(gctx
->libctx
, "SHAKE256", gctx
->propq
);
974 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED448_KEYLEN
) <= 0)
977 hashctx
= EVP_MD_CTX_new();
980 if (EVP_DigestInit_ex(hashctx
, shake
, NULL
) != 1)
982 if (EVP_DigestUpdate(hashctx
, privkey
, 57) != 1)
984 if (EVP_DigestFinalXOF(hashctx
, buff
, sizeof(buff
)) != 1)
991 if (s390x_ed448_mul(x_dst
, pubkey
,
992 generator_x
, generator_y
, buff
) != 1)
995 pubkey
[56] |= ((x_dst
[0] & 0x01) << 7);
996 EVP_MD_CTX_free(hashctx
);
1002 EVP_MD_CTX_free(hashctx
);