2 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * ECDSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
17 #include "internal/cryptlib.h"
18 #include <openssl/x509.h>
19 #include <openssl/ec.h>
20 #include <openssl/rand.h>
21 #include <openssl/core_names.h>
22 #include "internal/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
27 #include "curve448/curve448_local.h"
29 #define ISX448(id) ((id) == EVP_PKEY_X448)
30 #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
31 #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
32 : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
34 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
43 /* Setup EVP_PKEY using public, private or generation */
44 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
45 const unsigned char *p, int plen, ecx_key_op_t op)
48 unsigned char *privkey, *pubkey;
50 if (op != KEY_OP_KEYGEN) {
54 /* Algorithm parameters must be absent */
55 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
56 if (ptype != V_ASN1_UNDEF) {
57 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
62 if (p == NULL || plen != KEYLENID(id)) {
63 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
68 key = ecx_key_new(KEYLENID(id), 1);
70 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
75 if (op == KEY_OP_PUBLIC) {
76 memcpy(pubkey, p, plen);
78 privkey = ecx_key_allocate_privkey(key);
79 if (privkey == NULL) {
80 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
83 if (op == KEY_OP_KEYGEN) {
84 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
86 if (id == EVP_PKEY_X25519) {
88 privkey[X25519_KEYLEN - 1] &= 127;
89 privkey[X25519_KEYLEN - 1] |= 64;
90 } else if (id == EVP_PKEY_X448) {
92 privkey[X448_KEYLEN - 1] |= 128;
95 memcpy(privkey, p, KEYLENID(id));
99 X25519_public_from_private(pubkey, privkey);
101 case EVP_PKEY_ED25519:
102 ED25519_public_from_private(pubkey, privkey);
105 X448_public_from_private(pubkey, privkey);
109 * TODO(3.0): We set the library context to NULL for now. This will
112 ED448_public_from_private(NULL, pubkey, privkey);
117 EVP_PKEY_assign(pkey, id, key);
124 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
126 const ECX_KEY *ecxkey = pkey->pkey.ecx;
129 if (ecxkey == NULL) {
130 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
134 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
136 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
140 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
141 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
143 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
149 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
151 const unsigned char *p;
155 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
157 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
161 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
163 const ECX_KEY *akey = a->pkey.ecx;
164 const ECX_KEY *bkey = b->pkey.ecx;
166 if (akey == NULL || bkey == NULL)
169 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
172 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
174 const unsigned char *p;
176 ASN1_OCTET_STRING *oct = NULL;
177 const X509_ALGOR *palg;
180 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
183 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
188 p = ASN1_STRING_get0_data(oct);
189 plen = ASN1_STRING_length(oct);
192 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
193 ASN1_STRING_clear_free(oct);
197 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
199 const ECX_KEY *ecxkey = pkey->pkey.ecx;
200 ASN1_OCTET_STRING oct;
201 unsigned char *penc = NULL;
204 if (ecxkey == NULL || ecxkey->privkey == NULL) {
205 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
209 oct.data = ecxkey->privkey;
210 oct.length = KEYLEN(pkey);
213 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
215 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
219 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
220 V_ASN1_UNDEF, NULL, penc, penclen)) {
221 OPENSSL_clear_free(penc, penclen);
222 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
229 static int ecx_size(const EVP_PKEY *pkey)
234 static int ecx_bits(const EVP_PKEY *pkey)
236 if (IS25519(pkey->ameth->pkey_id)) {
238 } else if(ISX448(pkey->ameth->pkey_id)) {
245 static int ecx_security_bits(const EVP_PKEY *pkey)
247 if (IS25519(pkey->ameth->pkey_id)) {
248 return X25519_SECURITY_BITS;
250 return X448_SECURITY_BITS;
254 static void ecx_free(EVP_PKEY *pkey)
256 ecx_key_free(pkey->pkey.ecx);
259 /* "parameters" are always equal */
260 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
265 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
266 ASN1_PCTX *ctx, ecx_key_op_t op)
268 const ECX_KEY *ecxkey = pkey->pkey.ecx;
269 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
271 if (op == KEY_OP_PRIVATE) {
272 if (ecxkey == NULL || ecxkey->privkey == NULL) {
273 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
277 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
279 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
281 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
285 if (ecxkey == NULL) {
286 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
290 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
293 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
296 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
302 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
305 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
308 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
311 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
314 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
318 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
319 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
322 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
323 if (pkey->pkey.ecx != NULL) {
324 unsigned char **ppt = arg2;
326 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
338 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
341 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
342 /* We currently only support Pure EdDSA which takes no digest */
343 *(int *)arg2 = NID_undef;
352 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
355 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
359 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
361 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
365 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
368 const ECX_KEY *key = pkey->pkey.ecx;
371 *len = KEYLENID(pkey->ameth->pkey_id);
376 || key->privkey == NULL
377 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
380 *len = KEYLENID(pkey->ameth->pkey_id);
381 memcpy(priv, key->privkey, *len);
386 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
389 const ECX_KEY *key = pkey->pkey.ecx;
392 *len = KEYLENID(pkey->ameth->pkey_id);
397 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
400 *len = KEYLENID(pkey->ameth->pkey_id);
401 memcpy(pub, key->pubkey, *len);
406 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
409 * We provide no mechanism to "update" an ECX key once it has been set,
410 * therefore we do not have to maintain a dirty count.
415 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
416 EVP_KEYMGMT *to_keymgmt)
418 const ECX_KEY *key = from->pkey.ecx;
420 OSSL_PARAM *params = NULL;
423 ossl_param_bld_init(&tmpl);
425 /* A key must at least have a public part */
426 if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
427 key->pubkey, key->keylen))
430 if (key->privkey != NULL) {
431 if (!ossl_param_bld_push_octet_string(&tmpl,
432 OSSL_PKEY_PARAM_PRIV_KEY,
433 key->privkey, key->keylen))
437 params = ossl_param_bld_to_param(&tmpl);
439 /* We export, the provider imports */
440 rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
444 ossl_param_bld_free(params);
448 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
453 "OpenSSL X25519 algorithm",
493 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
498 "OpenSSL X448 algorithm",
538 static int ecd_size25519(const EVP_PKEY *pkey)
540 return ED25519_SIGSIZE;
543 static int ecd_size448(const EVP_PKEY *pkey)
545 return ED448_SIGSIZE;
548 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
549 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
552 const ASN1_OBJECT *obj;
556 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
557 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
558 nid = OBJ_obj2nid(obj);
559 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
560 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
564 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
570 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
571 X509_ALGOR *alg1, X509_ALGOR *alg2,
572 ASN1_BIT_STRING *str)
574 /* Set algorithms identifiers */
575 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
577 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
578 /* Algorithm identifiers set: carry on as normal */
582 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
583 const ASN1_STRING *sig)
585 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
590 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
591 X509_ALGOR *alg1, X509_ALGOR *alg2,
592 ASN1_BIT_STRING *str)
594 /* Set algorithm identifier */
595 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
597 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
598 /* Algorithm identifier set: carry on as normal */
602 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
603 const ASN1_STRING *sig)
605 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
611 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
616 "OpenSSL ED25519 algorithm",
641 ecd_sig_info_set25519,
653 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
658 "OpenSSL ED448 algorithm",
695 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
697 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
700 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
702 const unsigned char **privkey,
703 const unsigned char **pubkey)
705 const ECX_KEY *ecxkey, *peerkey;
707 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
708 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
711 ecxkey = ctx->pkey->pkey.ecx;
712 peerkey = ctx->peerkey->pkey.ecx;
713 if (ecxkey == NULL || ecxkey->privkey == NULL) {
714 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
717 if (peerkey == NULL) {
718 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
721 *privkey = ecxkey->privkey;
722 *pubkey = peerkey->pubkey;
727 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
730 const unsigned char *privkey, *pubkey;
732 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
734 && X25519(key, privkey, pubkey) == 0))
736 *keylen = X25519_KEYLEN;
740 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
743 const unsigned char *privkey, *pubkey;
745 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
747 && X448(key, privkey, pubkey) == 0))
749 *keylen = X448_KEYLEN;
753 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
755 /* Only need to handle peer key for derivation */
756 if (type == EVP_PKEY_CTRL_PEER_KEY)
761 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
765 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
766 pkey_ecx_derive25519,
771 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
775 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
781 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
782 size_t *siglen, const unsigned char *tbs,
785 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
788 *siglen = ED25519_SIGSIZE;
791 if (*siglen < ED25519_SIGSIZE) {
792 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
796 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
798 *siglen = ED25519_SIGSIZE;
802 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
803 size_t *siglen, const unsigned char *tbs,
806 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
809 *siglen = ED448_SIGSIZE;
812 if (*siglen < ED448_SIGSIZE) {
813 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
818 * TODO(3.0): We use NULL for the library context for now. Will need to
821 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
824 *siglen = ED448_SIGSIZE;
828 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
829 size_t siglen, const unsigned char *tbs,
832 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
834 if (siglen != ED25519_SIGSIZE)
837 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
840 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
841 size_t siglen, const unsigned char *tbs,
844 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
846 if (siglen != ED448_SIGSIZE)
850 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
853 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
856 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
859 case EVP_PKEY_CTRL_MD:
860 /* Only NULL allowed as digest */
861 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
863 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
866 case EVP_PKEY_CTRL_DIGESTINIT:
872 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
873 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
876 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
879 pkey_ecd_digestsign25519,
880 pkey_ecd_digestverify25519
883 static const EVP_PKEY_METHOD ed448_pkey_meth = {
884 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
887 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
890 pkey_ecd_digestsign448,
891 pkey_ecd_digestverify448
895 # include "s390x_arch.h"
896 # include "internal/constant_time.h"
898 static void s390x_x25519_mod_p(unsigned char u[32])
900 unsigned char u_red[32];
904 memcpy(u_red, u, sizeof(u_red));
906 c += (unsigned int)u_red[31] + 19;
907 u_red[31] = (unsigned char)c;
910 for (i = 30; i >= 0; i--) {
911 c += (unsigned int)u_red[i];
912 u_red[i] = (unsigned char)c;
916 c = (u_red[0] & 0x80) >> 7;
918 constant_time_cond_swap_buff(0 - (unsigned char)c,
919 u, u_red, sizeof(u_red));
922 static void s390x_x448_mod_p(unsigned char u[56])
924 unsigned char u_red[56];
928 memcpy(u_red, u, sizeof(u_red));
930 c += (unsigned int)u_red[55] + 1;
931 u_red[55] = (unsigned char)c;
934 for (i = 54; i >= 28; i--) {
935 c += (unsigned int)u_red[i];
936 u_red[i] = (unsigned char)c;
940 c += (unsigned int)u_red[27] + 1;
941 u_red[27] = (unsigned char)c;
944 for (i = 26; i >= 0; i--) {
945 c += (unsigned int)u_red[i];
946 u_red[i] = (unsigned char)c;
950 constant_time_cond_swap_buff(0 - (unsigned char)c,
951 u, u_red, sizeof(u_red));
954 int s390x_x25519_mul(unsigned char u_dst[32],
955 const unsigned char u_src[32],
956 const unsigned char d_src[32])
960 unsigned char u_dst[32];
961 unsigned char u_src[32];
962 unsigned char d_src[32];
964 unsigned long long buff[512];
968 memset(¶m, 0, sizeof(param));
970 s390x_flip_endian32(param.x25519.u_src, u_src);
971 param.x25519.u_src[0] &= 0x7f;
972 s390x_x25519_mod_p(param.x25519.u_src);
974 s390x_flip_endian32(param.x25519.d_src, d_src);
975 param.x25519.d_src[31] &= 248;
976 param.x25519.d_src[0] &= 127;
977 param.x25519.d_src[0] |= 64;
979 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
981 s390x_flip_endian32(u_dst, param.x25519.u_dst);
983 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
987 int s390x_x448_mul(unsigned char u_dst[56],
988 const unsigned char u_src[56],
989 const unsigned char d_src[56])
993 unsigned char u_dst[64];
994 unsigned char u_src[64];
995 unsigned char d_src[64];
997 unsigned long long buff[512];
1001 memset(¶m, 0, sizeof(param));
1003 memcpy(param.x448.u_src, u_src, 56);
1004 memcpy(param.x448.d_src, d_src, 56);
1006 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1007 s390x_x448_mod_p(param.x448.u_src + 8);
1009 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1010 param.x448.d_src[63] &= 252;
1011 param.x448.d_src[8] |= 128;
1013 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1015 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1016 memcpy(u_dst, param.x448.u_dst, 56);
1019 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1023 static int s390x_ed25519_mul(unsigned char x_dst[32],
1024 unsigned char y_dst[32],
1025 const unsigned char x_src[32],
1026 const unsigned char y_src[32],
1027 const unsigned char d_src[32])
1031 unsigned char x_dst[32];
1032 unsigned char y_dst[32];
1033 unsigned char x_src[32];
1034 unsigned char y_src[32];
1035 unsigned char d_src[32];
1037 unsigned long long buff[512];
1041 memset(¶m, 0, sizeof(param));
1043 s390x_flip_endian32(param.ed25519.x_src, x_src);
1044 s390x_flip_endian32(param.ed25519.y_src, y_src);
1045 s390x_flip_endian32(param.ed25519.d_src, d_src);
1047 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1049 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1050 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1053 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1057 static int s390x_ed448_mul(unsigned char x_dst[57],
1058 unsigned char y_dst[57],
1059 const unsigned char x_src[57],
1060 const unsigned char y_src[57],
1061 const unsigned char d_src[57])
1065 unsigned char x_dst[64];
1066 unsigned char y_dst[64];
1067 unsigned char x_src[64];
1068 unsigned char y_src[64];
1069 unsigned char d_src[64];
1071 unsigned long long buff[512];
1075 memset(¶m, 0, sizeof(param));
1077 memcpy(param.ed448.x_src, x_src, 57);
1078 memcpy(param.ed448.y_src, y_src, 57);
1079 memcpy(param.ed448.d_src, d_src, 57);
1080 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1081 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1082 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1084 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1086 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1087 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1088 memcpy(x_dst, param.ed448.x_dst, 57);
1089 memcpy(y_dst, param.ed448.y_dst, 57);
1092 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1096 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1098 static const unsigned char generator[] = {
1099 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1103 ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
1104 unsigned char *privkey = NULL, *pubkey;
1107 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1111 pubkey = key->pubkey;
1113 privkey = ecx_key_allocate_privkey(key);
1114 if (privkey == NULL) {
1115 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1119 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1126 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1129 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1136 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1138 static const unsigned char generator[] = {
1139 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1145 ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
1146 unsigned char *privkey = NULL, *pubkey;
1149 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1153 pubkey = key->pubkey;
1155 privkey = ecx_key_allocate_privkey(key);
1156 if (privkey == NULL) {
1157 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1161 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1167 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1170 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1177 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1179 static const unsigned char generator_x[] = {
1180 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1181 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1182 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1184 static const unsigned char generator_y[] = {
1185 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1186 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1187 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1189 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1190 ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
1191 unsigned char *privkey = NULL, *pubkey;
1195 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1199 pubkey = key->pubkey;
1201 privkey = ecx_key_allocate_privkey(key);
1202 if (privkey == NULL) {
1203 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1207 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1210 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1217 if (s390x_ed25519_mul(x_dst, pubkey,
1218 generator_x, generator_y, buff) != 1)
1221 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1223 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1230 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1232 static const unsigned char generator_x[] = {
1233 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1234 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1235 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1236 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1237 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1239 static const unsigned char generator_y[] = {
1240 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1241 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1242 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1243 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1244 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1246 unsigned char x_dst[57], buff[114];
1247 ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
1248 unsigned char *privkey = NULL, *pubkey;
1249 EVP_MD_CTX *hashctx = NULL;
1252 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1256 pubkey = key->pubkey;
1258 privkey = ecx_key_allocate_privkey(key);
1259 if (privkey == NULL) {
1260 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1264 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1267 hashctx = EVP_MD_CTX_new();
1268 if (hashctx == NULL)
1270 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1272 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1274 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1281 if (s390x_ed448_mul(x_dst, pubkey,
1282 generator_x, generator_y, buff) != 1)
1285 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1287 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1288 EVP_MD_CTX_free(hashctx);
1292 EVP_MD_CTX_free(hashctx);
1296 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1299 const unsigned char *privkey, *pubkey;
1301 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1305 return s390x_x25519_mul(key, pubkey, privkey);
1307 *keylen = X25519_KEYLEN;
1311 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1314 const unsigned char *privkey, *pubkey;
1316 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1320 return s390x_x448_mul(key, pubkey, privkey);
1322 *keylen = X448_KEYLEN;
1326 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1327 unsigned char *sig, size_t *siglen,
1328 const unsigned char *tbs,
1333 unsigned char sig[64];
1334 unsigned char priv[32];
1336 unsigned long long buff[512];
1338 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1342 *siglen = ED25519_SIGSIZE;
1346 if (*siglen < ED25519_SIGSIZE) {
1347 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1351 memset(¶m, 0, sizeof(param));
1352 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1354 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1355 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1359 s390x_flip_endian32(sig, param.ed25519.sig);
1360 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1362 *siglen = ED25519_SIGSIZE;
1366 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1367 unsigned char *sig, size_t *siglen,
1368 const unsigned char *tbs,
1373 unsigned char sig[128];
1374 unsigned char priv[64];
1376 unsigned long long buff[512];
1378 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1382 *siglen = ED448_SIGSIZE;
1386 if (*siglen < ED448_SIGSIZE) {
1387 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1391 memset(¶m, 0, sizeof(param));
1392 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1394 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1395 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1399 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1400 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1401 memcpy(sig, param.ed448.sig, 57);
1402 memcpy(sig + 57, param.ed448.sig + 64, 57);
1404 *siglen = ED448_SIGSIZE;
1408 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1409 const unsigned char *sig,
1411 const unsigned char *tbs,
1416 unsigned char sig[64];
1417 unsigned char pub[32];
1419 unsigned long long buff[512];
1421 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1423 if (siglen != ED25519_SIGSIZE)
1426 memset(¶m, 0, sizeof(param));
1427 s390x_flip_endian32(param.ed25519.sig, sig);
1428 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1429 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1431 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1432 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1435 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1436 const unsigned char *sig,
1438 const unsigned char *tbs,
1443 unsigned char sig[128];
1444 unsigned char pub[64];
1446 unsigned long long buff[512];
1448 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1450 if (siglen != ED448_SIGSIZE)
1453 memset(¶m, 0, sizeof(param));
1454 memcpy(param.ed448.sig, sig, 57);
1455 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1456 memcpy(param.ed448.sig + 64, sig + 57, 57);
1457 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1458 memcpy(param.ed448.pub, edkey->pubkey, 57);
1459 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1461 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1462 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1465 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1467 0, 0, 0, 0, 0, 0, 0,
1468 s390x_pkey_ecx_keygen25519,
1469 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1470 s390x_pkey_ecx_derive25519,
1475 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1477 0, 0, 0, 0, 0, 0, 0,
1478 s390x_pkey_ecx_keygen448,
1479 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1480 s390x_pkey_ecx_derive448,
1484 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1485 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1487 s390x_pkey_ecd_keygen25519,
1488 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1491 s390x_pkey_ecd_digestsign25519,
1492 s390x_pkey_ecd_digestverify25519
1495 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1496 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1498 s390x_pkey_ecd_keygen448,
1499 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1502 s390x_pkey_ecd_digestsign448,
1503 s390x_pkey_ecd_digestverify448
1507 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1510 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1511 return &ecx25519_s390x_pkey_meth;
1513 return &ecx25519_pkey_meth;
1516 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1519 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1520 return &ecx448_s390x_pkey_meth;
1522 return &ecx448_pkey_meth;
1525 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1528 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1529 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1530 && OPENSSL_s390xcap_P.kdsa[0]
1531 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1532 return &ed25519_s390x_pkey_meth;
1534 return &ed25519_pkey_meth;
1537 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1540 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1541 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1542 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1543 return &ed448_s390x_pkey_meth;
1545 return &ed448_pkey_meth;