2 * Copyright 2006-2018 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 "internal/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
27 #include "curve448/curve448_local.h"
29 #define ISX448(id) ((id) == EVP_PKEY_X448)
30 #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
31 #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
32 : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
34 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
43 /* Setup EVP_PKEY using public, private or generation */
44 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
45 const unsigned char *p, int plen, ecx_key_op_t op)
48 unsigned char *privkey, *pubkey;
50 if (op != KEY_OP_KEYGEN) {
54 /* Algorithm parameters must be absent */
55 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
56 if (ptype != V_ASN1_UNDEF) {
57 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
62 if (p == NULL || plen != KEYLENID(id)) {
63 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
68 key = ecx_key_new(KEYLENID(id), 1);
70 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
75 if (op == KEY_OP_PUBLIC) {
76 memcpy(pubkey, p, plen);
78 privkey = ecx_key_allocate_privkey(key);
79 if (privkey == NULL) {
80 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
83 if (op == KEY_OP_KEYGEN) {
84 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
86 if (id == EVP_PKEY_X25519) {
88 privkey[X25519_KEYLEN - 1] &= 127;
89 privkey[X25519_KEYLEN - 1] |= 64;
90 } else if (id == EVP_PKEY_X448) {
92 privkey[X448_KEYLEN - 1] |= 128;
95 memcpy(privkey, p, KEYLENID(id));
99 X25519_public_from_private(pubkey, privkey);
101 case EVP_PKEY_ED25519:
102 ED25519_public_from_private(pubkey, privkey);
105 X448_public_from_private(pubkey, privkey);
109 * TODO(3.0): We set the library context to NULL for now. This will
112 ED448_public_from_private(NULL, pubkey, privkey);
117 EVP_PKEY_assign(pkey, id, key);
124 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
126 const ECX_KEY *ecxkey = pkey->pkey.ecx;
129 if (ecxkey == NULL) {
130 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
134 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
136 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
140 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
141 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
143 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
149 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
151 const unsigned char *p;
155 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
157 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
161 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
163 const ECX_KEY *akey = a->pkey.ecx;
164 const ECX_KEY *bkey = b->pkey.ecx;
166 if (akey == NULL || bkey == NULL)
169 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
172 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
174 const unsigned char *p;
176 ASN1_OCTET_STRING *oct = NULL;
177 const X509_ALGOR *palg;
180 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
183 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
188 p = ASN1_STRING_get0_data(oct);
189 plen = ASN1_STRING_length(oct);
192 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
193 ASN1_STRING_clear_free(oct);
197 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
199 const ECX_KEY *ecxkey = pkey->pkey.ecx;
200 ASN1_OCTET_STRING oct;
201 unsigned char *penc = NULL;
204 if (ecxkey == NULL || ecxkey->privkey == NULL) {
205 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
209 oct.data = ecxkey->privkey;
210 oct.length = KEYLEN(pkey);
213 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
215 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
219 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
220 V_ASN1_UNDEF, NULL, penc, penclen)) {
221 OPENSSL_clear_free(penc, penclen);
222 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
229 static int ecx_size(const EVP_PKEY *pkey)
234 static int ecx_bits(const EVP_PKEY *pkey)
236 if (IS25519(pkey->ameth->pkey_id)) {
238 } else if(ISX448(pkey->ameth->pkey_id)) {
245 static int ecx_security_bits(const EVP_PKEY *pkey)
247 if (IS25519(pkey->ameth->pkey_id)) {
248 return X25519_SECURITY_BITS;
250 return X448_SECURITY_BITS;
254 static void ecx_free(EVP_PKEY *pkey)
256 ecx_key_free(pkey->pkey.ecx);
259 /* "parameters" are always equal */
260 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
265 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
266 ASN1_PCTX *ctx, ecx_key_op_t op)
268 const ECX_KEY *ecxkey = pkey->pkey.ecx;
269 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
271 if (op == KEY_OP_PRIVATE) {
272 if (ecxkey == NULL || ecxkey->privkey == NULL) {
273 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
277 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
279 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
281 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
285 if (ecxkey == NULL) {
286 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
290 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
293 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
296 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
302 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
305 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
308 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
311 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
314 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
318 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
319 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
322 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
323 if (pkey->pkey.ecx != NULL) {
324 unsigned char **ppt = arg2;
326 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
338 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
341 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
342 /* We currently only support Pure EdDSA which takes no digest */
343 *(int *)arg2 = NID_undef;
352 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
355 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
359 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
361 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
365 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
368 const ECX_KEY *key = pkey->pkey.ecx;
371 *len = KEYLENID(pkey->ameth->pkey_id);
376 || key->privkey == NULL
377 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
380 *len = KEYLENID(pkey->ameth->pkey_id);
381 memcpy(priv, key->privkey, *len);
386 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
389 const ECX_KEY *key = pkey->pkey.ecx;
392 *len = KEYLENID(pkey->ameth->pkey_id);
397 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
400 *len = KEYLENID(pkey->ameth->pkey_id);
401 memcpy(pub, key->pubkey, *len);
406 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
409 * We provide no mechanism to "update" an ECX key once it has been set,
410 * therefore we do not have to maintain a dirty count.
415 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
416 EVP_KEYMGMT *to_keymgmt)
418 const ECX_KEY *key = from->pkey.ecx;
420 OSSL_PARAM *params = NULL;
423 ossl_param_bld_init(&tmpl);
425 /* A key must at least have a public part */
426 if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
427 key->pubkey, key->keylen))
430 if (key->privkey != NULL) {
431 if (!ossl_param_bld_push_octet_string(&tmpl,
432 OSSL_PKEY_PARAM_PRIV_KEY,
433 key->privkey, key->keylen))
437 params = ossl_param_bld_to_param(&tmpl);
439 /* We export, the provider imports */
440 rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
444 ossl_param_bld_free(params);
448 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
453 "OpenSSL X25519 algorithm",
493 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
498 "OpenSSL X448 algorithm",
538 static int ecd_size25519(const EVP_PKEY *pkey)
540 return ED25519_SIGSIZE;
543 static int ecd_size448(const EVP_PKEY *pkey)
545 return ED448_SIGSIZE;
548 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
549 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
552 const ASN1_OBJECT *obj;
556 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
557 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
558 nid = OBJ_obj2nid(obj);
559 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
560 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
564 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
570 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
571 X509_ALGOR *alg1, X509_ALGOR *alg2,
572 ASN1_BIT_STRING *str)
574 /* Set algorithms identifiers */
575 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
577 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
578 /* Algorithm identifiers set: carry on as normal */
582 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
583 const ASN1_STRING *sig)
585 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
590 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
591 X509_ALGOR *alg1, X509_ALGOR *alg2,
592 ASN1_BIT_STRING *str)
594 /* Set algorithm identifier */
595 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
597 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
598 /* Algorithm identifier set: carry on as normal */
602 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
603 const ASN1_STRING *sig)
605 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
611 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
616 "OpenSSL ED25519 algorithm",
641 ecd_sig_info_set25519,
655 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
660 "OpenSSL ED448 algorithm",
699 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
701 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
704 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
706 const unsigned char **privkey,
707 const unsigned char **pubkey)
709 const ECX_KEY *ecxkey, *peerkey;
711 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
712 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
715 ecxkey = ctx->pkey->pkey.ecx;
716 peerkey = ctx->peerkey->pkey.ecx;
717 if (ecxkey == NULL || ecxkey->privkey == NULL) {
718 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
721 if (peerkey == NULL) {
722 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
725 *privkey = ecxkey->privkey;
726 *pubkey = peerkey->pubkey;
731 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
734 const unsigned char *privkey, *pubkey;
736 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
738 && X25519(key, privkey, pubkey) == 0))
740 *keylen = X25519_KEYLEN;
744 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
747 const unsigned char *privkey, *pubkey;
749 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
751 && X448(key, privkey, pubkey) == 0))
753 *keylen = X448_KEYLEN;
757 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
759 /* Only need to handle peer key for derivation */
760 if (type == EVP_PKEY_CTRL_PEER_KEY)
765 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
769 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
770 pkey_ecx_derive25519,
775 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
779 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
785 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
786 size_t *siglen, const unsigned char *tbs,
789 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
792 *siglen = ED25519_SIGSIZE;
795 if (*siglen < ED25519_SIGSIZE) {
796 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
800 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
802 *siglen = ED25519_SIGSIZE;
806 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
807 size_t *siglen, const unsigned char *tbs,
810 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
813 *siglen = ED448_SIGSIZE;
816 if (*siglen < ED448_SIGSIZE) {
817 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
822 * TODO(3.0): We use NULL for the library context for now. Will need to
825 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
828 *siglen = ED448_SIGSIZE;
832 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
833 size_t siglen, const unsigned char *tbs,
836 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
838 if (siglen != ED25519_SIGSIZE)
841 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
844 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
845 size_t siglen, const unsigned char *tbs,
848 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
850 if (siglen != ED448_SIGSIZE)
854 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
857 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
860 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
863 case EVP_PKEY_CTRL_MD:
864 /* Only NULL allowed as digest */
865 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
867 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
870 case EVP_PKEY_CTRL_DIGESTINIT:
876 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
877 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
880 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
883 pkey_ecd_digestsign25519,
884 pkey_ecd_digestverify25519
887 static const EVP_PKEY_METHOD ed448_pkey_meth = {
888 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
894 pkey_ecd_digestsign448,
895 pkey_ecd_digestverify448
899 # include "s390x_arch.h"
900 # include "internal/constant_time.h"
902 static void s390x_x25519_mod_p(unsigned char u[32])
904 unsigned char u_red[32];
908 memcpy(u_red, u, sizeof(u_red));
910 c += (unsigned int)u_red[31] + 19;
911 u_red[31] = (unsigned char)c;
914 for (i = 30; i >= 0; i--) {
915 c += (unsigned int)u_red[i];
916 u_red[i] = (unsigned char)c;
920 c = (u_red[0] & 0x80) >> 7;
922 constant_time_cond_swap_buff(0 - (unsigned char)c,
923 u, u_red, sizeof(u_red));
926 static void s390x_x448_mod_p(unsigned char u[56])
928 unsigned char u_red[56];
932 memcpy(u_red, u, sizeof(u_red));
934 c += (unsigned int)u_red[55] + 1;
935 u_red[55] = (unsigned char)c;
938 for (i = 54; i >= 28; i--) {
939 c += (unsigned int)u_red[i];
940 u_red[i] = (unsigned char)c;
944 c += (unsigned int)u_red[27] + 1;
945 u_red[27] = (unsigned char)c;
948 for (i = 26; i >= 0; i--) {
949 c += (unsigned int)u_red[i];
950 u_red[i] = (unsigned char)c;
954 constant_time_cond_swap_buff(0 - (unsigned char)c,
955 u, u_red, sizeof(u_red));
958 int s390x_x25519_mul(unsigned char u_dst[32],
959 const unsigned char u_src[32],
960 const unsigned char d_src[32])
964 unsigned char u_dst[32];
965 unsigned char u_src[32];
966 unsigned char d_src[32];
968 unsigned long long buff[512];
972 memset(¶m, 0, sizeof(param));
974 s390x_flip_endian32(param.x25519.u_src, u_src);
975 param.x25519.u_src[0] &= 0x7f;
976 s390x_x25519_mod_p(param.x25519.u_src);
978 s390x_flip_endian32(param.x25519.d_src, d_src);
979 param.x25519.d_src[31] &= 248;
980 param.x25519.d_src[0] &= 127;
981 param.x25519.d_src[0] |= 64;
983 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
985 s390x_flip_endian32(u_dst, param.x25519.u_dst);
987 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
991 int s390x_x448_mul(unsigned char u_dst[56],
992 const unsigned char u_src[56],
993 const unsigned char d_src[56])
997 unsigned char u_dst[64];
998 unsigned char u_src[64];
999 unsigned char d_src[64];
1001 unsigned long long buff[512];
1005 memset(¶m, 0, sizeof(param));
1007 memcpy(param.x448.u_src, u_src, 56);
1008 memcpy(param.x448.d_src, d_src, 56);
1010 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1011 s390x_x448_mod_p(param.x448.u_src + 8);
1013 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1014 param.x448.d_src[63] &= 252;
1015 param.x448.d_src[8] |= 128;
1017 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1019 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1020 memcpy(u_dst, param.x448.u_dst, 56);
1023 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1027 static int s390x_ed25519_mul(unsigned char x_dst[32],
1028 unsigned char y_dst[32],
1029 const unsigned char x_src[32],
1030 const unsigned char y_src[32],
1031 const unsigned char d_src[32])
1035 unsigned char x_dst[32];
1036 unsigned char y_dst[32];
1037 unsigned char x_src[32];
1038 unsigned char y_src[32];
1039 unsigned char d_src[32];
1041 unsigned long long buff[512];
1045 memset(¶m, 0, sizeof(param));
1047 s390x_flip_endian32(param.ed25519.x_src, x_src);
1048 s390x_flip_endian32(param.ed25519.y_src, y_src);
1049 s390x_flip_endian32(param.ed25519.d_src, d_src);
1051 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1053 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1054 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1057 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1061 static int s390x_ed448_mul(unsigned char x_dst[57],
1062 unsigned char y_dst[57],
1063 const unsigned char x_src[57],
1064 const unsigned char y_src[57],
1065 const unsigned char d_src[57])
1069 unsigned char x_dst[64];
1070 unsigned char y_dst[64];
1071 unsigned char x_src[64];
1072 unsigned char y_src[64];
1073 unsigned char d_src[64];
1075 unsigned long long buff[512];
1079 memset(¶m, 0, sizeof(param));
1081 memcpy(param.ed448.x_src, x_src, 57);
1082 memcpy(param.ed448.y_src, y_src, 57);
1083 memcpy(param.ed448.d_src, d_src, 57);
1084 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1085 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1086 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1088 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1090 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1091 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1092 memcpy(x_dst, param.ed448.x_dst, 57);
1093 memcpy(y_dst, param.ed448.y_dst, 57);
1096 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1100 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1102 static const unsigned char generator[] = {
1103 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1107 ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
1108 unsigned char *privkey = NULL, *pubkey;
1111 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1115 pubkey = key->pubkey;
1117 privkey = ecx_key_allocate_privkey(key);
1118 if (privkey == NULL) {
1119 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1123 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1130 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1133 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1140 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1142 static const unsigned char generator[] = {
1143 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1149 ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
1150 unsigned char *privkey = NULL, *pubkey;
1153 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1157 pubkey = key->pubkey;
1159 privkey = ecx_key_allocate_privkey(key);
1160 if (privkey == NULL) {
1161 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1165 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1171 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1174 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1181 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1183 static const unsigned char generator_x[] = {
1184 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1185 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1186 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1188 static const unsigned char generator_y[] = {
1189 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1190 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1191 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1193 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1194 ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
1195 unsigned char *privkey = NULL, *pubkey;
1199 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1203 pubkey = key->pubkey;
1205 privkey = ecx_key_allocate_privkey(key);
1206 if (privkey == NULL) {
1207 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1211 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1214 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1221 if (s390x_ed25519_mul(x_dst, pubkey,
1222 generator_x, generator_y, buff) != 1)
1225 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1227 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1234 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1236 static const unsigned char generator_x[] = {
1237 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1238 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1239 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1240 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1241 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1243 static const unsigned char generator_y[] = {
1244 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1245 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1246 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1247 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1248 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1250 unsigned char x_dst[57], buff[114];
1251 ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
1252 unsigned char *privkey = NULL, *pubkey;
1253 EVP_MD_CTX *hashctx = NULL;
1256 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1260 pubkey = key->pubkey;
1262 privkey = ecx_key_allocate_privkey(key);
1263 if (privkey == NULL) {
1264 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1268 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1271 hashctx = EVP_MD_CTX_new();
1272 if (hashctx == NULL)
1274 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1276 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1278 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1285 if (s390x_ed448_mul(x_dst, pubkey,
1286 generator_x, generator_y, buff) != 1)
1289 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1291 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1292 EVP_MD_CTX_free(hashctx);
1296 EVP_MD_CTX_free(hashctx);
1300 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1303 const unsigned char *privkey, *pubkey;
1305 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1309 return s390x_x25519_mul(key, pubkey, privkey);
1311 *keylen = X25519_KEYLEN;
1315 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1318 const unsigned char *privkey, *pubkey;
1320 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1324 return s390x_x448_mul(key, pubkey, privkey);
1326 *keylen = X448_KEYLEN;
1330 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1331 unsigned char *sig, size_t *siglen,
1332 const unsigned char *tbs,
1337 unsigned char sig[64];
1338 unsigned char priv[32];
1340 unsigned long long buff[512];
1342 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1346 *siglen = ED25519_SIGSIZE;
1350 if (*siglen < ED25519_SIGSIZE) {
1351 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1355 memset(¶m, 0, sizeof(param));
1356 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1358 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1359 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1363 s390x_flip_endian32(sig, param.ed25519.sig);
1364 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1366 *siglen = ED25519_SIGSIZE;
1370 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1371 unsigned char *sig, size_t *siglen,
1372 const unsigned char *tbs,
1377 unsigned char sig[128];
1378 unsigned char priv[64];
1380 unsigned long long buff[512];
1382 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1386 *siglen = ED448_SIGSIZE;
1390 if (*siglen < ED448_SIGSIZE) {
1391 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1395 memset(¶m, 0, sizeof(param));
1396 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1398 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1399 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1403 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1404 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1405 memcpy(sig, param.ed448.sig, 57);
1406 memcpy(sig + 57, param.ed448.sig + 64, 57);
1408 *siglen = ED448_SIGSIZE;
1412 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1413 const unsigned char *sig,
1415 const unsigned char *tbs,
1420 unsigned char sig[64];
1421 unsigned char pub[32];
1423 unsigned long long buff[512];
1425 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1427 if (siglen != ED25519_SIGSIZE)
1430 memset(¶m, 0, sizeof(param));
1431 s390x_flip_endian32(param.ed25519.sig, sig);
1432 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1433 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1435 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1436 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1439 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1440 const unsigned char *sig,
1442 const unsigned char *tbs,
1447 unsigned char sig[128];
1448 unsigned char pub[64];
1450 unsigned long long buff[512];
1452 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1454 if (siglen != ED448_SIGSIZE)
1457 memset(¶m, 0, sizeof(param));
1458 memcpy(param.ed448.sig, sig, 57);
1459 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1460 memcpy(param.ed448.sig + 64, sig + 57, 57);
1461 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1462 memcpy(param.ed448.pub, edkey->pubkey, 57);
1463 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1465 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1466 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1469 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1471 0, 0, 0, 0, 0, 0, 0,
1472 s390x_pkey_ecx_keygen25519,
1473 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1474 s390x_pkey_ecx_derive25519,
1479 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1481 0, 0, 0, 0, 0, 0, 0,
1482 s390x_pkey_ecx_keygen448,
1483 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1484 s390x_pkey_ecx_derive448,
1488 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1489 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1491 s390x_pkey_ecd_keygen25519,
1492 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1495 s390x_pkey_ecd_digestsign25519,
1496 s390x_pkey_ecd_digestverify25519
1499 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1500 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1502 s390x_pkey_ecd_keygen448,
1503 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1506 s390x_pkey_ecd_digestsign448,
1507 s390x_pkey_ecd_digestverify448
1511 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1514 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1515 return &ecx25519_s390x_pkey_meth;
1517 return &ecx25519_pkey_meth;
1520 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1523 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1524 return &ecx448_s390x_pkey_meth;
1526 return &ecx448_pkey_meth;
1529 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1532 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1533 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1534 && OPENSSL_s390xcap_P.kdsa[0]
1535 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1536 return &ed25519_s390x_pkey_meth;
1538 return &ed25519_pkey_meth;
1541 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1544 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1545 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1546 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1547 return &ed448_s390x_pkey_meth;
1549 return &ed448_pkey_meth;