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)
411 const ECX_KEY *key = from->pkey.ecx;
412 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
413 OSSL_PARAM *params = NULL;
420 /* A key must at least have a public part */
421 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
422 key->pubkey, key->keylen))
424 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
426 if (key->privkey != NULL) {
427 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
428 OSSL_PKEY_PARAM_PRIV_KEY,
429 key->privkey, key->keylen))
431 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
434 params = OSSL_PARAM_BLD_to_param(tmpl);
436 /* We export, the provider imports */
437 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
440 OSSL_PARAM_BLD_free(tmpl);
441 OSSL_PARAM_BLD_free_params(params);
445 static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
448 EVP_PKEY *pkey = key;
449 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
452 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
456 if (!ecx_key_fromdata(ecx, params, 1)
457 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
464 static int x25519_import_from(const OSSL_PARAM params[], void *key)
466 return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
469 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
474 "OpenSSL X25519 algorithm",
515 static int x448_import_from(const OSSL_PARAM params[], void *key)
517 return ecx_generic_import_from(params, key, EVP_PKEY_X448);
520 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
525 "OpenSSL X448 algorithm",
566 static int ecd_size25519(const EVP_PKEY *pkey)
568 return ED25519_SIGSIZE;
571 static int ecd_size448(const EVP_PKEY *pkey)
573 return ED448_SIGSIZE;
576 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
577 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
580 const ASN1_OBJECT *obj;
584 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
585 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
586 nid = OBJ_obj2nid(obj);
587 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
588 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
592 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
598 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
599 X509_ALGOR *alg1, X509_ALGOR *alg2,
600 ASN1_BIT_STRING *str)
602 /* Set algorithms identifiers */
603 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
605 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
606 /* Algorithm identifiers set: carry on as normal */
610 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
611 const ASN1_STRING *sig)
613 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
618 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
619 X509_ALGOR *alg1, X509_ALGOR *alg2,
620 ASN1_BIT_STRING *str)
622 /* Set algorithm identifier */
623 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
625 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
626 /* Algorithm identifier set: carry on as normal */
630 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
631 const ASN1_STRING *sig)
633 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
638 static int ed25519_import_from(const OSSL_PARAM params[], void *key)
640 return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
643 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
648 "OpenSSL ED25519 algorithm",
673 ecd_sig_info_set25519,
688 static int ed448_import_from(const OSSL_PARAM params[], void *key)
690 return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
693 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
698 "OpenSSL ED448 algorithm",
738 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
740 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
743 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
745 const unsigned char **privkey,
746 const unsigned char **pubkey)
748 const ECX_KEY *ecxkey, *peerkey;
750 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
751 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
754 ecxkey = ctx->pkey->pkey.ecx;
755 peerkey = ctx->peerkey->pkey.ecx;
756 if (ecxkey == NULL || ecxkey->privkey == NULL) {
757 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
760 if (peerkey == NULL) {
761 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
764 *privkey = ecxkey->privkey;
765 *pubkey = peerkey->pubkey;
770 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
773 const unsigned char *privkey, *pubkey;
775 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
777 && X25519(key, privkey, pubkey) == 0))
779 *keylen = X25519_KEYLEN;
783 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
786 const unsigned char *privkey, *pubkey;
788 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
790 && X448(key, privkey, pubkey) == 0))
792 *keylen = X448_KEYLEN;
796 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
798 /* Only need to handle peer key for derivation */
799 if (type == EVP_PKEY_CTRL_PEER_KEY)
804 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
809 pkey_ecx_derive25519,
814 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
818 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
824 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
825 size_t *siglen, const unsigned char *tbs,
828 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
831 *siglen = ED25519_SIGSIZE;
834 if (*siglen < ED25519_SIGSIZE) {
835 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
839 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
841 *siglen = ED25519_SIGSIZE;
845 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
846 size_t *siglen, const unsigned char *tbs,
849 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
852 *siglen = ED448_SIGSIZE;
855 if (*siglen < ED448_SIGSIZE) {
856 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
861 * TODO(3.0): We use NULL for the library context for now. Will need to
864 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
867 *siglen = ED448_SIGSIZE;
871 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
872 size_t siglen, const unsigned char *tbs,
875 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
877 if (siglen != ED25519_SIGSIZE)
880 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
883 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
884 size_t siglen, const unsigned char *tbs,
887 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
889 if (siglen != ED448_SIGSIZE)
893 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
896 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
899 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
902 case EVP_PKEY_CTRL_MD:
903 /* Only NULL allowed as digest */
904 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
906 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
909 case EVP_PKEY_CTRL_DIGESTINIT:
915 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
916 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
919 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
922 pkey_ecd_digestsign25519,
923 pkey_ecd_digestverify25519
926 static const EVP_PKEY_METHOD ed448_pkey_meth = {
927 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
930 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
933 pkey_ecd_digestsign448,
934 pkey_ecd_digestverify448
938 # include "s390x_arch.h"
939 # include "internal/constant_time.h"
941 static void s390x_x25519_mod_p(unsigned char u[32])
943 unsigned char u_red[32];
947 memcpy(u_red, u, sizeof(u_red));
949 c += (unsigned int)u_red[31] + 19;
950 u_red[31] = (unsigned char)c;
953 for (i = 30; i >= 0; i--) {
954 c += (unsigned int)u_red[i];
955 u_red[i] = (unsigned char)c;
959 c = (u_red[0] & 0x80) >> 7;
961 constant_time_cond_swap_buff(0 - (unsigned char)c,
962 u, u_red, sizeof(u_red));
965 static void s390x_x448_mod_p(unsigned char u[56])
967 unsigned char u_red[56];
971 memcpy(u_red, u, sizeof(u_red));
973 c += (unsigned int)u_red[55] + 1;
974 u_red[55] = (unsigned char)c;
977 for (i = 54; i >= 28; i--) {
978 c += (unsigned int)u_red[i];
979 u_red[i] = (unsigned char)c;
983 c += (unsigned int)u_red[27] + 1;
984 u_red[27] = (unsigned char)c;
987 for (i = 26; i >= 0; i--) {
988 c += (unsigned int)u_red[i];
989 u_red[i] = (unsigned char)c;
993 constant_time_cond_swap_buff(0 - (unsigned char)c,
994 u, u_red, sizeof(u_red));
997 int s390x_x25519_mul(unsigned char u_dst[32],
998 const unsigned char u_src[32],
999 const unsigned char d_src[32])
1003 unsigned char u_dst[32];
1004 unsigned char u_src[32];
1005 unsigned char d_src[32];
1007 unsigned long long buff[512];
1011 memset(¶m, 0, sizeof(param));
1013 s390x_flip_endian32(param.x25519.u_src, u_src);
1014 param.x25519.u_src[0] &= 0x7f;
1015 s390x_x25519_mod_p(param.x25519.u_src);
1017 s390x_flip_endian32(param.x25519.d_src, d_src);
1018 param.x25519.d_src[31] &= 248;
1019 param.x25519.d_src[0] &= 127;
1020 param.x25519.d_src[0] |= 64;
1022 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
1024 s390x_flip_endian32(u_dst, param.x25519.u_dst);
1026 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
1030 int s390x_x448_mul(unsigned char u_dst[56],
1031 const unsigned char u_src[56],
1032 const unsigned char d_src[56])
1036 unsigned char u_dst[64];
1037 unsigned char u_src[64];
1038 unsigned char d_src[64];
1040 unsigned long long buff[512];
1044 memset(¶m, 0, sizeof(param));
1046 memcpy(param.x448.u_src, u_src, 56);
1047 memcpy(param.x448.d_src, d_src, 56);
1049 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1050 s390x_x448_mod_p(param.x448.u_src + 8);
1052 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1053 param.x448.d_src[63] &= 252;
1054 param.x448.d_src[8] |= 128;
1056 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1058 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1059 memcpy(u_dst, param.x448.u_dst, 56);
1062 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1066 static int s390x_ed25519_mul(unsigned char x_dst[32],
1067 unsigned char y_dst[32],
1068 const unsigned char x_src[32],
1069 const unsigned char y_src[32],
1070 const unsigned char d_src[32])
1074 unsigned char x_dst[32];
1075 unsigned char y_dst[32];
1076 unsigned char x_src[32];
1077 unsigned char y_src[32];
1078 unsigned char d_src[32];
1080 unsigned long long buff[512];
1084 memset(¶m, 0, sizeof(param));
1086 s390x_flip_endian32(param.ed25519.x_src, x_src);
1087 s390x_flip_endian32(param.ed25519.y_src, y_src);
1088 s390x_flip_endian32(param.ed25519.d_src, d_src);
1090 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1092 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1093 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1096 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1100 static int s390x_ed448_mul(unsigned char x_dst[57],
1101 unsigned char y_dst[57],
1102 const unsigned char x_src[57],
1103 const unsigned char y_src[57],
1104 const unsigned char d_src[57])
1108 unsigned char x_dst[64];
1109 unsigned char y_dst[64];
1110 unsigned char x_src[64];
1111 unsigned char y_src[64];
1112 unsigned char d_src[64];
1114 unsigned long long buff[512];
1118 memset(¶m, 0, sizeof(param));
1120 memcpy(param.ed448.x_src, x_src, 57);
1121 memcpy(param.ed448.y_src, y_src, 57);
1122 memcpy(param.ed448.d_src, d_src, 57);
1123 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1124 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1125 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1127 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1129 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1130 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1131 memcpy(x_dst, param.ed448.x_dst, 57);
1132 memcpy(y_dst, param.ed448.y_dst, 57);
1135 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1139 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1141 static const unsigned char generator[] = {
1142 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1146 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1147 unsigned char *privkey = NULL, *pubkey;
1150 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1154 pubkey = key->pubkey;
1156 privkey = ecx_key_allocate_privkey(key);
1157 if (privkey == NULL) {
1158 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1162 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1169 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1172 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1179 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1181 static const unsigned char generator[] = {
1182 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1183 0x00, 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
1188 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1189 unsigned char *privkey = NULL, *pubkey;
1192 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1196 pubkey = key->pubkey;
1198 privkey = ecx_key_allocate_privkey(key);
1199 if (privkey == NULL) {
1200 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1204 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1210 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1213 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1220 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1222 static const unsigned char generator_x[] = {
1223 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1224 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1225 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1227 static const unsigned char generator_y[] = {
1228 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1229 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1230 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1232 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1233 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1234 unsigned char *privkey = NULL, *pubkey;
1238 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1242 pubkey = key->pubkey;
1244 privkey = ecx_key_allocate_privkey(key);
1245 if (privkey == NULL) {
1246 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1250 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1253 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1260 if (s390x_ed25519_mul(x_dst, pubkey,
1261 generator_x, generator_y, buff) != 1)
1264 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1266 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1273 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1275 static const unsigned char generator_x[] = {
1276 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1277 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1278 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1279 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1280 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1282 static const unsigned char generator_y[] = {
1283 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1284 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1285 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1286 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1287 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1289 unsigned char x_dst[57], buff[114];
1290 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1291 unsigned char *privkey = NULL, *pubkey;
1292 EVP_MD_CTX *hashctx = NULL;
1295 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1299 pubkey = key->pubkey;
1301 privkey = ecx_key_allocate_privkey(key);
1302 if (privkey == NULL) {
1303 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1307 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1310 hashctx = EVP_MD_CTX_new();
1311 if (hashctx == NULL)
1313 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1315 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1317 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1324 if (s390x_ed448_mul(x_dst, pubkey,
1325 generator_x, generator_y, buff) != 1)
1328 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1330 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1331 EVP_MD_CTX_free(hashctx);
1335 EVP_MD_CTX_free(hashctx);
1339 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1342 const unsigned char *privkey, *pubkey;
1344 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1348 return s390x_x25519_mul(key, pubkey, privkey);
1350 *keylen = X25519_KEYLEN;
1354 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1357 const unsigned char *privkey, *pubkey;
1359 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1363 return s390x_x448_mul(key, pubkey, privkey);
1365 *keylen = X448_KEYLEN;
1369 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1370 unsigned char *sig, size_t *siglen,
1371 const unsigned char *tbs,
1376 unsigned char sig[64];
1377 unsigned char priv[32];
1379 unsigned long long buff[512];
1381 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1385 *siglen = ED25519_SIGSIZE;
1389 if (*siglen < ED25519_SIGSIZE) {
1390 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1394 memset(¶m, 0, sizeof(param));
1395 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1397 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1398 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1402 s390x_flip_endian32(sig, param.ed25519.sig);
1403 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1405 *siglen = ED25519_SIGSIZE;
1409 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1410 unsigned char *sig, size_t *siglen,
1411 const unsigned char *tbs,
1416 unsigned char sig[128];
1417 unsigned char priv[64];
1419 unsigned long long buff[512];
1421 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1425 *siglen = ED448_SIGSIZE;
1429 if (*siglen < ED448_SIGSIZE) {
1430 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1434 memset(¶m, 0, sizeof(param));
1435 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1437 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1438 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1442 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1443 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1444 memcpy(sig, param.ed448.sig, 57);
1445 memcpy(sig + 57, param.ed448.sig + 64, 57);
1447 *siglen = ED448_SIGSIZE;
1451 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1452 const unsigned char *sig,
1454 const unsigned char *tbs,
1459 unsigned char sig[64];
1460 unsigned char pub[32];
1462 unsigned long long buff[512];
1464 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1466 if (siglen != ED25519_SIGSIZE)
1469 memset(¶m, 0, sizeof(param));
1470 s390x_flip_endian32(param.ed25519.sig, sig);
1471 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1472 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1474 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1475 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1478 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1479 const unsigned char *sig,
1481 const unsigned char *tbs,
1486 unsigned char sig[128];
1487 unsigned char pub[64];
1489 unsigned long long buff[512];
1491 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1493 if (siglen != ED448_SIGSIZE)
1496 memset(¶m, 0, sizeof(param));
1497 memcpy(param.ed448.sig, sig, 57);
1498 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1499 memcpy(param.ed448.sig + 64, sig + 57, 57);
1500 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1501 memcpy(param.ed448.pub, edkey->pubkey, 57);
1502 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1504 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1505 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1508 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1510 0, 0, 0, 0, 0, 0, 0,
1511 s390x_pkey_ecx_keygen25519,
1512 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1513 s390x_pkey_ecx_derive25519,
1518 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1520 0, 0, 0, 0, 0, 0, 0,
1521 s390x_pkey_ecx_keygen448,
1522 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1523 s390x_pkey_ecx_derive448,
1527 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1528 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1530 s390x_pkey_ecd_keygen25519,
1531 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1534 s390x_pkey_ecd_digestsign25519,
1535 s390x_pkey_ecd_digestverify25519
1538 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1539 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1541 s390x_pkey_ecd_keygen448,
1542 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1545 s390x_pkey_ecd_digestsign448,
1546 s390x_pkey_ecd_digestverify448
1550 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1553 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1554 return &ecx25519_s390x_pkey_meth;
1556 return &ecx25519_pkey_meth;
1559 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1562 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1563 return &ecx448_s390x_pkey_meth;
1565 return &ecx448_pkey_meth;
1568 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1571 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1572 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1573 && OPENSSL_s390xcap_P.kdsa[0]
1574 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1575 return &ed25519_s390x_pkey_meth;
1577 return &ed25519_pkey_meth;
1580 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1583 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1584 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1585 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1586 return &ed448_s390x_pkey_meth;
1588 return &ed448_pkey_meth;