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,
39 OPENSSL_CTX *libctx, const char *propq)
42 unsigned char *privkey, *pubkey;
44 if (op != KEY_OP_KEYGEN) {
48 /* Algorithm parameters must be absent */
49 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
50 if (ptype != V_ASN1_UNDEF) {
51 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
56 if (p == NULL || plen != KEYLENID(id)) {
57 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
62 key = ecx_key_new(KEYNID2TYPE(id), 1);
64 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
69 if (op == KEY_OP_PUBLIC) {
70 memcpy(pubkey, p, plen);
72 privkey = ecx_key_allocate_privkey(key);
73 if (privkey == NULL) {
74 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
77 if (op == KEY_OP_KEYGEN) {
78 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
80 if (id == EVP_PKEY_X25519) {
82 privkey[X25519_KEYLEN - 1] &= 127;
83 privkey[X25519_KEYLEN - 1] |= 64;
84 } else if (id == EVP_PKEY_X448) {
86 privkey[X448_KEYLEN - 1] |= 128;
89 memcpy(privkey, p, KEYLENID(id));
93 X25519_public_from_private(pubkey, privkey);
95 case EVP_PKEY_ED25519:
96 ED25519_public_from_private(pubkey, privkey);
99 X448_public_from_private(pubkey, privkey);
102 ED448_public_from_private(libctx, pubkey, privkey);
107 EVP_PKEY_assign(pkey, id, key);
114 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
116 const ECX_KEY *ecxkey = pkey->pkey.ecx;
119 if (ecxkey == NULL) {
120 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
124 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
126 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
130 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
131 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
133 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
139 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
141 const unsigned char *p;
145 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
147 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
148 KEY_OP_PUBLIC, NULL, NULL);
151 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
153 const ECX_KEY *akey = a->pkey.ecx;
154 const ECX_KEY *bkey = b->pkey.ecx;
156 if (akey == NULL || bkey == NULL)
159 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
162 static int ecx_priv_decode_with_libctx(EVP_PKEY *pkey,
163 const PKCS8_PRIV_KEY_INFO *p8,
164 OPENSSL_CTX *libctx, const char *propq)
166 const unsigned char *p;
168 ASN1_OCTET_STRING *oct = NULL;
169 const X509_ALGOR *palg;
172 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
175 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
180 p = ASN1_STRING_get0_data(oct);
181 plen = ASN1_STRING_length(oct);
184 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,
313 KEY_OP_PUBLIC, NULL, NULL);
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 /* TODO(3.0): We should pass a libctx here */
349 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
350 KEY_OP_PRIVATE, NULL, NULL);
353 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
355 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
356 KEY_OP_PUBLIC, NULL, NULL);
359 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
362 const ECX_KEY *key = pkey->pkey.ecx;
365 *len = KEYLENID(pkey->ameth->pkey_id);
370 || key->privkey == NULL
371 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
374 *len = KEYLENID(pkey->ameth->pkey_id);
375 memcpy(priv, key->privkey, *len);
380 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
383 const ECX_KEY *key = pkey->pkey.ecx;
386 *len = KEYLENID(pkey->ameth->pkey_id);
391 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
394 *len = KEYLENID(pkey->ameth->pkey_id);
395 memcpy(pub, key->pubkey, *len);
400 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
403 * We provide no mechanism to "update" an ECX key once it has been set,
404 * therefore we do not have to maintain a dirty count.
409 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
410 EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
413 const ECX_KEY *key = from->pkey.ecx;
414 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
415 OSSL_PARAM *params = NULL;
422 /* A key must at least have a public part */
423 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
424 key->pubkey, key->keylen))
426 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
428 if (key->privkey != NULL) {
429 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
430 OSSL_PKEY_PARAM_PRIV_KEY,
431 key->privkey, key->keylen))
433 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
436 params = OSSL_PARAM_BLD_to_param(tmpl);
438 /* We export, the provider imports */
439 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
442 OSSL_PARAM_BLD_free(tmpl);
443 OSSL_PARAM_BLD_free_params(params);
447 static int ecx_generic_import_from(const OSSL_PARAM params[], void *key,
450 EVP_PKEY *pkey = key;
451 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
454 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
458 if (!ecx_key_fromdata(ecx, params, 1)
459 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
466 static int x25519_import_from(const OSSL_PARAM params[], void *key)
468 return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
471 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
476 "OpenSSL X25519 algorithm",
516 ecx_priv_decode_with_libctx
519 static int x448_import_from(const OSSL_PARAM params[], void *key)
521 return ecx_generic_import_from(params, key, EVP_PKEY_X448);
524 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
529 "OpenSSL X448 algorithm",
569 ecx_priv_decode_with_libctx
572 static int ecd_size25519(const EVP_PKEY *pkey)
574 return ED25519_SIGSIZE;
577 static int ecd_size448(const EVP_PKEY *pkey)
579 return ED448_SIGSIZE;
582 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
583 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
586 const ASN1_OBJECT *obj;
590 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
591 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
592 nid = OBJ_obj2nid(obj);
593 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
594 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
598 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
604 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
605 X509_ALGOR *alg1, X509_ALGOR *alg2,
606 ASN1_BIT_STRING *str)
608 /* Set algorithms identifiers */
609 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
611 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
612 /* Algorithm identifiers set: carry on as normal */
616 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
617 const ASN1_STRING *sig)
619 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
624 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
625 X509_ALGOR *alg1, X509_ALGOR *alg2,
626 ASN1_BIT_STRING *str)
628 /* Set algorithm identifier */
629 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
631 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
632 /* Algorithm identifier set: carry on as normal */
636 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
637 const ASN1_STRING *sig)
639 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
644 static int ed25519_import_from(const OSSL_PARAM params[], void *key)
646 return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
649 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
654 "OpenSSL ED25519 algorithm",
679 ecd_sig_info_set25519,
693 ecx_priv_decode_with_libctx
696 static int ed448_import_from(const OSSL_PARAM params[], void *key)
698 return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
701 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
706 "OpenSSL ED448 algorithm",
745 ecx_priv_decode_with_libctx
748 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
750 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
754 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
756 const unsigned char **privkey,
757 const unsigned char **pubkey)
759 const ECX_KEY *ecxkey, *peerkey;
761 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
762 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
765 ecxkey = ctx->pkey->pkey.ecx;
766 peerkey = ctx->peerkey->pkey.ecx;
767 if (ecxkey == NULL || ecxkey->privkey == NULL) {
768 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
771 if (peerkey == NULL) {
772 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
775 *privkey = ecxkey->privkey;
776 *pubkey = peerkey->pubkey;
781 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
784 const unsigned char *privkey, *pubkey;
786 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
788 && X25519(key, privkey, pubkey) == 0))
790 *keylen = X25519_KEYLEN;
794 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
797 const unsigned char *privkey, *pubkey;
799 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
801 && X448(key, privkey, pubkey) == 0))
803 *keylen = X448_KEYLEN;
807 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
809 /* Only need to handle peer key for derivation */
810 if (type == EVP_PKEY_CTRL_PEER_KEY)
815 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
819 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
820 pkey_ecx_derive25519,
825 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
829 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
836 size_t *siglen, const unsigned char *tbs,
839 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
842 *siglen = ED25519_SIGSIZE;
845 if (*siglen < ED25519_SIGSIZE) {
846 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
850 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
853 *siglen = ED25519_SIGSIZE;
857 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
858 size_t *siglen, const unsigned char *tbs,
861 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
864 *siglen = ED448_SIGSIZE;
867 if (*siglen < ED448_SIGSIZE) {
868 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
873 * TODO(3.0): We use NULL for the library context for now. Will need to
876 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
879 *siglen = ED448_SIGSIZE;
883 static int pkey_ecd_digestverify25519(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 != ED25519_SIGSIZE)
892 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
895 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
896 size_t siglen, const unsigned char *tbs,
899 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
901 if (siglen != ED448_SIGSIZE)
905 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
908 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
911 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
914 case EVP_PKEY_CTRL_MD:
915 /* Only NULL allowed as digest */
916 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
918 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
921 case EVP_PKEY_CTRL_DIGESTINIT:
927 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
928 EVP_PKEY_ED25519, 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_digestsign25519,
935 pkey_ecd_digestverify25519
938 static const EVP_PKEY_METHOD ed448_pkey_meth = {
939 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
942 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
945 pkey_ecd_digestsign448,
946 pkey_ecd_digestverify448
950 # include "s390x_arch.h"
951 # include "internal/constant_time.h"
953 static void s390x_x25519_mod_p(unsigned char u[32])
955 unsigned char u_red[32];
959 memcpy(u_red, u, sizeof(u_red));
961 c += (unsigned int)u_red[31] + 19;
962 u_red[31] = (unsigned char)c;
965 for (i = 30; i >= 0; i--) {
966 c += (unsigned int)u_red[i];
967 u_red[i] = (unsigned char)c;
971 c = (u_red[0] & 0x80) >> 7;
973 constant_time_cond_swap_buff(0 - (unsigned char)c,
974 u, u_red, sizeof(u_red));
977 static void s390x_x448_mod_p(unsigned char u[56])
979 unsigned char u_red[56];
983 memcpy(u_red, u, sizeof(u_red));
985 c += (unsigned int)u_red[55] + 1;
986 u_red[55] = (unsigned char)c;
989 for (i = 54; i >= 28; i--) {
990 c += (unsigned int)u_red[i];
991 u_red[i] = (unsigned char)c;
995 c += (unsigned int)u_red[27] + 1;
996 u_red[27] = (unsigned char)c;
999 for (i = 26; i >= 0; i--) {
1000 c += (unsigned int)u_red[i];
1001 u_red[i] = (unsigned char)c;
1005 constant_time_cond_swap_buff(0 - (unsigned char)c,
1006 u, u_red, sizeof(u_red));
1009 int s390x_x25519_mul(unsigned char u_dst[32],
1010 const unsigned char u_src[32],
1011 const unsigned char d_src[32])
1015 unsigned char u_dst[32];
1016 unsigned char u_src[32];
1017 unsigned char d_src[32];
1019 unsigned long long buff[512];
1023 memset(¶m, 0, sizeof(param));
1025 s390x_flip_endian32(param.x25519.u_src, u_src);
1026 param.x25519.u_src[0] &= 0x7f;
1027 s390x_x25519_mod_p(param.x25519.u_src);
1029 s390x_flip_endian32(param.x25519.d_src, d_src);
1030 param.x25519.d_src[31] &= 248;
1031 param.x25519.d_src[0] &= 127;
1032 param.x25519.d_src[0] |= 64;
1034 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
1036 s390x_flip_endian32(u_dst, param.x25519.u_dst);
1038 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
1042 int s390x_x448_mul(unsigned char u_dst[56],
1043 const unsigned char u_src[56],
1044 const unsigned char d_src[56])
1048 unsigned char u_dst[64];
1049 unsigned char u_src[64];
1050 unsigned char d_src[64];
1052 unsigned long long buff[512];
1056 memset(¶m, 0, sizeof(param));
1058 memcpy(param.x448.u_src, u_src, 56);
1059 memcpy(param.x448.d_src, d_src, 56);
1061 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1062 s390x_x448_mod_p(param.x448.u_src + 8);
1064 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1065 param.x448.d_src[63] &= 252;
1066 param.x448.d_src[8] |= 128;
1068 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1070 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1071 memcpy(u_dst, param.x448.u_dst, 56);
1074 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1078 static int s390x_ed25519_mul(unsigned char x_dst[32],
1079 unsigned char y_dst[32],
1080 const unsigned char x_src[32],
1081 const unsigned char y_src[32],
1082 const unsigned char d_src[32])
1086 unsigned char x_dst[32];
1087 unsigned char y_dst[32];
1088 unsigned char x_src[32];
1089 unsigned char y_src[32];
1090 unsigned char d_src[32];
1092 unsigned long long buff[512];
1096 memset(¶m, 0, sizeof(param));
1098 s390x_flip_endian32(param.ed25519.x_src, x_src);
1099 s390x_flip_endian32(param.ed25519.y_src, y_src);
1100 s390x_flip_endian32(param.ed25519.d_src, d_src);
1102 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1104 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1105 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1108 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1112 static int s390x_ed448_mul(unsigned char x_dst[57],
1113 unsigned char y_dst[57],
1114 const unsigned char x_src[57],
1115 const unsigned char y_src[57],
1116 const unsigned char d_src[57])
1120 unsigned char x_dst[64];
1121 unsigned char y_dst[64];
1122 unsigned char x_src[64];
1123 unsigned char y_src[64];
1124 unsigned char d_src[64];
1126 unsigned long long buff[512];
1130 memset(¶m, 0, sizeof(param));
1132 memcpy(param.ed448.x_src, x_src, 57);
1133 memcpy(param.ed448.y_src, y_src, 57);
1134 memcpy(param.ed448.d_src, d_src, 57);
1135 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1136 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1137 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1139 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1141 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1142 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1143 memcpy(x_dst, param.ed448.x_dst, 57);
1144 memcpy(y_dst, param.ed448.y_dst, 57);
1147 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1151 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1153 static const unsigned char generator[] = {
1154 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1158 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1159 unsigned char *privkey = NULL, *pubkey;
1162 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1166 pubkey = key->pubkey;
1168 privkey = ecx_key_allocate_privkey(key);
1169 if (privkey == NULL) {
1170 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1174 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1181 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1184 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1191 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1193 static const unsigned char generator[] = {
1194 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1200 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1201 unsigned char *privkey = NULL, *pubkey;
1204 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1208 pubkey = key->pubkey;
1210 privkey = ecx_key_allocate_privkey(key);
1211 if (privkey == NULL) {
1212 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1216 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1222 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1225 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1232 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1234 static const unsigned char generator_x[] = {
1235 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1236 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1237 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1239 static const unsigned char generator_y[] = {
1240 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1241 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1242 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1244 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1245 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1246 unsigned char *privkey = NULL, *pubkey;
1250 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1254 pubkey = key->pubkey;
1256 privkey = ecx_key_allocate_privkey(key);
1257 if (privkey == NULL) {
1258 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1262 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1265 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1272 if (s390x_ed25519_mul(x_dst, pubkey,
1273 generator_x, generator_y, buff) != 1)
1276 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1278 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1285 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1287 static const unsigned char generator_x[] = {
1288 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1289 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1290 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1291 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1292 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1294 static const unsigned char generator_y[] = {
1295 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1296 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1297 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1298 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1299 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1301 unsigned char x_dst[57], buff[114];
1302 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1303 unsigned char *privkey = NULL, *pubkey;
1304 EVP_MD_CTX *hashctx = NULL;
1307 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1311 pubkey = key->pubkey;
1313 privkey = ecx_key_allocate_privkey(key);
1314 if (privkey == NULL) {
1315 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1319 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1322 hashctx = EVP_MD_CTX_new();
1323 if (hashctx == NULL)
1325 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1327 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1329 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1336 if (s390x_ed448_mul(x_dst, pubkey,
1337 generator_x, generator_y, buff) != 1)
1340 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1342 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1343 EVP_MD_CTX_free(hashctx);
1347 EVP_MD_CTX_free(hashctx);
1351 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1354 const unsigned char *privkey, *pubkey;
1356 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1360 return s390x_x25519_mul(key, pubkey, privkey);
1362 *keylen = X25519_KEYLEN;
1366 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1369 const unsigned char *privkey, *pubkey;
1371 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1375 return s390x_x448_mul(key, pubkey, privkey);
1377 *keylen = X448_KEYLEN;
1381 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1382 unsigned char *sig, size_t *siglen,
1383 const unsigned char *tbs,
1388 unsigned char sig[64];
1389 unsigned char priv[32];
1391 unsigned long long buff[512];
1393 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1397 *siglen = ED25519_SIGSIZE;
1401 if (*siglen < ED25519_SIGSIZE) {
1402 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1406 memset(¶m, 0, sizeof(param));
1407 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1409 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1410 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1414 s390x_flip_endian32(sig, param.ed25519.sig);
1415 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1417 *siglen = ED25519_SIGSIZE;
1421 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1422 unsigned char *sig, size_t *siglen,
1423 const unsigned char *tbs,
1428 unsigned char sig[128];
1429 unsigned char priv[64];
1431 unsigned long long buff[512];
1433 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1437 *siglen = ED448_SIGSIZE;
1441 if (*siglen < ED448_SIGSIZE) {
1442 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1446 memset(¶m, 0, sizeof(param));
1447 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1449 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1450 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1454 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1455 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1456 memcpy(sig, param.ed448.sig, 57);
1457 memcpy(sig + 57, param.ed448.sig + 64, 57);
1459 *siglen = ED448_SIGSIZE;
1463 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1464 const unsigned char *sig,
1466 const unsigned char *tbs,
1471 unsigned char sig[64];
1472 unsigned char pub[32];
1474 unsigned long long buff[512];
1476 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1478 if (siglen != ED25519_SIGSIZE)
1481 memset(¶m, 0, sizeof(param));
1482 s390x_flip_endian32(param.ed25519.sig, sig);
1483 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1484 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1486 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1487 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1490 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1491 const unsigned char *sig,
1493 const unsigned char *tbs,
1498 unsigned char sig[128];
1499 unsigned char pub[64];
1501 unsigned long long buff[512];
1503 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1505 if (siglen != ED448_SIGSIZE)
1508 memset(¶m, 0, sizeof(param));
1509 memcpy(param.ed448.sig, sig, 57);
1510 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1511 memcpy(param.ed448.sig + 64, sig + 57, 57);
1512 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1513 memcpy(param.ed448.pub, edkey->pubkey, 57);
1514 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1516 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1517 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1520 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1522 0, 0, 0, 0, 0, 0, 0,
1523 s390x_pkey_ecx_keygen25519,
1524 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1525 s390x_pkey_ecx_derive25519,
1530 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1532 0, 0, 0, 0, 0, 0, 0,
1533 s390x_pkey_ecx_keygen448,
1534 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1535 s390x_pkey_ecx_derive448,
1539 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1540 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1542 s390x_pkey_ecd_keygen25519,
1543 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1546 s390x_pkey_ecd_digestsign25519,
1547 s390x_pkey_ecd_digestverify25519
1550 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1551 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1553 s390x_pkey_ecd_keygen448,
1554 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1557 s390x_pkey_ecd_digestsign448,
1558 s390x_pkey_ecd_digestverify448
1562 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1565 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1566 return &ecx25519_s390x_pkey_meth;
1568 return &ecx25519_pkey_meth;
1571 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1574 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1575 return &ecx448_s390x_pkey_meth;
1577 return &ecx448_pkey_meth;
1580 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1583 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1584 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1585 && OPENSSL_s390xcap_P.kdsa[0]
1586 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1587 return &ed25519_s390x_pkey_meth;
1589 return &ed25519_pkey_meth;
1592 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1595 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1596 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1597 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1598 return &ed448_s390x_pkey_meth;
1600 return &ed448_pkey_meth;