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 "crypto/asn1.h"
22 #include "crypto/evp.h"
24 #include "curve448/curve448_local.h"
26 #define X25519_BITS 253
27 #define X25519_SECURITY_BITS 128
29 #define ED25519_SIGSIZE 64
32 #define ED448_BITS 456
33 #define X448_SECURITY_BITS 224
35 #define ED448_SIGSIZE 114
37 #define ISX448(id) ((id) == EVP_PKEY_X448)
38 #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
39 #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
40 : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
42 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
51 /* Setup EVP_PKEY using public, private or generation */
52 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
53 const unsigned char *p, int plen, ecx_key_op_t op)
56 unsigned char *privkey, *pubkey;
58 if (op != KEY_OP_KEYGEN) {
62 /* Algorithm parameters must be absent */
63 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
64 if (ptype != V_ASN1_UNDEF) {
65 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
70 if (p == NULL || plen != KEYLENID(id)) {
71 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
76 key = OPENSSL_zalloc(sizeof(*key));
78 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
83 if (op == KEY_OP_PUBLIC) {
84 memcpy(pubkey, p, plen);
86 privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
87 if (privkey == NULL) {
88 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
91 if (op == KEY_OP_KEYGEN) {
92 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
93 OPENSSL_secure_free(privkey);
97 if (id == EVP_PKEY_X25519) {
99 privkey[X25519_KEYLEN - 1] &= 127;
100 privkey[X25519_KEYLEN - 1] |= 64;
101 } else if (id == EVP_PKEY_X448) {
103 privkey[X448_KEYLEN - 1] |= 128;
106 memcpy(privkey, p, KEYLENID(id));
109 case EVP_PKEY_X25519:
110 X25519_public_from_private(pubkey, privkey);
112 case EVP_PKEY_ED25519:
113 ED25519_public_from_private(pubkey, privkey);
116 X448_public_from_private(pubkey, privkey);
120 * TODO(3.0): We set the library context to NULL for now. This will
123 ED448_public_from_private(NULL, pubkey, privkey);
128 EVP_PKEY_assign(pkey, id, key);
135 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
137 const ECX_KEY *ecxkey = pkey->pkey.ecx;
140 if (ecxkey == NULL) {
141 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
145 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
147 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
151 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
152 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
154 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
160 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
162 const unsigned char *p;
166 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
168 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
172 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
174 const ECX_KEY *akey = a->pkey.ecx;
175 const ECX_KEY *bkey = b->pkey.ecx;
177 if (akey == NULL || bkey == NULL)
180 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
183 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
185 const unsigned char *p;
187 ASN1_OCTET_STRING *oct = NULL;
188 const X509_ALGOR *palg;
191 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
194 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
199 p = ASN1_STRING_get0_data(oct);
200 plen = ASN1_STRING_length(oct);
203 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
204 ASN1_STRING_clear_free(oct);
208 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
210 const ECX_KEY *ecxkey = pkey->pkey.ecx;
211 ASN1_OCTET_STRING oct;
212 unsigned char *penc = NULL;
215 if (ecxkey == NULL || ecxkey->privkey == NULL) {
216 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
220 oct.data = ecxkey->privkey;
221 oct.length = KEYLEN(pkey);
224 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
226 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
230 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
231 V_ASN1_UNDEF, NULL, penc, penclen)) {
232 OPENSSL_clear_free(penc, penclen);
233 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
240 static int ecx_size(const EVP_PKEY *pkey)
245 static int ecx_bits(const EVP_PKEY *pkey)
247 if (IS25519(pkey->ameth->pkey_id)) {
249 } else if(ISX448(pkey->ameth->pkey_id)) {
256 static int ecx_security_bits(const EVP_PKEY *pkey)
258 if (IS25519(pkey->ameth->pkey_id)) {
259 return X25519_SECURITY_BITS;
261 return X448_SECURITY_BITS;
265 static void ecx_free(EVP_PKEY *pkey)
267 if (pkey->pkey.ecx != NULL)
268 OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
269 OPENSSL_free(pkey->pkey.ecx);
272 /* "parameters" are always equal */
273 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
278 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
279 ASN1_PCTX *ctx, ecx_key_op_t op)
281 const ECX_KEY *ecxkey = pkey->pkey.ecx;
282 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
284 if (op == KEY_OP_PRIVATE) {
285 if (ecxkey == NULL || ecxkey->privkey == NULL) {
286 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
290 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
292 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
294 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
298 if (ecxkey == NULL) {
299 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
303 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
306 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
309 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
315 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
318 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
321 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
324 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
327 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
331 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
332 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
335 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
336 if (pkey->pkey.ecx != NULL) {
337 unsigned char **ppt = arg2;
339 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
351 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
354 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
355 /* We currently only support Pure EdDSA which takes no digest */
356 *(int *)arg2 = NID_undef;
365 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
368 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
372 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
374 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
378 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
381 const ECX_KEY *key = pkey->pkey.ecx;
384 *len = KEYLENID(pkey->ameth->pkey_id);
389 || key->privkey == NULL
390 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
393 *len = KEYLENID(pkey->ameth->pkey_id);
394 memcpy(priv, key->privkey, *len);
399 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
402 const ECX_KEY *key = pkey->pkey.ecx;
405 *len = KEYLENID(pkey->ameth->pkey_id);
410 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
413 *len = KEYLENID(pkey->ameth->pkey_id);
414 memcpy(pub, key->pubkey, *len);
419 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
424 "OpenSSL X25519 algorithm",
462 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
467 "OpenSSL X448 algorithm",
505 static int ecd_size25519(const EVP_PKEY *pkey)
507 return ED25519_SIGSIZE;
510 static int ecd_size448(const EVP_PKEY *pkey)
512 return ED448_SIGSIZE;
515 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
516 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
519 const ASN1_OBJECT *obj;
523 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
524 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
525 nid = OBJ_obj2nid(obj);
526 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
527 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
531 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
537 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
538 X509_ALGOR *alg1, X509_ALGOR *alg2,
539 ASN1_BIT_STRING *str)
541 /* Set algorithms identifiers */
542 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
544 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
545 /* Algorithm identifiers set: carry on as normal */
549 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
550 const ASN1_STRING *sig)
552 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
557 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
558 X509_ALGOR *alg1, X509_ALGOR *alg2,
559 ASN1_BIT_STRING *str)
561 /* Set algorithm identifier */
562 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
564 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
565 /* Algorithm identifier set: carry on as normal */
569 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
570 const ASN1_STRING *sig)
572 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
578 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
583 "OpenSSL ED25519 algorithm",
608 ecd_sig_info_set25519,
620 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
625 "OpenSSL ED448 algorithm",
662 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
664 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
667 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
669 const unsigned char **privkey,
670 const unsigned char **pubkey)
672 const ECX_KEY *ecxkey, *peerkey;
674 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
675 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
678 ecxkey = ctx->pkey->pkey.ecx;
679 peerkey = ctx->peerkey->pkey.ecx;
680 if (ecxkey == NULL || ecxkey->privkey == NULL) {
681 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
684 if (peerkey == NULL) {
685 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
688 *privkey = ecxkey->privkey;
689 *pubkey = peerkey->pubkey;
694 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
697 const unsigned char *privkey, *pubkey;
699 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
701 && X25519(key, privkey, pubkey) == 0))
703 *keylen = X25519_KEYLEN;
707 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
710 const unsigned char *privkey, *pubkey;
712 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
714 && X448(key, privkey, pubkey) == 0))
716 *keylen = X448_KEYLEN;
720 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
722 /* Only need to handle peer key for derivation */
723 if (type == EVP_PKEY_CTRL_PEER_KEY)
728 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
732 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
733 pkey_ecx_derive25519,
738 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
742 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
748 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
749 size_t *siglen, const unsigned char *tbs,
752 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
755 *siglen = ED25519_SIGSIZE;
758 if (*siglen < ED25519_SIGSIZE) {
759 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
763 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
765 *siglen = ED25519_SIGSIZE;
769 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
770 size_t *siglen, const unsigned char *tbs,
773 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
776 *siglen = ED448_SIGSIZE;
779 if (*siglen < ED448_SIGSIZE) {
780 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
785 * TODO(3.0): We use NULL for the library context for now. Will need to
788 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
791 *siglen = ED448_SIGSIZE;
795 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
796 size_t siglen, const unsigned char *tbs,
799 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
801 if (siglen != ED25519_SIGSIZE)
804 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
807 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
808 size_t siglen, const unsigned char *tbs,
811 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
813 if (siglen != ED448_SIGSIZE)
817 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
820 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
823 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
826 case EVP_PKEY_CTRL_MD:
827 /* Only NULL allowed as digest */
828 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
830 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
833 case EVP_PKEY_CTRL_DIGESTINIT:
839 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
840 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
843 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
846 pkey_ecd_digestsign25519,
847 pkey_ecd_digestverify25519
850 static const EVP_PKEY_METHOD ed448_pkey_meth = {
851 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
854 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
857 pkey_ecd_digestsign448,
858 pkey_ecd_digestverify448
862 # include "s390x_arch.h"
863 # include "internal/constant_time.h"
865 static void s390x_x25519_mod_p(unsigned char u[32])
867 unsigned char u_red[32];
871 memcpy(u_red, u, sizeof(u_red));
873 c += (unsigned int)u_red[31] + 19;
874 u_red[31] = (unsigned char)c;
877 for (i = 30; i >= 0; i--) {
878 c += (unsigned int)u_red[i];
879 u_red[i] = (unsigned char)c;
883 c = (u_red[0] & 0x80) >> 7;
885 constant_time_cond_swap_buff(0 - (unsigned char)c,
886 u, u_red, sizeof(u_red));
889 static void s390x_x448_mod_p(unsigned char u[56])
891 unsigned char u_red[56];
895 memcpy(u_red, u, sizeof(u_red));
897 c += (unsigned int)u_red[55] + 1;
898 u_red[55] = (unsigned char)c;
901 for (i = 54; i >= 28; i--) {
902 c += (unsigned int)u_red[i];
903 u_red[i] = (unsigned char)c;
907 c += (unsigned int)u_red[27] + 1;
908 u_red[27] = (unsigned char)c;
911 for (i = 26; i >= 0; i--) {
912 c += (unsigned int)u_red[i];
913 u_red[i] = (unsigned char)c;
917 constant_time_cond_swap_buff(0 - (unsigned char)c,
918 u, u_red, sizeof(u_red));
921 static int s390x_x25519_mul(unsigned char u_dst[32],
922 const unsigned char u_src[32],
923 const unsigned char d_src[32])
927 unsigned char u_dst[32];
928 unsigned char u_src[32];
929 unsigned char d_src[32];
931 unsigned long long buff[512];
935 memset(¶m, 0, sizeof(param));
937 s390x_flip_endian32(param.x25519.u_src, u_src);
938 param.x25519.u_src[0] &= 0x7f;
939 s390x_x25519_mod_p(param.x25519.u_src);
941 s390x_flip_endian32(param.x25519.d_src, d_src);
942 param.x25519.d_src[31] &= 248;
943 param.x25519.d_src[0] &= 127;
944 param.x25519.d_src[0] |= 64;
946 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
948 s390x_flip_endian32(u_dst, param.x25519.u_dst);
950 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
954 static int s390x_x448_mul(unsigned char u_dst[56],
955 const unsigned char u_src[56],
956 const unsigned char d_src[56])
960 unsigned char u_dst[64];
961 unsigned char u_src[64];
962 unsigned char d_src[64];
964 unsigned long long buff[512];
968 memset(¶m, 0, sizeof(param));
970 memcpy(param.x448.u_src, u_src, 56);
971 memcpy(param.x448.d_src, d_src, 56);
973 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
974 s390x_x448_mod_p(param.x448.u_src + 8);
976 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
977 param.x448.d_src[63] &= 252;
978 param.x448.d_src[8] |= 128;
980 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
982 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
983 memcpy(u_dst, param.x448.u_dst, 56);
986 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
990 static int s390x_ed25519_mul(unsigned char x_dst[32],
991 unsigned char y_dst[32],
992 const unsigned char x_src[32],
993 const unsigned char y_src[32],
994 const unsigned char d_src[32])
998 unsigned char x_dst[32];
999 unsigned char y_dst[32];
1000 unsigned char x_src[32];
1001 unsigned char y_src[32];
1002 unsigned char d_src[32];
1004 unsigned long long buff[512];
1008 memset(¶m, 0, sizeof(param));
1010 s390x_flip_endian32(param.ed25519.x_src, x_src);
1011 s390x_flip_endian32(param.ed25519.y_src, y_src);
1012 s390x_flip_endian32(param.ed25519.d_src, d_src);
1014 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1016 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1017 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1020 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1024 static int s390x_ed448_mul(unsigned char x_dst[57],
1025 unsigned char y_dst[57],
1026 const unsigned char x_src[57],
1027 const unsigned char y_src[57],
1028 const unsigned char d_src[57])
1032 unsigned char x_dst[64];
1033 unsigned char y_dst[64];
1034 unsigned char x_src[64];
1035 unsigned char y_src[64];
1036 unsigned char d_src[64];
1038 unsigned long long buff[512];
1042 memset(¶m, 0, sizeof(param));
1044 memcpy(param.ed448.x_src, x_src, 57);
1045 memcpy(param.ed448.y_src, y_src, 57);
1046 memcpy(param.ed448.d_src, d_src, 57);
1047 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1048 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1049 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1051 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1053 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1054 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1055 memcpy(x_dst, param.ed448.x_dst, 57);
1056 memcpy(y_dst, param.ed448.y_dst, 57);
1059 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1063 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1065 static const unsigned char generator[] = {
1066 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1068 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1071 unsigned char *privkey = NULL, *pubkey;
1073 key = OPENSSL_zalloc(sizeof(*key));
1075 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1079 pubkey = key->pubkey;
1081 privkey = key->privkey = OPENSSL_secure_malloc(X25519_KEYLEN);
1082 if (privkey == NULL) {
1083 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1087 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1094 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1097 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1100 OPENSSL_secure_clear_free(privkey, X25519_KEYLEN);
1101 key->privkey = NULL;
1106 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1108 static const unsigned char generator[] = {
1109 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1116 unsigned char *privkey = NULL, *pubkey;
1118 key = OPENSSL_zalloc(sizeof(*key));
1120 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1124 pubkey = key->pubkey;
1126 privkey = key->privkey = OPENSSL_secure_malloc(X448_KEYLEN);
1127 if (privkey == NULL) {
1128 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1132 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1138 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1141 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1144 OPENSSL_secure_clear_free(privkey, X448_KEYLEN);
1145 key->privkey = NULL;
1150 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1152 static const unsigned char generator_x[] = {
1153 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1154 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1155 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1157 static const unsigned char generator_y[] = {
1158 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1159 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1160 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1162 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1164 unsigned char *privkey = NULL, *pubkey;
1167 key = OPENSSL_zalloc(sizeof(*key));
1169 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1173 pubkey = key->pubkey;
1175 privkey = key->privkey = OPENSSL_secure_malloc(ED25519_KEYLEN);
1176 if (privkey == NULL) {
1177 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1181 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1184 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1191 if (s390x_ed25519_mul(x_dst, pubkey,
1192 generator_x, generator_y, buff) != 1)
1195 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1197 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1200 OPENSSL_secure_clear_free(privkey, ED25519_KEYLEN);
1201 key->privkey = NULL;
1206 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1208 static const unsigned char generator_x[] = {
1209 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1210 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1211 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1212 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1213 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1215 static const unsigned char generator_y[] = {
1216 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1217 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1218 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1219 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1220 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1222 unsigned char x_dst[57], buff[114];
1224 unsigned char *privkey = NULL, *pubkey;
1225 EVP_MD_CTX *hashctx = NULL;
1227 key = OPENSSL_zalloc(sizeof(*key));
1229 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1233 pubkey = key->pubkey;
1235 privkey = key->privkey = OPENSSL_secure_malloc(ED448_KEYLEN);
1236 if (privkey == NULL) {
1237 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1241 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1244 hashctx = EVP_MD_CTX_new();
1245 if (hashctx == NULL)
1247 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1249 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1251 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1258 if (s390x_ed448_mul(x_dst, pubkey,
1259 generator_x, generator_y, buff) != 1)
1262 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1264 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1265 EVP_MD_CTX_free(hashctx);
1268 OPENSSL_secure_clear_free(privkey, ED448_KEYLEN);
1269 key->privkey = NULL;
1271 EVP_MD_CTX_free(hashctx);
1275 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1278 const unsigned char *privkey, *pubkey;
1280 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1284 return s390x_x25519_mul(key, pubkey, privkey);
1286 *keylen = X25519_KEYLEN;
1290 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1293 const unsigned char *privkey, *pubkey;
1295 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1299 return s390x_x448_mul(key, pubkey, privkey);
1301 *keylen = X448_KEYLEN;
1305 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1306 unsigned char *sig, size_t *siglen,
1307 const unsigned char *tbs,
1312 unsigned char sig[64];
1313 unsigned char priv[32];
1315 unsigned long long buff[512];
1317 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1321 *siglen = ED25519_SIGSIZE;
1325 if (*siglen < ED25519_SIGSIZE) {
1326 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1330 memset(¶m, 0, sizeof(param));
1331 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1333 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1334 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1338 s390x_flip_endian32(sig, param.ed25519.sig);
1339 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1341 *siglen = ED25519_SIGSIZE;
1345 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1346 unsigned char *sig, size_t *siglen,
1347 const unsigned char *tbs,
1352 unsigned char sig[128];
1353 unsigned char priv[64];
1355 unsigned long long buff[512];
1357 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1361 *siglen = ED448_SIGSIZE;
1365 if (*siglen < ED448_SIGSIZE) {
1366 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1370 memset(¶m, 0, sizeof(param));
1371 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1373 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1374 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1378 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1379 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1380 memcpy(sig, param.ed448.sig, 57);
1381 memcpy(sig + 57, param.ed448.sig + 64, 57);
1383 *siglen = ED448_SIGSIZE;
1387 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1388 const unsigned char *sig,
1390 const unsigned char *tbs,
1395 unsigned char sig[64];
1396 unsigned char pub[32];
1398 unsigned long long buff[512];
1400 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1402 if (siglen != ED25519_SIGSIZE)
1405 memset(¶m, 0, sizeof(param));
1406 s390x_flip_endian32(param.ed25519.sig, sig);
1407 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1408 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1410 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1411 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1414 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1415 const unsigned char *sig,
1417 const unsigned char *tbs,
1422 unsigned char sig[128];
1423 unsigned char pub[64];
1425 unsigned long long buff[512];
1427 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1429 if (siglen != ED448_SIGSIZE)
1432 memset(¶m, 0, sizeof(param));
1433 memcpy(param.ed448.sig, sig, 57);
1434 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1435 memcpy(param.ed448.sig + 64, sig + 57, 57);
1436 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1437 memcpy(param.ed448.pub, edkey->pubkey, 57);
1438 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1440 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1441 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1444 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1446 0, 0, 0, 0, 0, 0, 0,
1447 s390x_pkey_ecx_keygen25519,
1448 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1449 s390x_pkey_ecx_derive25519,
1454 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1456 0, 0, 0, 0, 0, 0, 0,
1457 s390x_pkey_ecx_keygen448,
1458 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1459 s390x_pkey_ecx_derive448,
1463 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1464 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1466 s390x_pkey_ecd_keygen25519,
1467 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1470 s390x_pkey_ecd_digestsign25519,
1471 s390x_pkey_ecd_digestverify25519
1474 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1475 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1477 s390x_pkey_ecd_keygen448,
1478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1481 s390x_pkey_ecd_digestsign448,
1482 s390x_pkey_ecd_digestverify448
1486 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1489 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1490 return &ecx25519_s390x_pkey_meth;
1492 return &ecx25519_pkey_meth;
1495 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1498 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1499 return &ecx448_s390x_pkey_meth;
1501 return &ecx448_pkey_meth;
1504 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1507 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1508 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1509 && OPENSSL_s390xcap_P.kdsa[0]
1510 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1511 return &ed25519_s390x_pkey_meth;
1513 return &ed25519_pkey_meth;
1516 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1519 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1520 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1521 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1522 return &ed448_s390x_pkey_meth;
1524 return &ed448_pkey_meth;