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 KEYNID2TYPE(id) \
35 (IS25519(id) ? ECX_KEY_TYPE_X25519 \
36 : ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
37 : ((id) == EVP_PKEY_ED25519 ? ECX_KEY_TYPE_ED25519 \
38 : ECX_KEY_TYPE_ED448)))
39 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
48 /* Setup EVP_PKEY using public, private or generation */
49 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
50 const unsigned char *p, int plen, ecx_key_op_t op)
53 unsigned char *privkey, *pubkey;
55 if (op != KEY_OP_KEYGEN) {
59 /* Algorithm parameters must be absent */
60 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
61 if (ptype != V_ASN1_UNDEF) {
62 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
67 if (p == NULL || plen != KEYLENID(id)) {
68 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
73 key = ecx_key_new(KEYNID2TYPE(id), 1);
75 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
80 if (op == KEY_OP_PUBLIC) {
81 memcpy(pubkey, p, plen);
83 privkey = ecx_key_allocate_privkey(key);
84 if (privkey == NULL) {
85 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
88 if (op == KEY_OP_KEYGEN) {
89 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
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 ecx_key_free(pkey->pkey.ecx);
264 /* "parameters" are always equal */
265 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
270 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
271 ASN1_PCTX *ctx, ecx_key_op_t op)
273 const ECX_KEY *ecxkey = pkey->pkey.ecx;
274 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
276 if (op == KEY_OP_PRIVATE) {
277 if (ecxkey == NULL || ecxkey->privkey == NULL) {
278 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
282 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
284 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
286 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
290 if (ecxkey == NULL) {
291 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
295 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
298 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
301 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
307 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
310 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
313 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
316 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
319 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
323 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
324 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
327 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
328 if (pkey->pkey.ecx != NULL) {
329 unsigned char **ppt = arg2;
331 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
343 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
346 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
347 /* We currently only support Pure EdDSA which takes no digest */
348 *(int *)arg2 = NID_undef;
357 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
360 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
364 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
366 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
370 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
373 const ECX_KEY *key = pkey->pkey.ecx;
376 *len = KEYLENID(pkey->ameth->pkey_id);
381 || key->privkey == NULL
382 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
385 *len = KEYLENID(pkey->ameth->pkey_id);
386 memcpy(priv, key->privkey, *len);
391 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
394 const ECX_KEY *key = pkey->pkey.ecx;
397 *len = KEYLENID(pkey->ameth->pkey_id);
402 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
405 *len = KEYLENID(pkey->ameth->pkey_id);
406 memcpy(pub, key->pubkey, *len);
411 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
414 * We provide no mechanism to "update" an ECX key once it has been set,
415 * therefore we do not have to maintain a dirty count.
420 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
421 EVP_KEYMGMT *to_keymgmt)
423 const ECX_KEY *key = from->pkey.ecx;
425 OSSL_PARAM *params = NULL;
429 ossl_param_bld_init(&tmpl);
431 /* A key must at least have a public part */
432 if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
433 key->pubkey, key->keylen))
435 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
437 if (key->privkey != NULL) {
438 if (!ossl_param_bld_push_octet_string(&tmpl,
439 OSSL_PKEY_PARAM_PRIV_KEY,
440 key->privkey, key->keylen))
442 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
445 params = ossl_param_bld_to_param(&tmpl);
447 /* We export, the provider imports */
448 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
451 ossl_param_bld_free(params);
455 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
460 "OpenSSL X25519 algorithm",
500 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
505 "OpenSSL X448 algorithm",
545 static int ecd_size25519(const EVP_PKEY *pkey)
547 return ED25519_SIGSIZE;
550 static int ecd_size448(const EVP_PKEY *pkey)
552 return ED448_SIGSIZE;
555 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
556 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
559 const ASN1_OBJECT *obj;
563 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
564 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
565 nid = OBJ_obj2nid(obj);
566 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
567 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
571 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
577 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
578 X509_ALGOR *alg1, X509_ALGOR *alg2,
579 ASN1_BIT_STRING *str)
581 /* Set algorithms identifiers */
582 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
584 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
585 /* Algorithm identifiers set: carry on as normal */
589 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
590 const ASN1_STRING *sig)
592 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
597 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
598 X509_ALGOR *alg1, X509_ALGOR *alg2,
599 ASN1_BIT_STRING *str)
601 /* Set algorithm identifier */
602 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
604 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
605 /* Algorithm identifier set: carry on as normal */
609 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
610 const ASN1_STRING *sig)
612 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
618 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
623 "OpenSSL ED25519 algorithm",
648 ecd_sig_info_set25519,
662 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
667 "OpenSSL ED448 algorithm",
706 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
708 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
711 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
713 const unsigned char **privkey,
714 const unsigned char **pubkey)
716 const ECX_KEY *ecxkey, *peerkey;
718 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
719 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
722 ecxkey = ctx->pkey->pkey.ecx;
723 peerkey = ctx->peerkey->pkey.ecx;
724 if (ecxkey == NULL || ecxkey->privkey == NULL) {
725 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
728 if (peerkey == NULL) {
729 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
732 *privkey = ecxkey->privkey;
733 *pubkey = peerkey->pubkey;
738 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
741 const unsigned char *privkey, *pubkey;
743 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
745 && X25519(key, privkey, pubkey) == 0))
747 *keylen = X25519_KEYLEN;
751 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
754 const unsigned char *privkey, *pubkey;
756 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
758 && X448(key, privkey, pubkey) == 0))
760 *keylen = X448_KEYLEN;
764 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
766 /* Only need to handle peer key for derivation */
767 if (type == EVP_PKEY_CTRL_PEER_KEY)
772 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
776 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
777 pkey_ecx_derive25519,
782 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
786 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
792 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
793 size_t *siglen, const unsigned char *tbs,
796 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
799 *siglen = ED25519_SIGSIZE;
802 if (*siglen < ED25519_SIGSIZE) {
803 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
807 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
809 *siglen = ED25519_SIGSIZE;
813 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
814 size_t *siglen, const unsigned char *tbs,
817 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
820 *siglen = ED448_SIGSIZE;
823 if (*siglen < ED448_SIGSIZE) {
824 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
829 * TODO(3.0): We use NULL for the library context for now. Will need to
832 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
835 *siglen = ED448_SIGSIZE;
839 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
840 size_t siglen, const unsigned char *tbs,
843 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
845 if (siglen != ED25519_SIGSIZE)
848 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
851 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
852 size_t siglen, const unsigned char *tbs,
855 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
857 if (siglen != ED448_SIGSIZE)
861 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
864 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
867 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
870 case EVP_PKEY_CTRL_MD:
871 /* Only NULL allowed as digest */
872 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
874 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
877 case EVP_PKEY_CTRL_DIGESTINIT:
883 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
884 EVP_PKEY_ED25519, 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_digestsign25519,
891 pkey_ecd_digestverify25519
894 static const EVP_PKEY_METHOD ed448_pkey_meth = {
895 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
898 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901 pkey_ecd_digestsign448,
902 pkey_ecd_digestverify448
906 # include "s390x_arch.h"
907 # include "internal/constant_time.h"
909 static void s390x_x25519_mod_p(unsigned char u[32])
911 unsigned char u_red[32];
915 memcpy(u_red, u, sizeof(u_red));
917 c += (unsigned int)u_red[31] + 19;
918 u_red[31] = (unsigned char)c;
921 for (i = 30; i >= 0; i--) {
922 c += (unsigned int)u_red[i];
923 u_red[i] = (unsigned char)c;
927 c = (u_red[0] & 0x80) >> 7;
929 constant_time_cond_swap_buff(0 - (unsigned char)c,
930 u, u_red, sizeof(u_red));
933 static void s390x_x448_mod_p(unsigned char u[56])
935 unsigned char u_red[56];
939 memcpy(u_red, u, sizeof(u_red));
941 c += (unsigned int)u_red[55] + 1;
942 u_red[55] = (unsigned char)c;
945 for (i = 54; i >= 28; i--) {
946 c += (unsigned int)u_red[i];
947 u_red[i] = (unsigned char)c;
951 c += (unsigned int)u_red[27] + 1;
952 u_red[27] = (unsigned char)c;
955 for (i = 26; i >= 0; i--) {
956 c += (unsigned int)u_red[i];
957 u_red[i] = (unsigned char)c;
961 constant_time_cond_swap_buff(0 - (unsigned char)c,
962 u, u_red, sizeof(u_red));
965 int s390x_x25519_mul(unsigned char u_dst[32],
966 const unsigned char u_src[32],
967 const unsigned char d_src[32])
971 unsigned char u_dst[32];
972 unsigned char u_src[32];
973 unsigned char d_src[32];
975 unsigned long long buff[512];
979 memset(¶m, 0, sizeof(param));
981 s390x_flip_endian32(param.x25519.u_src, u_src);
982 param.x25519.u_src[0] &= 0x7f;
983 s390x_x25519_mod_p(param.x25519.u_src);
985 s390x_flip_endian32(param.x25519.d_src, d_src);
986 param.x25519.d_src[31] &= 248;
987 param.x25519.d_src[0] &= 127;
988 param.x25519.d_src[0] |= 64;
990 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
992 s390x_flip_endian32(u_dst, param.x25519.u_dst);
994 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
998 int s390x_x448_mul(unsigned char u_dst[56],
999 const unsigned char u_src[56],
1000 const unsigned char d_src[56])
1004 unsigned char u_dst[64];
1005 unsigned char u_src[64];
1006 unsigned char d_src[64];
1008 unsigned long long buff[512];
1012 memset(¶m, 0, sizeof(param));
1014 memcpy(param.x448.u_src, u_src, 56);
1015 memcpy(param.x448.d_src, d_src, 56);
1017 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1018 s390x_x448_mod_p(param.x448.u_src + 8);
1020 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1021 param.x448.d_src[63] &= 252;
1022 param.x448.d_src[8] |= 128;
1024 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1026 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1027 memcpy(u_dst, param.x448.u_dst, 56);
1030 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1034 static int s390x_ed25519_mul(unsigned char x_dst[32],
1035 unsigned char y_dst[32],
1036 const unsigned char x_src[32],
1037 const unsigned char y_src[32],
1038 const unsigned char d_src[32])
1042 unsigned char x_dst[32];
1043 unsigned char y_dst[32];
1044 unsigned char x_src[32];
1045 unsigned char y_src[32];
1046 unsigned char d_src[32];
1048 unsigned long long buff[512];
1052 memset(¶m, 0, sizeof(param));
1054 s390x_flip_endian32(param.ed25519.x_src, x_src);
1055 s390x_flip_endian32(param.ed25519.y_src, y_src);
1056 s390x_flip_endian32(param.ed25519.d_src, d_src);
1058 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1060 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1061 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1064 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1068 static int s390x_ed448_mul(unsigned char x_dst[57],
1069 unsigned char y_dst[57],
1070 const unsigned char x_src[57],
1071 const unsigned char y_src[57],
1072 const unsigned char d_src[57])
1076 unsigned char x_dst[64];
1077 unsigned char y_dst[64];
1078 unsigned char x_src[64];
1079 unsigned char y_src[64];
1080 unsigned char d_src[64];
1082 unsigned long long buff[512];
1086 memset(¶m, 0, sizeof(param));
1088 memcpy(param.ed448.x_src, x_src, 57);
1089 memcpy(param.ed448.y_src, y_src, 57);
1090 memcpy(param.ed448.d_src, d_src, 57);
1091 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1092 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1093 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1095 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1097 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1098 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1099 memcpy(x_dst, param.ed448.x_dst, 57);
1100 memcpy(y_dst, param.ed448.y_dst, 57);
1103 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1107 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1109 static const unsigned char generator[] = {
1110 0x09, 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
1114 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1115 unsigned char *privkey = NULL, *pubkey;
1118 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1122 pubkey = key->pubkey;
1124 privkey = ecx_key_allocate_privkey(key);
1125 if (privkey == NULL) {
1126 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1130 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1137 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1140 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1147 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1149 static const unsigned char generator[] = {
1150 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1156 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1157 unsigned char *privkey = NULL, *pubkey;
1160 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1164 pubkey = key->pubkey;
1166 privkey = ecx_key_allocate_privkey(key);
1167 if (privkey == NULL) {
1168 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1172 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1178 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1181 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1188 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1190 static const unsigned char generator_x[] = {
1191 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1192 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1193 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1195 static const unsigned char generator_y[] = {
1196 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1197 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1198 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1200 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1201 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1202 unsigned char *privkey = NULL, *pubkey;
1206 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1210 pubkey = key->pubkey;
1212 privkey = ecx_key_allocate_privkey(key);
1213 if (privkey == NULL) {
1214 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1218 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1221 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1228 if (s390x_ed25519_mul(x_dst, pubkey,
1229 generator_x, generator_y, buff) != 1)
1232 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1234 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1241 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1243 static const unsigned char generator_x[] = {
1244 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1245 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1246 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1247 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1248 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1250 static const unsigned char generator_y[] = {
1251 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1252 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1253 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1254 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1255 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1257 unsigned char x_dst[57], buff[114];
1258 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1259 unsigned char *privkey = NULL, *pubkey;
1260 EVP_MD_CTX *hashctx = NULL;
1263 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1267 pubkey = key->pubkey;
1269 privkey = ecx_key_allocate_privkey(key);
1270 if (privkey == NULL) {
1271 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1275 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1278 hashctx = EVP_MD_CTX_new();
1279 if (hashctx == NULL)
1281 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1283 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1285 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1292 if (s390x_ed448_mul(x_dst, pubkey,
1293 generator_x, generator_y, buff) != 1)
1296 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1298 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1299 EVP_MD_CTX_free(hashctx);
1303 EVP_MD_CTX_free(hashctx);
1307 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1310 const unsigned char *privkey, *pubkey;
1312 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1316 return s390x_x25519_mul(key, pubkey, privkey);
1318 *keylen = X25519_KEYLEN;
1322 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1325 const unsigned char *privkey, *pubkey;
1327 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1331 return s390x_x448_mul(key, pubkey, privkey);
1333 *keylen = X448_KEYLEN;
1337 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1338 unsigned char *sig, size_t *siglen,
1339 const unsigned char *tbs,
1344 unsigned char sig[64];
1345 unsigned char priv[32];
1347 unsigned long long buff[512];
1349 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1353 *siglen = ED25519_SIGSIZE;
1357 if (*siglen < ED25519_SIGSIZE) {
1358 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1362 memset(¶m, 0, sizeof(param));
1363 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1365 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1366 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1370 s390x_flip_endian32(sig, param.ed25519.sig);
1371 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1373 *siglen = ED25519_SIGSIZE;
1377 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1378 unsigned char *sig, size_t *siglen,
1379 const unsigned char *tbs,
1384 unsigned char sig[128];
1385 unsigned char priv[64];
1387 unsigned long long buff[512];
1389 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1393 *siglen = ED448_SIGSIZE;
1397 if (*siglen < ED448_SIGSIZE) {
1398 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1402 memset(¶m, 0, sizeof(param));
1403 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1405 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1406 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1410 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1411 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1412 memcpy(sig, param.ed448.sig, 57);
1413 memcpy(sig + 57, param.ed448.sig + 64, 57);
1415 *siglen = ED448_SIGSIZE;
1419 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1420 const unsigned char *sig,
1422 const unsigned char *tbs,
1427 unsigned char sig[64];
1428 unsigned char pub[32];
1430 unsigned long long buff[512];
1432 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1434 if (siglen != ED25519_SIGSIZE)
1437 memset(¶m, 0, sizeof(param));
1438 s390x_flip_endian32(param.ed25519.sig, sig);
1439 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1440 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1442 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1443 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1446 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1447 const unsigned char *sig,
1449 const unsigned char *tbs,
1454 unsigned char sig[128];
1455 unsigned char pub[64];
1457 unsigned long long buff[512];
1459 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1461 if (siglen != ED448_SIGSIZE)
1464 memset(¶m, 0, sizeof(param));
1465 memcpy(param.ed448.sig, sig, 57);
1466 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1467 memcpy(param.ed448.sig + 64, sig + 57, 57);
1468 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1469 memcpy(param.ed448.pub, edkey->pubkey, 57);
1470 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1472 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1473 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1476 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1478 0, 0, 0, 0, 0, 0, 0,
1479 s390x_pkey_ecx_keygen25519,
1480 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1481 s390x_pkey_ecx_derive25519,
1486 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1488 0, 0, 0, 0, 0, 0, 0,
1489 s390x_pkey_ecx_keygen448,
1490 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1491 s390x_pkey_ecx_derive448,
1495 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1496 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1498 s390x_pkey_ecd_keygen25519,
1499 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1502 s390x_pkey_ecd_digestsign25519,
1503 s390x_pkey_ecd_digestverify25519
1506 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1507 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1509 s390x_pkey_ecd_keygen448,
1510 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1513 s390x_pkey_ecd_digestsign448,
1514 s390x_pkey_ecd_digestverify448
1518 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1521 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1522 return &ecx25519_s390x_pkey_meth;
1524 return &ecx25519_pkey_meth;
1527 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1530 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1531 return &ecx448_s390x_pkey_meth;
1533 return &ecx448_pkey_meth;
1536 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1539 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1540 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1541 && OPENSSL_s390xcap_P.kdsa[0]
1542 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1543 return &ed25519_s390x_pkey_meth;
1545 return &ed25519_pkey_meth;
1548 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1551 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1552 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1553 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1554 return &ed448_s390x_pkey_meth;
1556 return &ed448_pkey_meth;