2 * Copyright 2006-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
11 * ECDSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
17 #include "internal/cryptlib.h"
18 #include <openssl/x509.h>
19 #include <openssl/ec.h>
20 #include <openssl/rand.h>
21 #include <openssl/core_names.h>
22 #include "openssl/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
27 #include "curve448/curve448_local.h"
28 #include "ecx_backend.h"
36 /* Setup EVP_PKEY using public, private or generation */
37 static int ecx_key_op(EVP_PKEY
*pkey
, int id
, const X509_ALGOR
*palg
,
38 const unsigned char *p
, int plen
, ecx_key_op_t op
,
39 OSSL_LIB_CTX
*libctx
, const char *propq
)
42 unsigned char *privkey
, *pubkey
;
44 if (op
!= KEY_OP_KEYGEN
) {
48 /* Algorithm parameters must be absent */
49 X509_ALGOR_get0(NULL
, &ptype
, NULL
, palg
);
50 if (ptype
!= V_ASN1_UNDEF
) {
51 ECerr(EC_F_ECX_KEY_OP
, EC_R_INVALID_ENCODING
);
56 if (p
== NULL
|| plen
!= KEYLENID(id
)) {
57 ECerr(EC_F_ECX_KEY_OP
, EC_R_INVALID_ENCODING
);
62 key
= ecx_key_new(libctx
, KEYNID2TYPE(id
), 1, propq
);
64 ECerr(EC_F_ECX_KEY_OP
, ERR_R_MALLOC_FAILURE
);
69 if (op
== KEY_OP_PUBLIC
) {
70 memcpy(pubkey
, p
, plen
);
72 privkey
= ecx_key_allocate_privkey(key
);
73 if (privkey
== NULL
) {
74 ECerr(EC_F_ECX_KEY_OP
, ERR_R_MALLOC_FAILURE
);
77 if (op
== KEY_OP_KEYGEN
) {
78 if (RAND_priv_bytes_ex(libctx
, privkey
, KEYLENID(id
)) <= 0)
80 if (id
== EVP_PKEY_X25519
) {
82 privkey
[X25519_KEYLEN
- 1] &= 127;
83 privkey
[X25519_KEYLEN
- 1] |= 64;
84 } else if (id
== EVP_PKEY_X448
) {
86 privkey
[X448_KEYLEN
- 1] |= 128;
89 memcpy(privkey
, p
, KEYLENID(id
));
91 if (!ecx_public_from_private(key
)) {
92 ECerr(EC_F_ECX_KEY_OP
, EC_R_FAILED_MAKING_PUBLIC_KEY
);
97 EVP_PKEY_assign(pkey
, id
, key
);
104 static int ecx_pub_encode(X509_PUBKEY
*pk
, const EVP_PKEY
*pkey
)
106 const ECX_KEY
*ecxkey
= pkey
->pkey
.ecx
;
109 if (ecxkey
== NULL
) {
110 ECerr(EC_F_ECX_PUB_ENCODE
, EC_R_INVALID_KEY
);
114 penc
= OPENSSL_memdup(ecxkey
->pubkey
, KEYLEN(pkey
));
116 ECerr(EC_F_ECX_PUB_ENCODE
, ERR_R_MALLOC_FAILURE
);
120 if (!X509_PUBKEY_set0_param(pk
, OBJ_nid2obj(pkey
->ameth
->pkey_id
),
121 V_ASN1_UNDEF
, NULL
, penc
, KEYLEN(pkey
))) {
123 ECerr(EC_F_ECX_PUB_ENCODE
, ERR_R_MALLOC_FAILURE
);
129 static int ecx_pub_decode(EVP_PKEY
*pkey
, const X509_PUBKEY
*pubkey
)
131 const unsigned char *p
;
135 if (!X509_PUBKEY_get0_param(NULL
, &p
, &pklen
, &palg
, pubkey
))
137 return ecx_key_op(pkey
, pkey
->ameth
->pkey_id
, palg
, p
, pklen
,
138 KEY_OP_PUBLIC
, NULL
, NULL
);
141 static int ecx_pub_cmp(const EVP_PKEY
*a
, const EVP_PKEY
*b
)
143 const ECX_KEY
*akey
= a
->pkey
.ecx
;
144 const ECX_KEY
*bkey
= b
->pkey
.ecx
;
146 if (akey
== NULL
|| bkey
== NULL
)
149 return CRYPTO_memcmp(akey
->pubkey
, bkey
->pubkey
, KEYLEN(a
)) == 0;
152 static int ecx_priv_decode_ex(EVP_PKEY
*pkey
, const PKCS8_PRIV_KEY_INFO
*p8
,
153 OSSL_LIB_CTX
*libctx
, const char *propq
)
155 const unsigned char *p
;
157 ASN1_OCTET_STRING
*oct
= NULL
;
158 const X509_ALGOR
*palg
;
161 if (!PKCS8_pkey_get0(NULL
, &p
, &plen
, &palg
, p8
))
164 oct
= d2i_ASN1_OCTET_STRING(NULL
, &p
, plen
);
169 p
= ASN1_STRING_get0_data(oct
);
170 plen
= ASN1_STRING_length(oct
);
173 rv
= ecx_key_op(pkey
, pkey
->ameth
->pkey_id
, palg
, p
, plen
, KEY_OP_PRIVATE
,
175 ASN1_STRING_clear_free(oct
);
179 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO
*p8
, const EVP_PKEY
*pkey
)
181 const ECX_KEY
*ecxkey
= pkey
->pkey
.ecx
;
182 ASN1_OCTET_STRING oct
;
183 unsigned char *penc
= NULL
;
186 if (ecxkey
== NULL
|| ecxkey
->privkey
== NULL
) {
187 ECerr(EC_F_ECX_PRIV_ENCODE
, EC_R_INVALID_PRIVATE_KEY
);
191 oct
.data
= ecxkey
->privkey
;
192 oct
.length
= KEYLEN(pkey
);
195 penclen
= i2d_ASN1_OCTET_STRING(&oct
, &penc
);
197 ECerr(EC_F_ECX_PRIV_ENCODE
, ERR_R_MALLOC_FAILURE
);
201 if (!PKCS8_pkey_set0(p8
, OBJ_nid2obj(pkey
->ameth
->pkey_id
), 0,
202 V_ASN1_UNDEF
, NULL
, penc
, penclen
)) {
203 OPENSSL_clear_free(penc
, penclen
);
204 ECerr(EC_F_ECX_PRIV_ENCODE
, ERR_R_MALLOC_FAILURE
);
211 static int ecx_size(const EVP_PKEY
*pkey
)
216 static int ecx_bits(const EVP_PKEY
*pkey
)
218 if (IS25519(pkey
->ameth
->pkey_id
)) {
220 } else if(ISX448(pkey
->ameth
->pkey_id
)) {
227 static int ecx_security_bits(const EVP_PKEY
*pkey
)
229 if (IS25519(pkey
->ameth
->pkey_id
)) {
230 return X25519_SECURITY_BITS
;
232 return X448_SECURITY_BITS
;
236 static void ecx_free(EVP_PKEY
*pkey
)
238 ecx_key_free(pkey
->pkey
.ecx
);
241 /* "parameters" are always equal */
242 static int ecx_cmp_parameters(const EVP_PKEY
*a
, const EVP_PKEY
*b
)
247 static int ecx_key_print(BIO
*bp
, const EVP_PKEY
*pkey
, int indent
,
248 ASN1_PCTX
*ctx
, ecx_key_op_t op
)
250 const ECX_KEY
*ecxkey
= pkey
->pkey
.ecx
;
251 const char *nm
= OBJ_nid2ln(pkey
->ameth
->pkey_id
);
253 if (op
== KEY_OP_PRIVATE
) {
254 if (ecxkey
== NULL
|| ecxkey
->privkey
== NULL
) {
255 if (BIO_printf(bp
, "%*s<INVALID PRIVATE KEY>\n", indent
, "") <= 0)
259 if (BIO_printf(bp
, "%*s%s Private-Key:\n", indent
, "", nm
) <= 0)
261 if (BIO_printf(bp
, "%*spriv:\n", indent
, "") <= 0)
263 if (ASN1_buf_print(bp
, ecxkey
->privkey
, KEYLEN(pkey
),
267 if (ecxkey
== NULL
) {
268 if (BIO_printf(bp
, "%*s<INVALID PUBLIC KEY>\n", indent
, "") <= 0)
272 if (BIO_printf(bp
, "%*s%s Public-Key:\n", indent
, "", nm
) <= 0)
275 if (BIO_printf(bp
, "%*spub:\n", indent
, "") <= 0)
278 if (ASN1_buf_print(bp
, ecxkey
->pubkey
, KEYLEN(pkey
),
284 static int ecx_priv_print(BIO
*bp
, const EVP_PKEY
*pkey
, int indent
,
287 return ecx_key_print(bp
, pkey
, indent
, ctx
, KEY_OP_PRIVATE
);
290 static int ecx_pub_print(BIO
*bp
, const EVP_PKEY
*pkey
, int indent
,
293 return ecx_key_print(bp
, pkey
, indent
, ctx
, KEY_OP_PUBLIC
);
296 static int ecx_ctrl(EVP_PKEY
*pkey
, int op
, long arg1
, void *arg2
)
300 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT
:
301 return ecx_key_op(pkey
, pkey
->ameth
->pkey_id
, NULL
, arg2
, arg1
,
302 KEY_OP_PUBLIC
, NULL
, NULL
);
304 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT
:
305 if (pkey
->pkey
.ecx
!= NULL
) {
306 unsigned char **ppt
= arg2
;
308 *ppt
= OPENSSL_memdup(pkey
->pkey
.ecx
->pubkey
, KEYLEN(pkey
));
320 static int ecd_ctrl(EVP_PKEY
*pkey
, int op
, long arg1
, void *arg2
)
323 case ASN1_PKEY_CTRL_DEFAULT_MD_NID
:
324 /* We currently only support Pure EdDSA which takes no digest */
325 *(int *)arg2
= NID_undef
;
334 static int ecx_set_priv_key(EVP_PKEY
*pkey
, const unsigned char *priv
,
337 /* TODO(3.0): We should pass a libctx here */
338 return ecx_key_op(pkey
, pkey
->ameth
->pkey_id
, NULL
, priv
, len
,
339 KEY_OP_PRIVATE
, NULL
, NULL
);
342 static int ecx_set_pub_key(EVP_PKEY
*pkey
, const unsigned char *pub
, size_t len
)
344 return ecx_key_op(pkey
, pkey
->ameth
->pkey_id
, NULL
, pub
, len
,
345 KEY_OP_PUBLIC
, NULL
, NULL
);
348 static int ecx_get_priv_key(const EVP_PKEY
*pkey
, unsigned char *priv
,
351 const ECX_KEY
*key
= pkey
->pkey
.ecx
;
354 *len
= KEYLENID(pkey
->ameth
->pkey_id
);
359 || key
->privkey
== NULL
360 || *len
< (size_t)KEYLENID(pkey
->ameth
->pkey_id
))
363 *len
= KEYLENID(pkey
->ameth
->pkey_id
);
364 memcpy(priv
, key
->privkey
, *len
);
369 static int ecx_get_pub_key(const EVP_PKEY
*pkey
, unsigned char *pub
,
372 const ECX_KEY
*key
= pkey
->pkey
.ecx
;
375 *len
= KEYLENID(pkey
->ameth
->pkey_id
);
380 || *len
< (size_t)KEYLENID(pkey
->ameth
->pkey_id
))
383 *len
= KEYLENID(pkey
->ameth
->pkey_id
);
384 memcpy(pub
, key
->pubkey
, *len
);
389 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY
*pkey
)
392 * We provide no mechanism to "update" an ECX key once it has been set,
393 * therefore we do not have to maintain a dirty count.
398 static int ecx_pkey_export_to(const EVP_PKEY
*from
, void *to_keydata
,
399 EVP_KEYMGMT
*to_keymgmt
, OSSL_LIB_CTX
*libctx
,
402 const ECX_KEY
*key
= from
->pkey
.ecx
;
403 OSSL_PARAM_BLD
*tmpl
= OSSL_PARAM_BLD_new();
404 OSSL_PARAM
*params
= NULL
;
411 /* A key must at least have a public part */
412 if (!OSSL_PARAM_BLD_push_octet_string(tmpl
, OSSL_PKEY_PARAM_PUB_KEY
,
413 key
->pubkey
, key
->keylen
))
415 selection
|= OSSL_KEYMGMT_SELECT_PUBLIC_KEY
;
417 if (key
->privkey
!= NULL
) {
418 if (!OSSL_PARAM_BLD_push_octet_string(tmpl
,
419 OSSL_PKEY_PARAM_PRIV_KEY
,
420 key
->privkey
, key
->keylen
))
422 selection
|= OSSL_KEYMGMT_SELECT_PRIVATE_KEY
;
425 params
= OSSL_PARAM_BLD_to_param(tmpl
);
427 /* We export, the provider imports */
428 rv
= evp_keymgmt_import(to_keymgmt
, to_keydata
, selection
, params
);
431 OSSL_PARAM_BLD_free(tmpl
);
432 OSSL_PARAM_BLD_free_params(params
);
436 static int ecx_generic_import_from(const OSSL_PARAM params
[], void *vpctx
,
439 EVP_PKEY_CTX
*pctx
= vpctx
;
440 EVP_PKEY
*pkey
= EVP_PKEY_CTX_get0_pkey(pctx
);
441 ECX_KEY
*ecx
= ecx_key_new(pctx
->libctx
, KEYNID2TYPE(keytype
), 0,
445 ERR_raise(ERR_LIB_DH
, ERR_R_MALLOC_FAILURE
);
449 if (!ecx_key_fromdata(ecx
, params
, 1)
450 || !EVP_PKEY_assign(pkey
, keytype
, ecx
)) {
457 static int x25519_import_from(const OSSL_PARAM params
[], void *vpctx
)
459 return ecx_generic_import_from(params
, vpctx
, EVP_PKEY_X25519
);
462 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth
= {
467 "OpenSSL X25519 algorithm",
510 static int x448_import_from(const OSSL_PARAM params
[], void *vpctx
)
512 return ecx_generic_import_from(params
, vpctx
, EVP_PKEY_X448
);
515 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth
= {
520 "OpenSSL X448 algorithm",
563 static int ecd_size25519(const EVP_PKEY
*pkey
)
565 return ED25519_SIGSIZE
;
568 static int ecd_size448(const EVP_PKEY
*pkey
)
570 return ED448_SIGSIZE
;
573 static int ecd_item_verify(EVP_MD_CTX
*ctx
, const ASN1_ITEM
*it
,
574 const void *asn
, const X509_ALGOR
*sigalg
,
575 const ASN1_BIT_STRING
*str
, EVP_PKEY
*pkey
)
577 const ASN1_OBJECT
*obj
;
581 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
582 X509_ALGOR_get0(&obj
, &ptype
, NULL
, sigalg
);
583 nid
= OBJ_obj2nid(obj
);
584 if ((nid
!= NID_ED25519
&& nid
!= NID_ED448
) || ptype
!= V_ASN1_UNDEF
) {
585 ECerr(EC_F_ECD_ITEM_VERIFY
, EC_R_INVALID_ENCODING
);
589 if (!EVP_DigestVerifyInit(ctx
, NULL
, NULL
, NULL
, pkey
))
595 static int ecd_item_sign25519(EVP_MD_CTX
*ctx
, const ASN1_ITEM
*it
,
597 X509_ALGOR
*alg1
, X509_ALGOR
*alg2
,
598 ASN1_BIT_STRING
*str
)
600 /* Set algorithms identifiers */
601 X509_ALGOR_set0(alg1
, OBJ_nid2obj(NID_ED25519
), V_ASN1_UNDEF
, NULL
);
603 X509_ALGOR_set0(alg2
, OBJ_nid2obj(NID_ED25519
), V_ASN1_UNDEF
, NULL
);
604 /* Algorithm identifiers set: carry on as normal */
608 static int ecd_sig_info_set25519(X509_SIG_INFO
*siginf
, const X509_ALGOR
*alg
,
609 const ASN1_STRING
*sig
)
611 X509_SIG_INFO_set(siginf
, NID_undef
, NID_ED25519
, X25519_SECURITY_BITS
,
616 static int ecd_item_sign448(EVP_MD_CTX
*ctx
, const ASN1_ITEM
*it
,
618 X509_ALGOR
*alg1
, X509_ALGOR
*alg2
,
619 ASN1_BIT_STRING
*str
)
621 /* Set algorithm identifier */
622 X509_ALGOR_set0(alg1
, OBJ_nid2obj(NID_ED448
), V_ASN1_UNDEF
, NULL
);
624 X509_ALGOR_set0(alg2
, OBJ_nid2obj(NID_ED448
), V_ASN1_UNDEF
, NULL
);
625 /* Algorithm identifier set: carry on as normal */
629 static int ecd_sig_info_set448(X509_SIG_INFO
*siginf
, const X509_ALGOR
*alg
,
630 const ASN1_STRING
*sig
)
632 X509_SIG_INFO_set(siginf
, NID_undef
, NID_ED448
, X448_SECURITY_BITS
,
637 static int ed25519_import_from(const OSSL_PARAM params
[], void *vpctx
)
639 return ecx_generic_import_from(params
, vpctx
, EVP_PKEY_ED25519
);
642 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth
= {
647 "OpenSSL ED25519 algorithm",
672 ecd_sig_info_set25519
,
689 static int ed448_import_from(const OSSL_PARAM params
[], void *vpctx
)
691 return ecx_generic_import_from(params
, vpctx
, EVP_PKEY_ED448
);
694 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth
= {
699 "OpenSSL ED448 algorithm",
741 static int pkey_ecx_keygen(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
743 return ecx_key_op(pkey
, ctx
->pmeth
->pkey_id
, NULL
, NULL
, 0, KEY_OP_KEYGEN
,
747 static int validate_ecx_derive(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
749 const unsigned char **privkey
,
750 const unsigned char **pubkey
)
752 const ECX_KEY
*ecxkey
, *peerkey
;
754 if (ctx
->pkey
== NULL
|| ctx
->peerkey
== NULL
) {
755 ECerr(EC_F_VALIDATE_ECX_DERIVE
, EC_R_KEYS_NOT_SET
);
758 ecxkey
= ctx
->pkey
->pkey
.ecx
;
759 peerkey
= ctx
->peerkey
->pkey
.ecx
;
760 if (ecxkey
== NULL
|| ecxkey
->privkey
== NULL
) {
761 ECerr(EC_F_VALIDATE_ECX_DERIVE
, EC_R_INVALID_PRIVATE_KEY
);
764 if (peerkey
== NULL
) {
765 ECerr(EC_F_VALIDATE_ECX_DERIVE
, EC_R_INVALID_PEER_KEY
);
768 *privkey
= ecxkey
->privkey
;
769 *pubkey
= peerkey
->pubkey
;
774 static int pkey_ecx_derive25519(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
777 const unsigned char *privkey
, *pubkey
;
779 if (!validate_ecx_derive(ctx
, key
, keylen
, &privkey
, &pubkey
)
781 && X25519(key
, privkey
, pubkey
) == 0))
783 *keylen
= X25519_KEYLEN
;
787 static int pkey_ecx_derive448(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
790 const unsigned char *privkey
, *pubkey
;
792 if (!validate_ecx_derive(ctx
, key
, keylen
, &privkey
, &pubkey
)
794 && X448(key
, privkey
, pubkey
) == 0))
796 *keylen
= X448_KEYLEN
;
800 static int pkey_ecx_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
802 /* Only need to handle peer key for derivation */
803 if (type
== EVP_PKEY_CTRL_PEER_KEY
)
808 static const EVP_PKEY_METHOD ecx25519_pkey_meth
= {
812 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
813 pkey_ecx_derive25519
,
818 static const EVP_PKEY_METHOD ecx448_pkey_meth
= {
822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
828 static int pkey_ecd_digestsign25519(EVP_MD_CTX
*ctx
, unsigned char *sig
,
829 size_t *siglen
, const unsigned char *tbs
,
832 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
835 *siglen
= ED25519_SIGSIZE
;
838 if (*siglen
< ED25519_SIGSIZE
) {
839 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519
, EC_R_BUFFER_TOO_SMALL
);
843 if (ED25519_sign(sig
, tbs
, tbslen
, edkey
->pubkey
, edkey
->privkey
, NULL
,
846 *siglen
= ED25519_SIGSIZE
;
850 static int pkey_ecd_digestsign448(EVP_MD_CTX
*ctx
, unsigned char *sig
,
851 size_t *siglen
, const unsigned char *tbs
,
854 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
857 *siglen
= ED448_SIGSIZE
;
860 if (*siglen
< ED448_SIGSIZE
) {
861 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448
, EC_R_BUFFER_TOO_SMALL
);
865 if (ED448_sign(edkey
->libctx
, sig
, tbs
, tbslen
, edkey
->pubkey
, edkey
->privkey
,
866 NULL
, 0, edkey
->propq
) == 0)
868 *siglen
= ED448_SIGSIZE
;
872 static int pkey_ecd_digestverify25519(EVP_MD_CTX
*ctx
, const unsigned char *sig
,
873 size_t siglen
, const unsigned char *tbs
,
876 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
878 if (siglen
!= ED25519_SIGSIZE
)
881 return ED25519_verify(tbs
, tbslen
, sig
, edkey
->pubkey
,
882 edkey
->libctx
, edkey
->propq
);
885 static int pkey_ecd_digestverify448(EVP_MD_CTX
*ctx
, const unsigned char *sig
,
886 size_t siglen
, const unsigned char *tbs
,
889 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
891 if (siglen
!= ED448_SIGSIZE
)
894 return ED448_verify(edkey
->libctx
, tbs
, tbslen
, sig
, edkey
->pubkey
, NULL
, 0,
898 static int pkey_ecd_ctrl(EVP_PKEY_CTX
*ctx
, int type
, int p1
, void *p2
)
901 case EVP_PKEY_CTRL_MD
:
902 /* Only NULL allowed as digest */
903 if (p2
== NULL
|| (const EVP_MD
*)p2
== EVP_md_null())
905 ECerr(EC_F_PKEY_ECD_CTRL
, EC_R_INVALID_DIGEST_TYPE
);
908 case EVP_PKEY_CTRL_DIGESTINIT
:
914 static const EVP_PKEY_METHOD ed25519_pkey_meth
= {
915 EVP_PKEY_ED25519
, EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
918 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
921 pkey_ecd_digestsign25519
,
922 pkey_ecd_digestverify25519
925 static const EVP_PKEY_METHOD ed448_pkey_meth
= {
926 EVP_PKEY_ED448
, EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
932 pkey_ecd_digestsign448
,
933 pkey_ecd_digestverify448
937 # include "s390x_arch.h"
939 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
941 static const unsigned char generator
[] = {
942 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
946 ECX_KEY
*key
= ecx_key_new(ctx
->libctx
, ECX_KEY_TYPE_X25519
, 1,
948 unsigned char *privkey
= NULL
, *pubkey
;
951 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519
, ERR_R_MALLOC_FAILURE
);
955 pubkey
= key
->pubkey
;
957 privkey
= ecx_key_allocate_privkey(key
);
958 if (privkey
== NULL
) {
959 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519
, ERR_R_MALLOC_FAILURE
);
963 if (RAND_priv_bytes_ex(ctx
->libctx
, privkey
, X25519_KEYLEN
) <= 0)
970 if (s390x_x25519_mul(pubkey
, generator
, privkey
) != 1)
973 EVP_PKEY_assign(pkey
, ctx
->pmeth
->pkey_id
, key
);
980 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
982 static const unsigned char generator
[] = {
983 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
989 ECX_KEY
*key
= ecx_key_new(ctx
->libctx
, ECX_KEY_TYPE_X448
, 1,
991 unsigned char *privkey
= NULL
, *pubkey
;
994 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448
, ERR_R_MALLOC_FAILURE
);
998 pubkey
= key
->pubkey
;
1000 privkey
= ecx_key_allocate_privkey(key
);
1001 if (privkey
== NULL
) {
1002 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448
, ERR_R_MALLOC_FAILURE
);
1006 if (RAND_priv_bytes_ex(ctx
->libctx
, privkey
, X448_KEYLEN
) <= 0)
1012 if (s390x_x448_mul(pubkey
, generator
, privkey
) != 1)
1015 EVP_PKEY_assign(pkey
, ctx
->pmeth
->pkey_id
, key
);
1022 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
1024 static const unsigned char generator_x
[] = {
1025 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1026 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1027 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1029 static const unsigned char generator_y
[] = {
1030 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1031 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1032 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1034 unsigned char x_dst
[32], buff
[SHA512_DIGEST_LENGTH
];
1035 ECX_KEY
*key
= ecx_key_new(ctx
->libctx
, ECX_KEY_TYPE_ED25519
, 1,
1037 unsigned char *privkey
= NULL
, *pubkey
;
1041 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519
, ERR_R_MALLOC_FAILURE
);
1045 pubkey
= key
->pubkey
;
1047 privkey
= ecx_key_allocate_privkey(key
);
1048 if (privkey
== NULL
) {
1049 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519
, ERR_R_MALLOC_FAILURE
);
1053 if (RAND_priv_bytes_ex(ctx
->libctx
, privkey
, ED25519_KEYLEN
) <= 0)
1056 if (!EVP_Digest(privkey
, 32, buff
, &sz
, EVP_sha512(), NULL
))
1063 if (s390x_ed25519_mul(x_dst
, pubkey
,
1064 generator_x
, generator_y
, buff
) != 1)
1067 pubkey
[31] |= ((x_dst
[0] & 0x01) << 7);
1069 EVP_PKEY_assign(pkey
, ctx
->pmeth
->pkey_id
, key
);
1076 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX
*ctx
, EVP_PKEY
*pkey
)
1078 static const unsigned char generator_x
[] = {
1079 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1080 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1081 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1082 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1083 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1085 static const unsigned char generator_y
[] = {
1086 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1087 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1088 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1089 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1090 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1092 unsigned char x_dst
[57], buff
[114];
1093 ECX_KEY
*key
= ecx_key_new(ctx
->libctx
, ECX_KEY_TYPE_ED448
, 1,
1095 unsigned char *privkey
= NULL
, *pubkey
;
1096 EVP_MD_CTX
*hashctx
= NULL
;
1099 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448
, ERR_R_MALLOC_FAILURE
);
1103 pubkey
= key
->pubkey
;
1105 privkey
= ecx_key_allocate_privkey(key
);
1106 if (privkey
== NULL
) {
1107 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448
, ERR_R_MALLOC_FAILURE
);
1111 if (RAND_priv_bytes_ex(ctx
->libctx
, privkey
, ED448_KEYLEN
) <= 0)
1114 hashctx
= EVP_MD_CTX_new();
1115 if (hashctx
== NULL
)
1117 if (EVP_DigestInit_ex(hashctx
, EVP_shake256(), NULL
) != 1)
1119 if (EVP_DigestUpdate(hashctx
, privkey
, 57) != 1)
1121 if (EVP_DigestFinalXOF(hashctx
, buff
, sizeof(buff
)) != 1)
1128 if (s390x_ed448_mul(x_dst
, pubkey
,
1129 generator_x
, generator_y
, buff
) != 1)
1132 pubkey
[56] |= ((x_dst
[0] & 0x01) << 7);
1134 EVP_PKEY_assign(pkey
, ctx
->pmeth
->pkey_id
, key
);
1135 EVP_MD_CTX_free(hashctx
);
1139 EVP_MD_CTX_free(hashctx
);
1143 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
1146 const unsigned char *privkey
, *pubkey
;
1148 if (!validate_ecx_derive(ctx
, key
, keylen
, &privkey
, &pubkey
))
1152 return s390x_x25519_mul(key
, pubkey
, privkey
);
1154 *keylen
= X25519_KEYLEN
;
1158 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX
*ctx
, unsigned char *key
,
1161 const unsigned char *privkey
, *pubkey
;
1163 if (!validate_ecx_derive(ctx
, key
, keylen
, &privkey
, &pubkey
))
1167 return s390x_x448_mul(key
, pubkey
, privkey
);
1169 *keylen
= X448_KEYLEN
;
1173 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX
*ctx
,
1174 unsigned char *sig
, size_t *siglen
,
1175 const unsigned char *tbs
,
1180 unsigned char sig
[64];
1181 unsigned char priv
[32];
1183 unsigned long long buff
[512];
1185 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
1189 *siglen
= ED25519_SIGSIZE
;
1193 if (*siglen
< ED25519_SIGSIZE
) {
1194 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519
, EC_R_BUFFER_TOO_SMALL
);
1198 memset(¶m
, 0, sizeof(param
));
1199 memcpy(param
.ed25519
.priv
, edkey
->privkey
, sizeof(param
.ed25519
.priv
));
1201 rc
= s390x_kdsa(S390X_EDDSA_SIGN_ED25519
, ¶m
.ed25519
, tbs
, tbslen
);
1202 OPENSSL_cleanse(param
.ed25519
.priv
, sizeof(param
.ed25519
.priv
));
1206 s390x_flip_endian32(sig
, param
.ed25519
.sig
);
1207 s390x_flip_endian32(sig
+ 32, param
.ed25519
.sig
+ 32);
1209 *siglen
= ED25519_SIGSIZE
;
1213 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX
*ctx
,
1214 unsigned char *sig
, size_t *siglen
,
1215 const unsigned char *tbs
,
1220 unsigned char sig
[128];
1221 unsigned char priv
[64];
1223 unsigned long long buff
[512];
1225 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
1229 *siglen
= ED448_SIGSIZE
;
1233 if (*siglen
< ED448_SIGSIZE
) {
1234 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448
, EC_R_BUFFER_TOO_SMALL
);
1238 memset(¶m
, 0, sizeof(param
));
1239 memcpy(param
.ed448
.priv
+ 64 - 57, edkey
->privkey
, 57);
1241 rc
= s390x_kdsa(S390X_EDDSA_SIGN_ED448
, ¶m
.ed448
, tbs
, tbslen
);
1242 OPENSSL_cleanse(param
.ed448
.priv
, sizeof(param
.ed448
.priv
));
1246 s390x_flip_endian64(param
.ed448
.sig
, param
.ed448
.sig
);
1247 s390x_flip_endian64(param
.ed448
.sig
+ 64, param
.ed448
.sig
+ 64);
1248 memcpy(sig
, param
.ed448
.sig
, 57);
1249 memcpy(sig
+ 57, param
.ed448
.sig
+ 64, 57);
1251 *siglen
= ED448_SIGSIZE
;
1255 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX
*ctx
,
1256 const unsigned char *sig
,
1258 const unsigned char *tbs
,
1263 unsigned char sig
[64];
1264 unsigned char pub
[32];
1266 unsigned long long buff
[512];
1268 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
1270 if (siglen
!= ED25519_SIGSIZE
)
1273 memset(¶m
, 0, sizeof(param
));
1274 s390x_flip_endian32(param
.ed25519
.sig
, sig
);
1275 s390x_flip_endian32(param
.ed25519
.sig
+ 32, sig
+ 32);
1276 s390x_flip_endian32(param
.ed25519
.pub
, edkey
->pubkey
);
1278 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519
,
1279 ¶m
.ed25519
, tbs
, tbslen
) == 0 ? 1 : 0;
1282 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX
*ctx
,
1283 const unsigned char *sig
,
1285 const unsigned char *tbs
,
1290 unsigned char sig
[128];
1291 unsigned char pub
[64];
1293 unsigned long long buff
[512];
1295 const ECX_KEY
*edkey
= EVP_MD_CTX_pkey_ctx(ctx
)->pkey
->pkey
.ecx
;
1297 if (siglen
!= ED448_SIGSIZE
)
1300 memset(¶m
, 0, sizeof(param
));
1301 memcpy(param
.ed448
.sig
, sig
, 57);
1302 s390x_flip_endian64(param
.ed448
.sig
, param
.ed448
.sig
);
1303 memcpy(param
.ed448
.sig
+ 64, sig
+ 57, 57);
1304 s390x_flip_endian64(param
.ed448
.sig
+ 64, param
.ed448
.sig
+ 64);
1305 memcpy(param
.ed448
.pub
, edkey
->pubkey
, 57);
1306 s390x_flip_endian64(param
.ed448
.pub
, param
.ed448
.pub
);
1308 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448
,
1309 ¶m
.ed448
, tbs
, tbslen
) == 0 ? 1 : 0;
1312 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth
= {
1314 0, 0, 0, 0, 0, 0, 0,
1315 s390x_pkey_ecx_keygen25519
,
1316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1317 s390x_pkey_ecx_derive25519
,
1322 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth
= {
1324 0, 0, 0, 0, 0, 0, 0,
1325 s390x_pkey_ecx_keygen448
,
1326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1327 s390x_pkey_ecx_derive448
,
1331 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth
= {
1332 EVP_PKEY_ED25519
, EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
1334 s390x_pkey_ecd_keygen25519
,
1335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1338 s390x_pkey_ecd_digestsign25519
,
1339 s390x_pkey_ecd_digestverify25519
1342 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth
= {
1343 EVP_PKEY_ED448
, EVP_PKEY_FLAG_SIGCTX_CUSTOM
,
1345 s390x_pkey_ecd_keygen448
,
1346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1349 s390x_pkey_ecd_digestsign448
,
1350 s390x_pkey_ecd_digestverify448
1354 const EVP_PKEY_METHOD
*ecx25519_pkey_method(void)
1357 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519
))
1358 return &ecx25519_s390x_pkey_meth
;
1360 return &ecx25519_pkey_meth
;
1363 const EVP_PKEY_METHOD
*ecx448_pkey_method(void)
1366 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448
))
1367 return &ecx448_s390x_pkey_meth
;
1369 return &ecx448_pkey_meth
;
1372 const EVP_PKEY_METHOD
*ed25519_pkey_method(void)
1375 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519
)
1376 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519
)
1377 && OPENSSL_s390xcap_P
.kdsa
[0]
1378 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519
))
1379 return &ed25519_s390x_pkey_meth
;
1381 return &ed25519_pkey_meth
;
1384 const EVP_PKEY_METHOD
*ed448_pkey_method(void)
1387 if (OPENSSL_s390xcap_P
.pcc
[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448
)
1388 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448
)
1389 && OPENSSL_s390xcap_P
.kdsa
[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448
))
1390 return &ed448_s390x_pkey_meth
;
1392 return &ed448_pkey_meth
;