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 "crypto/asn1.h"
16 #include "crypto/evp.h"
18 #include "curve448/curve448_local.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"
857 # include "internal/constant_time.h"
859 static void s390x_x25519_mod_p(unsigned char u[32])
861 unsigned char u_red[32];
865 memcpy(u_red, u, sizeof(u_red));
867 c += (unsigned int)u_red[31] + 19;
868 u_red[31] = (unsigned char)c;
871 for (i = 30; i >= 0; i--) {
872 c += (unsigned int)u_red[i];
873 u_red[i] = (unsigned char)c;
877 c = (u_red[0] & 0x80) >> 7;
879 constant_time_cond_swap_buff(0 - (unsigned char)c,
880 u, u_red, sizeof(u_red));
883 static void s390x_x448_mod_p(unsigned char u[56])
885 unsigned char u_red[56];
889 memcpy(u_red, u, sizeof(u_red));
891 c += (unsigned int)u_red[55] + 1;
892 u_red[55] = (unsigned char)c;
895 for (i = 54; i >= 28; i--) {
896 c += (unsigned int)u_red[i];
897 u_red[i] = (unsigned char)c;
901 c += (unsigned int)u_red[27] + 1;
902 u_red[27] = (unsigned char)c;
905 for (i = 26; i >= 0; i--) {
906 c += (unsigned int)u_red[i];
907 u_red[i] = (unsigned char)c;
911 constant_time_cond_swap_buff(0 - (unsigned char)c,
912 u, u_red, sizeof(u_red));
915 static int s390x_x25519_mul(unsigned char u_dst[32],
916 const unsigned char u_src[32],
917 const unsigned char d_src[32])
921 unsigned char u_dst[32];
922 unsigned char u_src[32];
923 unsigned char d_src[32];
925 unsigned long long buff[512];
929 memset(¶m, 0, sizeof(param));
931 s390x_flip_endian32(param.x25519.u_src, u_src);
932 param.x25519.u_src[0] &= 0x7f;
933 s390x_x25519_mod_p(param.x25519.u_src);
935 s390x_flip_endian32(param.x25519.d_src, d_src);
936 param.x25519.d_src[31] &= 248;
937 param.x25519.d_src[0] &= 127;
938 param.x25519.d_src[0] |= 64;
940 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
942 s390x_flip_endian32(u_dst, param.x25519.u_dst);
944 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
948 static int s390x_x448_mul(unsigned char u_dst[56],
949 const unsigned char u_src[56],
950 const unsigned char d_src[56])
954 unsigned char u_dst[64];
955 unsigned char u_src[64];
956 unsigned char d_src[64];
958 unsigned long long buff[512];
962 memset(¶m, 0, sizeof(param));
964 memcpy(param.x448.u_src, u_src, 56);
965 memcpy(param.x448.d_src, d_src, 56);
967 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
968 s390x_x448_mod_p(param.x448.u_src + 8);
970 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
971 param.x448.d_src[63] &= 252;
972 param.x448.d_src[8] |= 128;
974 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
976 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
977 memcpy(u_dst, param.x448.u_dst, 56);
980 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
984 static int s390x_ed25519_mul(unsigned char x_dst[32],
985 unsigned char y_dst[32],
986 const unsigned char x_src[32],
987 const unsigned char y_src[32],
988 const unsigned char d_src[32])
992 unsigned char x_dst[32];
993 unsigned char y_dst[32];
994 unsigned char x_src[32];
995 unsigned char y_src[32];
996 unsigned char d_src[32];
998 unsigned long long buff[512];
1002 memset(¶m, 0, sizeof(param));
1004 s390x_flip_endian32(param.ed25519.x_src, x_src);
1005 s390x_flip_endian32(param.ed25519.y_src, y_src);
1006 s390x_flip_endian32(param.ed25519.d_src, d_src);
1008 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1010 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1011 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1014 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1018 static int s390x_ed448_mul(unsigned char x_dst[57],
1019 unsigned char y_dst[57],
1020 const unsigned char x_src[57],
1021 const unsigned char y_src[57],
1022 const unsigned char d_src[57])
1026 unsigned char x_dst[64];
1027 unsigned char y_dst[64];
1028 unsigned char x_src[64];
1029 unsigned char y_src[64];
1030 unsigned char d_src[64];
1032 unsigned long long buff[512];
1036 memset(¶m, 0, sizeof(param));
1038 memcpy(param.ed448.x_src, x_src, 57);
1039 memcpy(param.ed448.y_src, y_src, 57);
1040 memcpy(param.ed448.d_src, d_src, 57);
1041 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1042 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1043 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1045 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1047 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1048 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1049 memcpy(x_dst, param.ed448.x_dst, 57);
1050 memcpy(y_dst, param.ed448.y_dst, 57);
1053 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1057 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1059 static const unsigned char generator[] = {
1060 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1061 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1065 unsigned char *privkey = NULL, *pubkey;
1067 key = OPENSSL_zalloc(sizeof(*key));
1069 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1073 pubkey = key->pubkey;
1075 privkey = key->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
1076 if (privkey == NULL) {
1077 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1081 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1088 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1091 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1094 OPENSSL_secure_clear_free(privkey, X25519_KEYLEN);
1095 key->privkey = NULL;
1100 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1102 static const unsigned char generator[] = {
1103 0x05, 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, 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
1110 unsigned char *privkey = NULL, *pubkey;
1112 key = OPENSSL_zalloc(sizeof(*key));
1114 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1118 pubkey = key->pubkey;
1120 privkey = key->privkey = OPENSSL_secure_malloc(X448_KEYLEN);
1121 if (privkey == NULL) {
1122 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1126 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1132 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1135 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1138 OPENSSL_secure_clear_free(privkey, X448_KEYLEN);
1139 key->privkey = NULL;
1144 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1146 static const unsigned char generator_x[] = {
1147 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1148 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1149 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1151 static const unsigned char generator_y[] = {
1152 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1153 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1154 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1156 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1158 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 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1185 if (s390x_ed25519_mul(x_dst, pubkey,
1186 generator_x, generator_y, buff) != 1)
1189 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1191 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1194 OPENSSL_secure_clear_free(privkey, ED25519_KEYLEN);
1195 key->privkey = NULL;
1200 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1202 static const unsigned char generator_x[] = {
1203 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1204 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1205 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1206 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1207 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1209 static const unsigned char generator_y[] = {
1210 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1211 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1212 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1213 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1214 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1216 unsigned char x_dst[57], buff[114];
1218 unsigned char *privkey = NULL, *pubkey;
1219 EVP_MD_CTX *hashctx = NULL;
1221 key = OPENSSL_zalloc(sizeof(*key));
1223 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1227 pubkey = key->pubkey;
1229 privkey = key->privkey = OPENSSL_secure_malloc(ED448_KEYLEN);
1230 if (privkey == NULL) {
1231 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1235 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1238 hashctx = EVP_MD_CTX_new();
1239 if (hashctx == NULL)
1241 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1243 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1245 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1252 if (s390x_ed448_mul(x_dst, pubkey,
1253 generator_x, generator_y, buff) != 1)
1256 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1258 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1259 EVP_MD_CTX_free(hashctx);
1262 OPENSSL_secure_clear_free(privkey, ED448_KEYLEN);
1263 key->privkey = NULL;
1265 EVP_MD_CTX_free(hashctx);
1269 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1272 const unsigned char *privkey, *pubkey;
1274 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1278 return s390x_x25519_mul(key, pubkey, privkey);
1280 *keylen = X25519_KEYLEN;
1284 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1287 const unsigned char *privkey, *pubkey;
1289 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1293 return s390x_x448_mul(key, pubkey, privkey);
1295 *keylen = X448_KEYLEN;
1299 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1300 unsigned char *sig, size_t *siglen,
1301 const unsigned char *tbs,
1306 unsigned char sig[64];
1307 unsigned char priv[32];
1309 unsigned long long buff[512];
1311 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1315 *siglen = ED25519_SIGSIZE;
1319 if (*siglen < ED25519_SIGSIZE) {
1320 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1324 memset(¶m, 0, sizeof(param));
1325 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1327 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1328 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1332 s390x_flip_endian32(sig, param.ed25519.sig);
1333 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1335 *siglen = ED25519_SIGSIZE;
1339 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1340 unsigned char *sig, size_t *siglen,
1341 const unsigned char *tbs,
1346 unsigned char sig[128];
1347 unsigned char priv[64];
1349 unsigned long long buff[512];
1351 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1355 *siglen = ED448_SIGSIZE;
1359 if (*siglen < ED448_SIGSIZE) {
1360 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1364 memset(¶m, 0, sizeof(param));
1365 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1367 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1368 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1372 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1373 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1374 memcpy(sig, param.ed448.sig, 57);
1375 memcpy(sig + 57, param.ed448.sig + 64, 57);
1377 *siglen = ED448_SIGSIZE;
1381 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1382 const unsigned char *sig,
1384 const unsigned char *tbs,
1389 unsigned char sig[64];
1390 unsigned char pub[32];
1392 unsigned long long buff[512];
1394 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1396 if (siglen != ED25519_SIGSIZE)
1399 memset(¶m, 0, sizeof(param));
1400 s390x_flip_endian32(param.ed25519.sig, sig);
1401 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1402 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1404 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1405 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1408 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1409 const unsigned char *sig,
1411 const unsigned char *tbs,
1416 unsigned char sig[128];
1417 unsigned char pub[64];
1419 unsigned long long buff[512];
1421 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1423 if (siglen != ED448_SIGSIZE)
1426 memset(¶m, 0, sizeof(param));
1427 memcpy(param.ed448.sig, sig, 57);
1428 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1429 memcpy(param.ed448.sig + 64, sig + 57, 57);
1430 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1431 memcpy(param.ed448.pub, edkey->pubkey, 57);
1432 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1434 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1435 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1438 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1440 0, 0, 0, 0, 0, 0, 0,
1441 s390x_pkey_ecx_keygen25519,
1442 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1443 s390x_pkey_ecx_derive25519,
1448 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1450 0, 0, 0, 0, 0, 0, 0,
1451 s390x_pkey_ecx_keygen448,
1452 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1453 s390x_pkey_ecx_derive448,
1457 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1458 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1460 s390x_pkey_ecd_keygen25519,
1461 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1464 s390x_pkey_ecd_digestsign25519,
1465 s390x_pkey_ecd_digestverify25519
1468 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1469 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1471 s390x_pkey_ecd_keygen448,
1472 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1475 s390x_pkey_ecd_digestsign448,
1476 s390x_pkey_ecd_digestverify448
1480 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1483 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1484 return &ecx25519_s390x_pkey_meth;
1486 return &ecx25519_pkey_meth;
1489 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1492 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1493 return &ecx448_s390x_pkey_meth;
1495 return &ecx448_pkey_meth;
1498 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1501 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1502 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1503 && OPENSSL_s390xcap_P.kdsa[0]
1504 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1505 return &ed25519_s390x_pkey_meth;
1507 return &ed25519_pkey_meth;
1510 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1513 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1514 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1515 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1516 return &ed448_s390x_pkey_meth;
1518 return &ed448_pkey_meth;