2 * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * ECDSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
17 #include "internal/cryptlib.h"
18 #include <openssl/x509.h>
19 #include <openssl/ec.h>
20 #include <openssl/rand.h>
21 #include <openssl/core_names.h>
22 #include "internal/param_build.h"
23 #include "crypto/asn1.h"
24 #include "crypto/evp.h"
25 #include "crypto/ecx.h"
27 #include "curve448/curve448_local.h"
29 #define ISX448(id) ((id) == EVP_PKEY_X448)
30 #define IS25519(id) ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
31 #define KEYLENID(id) (IS25519(id) ? X25519_KEYLEN \
32 : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
34 #define KEYNID2TYPE(id) \
35 (IS25519(id) ? ECX_KEY_TYPE_X25519 \
36 : ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
37 : ((id) == EVP_PKEY_ED25519 ? ECX_KEY_TYPE_ED25519 \
38 : ECX_KEY_TYPE_ED448)))
39 #define KEYLEN(p) KEYLENID((p)->ameth->pkey_id)
48 /* Setup EVP_PKEY using public, private or generation */
49 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
50 const unsigned char *p, int plen, ecx_key_op_t op)
53 unsigned char *privkey, *pubkey;
55 if (op != KEY_OP_KEYGEN) {
59 /* Algorithm parameters must be absent */
60 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
61 if (ptype != V_ASN1_UNDEF) {
62 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
67 if (p == NULL || plen != KEYLENID(id)) {
68 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
73 key = ecx_key_new(KEYNID2TYPE(id), 1);
75 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
80 if (op == KEY_OP_PUBLIC) {
81 memcpy(pubkey, p, plen);
83 privkey = ecx_key_allocate_privkey(key);
84 if (privkey == NULL) {
85 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
88 if (op == KEY_OP_KEYGEN) {
89 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
91 if (id == EVP_PKEY_X25519) {
93 privkey[X25519_KEYLEN - 1] &= 127;
94 privkey[X25519_KEYLEN - 1] |= 64;
95 } else if (id == EVP_PKEY_X448) {
97 privkey[X448_KEYLEN - 1] |= 128;
100 memcpy(privkey, p, KEYLENID(id));
103 case EVP_PKEY_X25519:
104 X25519_public_from_private(pubkey, privkey);
106 case EVP_PKEY_ED25519:
107 ED25519_public_from_private(pubkey, privkey);
110 X448_public_from_private(pubkey, privkey);
114 * TODO(3.0): We set the library context to NULL for now. This will
117 ED448_public_from_private(NULL, pubkey, privkey);
122 EVP_PKEY_assign(pkey, id, key);
129 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
131 const ECX_KEY *ecxkey = pkey->pkey.ecx;
134 if (ecxkey == NULL) {
135 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
139 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
141 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
145 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
146 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
148 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
154 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
156 const unsigned char *p;
160 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
162 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
166 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
168 const ECX_KEY *akey = a->pkey.ecx;
169 const ECX_KEY *bkey = b->pkey.ecx;
171 if (akey == NULL || bkey == NULL)
174 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
177 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
179 const unsigned char *p;
181 ASN1_OCTET_STRING *oct = NULL;
182 const X509_ALGOR *palg;
185 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
188 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
193 p = ASN1_STRING_get0_data(oct);
194 plen = ASN1_STRING_length(oct);
197 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
198 ASN1_STRING_clear_free(oct);
202 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
204 const ECX_KEY *ecxkey = pkey->pkey.ecx;
205 ASN1_OCTET_STRING oct;
206 unsigned char *penc = NULL;
209 if (ecxkey == NULL || ecxkey->privkey == NULL) {
210 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
214 oct.data = ecxkey->privkey;
215 oct.length = KEYLEN(pkey);
218 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
220 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
224 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
225 V_ASN1_UNDEF, NULL, penc, penclen)) {
226 OPENSSL_clear_free(penc, penclen);
227 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
234 static int ecx_size(const EVP_PKEY *pkey)
239 static int ecx_bits(const EVP_PKEY *pkey)
241 if (IS25519(pkey->ameth->pkey_id)) {
243 } else if(ISX448(pkey->ameth->pkey_id)) {
250 static int ecx_security_bits(const EVP_PKEY *pkey)
252 if (IS25519(pkey->ameth->pkey_id)) {
253 return X25519_SECURITY_BITS;
255 return X448_SECURITY_BITS;
259 static void ecx_free(EVP_PKEY *pkey)
261 ecx_key_free(pkey->pkey.ecx);
264 /* "parameters" are always equal */
265 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
270 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
271 ASN1_PCTX *ctx, ecx_key_op_t op)
273 const ECX_KEY *ecxkey = pkey->pkey.ecx;
274 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
276 if (op == KEY_OP_PRIVATE) {
277 if (ecxkey == NULL || ecxkey->privkey == NULL) {
278 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
282 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
284 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
286 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
290 if (ecxkey == NULL) {
291 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
295 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
298 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
301 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
307 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
310 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
313 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
316 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
319 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
323 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
324 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
327 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
328 if (pkey->pkey.ecx != NULL) {
329 unsigned char **ppt = arg2;
331 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
343 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
346 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
347 /* We currently only support Pure EdDSA which takes no digest */
348 *(int *)arg2 = NID_undef;
357 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
360 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
364 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
366 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
370 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
373 const ECX_KEY *key = pkey->pkey.ecx;
376 *len = KEYLENID(pkey->ameth->pkey_id);
381 || key->privkey == NULL
382 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
385 *len = KEYLENID(pkey->ameth->pkey_id);
386 memcpy(priv, key->privkey, *len);
391 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
394 const ECX_KEY *key = pkey->pkey.ecx;
397 *len = KEYLENID(pkey->ameth->pkey_id);
402 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
405 *len = KEYLENID(pkey->ameth->pkey_id);
406 memcpy(pub, key->pubkey, *len);
411 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
414 * We provide no mechanism to "update" an ECX key once it has been set,
415 * therefore we do not have to maintain a dirty count.
420 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
421 EVP_KEYMGMT *to_keymgmt)
423 const ECX_KEY *key = from->pkey.ecx;
425 OSSL_PARAM *params = NULL;
428 ossl_param_bld_init(&tmpl);
430 /* A key must at least have a public part */
431 if (!ossl_param_bld_push_octet_string(&tmpl, OSSL_PKEY_PARAM_PUB_KEY,
432 key->pubkey, key->keylen))
435 if (key->privkey != NULL) {
436 if (!ossl_param_bld_push_octet_string(&tmpl,
437 OSSL_PKEY_PARAM_PRIV_KEY,
438 key->privkey, key->keylen))
442 params = ossl_param_bld_to_param(&tmpl);
444 /* We export, the provider imports */
445 rv = evp_keymgmt_import(to_keymgmt, to_keydata, OSSL_KEYMGMT_SELECT_ALL,
449 ossl_param_bld_free(params);
453 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
458 "OpenSSL X25519 algorithm",
498 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
503 "OpenSSL X448 algorithm",
543 static int ecd_size25519(const EVP_PKEY *pkey)
545 return ED25519_SIGSIZE;
548 static int ecd_size448(const EVP_PKEY *pkey)
550 return ED448_SIGSIZE;
553 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
554 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
557 const ASN1_OBJECT *obj;
561 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
562 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
563 nid = OBJ_obj2nid(obj);
564 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
565 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
569 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
575 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
576 X509_ALGOR *alg1, X509_ALGOR *alg2,
577 ASN1_BIT_STRING *str)
579 /* Set algorithms identifiers */
580 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
582 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
583 /* Algorithm identifiers set: carry on as normal */
587 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
588 const ASN1_STRING *sig)
590 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
595 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
596 X509_ALGOR *alg1, X509_ALGOR *alg2,
597 ASN1_BIT_STRING *str)
599 /* Set algorithm identifier */
600 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
602 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
603 /* Algorithm identifier set: carry on as normal */
607 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
608 const ASN1_STRING *sig)
610 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
616 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
621 "OpenSSL ED25519 algorithm",
646 ecd_sig_info_set25519,
660 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
665 "OpenSSL ED448 algorithm",
704 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
706 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
709 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
711 const unsigned char **privkey,
712 const unsigned char **pubkey)
714 const ECX_KEY *ecxkey, *peerkey;
716 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
717 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
720 ecxkey = ctx->pkey->pkey.ecx;
721 peerkey = ctx->peerkey->pkey.ecx;
722 if (ecxkey == NULL || ecxkey->privkey == NULL) {
723 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
726 if (peerkey == NULL) {
727 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
730 *privkey = ecxkey->privkey;
731 *pubkey = peerkey->pubkey;
736 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
739 const unsigned char *privkey, *pubkey;
741 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
743 && X25519(key, privkey, pubkey) == 0))
745 *keylen = X25519_KEYLEN;
749 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
752 const unsigned char *privkey, *pubkey;
754 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
756 && X448(key, privkey, pubkey) == 0))
758 *keylen = X448_KEYLEN;
762 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
764 /* Only need to handle peer key for derivation */
765 if (type == EVP_PKEY_CTRL_PEER_KEY)
770 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
774 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
775 pkey_ecx_derive25519,
780 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
784 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
790 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
791 size_t *siglen, const unsigned char *tbs,
794 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
797 *siglen = ED25519_SIGSIZE;
800 if (*siglen < ED25519_SIGSIZE) {
801 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
805 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
807 *siglen = ED25519_SIGSIZE;
811 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
812 size_t *siglen, const unsigned char *tbs,
815 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
818 *siglen = ED448_SIGSIZE;
821 if (*siglen < ED448_SIGSIZE) {
822 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
827 * TODO(3.0): We use NULL for the library context for now. Will need to
830 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
833 *siglen = ED448_SIGSIZE;
837 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
838 size_t siglen, const unsigned char *tbs,
841 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
843 if (siglen != ED25519_SIGSIZE)
846 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
849 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
850 size_t siglen, const unsigned char *tbs,
853 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
855 if (siglen != ED448_SIGSIZE)
859 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
862 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
865 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
868 case EVP_PKEY_CTRL_MD:
869 /* Only NULL allowed as digest */
870 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
872 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
875 case EVP_PKEY_CTRL_DIGESTINIT:
881 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
882 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
885 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
888 pkey_ecd_digestsign25519,
889 pkey_ecd_digestverify25519
892 static const EVP_PKEY_METHOD ed448_pkey_meth = {
893 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
899 pkey_ecd_digestsign448,
900 pkey_ecd_digestverify448
904 # include "s390x_arch.h"
905 # include "internal/constant_time.h"
907 static void s390x_x25519_mod_p(unsigned char u[32])
909 unsigned char u_red[32];
913 memcpy(u_red, u, sizeof(u_red));
915 c += (unsigned int)u_red[31] + 19;
916 u_red[31] = (unsigned char)c;
919 for (i = 30; i >= 0; i--) {
920 c += (unsigned int)u_red[i];
921 u_red[i] = (unsigned char)c;
925 c = (u_red[0] & 0x80) >> 7;
927 constant_time_cond_swap_buff(0 - (unsigned char)c,
928 u, u_red, sizeof(u_red));
931 static void s390x_x448_mod_p(unsigned char u[56])
933 unsigned char u_red[56];
937 memcpy(u_red, u, sizeof(u_red));
939 c += (unsigned int)u_red[55] + 1;
940 u_red[55] = (unsigned char)c;
943 for (i = 54; i >= 28; i--) {
944 c += (unsigned int)u_red[i];
945 u_red[i] = (unsigned char)c;
949 c += (unsigned int)u_red[27] + 1;
950 u_red[27] = (unsigned char)c;
953 for (i = 26; i >= 0; i--) {
954 c += (unsigned int)u_red[i];
955 u_red[i] = (unsigned char)c;
959 constant_time_cond_swap_buff(0 - (unsigned char)c,
960 u, u_red, sizeof(u_red));
963 int s390x_x25519_mul(unsigned char u_dst[32],
964 const unsigned char u_src[32],
965 const unsigned char d_src[32])
969 unsigned char u_dst[32];
970 unsigned char u_src[32];
971 unsigned char d_src[32];
973 unsigned long long buff[512];
977 memset(¶m, 0, sizeof(param));
979 s390x_flip_endian32(param.x25519.u_src, u_src);
980 param.x25519.u_src[0] &= 0x7f;
981 s390x_x25519_mod_p(param.x25519.u_src);
983 s390x_flip_endian32(param.x25519.d_src, d_src);
984 param.x25519.d_src[31] &= 248;
985 param.x25519.d_src[0] &= 127;
986 param.x25519.d_src[0] |= 64;
988 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, ¶m.x25519) ? 0 : 1;
990 s390x_flip_endian32(u_dst, param.x25519.u_dst);
992 OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
996 int s390x_x448_mul(unsigned char u_dst[56],
997 const unsigned char u_src[56],
998 const unsigned char d_src[56])
1002 unsigned char u_dst[64];
1003 unsigned char u_src[64];
1004 unsigned char d_src[64];
1006 unsigned long long buff[512];
1010 memset(¶m, 0, sizeof(param));
1012 memcpy(param.x448.u_src, u_src, 56);
1013 memcpy(param.x448.d_src, d_src, 56);
1015 s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1016 s390x_x448_mod_p(param.x448.u_src + 8);
1018 s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1019 param.x448.d_src[63] &= 252;
1020 param.x448.d_src[8] |= 128;
1022 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, ¶m.x448) ? 0 : 1;
1024 s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1025 memcpy(u_dst, param.x448.u_dst, 56);
1028 OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1032 static int s390x_ed25519_mul(unsigned char x_dst[32],
1033 unsigned char y_dst[32],
1034 const unsigned char x_src[32],
1035 const unsigned char y_src[32],
1036 const unsigned char d_src[32])
1040 unsigned char x_dst[32];
1041 unsigned char y_dst[32];
1042 unsigned char x_src[32];
1043 unsigned char y_src[32];
1044 unsigned char d_src[32];
1046 unsigned long long buff[512];
1050 memset(¶m, 0, sizeof(param));
1052 s390x_flip_endian32(param.ed25519.x_src, x_src);
1053 s390x_flip_endian32(param.ed25519.y_src, y_src);
1054 s390x_flip_endian32(param.ed25519.d_src, d_src);
1056 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, ¶m.ed25519) ? 0 : 1;
1058 s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1059 s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1062 OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1066 static int s390x_ed448_mul(unsigned char x_dst[57],
1067 unsigned char y_dst[57],
1068 const unsigned char x_src[57],
1069 const unsigned char y_src[57],
1070 const unsigned char d_src[57])
1074 unsigned char x_dst[64];
1075 unsigned char y_dst[64];
1076 unsigned char x_src[64];
1077 unsigned char y_src[64];
1078 unsigned char d_src[64];
1080 unsigned long long buff[512];
1084 memset(¶m, 0, sizeof(param));
1086 memcpy(param.ed448.x_src, x_src, 57);
1087 memcpy(param.ed448.y_src, y_src, 57);
1088 memcpy(param.ed448.d_src, d_src, 57);
1089 s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1090 s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1091 s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1093 rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, ¶m.ed448) ? 0 : 1;
1095 s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1096 s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1097 memcpy(x_dst, param.ed448.x_dst, 57);
1098 memcpy(y_dst, param.ed448.y_dst, 57);
1101 OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1105 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1107 static const unsigned char generator[] = {
1108 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1112 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
1113 unsigned char *privkey = NULL, *pubkey;
1116 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1120 pubkey = key->pubkey;
1122 privkey = ecx_key_allocate_privkey(key);
1123 if (privkey == NULL) {
1124 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1128 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1135 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1138 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1145 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1147 static const unsigned char generator[] = {
1148 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1154 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1155 unsigned char *privkey = NULL, *pubkey;
1158 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1162 pubkey = key->pubkey;
1164 privkey = ecx_key_allocate_privkey(key);
1165 if (privkey == NULL) {
1166 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1170 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1176 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1179 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1186 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1188 static const unsigned char generator_x[] = {
1189 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1190 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1191 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1193 static const unsigned char generator_y[] = {
1194 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1195 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1196 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1198 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1199 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1200 unsigned char *privkey = NULL, *pubkey;
1204 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, 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_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1216 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1219 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1226 if (s390x_ed25519_mul(x_dst, pubkey,
1227 generator_x, generator_y, buff) != 1)
1230 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1232 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1239 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1241 static const unsigned char generator_x[] = {
1242 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1243 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1244 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1245 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1246 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1248 static const unsigned char generator_y[] = {
1249 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1250 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1251 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1252 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1253 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1255 unsigned char x_dst[57], buff[114];
1256 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1257 unsigned char *privkey = NULL, *pubkey;
1258 EVP_MD_CTX *hashctx = NULL;
1261 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1265 pubkey = key->pubkey;
1267 privkey = ecx_key_allocate_privkey(key);
1268 if (privkey == NULL) {
1269 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1273 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1276 hashctx = EVP_MD_CTX_new();
1277 if (hashctx == NULL)
1279 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1281 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1283 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1290 if (s390x_ed448_mul(x_dst, pubkey,
1291 generator_x, generator_y, buff) != 1)
1294 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1296 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1297 EVP_MD_CTX_free(hashctx);
1301 EVP_MD_CTX_free(hashctx);
1305 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1308 const unsigned char *privkey, *pubkey;
1310 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1314 return s390x_x25519_mul(key, pubkey, privkey);
1316 *keylen = X25519_KEYLEN;
1320 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1323 const unsigned char *privkey, *pubkey;
1325 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1329 return s390x_x448_mul(key, pubkey, privkey);
1331 *keylen = X448_KEYLEN;
1335 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1336 unsigned char *sig, size_t *siglen,
1337 const unsigned char *tbs,
1342 unsigned char sig[64];
1343 unsigned char priv[32];
1345 unsigned long long buff[512];
1347 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1351 *siglen = ED25519_SIGSIZE;
1355 if (*siglen < ED25519_SIGSIZE) {
1356 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1360 memset(¶m, 0, sizeof(param));
1361 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1363 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1364 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1368 s390x_flip_endian32(sig, param.ed25519.sig);
1369 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1371 *siglen = ED25519_SIGSIZE;
1375 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1376 unsigned char *sig, size_t *siglen,
1377 const unsigned char *tbs,
1382 unsigned char sig[128];
1383 unsigned char priv[64];
1385 unsigned long long buff[512];
1387 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1391 *siglen = ED448_SIGSIZE;
1395 if (*siglen < ED448_SIGSIZE) {
1396 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1400 memset(¶m, 0, sizeof(param));
1401 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1403 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1404 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1408 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1409 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1410 memcpy(sig, param.ed448.sig, 57);
1411 memcpy(sig + 57, param.ed448.sig + 64, 57);
1413 *siglen = ED448_SIGSIZE;
1417 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1418 const unsigned char *sig,
1420 const unsigned char *tbs,
1425 unsigned char sig[64];
1426 unsigned char pub[32];
1428 unsigned long long buff[512];
1430 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1432 if (siglen != ED25519_SIGSIZE)
1435 memset(¶m, 0, sizeof(param));
1436 s390x_flip_endian32(param.ed25519.sig, sig);
1437 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1438 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1440 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1441 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1444 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1445 const unsigned char *sig,
1447 const unsigned char *tbs,
1452 unsigned char sig[128];
1453 unsigned char pub[64];
1455 unsigned long long buff[512];
1457 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1459 if (siglen != ED448_SIGSIZE)
1462 memset(¶m, 0, sizeof(param));
1463 memcpy(param.ed448.sig, sig, 57);
1464 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1465 memcpy(param.ed448.sig + 64, sig + 57, 57);
1466 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1467 memcpy(param.ed448.pub, edkey->pubkey, 57);
1468 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1470 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1471 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1474 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1476 0, 0, 0, 0, 0, 0, 0,
1477 s390x_pkey_ecx_keygen25519,
1478 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1479 s390x_pkey_ecx_derive25519,
1484 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1486 0, 0, 0, 0, 0, 0, 0,
1487 s390x_pkey_ecx_keygen448,
1488 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1489 s390x_pkey_ecx_derive448,
1493 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1494 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1496 s390x_pkey_ecd_keygen25519,
1497 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1500 s390x_pkey_ecd_digestsign25519,
1501 s390x_pkey_ecd_digestverify25519
1504 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1505 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1507 s390x_pkey_ecd_keygen448,
1508 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1511 s390x_pkey_ecd_digestsign448,
1512 s390x_pkey_ecd_digestverify448
1516 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1519 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1520 return &ecx25519_s390x_pkey_meth;
1522 return &ecx25519_pkey_meth;
1525 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1528 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1529 return &ecx448_s390x_pkey_meth;
1531 return &ecx448_pkey_meth;
1534 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1537 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1538 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1539 && OPENSSL_s390xcap_P.kdsa[0]
1540 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1541 return &ed25519_s390x_pkey_meth;
1543 return &ed25519_pkey_meth;
1546 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1549 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1550 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1551 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1552 return &ed448_s390x_pkey_meth;
1554 return &ed448_pkey_meth;