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 "openssl/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
27 #include "curve448/curve448_local.h"
28 #include "ecx_backend.h"
36 /* Setup EVP_PKEY using public, private or generation */
37 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
38 const unsigned char *p, int plen, ecx_key_op_t op)
41 unsigned char *privkey, *pubkey;
43 if (op != KEY_OP_KEYGEN) {
47 /* Algorithm parameters must be absent */
48 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
49 if (ptype != V_ASN1_UNDEF) {
50 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
55 if (p == NULL || plen != KEYLENID(id)) {
56 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
61 key = ecx_key_new(KEYNID2TYPE(id), 1);
63 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
68 if (op == KEY_OP_PUBLIC) {
69 memcpy(pubkey, p, plen);
71 privkey = ecx_key_allocate_privkey(key);
72 if (privkey == NULL) {
73 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
76 if (op == KEY_OP_KEYGEN) {
77 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
79 if (id == EVP_PKEY_X25519) {
81 privkey[X25519_KEYLEN - 1] &= 127;
82 privkey[X25519_KEYLEN - 1] |= 64;
83 } else if (id == EVP_PKEY_X448) {
85 privkey[X448_KEYLEN - 1] |= 128;
88 memcpy(privkey, p, KEYLENID(id));
92 X25519_public_from_private(pubkey, privkey);
94 case EVP_PKEY_ED25519:
95 ED25519_public_from_private(pubkey, privkey);
98 X448_public_from_private(pubkey, privkey);
102 * TODO(3.0): We set the library context to NULL for now. This will
105 ED448_public_from_private(NULL, pubkey, privkey);
110 EVP_PKEY_assign(pkey, id, key);
117 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
119 const ECX_KEY *ecxkey = pkey->pkey.ecx;
122 if (ecxkey == NULL) {
123 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
127 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
129 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
133 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
134 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
136 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
142 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
144 const unsigned char *p;
148 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
150 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
154 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
156 const ECX_KEY *akey = a->pkey.ecx;
157 const ECX_KEY *bkey = b->pkey.ecx;
159 if (akey == NULL || bkey == NULL)
162 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
165 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
167 const unsigned char *p;
169 ASN1_OCTET_STRING *oct = NULL;
170 const X509_ALGOR *palg;
173 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
176 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
181 p = ASN1_STRING_get0_data(oct);
182 plen = ASN1_STRING_length(oct);
185 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
186 ASN1_STRING_clear_free(oct);
190 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
192 const ECX_KEY *ecxkey = pkey->pkey.ecx;
193 ASN1_OCTET_STRING oct;
194 unsigned char *penc = NULL;
197 if (ecxkey == NULL || ecxkey->privkey == NULL) {
198 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
202 oct.data = ecxkey->privkey;
203 oct.length = KEYLEN(pkey);
206 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
208 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
212 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
213 V_ASN1_UNDEF, NULL, penc, penclen)) {
214 OPENSSL_clear_free(penc, penclen);
215 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
222 static int ecx_size(const EVP_PKEY *pkey)
227 static int ecx_bits(const EVP_PKEY *pkey)
229 if (IS25519(pkey->ameth->pkey_id)) {
231 } else if(ISX448(pkey->ameth->pkey_id)) {
238 static int ecx_security_bits(const EVP_PKEY *pkey)
240 if (IS25519(pkey->ameth->pkey_id)) {
241 return X25519_SECURITY_BITS;
243 return X448_SECURITY_BITS;
247 static void ecx_free(EVP_PKEY *pkey)
249 ecx_key_free(pkey->pkey.ecx);
252 /* "parameters" are always equal */
253 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
258 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
259 ASN1_PCTX *ctx, ecx_key_op_t op)
261 const ECX_KEY *ecxkey = pkey->pkey.ecx;
262 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
264 if (op == KEY_OP_PRIVATE) {
265 if (ecxkey == NULL || ecxkey->privkey == NULL) {
266 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
270 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
272 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
274 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
278 if (ecxkey == NULL) {
279 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
283 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
286 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
289 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
295 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
298 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
301 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
304 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
307 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
311 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
312 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
315 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
316 if (pkey->pkey.ecx != NULL) {
317 unsigned char **ppt = arg2;
319 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
331 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
334 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
335 /* We currently only support Pure EdDSA which takes no digest */
336 *(int *)arg2 = NID_undef;
345 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
348 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
352 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
354 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
358 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
361 const ECX_KEY *key = pkey->pkey.ecx;
364 *len = KEYLENID(pkey->ameth->pkey_id);
369 || key->privkey == NULL
370 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
373 *len = KEYLENID(pkey->ameth->pkey_id);
374 memcpy(priv, key->privkey, *len);
379 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
382 const ECX_KEY *key = pkey->pkey.ecx;
385 *len = KEYLENID(pkey->ameth->pkey_id);
390 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
393 *len = KEYLENID(pkey->ameth->pkey_id);
394 memcpy(pub, key->pubkey, *len);
399 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
402 * We provide no mechanism to "update" an ECX key once it has been set,
403 * therefore we do not have to maintain a dirty count.
408 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
409 EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
412 const ECX_KEY *key = from->pkey.ecx;
413 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
414 OSSL_PARAM *params = NULL;
421 /* A key must at least have a public part */
422 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
423 key->pubkey, key->keylen))
425 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
427 if (key->privkey != NULL) {
428 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
429 OSSL_PKEY_PARAM_PRIV_KEY,
430 key->privkey, key->keylen))
432 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
435 params = OSSL_PARAM_BLD_to_param(tmpl);
437 /* We export, the provider imports */
438 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
441 OSSL_PARAM_BLD_free(tmpl);
442 OSSL_PARAM_BLD_free_params(params);
446 static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
449 EVP_PKEY *pkey = key;
450 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
453 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
457 if (!ecx_key_fromdata(ecx, params, 1)
458 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
465 static int x25519_import_from(const OSSL_PARAM params[], void *key)
467 return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
470 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
475 "OpenSSL X25519 algorithm",
516 static int x448_import_from(const OSSL_PARAM params[], void *key)
518 return ecx_generic_import_from(params, key, EVP_PKEY_X448);
521 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
526 "OpenSSL X448 algorithm",
567 static int ecd_size25519(const EVP_PKEY *pkey)
569 return ED25519_SIGSIZE;
572 static int ecd_size448(const EVP_PKEY *pkey)
574 return ED448_SIGSIZE;
577 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
578 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
581 const ASN1_OBJECT *obj;
585 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
586 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
587 nid = OBJ_obj2nid(obj);
588 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
589 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
593 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
599 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
600 X509_ALGOR *alg1, X509_ALGOR *alg2,
601 ASN1_BIT_STRING *str)
603 /* Set algorithms identifiers */
604 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
606 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
607 /* Algorithm identifiers set: carry on as normal */
611 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
612 const ASN1_STRING *sig)
614 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
619 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
620 X509_ALGOR *alg1, X509_ALGOR *alg2,
621 ASN1_BIT_STRING *str)
623 /* Set algorithm identifier */
624 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
626 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
627 /* Algorithm identifier set: carry on as normal */
631 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
632 const ASN1_STRING *sig)
634 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
639 static int ed25519_import_from(const OSSL_PARAM params[], void *key)
641 return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
644 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
649 "OpenSSL ED25519 algorithm",
674 ecd_sig_info_set25519,
689 static int ed448_import_from(const OSSL_PARAM params[], void *key)
691 return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
694 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
699 "OpenSSL ED448 algorithm",
739 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
741 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
744 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
746 const unsigned char **privkey,
747 const unsigned char **pubkey)
749 const ECX_KEY *ecxkey, *peerkey;
751 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
752 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
755 ecxkey = ctx->pkey->pkey.ecx;
756 peerkey = ctx->peerkey->pkey.ecx;
757 if (ecxkey == NULL || ecxkey->privkey == NULL) {
758 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
761 if (peerkey == NULL) {
762 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
765 *privkey = ecxkey->privkey;
766 *pubkey = peerkey->pubkey;
771 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
774 const unsigned char *privkey, *pubkey;
776 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
778 && X25519(key, privkey, pubkey) == 0))
780 *keylen = X25519_KEYLEN;
784 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
787 const unsigned char *privkey, *pubkey;
789 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
791 && X448(key, privkey, pubkey) == 0))
793 *keylen = X448_KEYLEN;
797 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
799 /* Only need to handle peer key for derivation */
800 if (type == EVP_PKEY_CTRL_PEER_KEY)
805 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
810 pkey_ecx_derive25519,
815 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
825 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
826 size_t *siglen, const unsigned char *tbs,
829 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
832 *siglen = ED25519_SIGSIZE;
835 if (*siglen < ED25519_SIGSIZE) {
836 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
840 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
842 *siglen = ED25519_SIGSIZE;
846 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
847 size_t *siglen, const unsigned char *tbs,
850 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
853 *siglen = ED448_SIGSIZE;
856 if (*siglen < ED448_SIGSIZE) {
857 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
862 * TODO(3.0): We use NULL for the library context for now. Will need to
865 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
868 *siglen = ED448_SIGSIZE;
872 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
873 size_t siglen, const unsigned char *tbs,
876 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
878 if (siglen != ED25519_SIGSIZE)
881 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
884 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
885 size_t siglen, const unsigned char *tbs,
888 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
890 if (siglen != ED448_SIGSIZE)
894 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
897 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
900 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
903 case EVP_PKEY_CTRL_MD:
904 /* Only NULL allowed as digest */
905 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
907 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
910 case EVP_PKEY_CTRL_DIGESTINIT:
916 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
917 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
920 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
923 pkey_ecd_digestsign25519,
924 pkey_ecd_digestverify25519
927 static const EVP_PKEY_METHOD ed448_pkey_meth = {
928 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
934 pkey_ecd_digestsign448,
935 pkey_ecd_digestverify448
939 # include "s390x_arch.h"
940 # include "internal/constant_time.h"
942 static void s390x_x25519_mod_p(unsigned char u[32])
944 unsigned char u_red[32];
948 memcpy(u_red, u, sizeof(u_red));
950 c += (unsigned int)u_red[31] + 19;
951 u_red[31] = (unsigned char)c;
954 for (i = 30; i >= 0; i--) {
955 c += (unsigned int)u_red[i];
956 u_red[i] = (unsigned char)c;
960 c = (u_red[0] & 0x80) >> 7;
962 constant_time_cond_swap_buff(0 - (unsigned char)c,
963 u, u_red, sizeof(u_red));
966 static void s390x_x448_mod_p(unsigned char u[56])
968 unsigned char u_red[56];
972 memcpy(u_red, u, sizeof(u_red));
974 c += (unsigned int)u_red[55] + 1;
975 u_red[55] = (unsigned char)c;
978 for (i = 54; i >= 28; i--) {
979 c += (unsigned int)u_red[i];
980 u_red[i] = (unsigned char)c;
984 c += (unsigned int)u_red[27] + 1;
985 u_red[27] = (unsigned char)c;
988 for (i = 26; i >= 0; i--) {
989 c += (unsigned int)u_red[i];
990 u_red[i] = (unsigned char)c;
994 constant_time_cond_swap_buff(0 - (unsigned char)c,
995 u, u_red, sizeof(u_red));
998 int s390x_x25519_mul(unsigned char u_dst[32],
999 const unsigned char u_src[32],
1000 const unsigned char d_src[32])
1004 unsigned char u_dst[32];
1005 unsigned char u_src[32];
1006 unsigned char d_src[32];
1008 unsigned long long buff[512];
1012 memset(¶m, 0, sizeof(param));
1014 s390x_flip_endian32(param.x25519.u_src, u_src);
1015 param.x25519.u_src[0] &= 0x7f;
1016 s390x_x25519_mod_p(param.x25519.u_src);
1018 s390x_flip_endian32(param.x25519.d_src, d_src);
1019 param.x25519.d_src[31] &= 248;
1020 param.x25519.d_src[0] &= 127;
1021 param.x25519.d_src[0] |= 64;
1023 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
1025 s390x_flip_endian32(u_dst, param.x25519.u_dst);
1027 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
1031 int s390x_x448_mul(unsigned char u_dst[56],
1032 const unsigned char u_src[56],
1033 const unsigned char d_src[56])
1037 unsigned char u_dst[64];
1038 unsigned char u_src[64];
1039 unsigned char d_src[64];
1041 unsigned long long buff[512];
1045 memset(¶m, 0, sizeof(param));
1047 memcpy(param.x448.u_src, u_src, 56);
1048 memcpy(param.x448.d_src, d_src, 56);
1050 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1051 s390x_x448_mod_p(param.x448.u_src + 8);
1053 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1054 param.x448.d_src[63] &= 252;
1055 param.x448.d_src[8] |= 128;
1057 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1059 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1060 memcpy(u_dst, param.x448.u_dst, 56);
1063 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1067 static int s390x_ed25519_mul(unsigned char x_dst[32],
1068 unsigned char y_dst[32],
1069 const unsigned char x_src[32],
1070 const unsigned char y_src[32],
1071 const unsigned char d_src[32])
1075 unsigned char x_dst[32];
1076 unsigned char y_dst[32];
1077 unsigned char x_src[32];
1078 unsigned char y_src[32];
1079 unsigned char d_src[32];
1081 unsigned long long buff[512];
1085 memset(¶m, 0, sizeof(param));
1087 s390x_flip_endian32(param.ed25519.x_src, x_src);
1088 s390x_flip_endian32(param.ed25519.y_src, y_src);
1089 s390x_flip_endian32(param.ed25519.d_src, d_src);
1091 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1093 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1094 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1097 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1101 static int s390x_ed448_mul(unsigned char x_dst[57],
1102 unsigned char y_dst[57],
1103 const unsigned char x_src[57],
1104 const unsigned char y_src[57],
1105 const unsigned char d_src[57])
1109 unsigned char x_dst[64];
1110 unsigned char y_dst[64];
1111 unsigned char x_src[64];
1112 unsigned char y_src[64];
1113 unsigned char d_src[64];
1115 unsigned long long buff[512];
1119 memset(¶m, 0, sizeof(param));
1121 memcpy(param.ed448.x_src, x_src, 57);
1122 memcpy(param.ed448.y_src, y_src, 57);
1123 memcpy(param.ed448.d_src, d_src, 57);
1124 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1125 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1126 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1128 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1130 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1131 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1132 memcpy(x_dst, param.ed448.x_dst, 57);
1133 memcpy(y_dst, param.ed448.y_dst, 57);
1136 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1140 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1142 static const unsigned char generator[] = {
1143 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1147 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1148 unsigned char *privkey = NULL, *pubkey;
1151 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1155 pubkey = key->pubkey;
1157 privkey = ecx_key_allocate_privkey(key);
1158 if (privkey == NULL) {
1159 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1163 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1170 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1173 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1180 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1182 static const unsigned char generator[] = {
1183 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1189 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1190 unsigned char *privkey = NULL, *pubkey;
1193 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1197 pubkey = key->pubkey;
1199 privkey = ecx_key_allocate_privkey(key);
1200 if (privkey == NULL) {
1201 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1205 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1211 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1214 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1221 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1223 static const unsigned char generator_x[] = {
1224 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1225 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1226 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1228 static const unsigned char generator_y[] = {
1229 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1230 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1231 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1233 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1234 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1235 unsigned char *privkey = NULL, *pubkey;
1239 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1243 pubkey = key->pubkey;
1245 privkey = ecx_key_allocate_privkey(key);
1246 if (privkey == NULL) {
1247 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1251 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1254 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1261 if (s390x_ed25519_mul(x_dst, pubkey,
1262 generator_x, generator_y, buff) != 1)
1265 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1267 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1274 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1276 static const unsigned char generator_x[] = {
1277 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1278 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1279 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1280 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1281 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1283 static const unsigned char generator_y[] = {
1284 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1285 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1286 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1287 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1288 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1290 unsigned char x_dst[57], buff[114];
1291 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1292 unsigned char *privkey = NULL, *pubkey;
1293 EVP_MD_CTX *hashctx = NULL;
1296 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1300 pubkey = key->pubkey;
1302 privkey = ecx_key_allocate_privkey(key);
1303 if (privkey == NULL) {
1304 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1308 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1311 hashctx = EVP_MD_CTX_new();
1312 if (hashctx == NULL)
1314 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1316 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1318 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1325 if (s390x_ed448_mul(x_dst, pubkey,
1326 generator_x, generator_y, buff) != 1)
1329 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1331 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1332 EVP_MD_CTX_free(hashctx);
1336 EVP_MD_CTX_free(hashctx);
1340 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1343 const unsigned char *privkey, *pubkey;
1345 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1349 return s390x_x25519_mul(key, pubkey, privkey);
1351 *keylen = X25519_KEYLEN;
1355 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1358 const unsigned char *privkey, *pubkey;
1360 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1364 return s390x_x448_mul(key, pubkey, privkey);
1366 *keylen = X448_KEYLEN;
1370 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1371 unsigned char *sig, size_t *siglen,
1372 const unsigned char *tbs,
1377 unsigned char sig[64];
1378 unsigned char priv[32];
1380 unsigned long long buff[512];
1382 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1386 *siglen = ED25519_SIGSIZE;
1390 if (*siglen < ED25519_SIGSIZE) {
1391 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1395 memset(¶m, 0, sizeof(param));
1396 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1398 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1399 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1403 s390x_flip_endian32(sig, param.ed25519.sig);
1404 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1406 *siglen = ED25519_SIGSIZE;
1410 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1411 unsigned char *sig, size_t *siglen,
1412 const unsigned char *tbs,
1417 unsigned char sig[128];
1418 unsigned char priv[64];
1420 unsigned long long buff[512];
1422 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1426 *siglen = ED448_SIGSIZE;
1430 if (*siglen < ED448_SIGSIZE) {
1431 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1435 memset(¶m, 0, sizeof(param));
1436 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1438 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1439 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1443 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1444 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1445 memcpy(sig, param.ed448.sig, 57);
1446 memcpy(sig + 57, param.ed448.sig + 64, 57);
1448 *siglen = ED448_SIGSIZE;
1452 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1453 const unsigned char *sig,
1455 const unsigned char *tbs,
1460 unsigned char sig[64];
1461 unsigned char pub[32];
1463 unsigned long long buff[512];
1465 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1467 if (siglen != ED25519_SIGSIZE)
1470 memset(¶m, 0, sizeof(param));
1471 s390x_flip_endian32(param.ed25519.sig, sig);
1472 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1473 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1475 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1476 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1479 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1480 const unsigned char *sig,
1482 const unsigned char *tbs,
1487 unsigned char sig[128];
1488 unsigned char pub[64];
1490 unsigned long long buff[512];
1492 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1494 if (siglen != ED448_SIGSIZE)
1497 memset(¶m, 0, sizeof(param));
1498 memcpy(param.ed448.sig, sig, 57);
1499 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1500 memcpy(param.ed448.sig + 64, sig + 57, 57);
1501 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1502 memcpy(param.ed448.pub, edkey->pubkey, 57);
1503 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1505 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1506 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1509 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1511 0, 0, 0, 0, 0, 0, 0,
1512 s390x_pkey_ecx_keygen25519,
1513 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1514 s390x_pkey_ecx_derive25519,
1519 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1521 0, 0, 0, 0, 0, 0, 0,
1522 s390x_pkey_ecx_keygen448,
1523 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1524 s390x_pkey_ecx_derive448,
1528 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1529 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1531 s390x_pkey_ecd_keygen25519,
1532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1535 s390x_pkey_ecd_digestsign25519,
1536 s390x_pkey_ecd_digestverify25519
1539 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1540 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1542 s390x_pkey_ecd_keygen448,
1543 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1546 s390x_pkey_ecd_digestsign448,
1547 s390x_pkey_ecd_digestverify448
1551 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1554 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1555 return &ecx25519_s390x_pkey_meth;
1557 return &ecx25519_pkey_meth;
1560 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1563 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1564 return &ecx448_s390x_pkey_meth;
1566 return &ecx448_pkey_meth;
1569 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1572 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1573 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1574 && OPENSSL_s390xcap_P.kdsa[0]
1575 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1576 return &ed25519_s390x_pkey_meth;
1578 return &ed25519_pkey_meth;
1581 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1584 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1585 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1586 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1587 return &ed448_s390x_pkey_meth;
1589 return &ed448_pkey_meth;