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 #include "internal/cryptlib.h"
12 #include <openssl/x509.h>
13 #include <openssl/ec.h>
14 #include <openssl/rand.h>
15 #include "internal/asn1_int.h"
16 #include "internal/evp_int.h"
18 #include "curve448/curve448_lcl.h"
20 #define X25519_BITS 253
21 #define X25519_SECURITY_BITS 128
23 #define ED25519_SIGSIZE 64
26 #define ED448_BITS 456
27 #define X448_SECURITY_BITS 224
29 #define ED448_SIGSIZE 114
31 #define ISX448(id) ((id) == EVP_PKEY_X448)
32 #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
33 #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
34 : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
36 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
45 /* Setup EVP_PKEY using public, private or generation */
46 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
47 const unsigned char *p, int plen, ecx_key_op_t op)
50 unsigned char *privkey, *pubkey;
52 if (op != KEY_OP_KEYGEN) {
56 /* Algorithm parameters must be absent */
57 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
58 if (ptype != V_ASN1_UNDEF) {
59 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
64 if (p == NULL || plen != KEYLENID(id)) {
65 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
70 key = OPENSSL_zalloc(sizeof(*key));
72 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
77 if (op == KEY_OP_PUBLIC) {
78 memcpy(pubkey, p, plen);
80 privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
81 if (privkey == NULL) {
82 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
85 if (op == KEY_OP_KEYGEN) {
86 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
87 OPENSSL_secure_free(privkey);
91 if (id == EVP_PKEY_X25519) {
93 privkey[X25519_KEYLEN - 1] &= 127;
94 privkey[X25519_KEYLEN - 1] |= 64;
95 } else if (id == EVP_PKEY_X448) {
97 privkey[X448_KEYLEN - 1] |= 128;
100 memcpy(privkey, p, KEYLENID(id));
103 case EVP_PKEY_X25519:
104 X25519_public_from_private(pubkey, privkey);
106 case EVP_PKEY_ED25519:
107 ED25519_public_from_private(pubkey, privkey);
110 X448_public_from_private(pubkey, privkey);
114 * TODO(3.0): We set the library context to NULL for now. This will
117 ED448_public_from_private(NULL, pubkey, privkey);
122 EVP_PKEY_assign(pkey, id, key);
129 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
131 const ECX_KEY *ecxkey = pkey->pkey.ecx;
134 if (ecxkey == NULL) {
135 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
139 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
141 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
145 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
146 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
148 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
154 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
156 const unsigned char *p;
160 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
162 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
166 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
168 const ECX_KEY *akey = a->pkey.ecx;
169 const ECX_KEY *bkey = b->pkey.ecx;
171 if (akey == NULL || bkey == NULL)
174 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
177 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
179 const unsigned char *p;
181 ASN1_OCTET_STRING *oct = NULL;
182 const X509_ALGOR *palg;
185 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
188 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
193 p = ASN1_STRING_get0_data(oct);
194 plen = ASN1_STRING_length(oct);
197 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
198 ASN1_STRING_clear_free(oct);
202 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
204 const ECX_KEY *ecxkey = pkey->pkey.ecx;
205 ASN1_OCTET_STRING oct;
206 unsigned char *penc = NULL;
209 if (ecxkey == NULL || ecxkey->privkey == NULL) {
210 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
214 oct.data = ecxkey->privkey;
215 oct.length = KEYLEN(pkey);
218 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
220 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
224 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
225 V_ASN1_UNDEF, NULL, penc, penclen)) {
226 OPENSSL_clear_free(penc, penclen);
227 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
234 static int ecx_size(const EVP_PKEY *pkey)
239 static int ecx_bits(const EVP_PKEY *pkey)
241 if (IS25519(pkey->ameth->pkey_id)) {
243 } else if(ISX448(pkey->ameth->pkey_id)) {
250 static int ecx_security_bits(const EVP_PKEY *pkey)
252 if (IS25519(pkey->ameth->pkey_id)) {
253 return X25519_SECURITY_BITS;
255 return X448_SECURITY_BITS;
259 static void ecx_free(EVP_PKEY *pkey)
261 if (pkey->pkey.ecx != NULL)
262 OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
263 OPENSSL_free(pkey->pkey.ecx);
266 /* "parameters" are always equal */
267 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
272 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
273 ASN1_PCTX *ctx, ecx_key_op_t op)
275 const ECX_KEY *ecxkey = pkey->pkey.ecx;
276 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
278 if (op == KEY_OP_PRIVATE) {
279 if (ecxkey == NULL || ecxkey->privkey == NULL) {
280 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
284 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
286 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
288 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
292 if (ecxkey == NULL) {
293 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
297 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
300 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
303 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
309 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
312 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
315 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
318 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
321 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
325 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
326 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
329 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
330 if (pkey->pkey.ecx != NULL) {
331 unsigned char **ppt = arg2;
333 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
345 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
348 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
349 /* We currently only support Pure EdDSA which takes no digest */
350 *(int *)arg2 = NID_undef;
359 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
362 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
366 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
368 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
372 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
375 const ECX_KEY *key = pkey->pkey.ecx;
378 *len = KEYLENID(pkey->ameth->pkey_id);
383 || key->privkey == NULL
384 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
387 *len = KEYLENID(pkey->ameth->pkey_id);
388 memcpy(priv, key->privkey, *len);
393 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
396 const ECX_KEY *key = pkey->pkey.ecx;
399 *len = KEYLENID(pkey->ameth->pkey_id);
404 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
407 *len = KEYLENID(pkey->ameth->pkey_id);
408 memcpy(pub, key->pubkey, *len);
413 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
418 "OpenSSL X25519 algorithm",
456 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
461 "OpenSSL X448 algorithm",
499 static int ecd_size25519(const EVP_PKEY *pkey)
501 return ED25519_SIGSIZE;
504 static int ecd_size448(const EVP_PKEY *pkey)
506 return ED448_SIGSIZE;
509 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
510 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
513 const ASN1_OBJECT *obj;
517 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
518 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
519 nid = OBJ_obj2nid(obj);
520 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
521 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
525 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
531 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
532 X509_ALGOR *alg1, X509_ALGOR *alg2,
533 ASN1_BIT_STRING *str)
535 /* Set algorithms identifiers */
536 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
538 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
539 /* Algorithm identifiers set: carry on as normal */
543 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
544 const ASN1_STRING *sig)
546 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
551 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
552 X509_ALGOR *alg1, X509_ALGOR *alg2,
553 ASN1_BIT_STRING *str)
555 /* Set algorithm identifier */
556 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
558 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
559 /* Algorithm identifier set: carry on as normal */
563 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
564 const ASN1_STRING *sig)
566 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
572 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
577 "OpenSSL ED25519 algorithm",
602 ecd_sig_info_set25519,
614 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
619 "OpenSSL ED448 algorithm",
656 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
658 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
661 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
663 const unsigned char **privkey,
664 const unsigned char **pubkey)
666 const ECX_KEY *ecxkey, *peerkey;
668 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
669 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
672 ecxkey = ctx->pkey->pkey.ecx;
673 peerkey = ctx->peerkey->pkey.ecx;
674 if (ecxkey == NULL || ecxkey->privkey == NULL) {
675 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
678 if (peerkey == NULL) {
679 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
682 *privkey = ecxkey->privkey;
683 *pubkey = peerkey->pubkey;
688 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
691 const unsigned char *privkey, *pubkey;
693 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
695 && X25519(key, privkey, pubkey) == 0))
697 *keylen = X25519_KEYLEN;
701 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
704 const unsigned char *privkey, *pubkey;
706 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
708 && X448(key, privkey, pubkey) == 0))
710 *keylen = X448_KEYLEN;
714 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
716 /* Only need to handle peer key for derivation */
717 if (type == EVP_PKEY_CTRL_PEER_KEY)
722 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
726 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
727 pkey_ecx_derive25519,
732 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
736 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
742 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
743 size_t *siglen, const unsigned char *tbs,
746 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
749 *siglen = ED25519_SIGSIZE;
752 if (*siglen < ED25519_SIGSIZE) {
753 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
757 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
759 *siglen = ED25519_SIGSIZE;
763 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
764 size_t *siglen, const unsigned char *tbs,
767 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
770 *siglen = ED448_SIGSIZE;
773 if (*siglen < ED448_SIGSIZE) {
774 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
779 * TODO(3.0): We use NULL for the library context for now. Will need to
782 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
785 *siglen = ED448_SIGSIZE;
789 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
790 size_t siglen, const unsigned char *tbs,
793 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
795 if (siglen != ED25519_SIGSIZE)
798 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
801 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
802 size_t siglen, const unsigned char *tbs,
805 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
807 if (siglen != ED448_SIGSIZE)
811 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
814 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
817 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
820 case EVP_PKEY_CTRL_MD:
821 /* Only NULL allowed as digest */
822 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
824 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
827 case EVP_PKEY_CTRL_DIGESTINIT:
833 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
834 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
840 pkey_ecd_digestsign25519,
841 pkey_ecd_digestverify25519
844 static const EVP_PKEY_METHOD ed448_pkey_meth = {
845 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
851 pkey_ecd_digestsign448,
852 pkey_ecd_digestverify448
856 # include "s390x_arch.h"
858 static void s390x_x25519_mod_p(unsigned char u[32])
860 unsigned char u_red[32];
864 memcpy(u_red, u, sizeof(u_red));
866 c += (unsigned int)u_red[31] + 19;
867 u_red[31] = (unsigned char)c;
870 for (i = 30; c > 0 && i >= 0; i--) {
871 c += (unsigned int)u_red[i];
872 u_red[i] = (unsigned char)c;
876 if (u_red[0] & 0x80) {
878 memcpy(u, u_red, sizeof(u_red));
882 static void s390x_x448_mod_p(unsigned char u[56])
884 unsigned char u_red[56];
888 memcpy(u_red, u, sizeof(u_red));
890 c += (unsigned int)u_red[55] + 1;
891 u_red[55] = (unsigned char)c;
894 for (i = 54; i >= 28; i--) {
895 c += (unsigned int)u_red[i];
896 u_red[i] = (unsigned char)c;
900 c += (unsigned int)u_red[27] + 1;
901 u_red[27] = (unsigned char)c;
904 for (i = 26; c > 0 && i >= 0; i--) {
905 c += (unsigned int)u_red[i];
906 u_red[i] = (unsigned char)c;
910 if (u_red[0] & 0x80) {
912 memcpy(u, u_red, sizeof(u_red));
916 static int s390x_x25519_mul(unsigned char u_dst[32],
917 const unsigned char u_src[32],
918 const unsigned char d_src[32])
922 unsigned char u_dst[32];
923 unsigned char u_src[32];
924 unsigned char d_src[32];
926 unsigned long long buff[512];
930 memset(¶m, 0, sizeof(param));
932 s390x_flip_endian32(param.x25519.u_src, u_src);
933 param.x25519.u_src[0] &= 0x7f;
934 s390x_x25519_mod_p(param.x25519.u_src);
936 s390x_flip_endian32(param.x25519.d_src, d_src);
937 param.x25519.d_src[31] &= 248;
938 param.x25519.d_src[0] &= 127;
939 param.x25519.d_src[0] |= 64;
941 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
943 s390x_flip_endian32(u_dst, param.x25519.u_dst);
945 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
949 static int s390x_x448_mul(unsigned char u_dst[56],
950 const unsigned char u_src[56],
951 const unsigned char d_src[56])
955 unsigned char u_dst[64];
956 unsigned char u_src[64];
957 unsigned char d_src[64];
959 unsigned long long buff[512];
963 memset(¶m, 0, sizeof(param));
965 memcpy(param.x448.u_src, u_src, 56);
966 memcpy(param.x448.d_src, d_src, 56);
968 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
969 s390x_x448_mod_p(param.x448.u_src);
971 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
972 param.x448.d_src[63] &= 252;
973 param.x448.d_src[8] |= 128;
975 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
977 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
978 memcpy(u_dst, param.x448.u_dst, 56);
981 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
985 static int s390x_ed25519_mul(unsigned char x_dst[32],
986 unsigned char y_dst[32],
987 const unsigned char x_src[32],
988 const unsigned char y_src[32],
989 const unsigned char d_src[32])
993 unsigned char x_dst[32];
994 unsigned char y_dst[32];
995 unsigned char x_src[32];
996 unsigned char y_src[32];
997 unsigned char d_src[32];
999 unsigned long long buff[512];
1003 memset(¶m, 0, sizeof(param));
1005 s390x_flip_endian32(param.ed25519.x_src, x_src);
1006 s390x_flip_endian32(param.ed25519.y_src, y_src);
1007 s390x_flip_endian32(param.ed25519.d_src, d_src);
1009 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1011 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1012 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1015 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1019 static int s390x_ed448_mul(unsigned char x_dst[57],
1020 unsigned char y_dst[57],
1021 const unsigned char x_src[57],
1022 const unsigned char y_src[57],
1023 const unsigned char d_src[57])
1027 unsigned char x_dst[64];
1028 unsigned char y_dst[64];
1029 unsigned char x_src[64];
1030 unsigned char y_src[64];
1031 unsigned char d_src[64];
1033 unsigned long long buff[512];
1037 memset(¶m, 0, sizeof(param));
1039 memcpy(param.ed448.x_src, x_src, 57);
1040 memcpy(param.ed448.y_src, y_src, 57);
1041 memcpy(param.ed448.d_src, d_src, 57);
1042 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1043 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1044 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1046 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1048 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1049 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1050 memcpy(x_dst, param.ed448.x_dst, 57);
1051 memcpy(y_dst, param.ed448.y_dst, 57);
1054 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1058 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1060 static const unsigned char generator[] = {
1061 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1066 unsigned char *privkey = NULL, *pubkey;
1068 key = OPENSSL_zalloc(sizeof(*key));
1070 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1074 pubkey = key->pubkey;
1076 privkey = key->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
1077 if (privkey == NULL) {
1078 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1082 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1089 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1092 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1095 OPENSSL_secure_clear_free(privkey, X25519_KEYLEN);
1096 key->privkey = NULL;
1101 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1103 static const unsigned char generator[] = {
1104 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1111 unsigned char *privkey = NULL, *pubkey;
1113 key = OPENSSL_zalloc(sizeof(*key));
1115 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1119 pubkey = key->pubkey;
1121 privkey = key->privkey = OPENSSL_secure_malloc(X448_KEYLEN);
1122 if (privkey == NULL) {
1123 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1127 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1133 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1136 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1139 OPENSSL_secure_clear_free(privkey, X448_KEYLEN);
1140 key->privkey = NULL;
1145 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1147 static const unsigned char generator_x[] = {
1148 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1149 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1150 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1152 static const unsigned char generator_y[] = {
1153 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1154 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1155 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1157 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1159 unsigned char *privkey = NULL, *pubkey;
1161 key = OPENSSL_zalloc(sizeof(*key));
1163 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1167 pubkey = key->pubkey;
1169 privkey = key->privkey = OPENSSL_secure_malloc(ED25519_KEYLEN);
1170 if (privkey == NULL) {
1171 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1175 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1178 SHA512(privkey, 32, buff);
1183 if (s390x_ed25519_mul(x_dst, pubkey,
1184 generator_x, generator_y, buff) != 1)
1187 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1189 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1192 OPENSSL_secure_clear_free(privkey, ED25519_KEYLEN);
1193 key->privkey = NULL;
1198 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1200 static const unsigned char generator_x[] = {
1201 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1202 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1203 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1204 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1205 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1207 static const unsigned char generator_y[] = {
1208 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1209 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1210 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1211 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1212 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1214 unsigned char x_dst[57], buff[114];
1216 unsigned char *privkey = NULL, *pubkey;
1217 EVP_MD_CTX *hashctx = NULL;
1219 key = OPENSSL_zalloc(sizeof(*key));
1221 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1225 pubkey = key->pubkey;
1227 privkey = key->privkey = OPENSSL_secure_malloc(ED448_KEYLEN);
1228 if (privkey == NULL) {
1229 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1233 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1236 hashctx = EVP_MD_CTX_new();
1237 if (hashctx == NULL)
1239 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1241 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1243 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1250 if (s390x_ed448_mul(x_dst, pubkey,
1251 generator_x, generator_y, buff) != 1)
1254 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1256 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1257 EVP_MD_CTX_free(hashctx);
1260 OPENSSL_secure_clear_free(privkey, ED448_KEYLEN);
1261 key->privkey = NULL;
1263 EVP_MD_CTX_free(hashctx);
1267 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1270 const unsigned char *privkey, *pubkey;
1272 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1276 return s390x_x25519_mul(key, pubkey, privkey);
1278 *keylen = X25519_KEYLEN;
1282 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1285 const unsigned char *privkey, *pubkey;
1287 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1291 return s390x_x448_mul(key, pubkey, privkey);
1293 *keylen = X448_KEYLEN;
1297 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1298 unsigned char *sig, size_t *siglen,
1299 const unsigned char *tbs,
1304 unsigned char sig[64];
1305 unsigned char priv[32];
1307 unsigned long long buff[512];
1309 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1313 *siglen = ED25519_SIGSIZE;
1317 if (*siglen < ED25519_SIGSIZE) {
1318 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1322 memset(¶m, 0, sizeof(param));
1323 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1325 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1326 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1330 s390x_flip_endian32(sig, param.ed25519.sig);
1331 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1333 *siglen = ED25519_SIGSIZE;
1337 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1338 unsigned char *sig, size_t *siglen,
1339 const unsigned char *tbs,
1344 unsigned char sig[128];
1345 unsigned char priv[64];
1347 unsigned long long buff[512];
1349 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1353 *siglen = ED448_SIGSIZE;
1357 if (*siglen < ED448_SIGSIZE) {
1358 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1362 memset(¶m, 0, sizeof(param));
1363 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1365 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1366 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1370 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1371 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1372 memcpy(sig, param.ed448.sig, 57);
1373 memcpy(sig + 57, param.ed448.sig + 64, 57);
1375 *siglen = ED448_SIGSIZE;
1379 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1380 const unsigned char *sig,
1382 const unsigned char *tbs,
1387 unsigned char sig[64];
1388 unsigned char pub[32];
1390 unsigned long long buff[512];
1392 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1394 if (siglen != ED25519_SIGSIZE)
1397 memset(¶m, 0, sizeof(param));
1398 s390x_flip_endian32(param.ed25519.sig, sig);
1399 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1400 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1402 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1403 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1406 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1407 const unsigned char *sig,
1409 const unsigned char *tbs,
1414 unsigned char sig[128];
1415 unsigned char pub[64];
1417 unsigned long long buff[512];
1419 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1421 if (siglen != ED448_SIGSIZE)
1424 memset(¶m, 0, sizeof(param));
1425 memcpy(param.ed448.sig, sig, 57);
1426 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1427 memcpy(param.ed448.sig + 64, sig + 57, 57);
1428 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1429 memcpy(param.ed448.pub, edkey->pubkey, 57);
1430 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1432 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1433 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1436 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1438 0, 0, 0, 0, 0, 0, 0,
1439 s390x_pkey_ecx_keygen25519,
1440 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1441 s390x_pkey_ecx_derive25519,
1446 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1448 0, 0, 0, 0, 0, 0, 0,
1449 s390x_pkey_ecx_keygen448,
1450 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1451 s390x_pkey_ecx_derive448,
1455 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1456 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1458 s390x_pkey_ecd_keygen25519,
1459 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1462 s390x_pkey_ecd_digestsign25519,
1463 s390x_pkey_ecd_digestverify25519
1466 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1467 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1469 s390x_pkey_ecd_keygen448,
1470 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1473 s390x_pkey_ecd_digestsign448,
1474 s390x_pkey_ecd_digestverify448
1478 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1481 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1482 return &ecx25519_s390x_pkey_meth;
1484 return &ecx25519_pkey_meth;
1487 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1490 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1491 return &ecx448_s390x_pkey_meth;
1493 return &ecx448_pkey_meth;
1496 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1499 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1500 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1501 && OPENSSL_s390xcap_P.kdsa[0]
1502 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1503 return &ed25519_s390x_pkey_meth;
1505 return &ed25519_pkey_meth;
1508 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1511 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1512 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1513 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1514 return &ed448_s390x_pkey_meth;
1516 return &ed448_pkey_meth;