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;
1160 key = OPENSSL_zalloc(sizeof(*key));
1162 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1166 pubkey = key->pubkey;
1168 privkey = key->privkey = OPENSSL_secure_malloc(ED25519_KEYLEN);
1169 if (privkey == NULL) {
1170 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1174 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1177 SHA512(privkey, 32, buff);
1182 if (s390x_ed25519_mul(x_dst, pubkey,
1183 generator_x, generator_y, buff) != 1)
1186 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1188 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1191 OPENSSL_secure_clear_free(privkey, ED25519_KEYLEN);
1192 key->privkey = NULL;
1197 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1199 static const unsigned char generator_x[] = {
1200 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1201 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1202 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1203 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1204 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1206 static const unsigned char generator_y[] = {
1207 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1208 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1209 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1210 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1211 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1213 unsigned char x_dst[57], buff[114];
1215 unsigned char *privkey = NULL, *pubkey;
1216 EVP_MD_CTX *hashctx = NULL;
1218 key = OPENSSL_zalloc(sizeof(*key));
1220 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1224 pubkey = key->pubkey;
1226 privkey = key->privkey = OPENSSL_secure_malloc(ED448_KEYLEN);
1227 if (privkey == NULL) {
1228 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1232 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1235 hashctx = EVP_MD_CTX_new();
1236 if (hashctx == NULL)
1238 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1240 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1242 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1249 if (s390x_ed448_mul(x_dst, pubkey,
1250 generator_x, generator_y, buff) != 1)
1253 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1255 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1256 EVP_MD_CTX_free(hashctx);
1259 OPENSSL_secure_clear_free(privkey, ED448_KEYLEN);
1260 key->privkey = NULL;
1262 EVP_MD_CTX_free(hashctx);
1266 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1269 const unsigned char *privkey, *pubkey;
1271 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1275 return s390x_x25519_mul(key, pubkey, privkey);
1277 *keylen = X25519_KEYLEN;
1281 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1284 const unsigned char *privkey, *pubkey;
1286 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1290 return s390x_x448_mul(key, pubkey, privkey);
1292 *keylen = X448_KEYLEN;
1296 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1297 unsigned char *sig, size_t *siglen,
1298 const unsigned char *tbs,
1303 unsigned char sig[64];
1304 unsigned char priv[32];
1306 unsigned long long buff[512];
1308 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1312 *siglen = ED25519_SIGSIZE;
1316 if (*siglen < ED25519_SIGSIZE) {
1317 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1321 memset(¶m, 0, sizeof(param));
1322 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1324 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1325 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1329 s390x_flip_endian32(sig, param.ed25519.sig);
1330 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1332 *siglen = ED25519_SIGSIZE;
1336 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1337 unsigned char *sig, size_t *siglen,
1338 const unsigned char *tbs,
1343 unsigned char sig[128];
1344 unsigned char priv[64];
1346 unsigned long long buff[512];
1348 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1352 *siglen = ED448_SIGSIZE;
1356 if (*siglen < ED448_SIGSIZE) {
1357 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1361 memset(¶m, 0, sizeof(param));
1362 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1364 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1365 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1369 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1370 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1371 memcpy(sig, param.ed448.sig, 57);
1372 memcpy(sig + 57, param.ed448.sig + 64, 57);
1374 *siglen = ED448_SIGSIZE;
1378 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1379 const unsigned char *sig,
1381 const unsigned char *tbs,
1386 unsigned char sig[64];
1387 unsigned char pub[32];
1389 unsigned long long buff[512];
1391 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1393 if (siglen != ED25519_SIGSIZE)
1396 memset(¶m, 0, sizeof(param));
1397 s390x_flip_endian32(param.ed25519.sig, sig);
1398 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1399 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1401 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1402 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1405 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1406 const unsigned char *sig,
1408 const unsigned char *tbs,
1413 unsigned char sig[128];
1414 unsigned char pub[64];
1416 unsigned long long buff[512];
1418 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1420 if (siglen != ED448_SIGSIZE)
1423 memset(¶m, 0, sizeof(param));
1424 memcpy(param.ed448.sig, sig, 57);
1425 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1426 memcpy(param.ed448.sig + 64, sig + 57, 57);
1427 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1428 memcpy(param.ed448.pub, edkey->pubkey, 57);
1429 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1431 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1432 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1435 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1437 0, 0, 0, 0, 0, 0, 0,
1438 s390x_pkey_ecx_keygen25519,
1439 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1440 s390x_pkey_ecx_derive25519,
1445 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1447 0, 0, 0, 0, 0, 0, 0,
1448 s390x_pkey_ecx_keygen448,
1449 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1450 s390x_pkey_ecx_derive448,
1454 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1455 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1457 s390x_pkey_ecd_keygen25519,
1458 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1461 s390x_pkey_ecd_digestsign25519,
1462 s390x_pkey_ecd_digestverify25519
1465 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1466 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1468 s390x_pkey_ecd_keygen448,
1469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1472 s390x_pkey_ecd_digestsign448,
1473 s390x_pkey_ecd_digestverify448
1477 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1480 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1481 return &ecx25519_s390x_pkey_meth;
1483 return &ecx25519_pkey_meth;
1486 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1489 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1490 return &ecx448_s390x_pkey_meth;
1492 return &ecx448_pkey_meth;
1495 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1498 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1499 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1500 && OPENSSL_s390xcap_P.kdsa[0]
1501 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1502 return &ed25519_s390x_pkey_meth;
1504 return &ed25519_pkey_meth;
1507 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1510 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1511 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1512 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1513 return &ed448_s390x_pkey_meth;
1515 return &ed448_pkey_meth;