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_gen_set_params_fn ecx_gen_set_params
;
45 static OSSL_FUNC_keymgmt_gen_settable_params_fn ecx_gen_settable_params
;
46 static OSSL_FUNC_keymgmt_load_fn ecx_load
;
47 static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params
;
48 static OSSL_FUNC_keymgmt_get_params_fn x448_get_params
;
49 static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params
;
50 static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params
;
51 static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params
;
52 static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params
;
53 static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params
;
54 static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params
;
55 static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params
;
56 static OSSL_FUNC_keymgmt_set_params_fn x448_set_params
;
57 static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params
;
58 static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params
;
59 static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params
;
60 static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params
;
61 static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params
;
62 static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params
;
63 static OSSL_FUNC_keymgmt_has_fn ecx_has
;
64 static OSSL_FUNC_keymgmt_match_fn ecx_match
;
65 static OSSL_FUNC_keymgmt_validate_fn x25519_validate
;
66 static OSSL_FUNC_keymgmt_validate_fn x448_validate
;
67 static OSSL_FUNC_keymgmt_validate_fn ed25519_validate
;
68 static OSSL_FUNC_keymgmt_validate_fn ed448_validate
;
69 static OSSL_FUNC_keymgmt_import_fn ecx_import
;
70 static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types
;
71 static OSSL_FUNC_keymgmt_export_fn ecx_export
;
72 static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types
;
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 ossl_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 ossl_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 ossl_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 ossl_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
&& ossl_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
;
379 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
);
381 void *buf
= ecxkey
->pubkey
;
383 if (p
->data_size
!= ecxkey
->keylen
384 || !OSSL_PARAM_get_octet_string(p
, &buf
, sizeof(ecxkey
->pubkey
),
387 OPENSSL_clear_free(ecxkey
->privkey
, ecxkey
->keylen
);
388 ecxkey
->privkey
= NULL
;
389 ecxkey
->haspubkey
= 1;
391 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_PROPERTIES
);
393 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
394 || !set_property_query(ecxkey
, p
->data
))
401 static int x25519_set_params(void *key
, const OSSL_PARAM params
[])
403 return ecx_set_params(key
, params
);
406 static int x448_set_params(void *key
, const OSSL_PARAM params
[])
408 return ecx_set_params(key
, params
);
411 static int ed25519_set_params(void *key
, const OSSL_PARAM params
[])
416 static int ed448_set_params(void *key
, const OSSL_PARAM params
[])
421 static const OSSL_PARAM ecx_settable_params
[] = {
422 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY
, NULL
, 0),
423 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES
, NULL
, 0),
427 static const OSSL_PARAM ed_settable_params
[] = {
431 static const OSSL_PARAM
*x25519_settable_params(void *provctx
)
433 return ecx_settable_params
;
436 static const OSSL_PARAM
*x448_settable_params(void *provctx
)
438 return ecx_settable_params
;
441 static const OSSL_PARAM
*ed25519_settable_params(void *provctx
)
443 return ed_settable_params
;
446 static const OSSL_PARAM
*ed448_settable_params(void *provctx
)
448 return ed_settable_params
;
451 static void *ecx_gen_init(void *provctx
, int selection
,
452 const OSSL_PARAM params
[], ECX_KEY_TYPE type
)
454 OSSL_LIB_CTX
*libctx
= PROV_LIBCTX_OF(provctx
);
455 struct ecx_gen_ctx
*gctx
= NULL
;
457 if (!ossl_prov_is_running())
460 if ((gctx
= OPENSSL_zalloc(sizeof(*gctx
))) != NULL
) {
461 gctx
->libctx
= libctx
;
463 gctx
->selection
= selection
;
465 if (!ecx_gen_set_params(gctx
, params
)) {
472 static void *x25519_gen_init(void *provctx
, int selection
,
473 const OSSL_PARAM params
[])
475 return ecx_gen_init(provctx
, selection
, params
, ECX_KEY_TYPE_X25519
);
478 static void *x448_gen_init(void *provctx
, int selection
,
479 const OSSL_PARAM params
[])
481 return ecx_gen_init(provctx
, selection
, params
, ECX_KEY_TYPE_X448
);
484 static void *ed25519_gen_init(void *provctx
, int selection
,
485 const OSSL_PARAM params
[])
487 return ecx_gen_init(provctx
, selection
, params
, ECX_KEY_TYPE_ED25519
);
490 static void *ed448_gen_init(void *provctx
, int selection
,
491 const OSSL_PARAM params
[])
493 return ecx_gen_init(provctx
, selection
, params
, ECX_KEY_TYPE_ED448
);
496 static int ecx_gen_set_params(void *genctx
, const OSSL_PARAM params
[])
498 struct ecx_gen_ctx
*gctx
= genctx
;
504 p
= OSSL_PARAM_locate_const(params
, OSSL_PKEY_PARAM_GROUP_NAME
);
506 const char *groupname
= NULL
;
509 * We optionally allow setting a group name - but each algorithm only
510 * support one such name, so all we do is verify that it is the one we
513 switch (gctx
->type
) {
514 case ECX_KEY_TYPE_X25519
:
515 groupname
= "x25519";
517 case ECX_KEY_TYPE_X448
:
521 /* We only support this for key exchange at the moment */
524 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
526 || strcasecmp(p
->data
, groupname
) != 0) {
527 ERR_raise(ERR_LIB_PROV
, ERR_R_PASSED_INVALID_ARGUMENT
);
531 p
= OSSL_PARAM_locate_const(params
, OSSL_KDF_PARAM_PROPERTIES
);
533 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
535 OPENSSL_free(gctx
->propq
);
536 gctx
->propq
= OPENSSL_strdup(p
->data
);
537 if (gctx
->propq
== NULL
)
544 static const OSSL_PARAM
*ecx_gen_settable_params(ossl_unused
void *genctx
,
545 ossl_unused
void *provctx
)
547 static OSSL_PARAM settable
[] = {
548 OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME
, NULL
, 0),
549 OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES
, NULL
, 0),
555 static void *ecx_gen(struct ecx_gen_ctx
*gctx
)
558 unsigned char *privkey
;
562 if ((key
= ossl_ecx_key_new(gctx
->libctx
, gctx
->type
, 0,
563 gctx
->propq
)) == NULL
) {
564 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
568 /* If we're doing parameter generation then we just return a blank key */
569 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
572 if ((privkey
= ossl_ecx_key_allocate_privkey(key
)) == NULL
) {
573 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
576 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, key
->keylen
) <= 0)
578 switch (gctx
->type
) {
579 case ECX_KEY_TYPE_X25519
:
581 privkey
[X25519_KEYLEN
- 1] &= 127;
582 privkey
[X25519_KEYLEN
- 1] |= 64;
583 X25519_public_from_private(key
->pubkey
, privkey
);
585 case ECX_KEY_TYPE_X448
:
587 privkey
[X448_KEYLEN
- 1] |= 128;
588 X448_public_from_private(key
->pubkey
, privkey
);
590 case ECX_KEY_TYPE_ED25519
:
591 if (!ED25519_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
595 case ECX_KEY_TYPE_ED448
:
596 if (!ED448_public_from_private(gctx
->libctx
, key
->pubkey
, privkey
,
604 ossl_ecx_key_free(key
);
608 static void *x25519_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_X25519
))
617 return s390x_ecx_keygen25519(gctx
);
619 return ecx_gen(gctx
);
622 static void *x448_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_X448
))
631 return s390x_ecx_keygen448(gctx
);
633 return ecx_gen(gctx
);
636 static void *ed25519_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
638 struct ecx_gen_ctx
*gctx
= genctx
;
640 if (!ossl_prov_is_running())
644 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519
)
645 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519
)
646 && OPENSSL_s390xcap_P
.kdsa
[0]
647 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519
))
648 return s390x_ecd_keygen25519(gctx
);
650 return ecx_gen(gctx
);
653 static void *ed448_gen(void *genctx
, OSSL_CALLBACK
*osslcb
, void *cbarg
)
655 struct ecx_gen_ctx
*gctx
= genctx
;
657 if (!ossl_prov_is_running())
661 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448
)
662 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448
)
663 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448
))
664 return s390x_ecd_keygen448(gctx
);
666 return ecx_gen(gctx
);
669 static void ecx_gen_cleanup(void *genctx
)
671 struct ecx_gen_ctx
*gctx
= genctx
;
673 OPENSSL_free(gctx
->propq
);
677 void *ecx_load(const void *reference
, size_t reference_sz
)
681 if (ossl_prov_is_running() && reference_sz
== sizeof(key
)) {
682 /* The contents of the reference is the address to our object */
683 key
= *(ECX_KEY
**)reference
;
684 /* We grabbed, so we detach it */
685 *(ECX_KEY
**)reference
= NULL
;
691 static int ecx_key_pairwise_check(const ECX_KEY
*ecx
, int type
)
696 case ECX_KEY_TYPE_X25519
:
697 X25519_public_from_private(pub
, ecx
->privkey
);
699 case ECX_KEY_TYPE_X448
:
700 X448_public_from_private(pub
, ecx
->privkey
);
702 case ECX_KEY_TYPE_ED25519
:
703 if (!ED25519_public_from_private(ecx
->libctx
, pub
, ecx
->privkey
,
707 case ECX_KEY_TYPE_ED448
:
708 if (!ED448_public_from_private(ecx
->libctx
, pub
, ecx
->privkey
,
715 return CRYPTO_memcmp(ecx
->pubkey
, pub
, ecx
->keylen
) == 0;
718 static int ecx_validate(const void *keydata
, int selection
, int type
, size_t keylen
)
720 const ECX_KEY
*ecx
= keydata
;
723 if (!ossl_prov_is_running())
726 assert(keylen
== ecx
->keylen
);
729 * ECX keys have no parameters. But if EVP_PKEY_param_check() is called then
730 * we should return true.
732 if ((selection
& (OSSL_KEYMGMT_SELECT_KEYPAIR
733 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
734 | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
)) != 0)
737 if ((selection
& OSSL_KEYMGMT_SELECT_PUBLIC_KEY
) != 0)
738 ok
= ok
&& ecx
->haspubkey
;
740 if ((selection
& OSSL_KEYMGMT_SELECT_PRIVATE_KEY
) != 0)
741 ok
= ok
&& ecx
->privkey
!= NULL
;
743 if ((selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == OSSL_KEYMGMT_SELECT_KEYPAIR
)
744 ok
= ok
&& ecx_key_pairwise_check(ecx
, type
);
749 static int x25519_validate(const void *keydata
, int selection
, int checktype
)
751 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_X25519
, X25519_KEYLEN
);
754 static int x448_validate(const void *keydata
, int selection
, int checktype
)
756 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_X448
, X448_KEYLEN
);
759 static int ed25519_validate(const void *keydata
, int selection
, int checktype
)
761 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_ED25519
, ED25519_KEYLEN
);
764 static int ed448_validate(const void *keydata
, int selection
, int checktype
)
766 return ecx_validate(keydata
, selection
, ECX_KEY_TYPE_ED448
, ED448_KEYLEN
);
769 #define MAKE_KEYMGMT_FUNCTIONS(alg) \
770 const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \
771 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
772 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ossl_ecx_key_free }, \
773 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))alg##_get_params }, \
774 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))alg##_gettable_params }, \
775 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))alg##_set_params }, \
776 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))alg##_settable_params }, \
777 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ecx_has }, \
778 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ecx_match }, \
779 { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))alg##_validate }, \
780 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))ecx_import }, \
781 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
782 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ecx_export }, \
783 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ecx_imexport_types }, \
784 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
785 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ecx_gen_set_params }, \
786 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \
787 (void (*)(void))ecx_gen_settable_params }, \
788 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))alg##_gen }, \
789 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ecx_gen_cleanup }, \
790 { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))ecx_load }, \
794 MAKE_KEYMGMT_FUNCTIONS(x25519
)
795 MAKE_KEYMGMT_FUNCTIONS(x448
)
796 MAKE_KEYMGMT_FUNCTIONS(ed25519
)
797 MAKE_KEYMGMT_FUNCTIONS(ed448
)
800 # include "s390x_arch.h"
802 static void *s390x_ecx_keygen25519(struct ecx_gen_ctx
*gctx
)
804 static const unsigned char generator
[] = {
805 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
809 ECX_KEY
*key
= ossl_ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X25519
, 1,
811 unsigned char *privkey
= NULL
, *pubkey
;
814 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
818 /* If we're doing parameter generation then we just return a blank key */
819 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
822 pubkey
= key
->pubkey
;
824 privkey
= ossl_ecx_key_allocate_privkey(key
);
825 if (privkey
== NULL
) {
826 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
830 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X25519_KEYLEN
) <= 0)
837 if (s390x_x25519_mul(pubkey
, generator
, privkey
) != 1)
842 ossl_ecx_key_free(key
);
846 static void *s390x_ecx_keygen448(struct ecx_gen_ctx
*gctx
)
848 static const unsigned char generator
[] = {
849 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
855 ECX_KEY
*key
= ossl_ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_X448
, 1,
857 unsigned char *privkey
= NULL
, *pubkey
;
860 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
864 /* If we're doing parameter generation then we just return a blank key */
865 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
868 pubkey
= key
->pubkey
;
870 privkey
= ossl_ecx_key_allocate_privkey(key
);
871 if (privkey
== NULL
) {
872 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
876 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, X448_KEYLEN
) <= 0)
882 if (s390x_x448_mul(pubkey
, generator
, privkey
) != 1)
887 ossl_ecx_key_free(key
);
891 static void *s390x_ecd_keygen25519(struct ecx_gen_ctx
*gctx
)
893 static const unsigned char generator_x
[] = {
894 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
895 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
896 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
898 static const unsigned char generator_y
[] = {
899 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
900 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
901 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
903 unsigned char x_dst
[32], buff
[SHA512_DIGEST_LENGTH
];
904 ECX_KEY
*key
= ossl_ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED25519
, 1,
906 unsigned char *privkey
= NULL
, *pubkey
;
912 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
916 /* If we're doing parameter generation then we just return a blank key */
917 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
920 pubkey
= key
->pubkey
;
922 privkey
= ossl_ecx_key_allocate_privkey(key
);
923 if (privkey
== NULL
) {
924 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
928 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED25519_KEYLEN
) <= 0)
931 sha
= EVP_MD_fetch(gctx
->libctx
, "SHA512", gctx
->propq
);
934 j
= EVP_Digest(privkey
, 32, buff
, &sz
, sha
, NULL
);
943 if (s390x_ed25519_mul(x_dst
, pubkey
,
944 generator_x
, generator_y
, buff
) != 1)
947 pubkey
[31] |= ((x_dst
[0] & 0x01) << 7);
951 ossl_ecx_key_free(key
);
955 static void *s390x_ecd_keygen448(struct ecx_gen_ctx
*gctx
)
957 static const unsigned char generator_x
[] = {
958 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
959 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
960 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
961 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
962 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
964 static const unsigned char generator_y
[] = {
965 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
966 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
967 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
968 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
969 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
971 unsigned char x_dst
[57], buff
[114];
972 ECX_KEY
*key
= ossl_ecx_key_new(gctx
->libctx
, ECX_KEY_TYPE_ED448
, 1,
974 unsigned char *privkey
= NULL
, *pubkey
;
975 EVP_MD_CTX
*hashctx
= NULL
;
976 EVP_MD
*shake
= NULL
;
979 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
983 /* If we're doing parameter generation then we just return a blank key */
984 if ((gctx
->selection
& OSSL_KEYMGMT_SELECT_KEYPAIR
) == 0)
987 pubkey
= key
->pubkey
;
989 privkey
= ossl_ecx_key_allocate_privkey(key
);
990 if (privkey
== NULL
) {
991 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
995 shake
= EVP_MD_fetch(gctx
->libctx
, "SHAKE256", gctx
->propq
);
998 if (RAND_priv_bytes_ex(gctx
->libctx
, privkey
, ED448_KEYLEN
) <= 0)
1001 hashctx
= EVP_MD_CTX_new();
1002 if (hashctx
== NULL
)
1004 if (EVP_DigestInit_ex(hashctx
, shake
, NULL
) != 1)
1006 if (EVP_DigestUpdate(hashctx
, privkey
, 57) != 1)
1008 if (EVP_DigestFinalXOF(hashctx
, buff
, sizeof(buff
)) != 1)
1015 if (s390x_ed448_mul(x_dst
, pubkey
,
1016 generator_x
, generator_y
, buff
) != 1)
1019 pubkey
[56] |= ((x_dst
[0] & 0x01) << 7);
1020 EVP_MD_CTX_free(hashctx
);
1025 ossl_ecx_key_free(key
);
1026 EVP_MD_CTX_free(hashctx
);