2 * Copyright 2006-2020 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(libctx, 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));
91 if (!ecx_public_from_private(key)) {
92 ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
97 EVP_PKEY_assign(pkey, id, key);
104 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
106 const ECX_KEY *ecxkey = pkey->pkey.ecx;
109 if (ecxkey == NULL) {
110 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
114 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
116 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
120 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
121 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
123 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
129 static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
131 const unsigned char *p;
135 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
137 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
138 KEY_OP_PUBLIC, NULL, NULL);
141 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
143 const ECX_KEY *akey = a->pkey.ecx;
144 const ECX_KEY *bkey = b->pkey.ecx;
146 if (akey == NULL || bkey == NULL)
149 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
152 static int ecx_priv_decode_with_libctx(EVP_PKEY *pkey,
153 const PKCS8_PRIV_KEY_INFO *p8,
154 OPENSSL_CTX *libctx, const char *propq)
156 const unsigned char *p;
158 ASN1_OCTET_STRING *oct = NULL;
159 const X509_ALGOR *palg;
162 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
165 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
170 p = ASN1_STRING_get0_data(oct);
171 plen = ASN1_STRING_length(oct);
174 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE,
176 ASN1_STRING_clear_free(oct);
180 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
182 const ECX_KEY *ecxkey = pkey->pkey.ecx;
183 ASN1_OCTET_STRING oct;
184 unsigned char *penc = NULL;
187 if (ecxkey == NULL || ecxkey->privkey == NULL) {
188 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
192 oct.data = ecxkey->privkey;
193 oct.length = KEYLEN(pkey);
196 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
198 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
202 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
203 V_ASN1_UNDEF, NULL, penc, penclen)) {
204 OPENSSL_clear_free(penc, penclen);
205 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
212 static int ecx_size(const EVP_PKEY *pkey)
217 static int ecx_bits(const EVP_PKEY *pkey)
219 if (IS25519(pkey->ameth->pkey_id)) {
221 } else if(ISX448(pkey->ameth->pkey_id)) {
228 static int ecx_security_bits(const EVP_PKEY *pkey)
230 if (IS25519(pkey->ameth->pkey_id)) {
231 return X25519_SECURITY_BITS;
233 return X448_SECURITY_BITS;
237 static void ecx_free(EVP_PKEY *pkey)
239 ecx_key_free(pkey->pkey.ecx);
242 /* "parameters" are always equal */
243 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
248 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
249 ASN1_PCTX *ctx, ecx_key_op_t op)
251 const ECX_KEY *ecxkey = pkey->pkey.ecx;
252 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
254 if (op == KEY_OP_PRIVATE) {
255 if (ecxkey == NULL || ecxkey->privkey == NULL) {
256 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
260 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
262 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
264 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
268 if (ecxkey == NULL) {
269 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
273 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
276 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
279 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
285 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
288 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
291 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
294 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
297 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
301 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
302 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
303 KEY_OP_PUBLIC, NULL, NULL);
305 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
306 if (pkey->pkey.ecx != NULL) {
307 unsigned char **ppt = arg2;
309 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
321 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
324 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
325 /* We currently only support Pure EdDSA which takes no digest */
326 *(int *)arg2 = NID_undef;
335 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
338 /* TODO(3.0): We should pass a libctx here */
339 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
340 KEY_OP_PRIVATE, NULL, NULL);
343 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
345 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
346 KEY_OP_PUBLIC, NULL, NULL);
349 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
352 const ECX_KEY *key = pkey->pkey.ecx;
355 *len = KEYLENID(pkey->ameth->pkey_id);
360 || key->privkey == NULL
361 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
364 *len = KEYLENID(pkey->ameth->pkey_id);
365 memcpy(priv, key->privkey, *len);
370 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
373 const ECX_KEY *key = pkey->pkey.ecx;
376 *len = KEYLENID(pkey->ameth->pkey_id);
381 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
384 *len = KEYLENID(pkey->ameth->pkey_id);
385 memcpy(pub, key->pubkey, *len);
390 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
393 * We provide no mechanism to "update" an ECX key once it has been set,
394 * therefore we do not have to maintain a dirty count.
399 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
400 EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
403 const ECX_KEY *key = from->pkey.ecx;
404 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
405 OSSL_PARAM *params = NULL;
412 /* A key must at least have a public part */
413 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
414 key->pubkey, key->keylen))
416 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
418 if (key->privkey != NULL) {
419 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
420 OSSL_PKEY_PARAM_PRIV_KEY,
421 key->privkey, key->keylen))
423 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
426 params = OSSL_PARAM_BLD_to_param(tmpl);
428 /* We export, the provider imports */
429 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
432 OSSL_PARAM_BLD_free(tmpl);
433 OSSL_PARAM_BLD_free_params(params);
437 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
440 EVP_PKEY_CTX *pctx = vpctx;
441 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
442 ECX_KEY *ecx = ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0);
445 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
449 if (!ecx_key_fromdata(ecx, params, 1)
450 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
457 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
459 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
462 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
467 "OpenSSL X25519 algorithm",
507 ecx_priv_decode_with_libctx
510 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
512 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
515 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
520 "OpenSSL X448 algorithm",
560 ecx_priv_decode_with_libctx
563 static int ecd_size25519(const EVP_PKEY *pkey)
565 return ED25519_SIGSIZE;
568 static int ecd_size448(const EVP_PKEY *pkey)
570 return ED448_SIGSIZE;
573 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
574 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
577 const ASN1_OBJECT *obj;
581 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
582 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
583 nid = OBJ_obj2nid(obj);
584 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
585 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
589 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
595 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
596 X509_ALGOR *alg1, X509_ALGOR *alg2,
597 ASN1_BIT_STRING *str)
599 /* Set algorithms identifiers */
600 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
602 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
603 /* Algorithm identifiers set: carry on as normal */
607 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
608 const ASN1_STRING *sig)
610 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
615 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
616 X509_ALGOR *alg1, X509_ALGOR *alg2,
617 ASN1_BIT_STRING *str)
619 /* Set algorithm identifier */
620 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
622 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
623 /* Algorithm identifier set: carry on as normal */
627 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
628 const ASN1_STRING *sig)
630 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
635 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
637 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
640 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
645 "OpenSSL ED25519 algorithm",
670 ecd_sig_info_set25519,
684 ecx_priv_decode_with_libctx
687 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
689 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
692 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
697 "OpenSSL ED448 algorithm",
736 ecx_priv_decode_with_libctx
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,
745 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
747 const unsigned char **privkey,
748 const unsigned char **pubkey)
750 const ECX_KEY *ecxkey, *peerkey;
752 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
753 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
756 ecxkey = ctx->pkey->pkey.ecx;
757 peerkey = ctx->peerkey->pkey.ecx;
758 if (ecxkey == NULL || ecxkey->privkey == NULL) {
759 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
762 if (peerkey == NULL) {
763 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
766 *privkey = ecxkey->privkey;
767 *pubkey = peerkey->pubkey;
772 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
775 const unsigned char *privkey, *pubkey;
777 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
779 && X25519(key, privkey, pubkey) == 0))
781 *keylen = X25519_KEYLEN;
785 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
788 const unsigned char *privkey, *pubkey;
790 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
792 && X448(key, privkey, pubkey) == 0))
794 *keylen = X448_KEYLEN;
798 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
800 /* Only need to handle peer key for derivation */
801 if (type == EVP_PKEY_CTRL_PEER_KEY)
806 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
811 pkey_ecx_derive25519,
816 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
820 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
826 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
827 size_t *siglen, const unsigned char *tbs,
830 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
833 *siglen = ED25519_SIGSIZE;
836 if (*siglen < ED25519_SIGSIZE) {
837 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
841 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
844 *siglen = ED25519_SIGSIZE;
848 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
849 size_t *siglen, const unsigned char *tbs,
852 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
855 *siglen = ED448_SIGSIZE;
858 if (*siglen < ED448_SIGSIZE) {
859 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
864 * TODO(3.0): We use NULL for the library context for now. Will need to
867 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
870 *siglen = ED448_SIGSIZE;
874 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
875 size_t siglen, const unsigned char *tbs,
878 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
880 if (siglen != ED25519_SIGSIZE)
883 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
886 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
887 size_t siglen, const unsigned char *tbs,
890 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
892 if (siglen != ED448_SIGSIZE)
896 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
899 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
902 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
905 case EVP_PKEY_CTRL_MD:
906 /* Only NULL allowed as digest */
907 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
909 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
912 case EVP_PKEY_CTRL_DIGESTINIT:
918 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
919 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
922 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
925 pkey_ecd_digestsign25519,
926 pkey_ecd_digestverify25519
929 static const EVP_PKEY_METHOD ed448_pkey_meth = {
930 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
933 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
936 pkey_ecd_digestsign448,
937 pkey_ecd_digestverify448
941 # include "s390x_arch.h"
943 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
945 static const unsigned char generator[] = {
946 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
947 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
948 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
950 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1);
951 unsigned char *privkey = NULL, *pubkey;
954 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
958 pubkey = key->pubkey;
960 privkey = ecx_key_allocate_privkey(key);
961 if (privkey == NULL) {
962 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
966 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
973 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
976 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
983 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
985 static const unsigned char generator[] = {
986 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
989 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
992 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1);
993 unsigned char *privkey = NULL, *pubkey;
996 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1000 pubkey = key->pubkey;
1002 privkey = ecx_key_allocate_privkey(key);
1003 if (privkey == NULL) {
1004 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1008 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1014 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1017 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1024 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1026 static const unsigned char generator_x[] = {
1027 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1028 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1029 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1031 static const unsigned char generator_y[] = {
1032 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1033 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1034 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1036 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1037 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1);
1038 unsigned char *privkey = NULL, *pubkey;
1042 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1046 pubkey = key->pubkey;
1048 privkey = ecx_key_allocate_privkey(key);
1049 if (privkey == NULL) {
1050 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1054 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1057 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1064 if (s390x_ed25519_mul(x_dst, pubkey,
1065 generator_x, generator_y, buff) != 1)
1068 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1070 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1077 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1079 static const unsigned char generator_x[] = {
1080 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1081 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1082 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1083 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1084 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1086 static const unsigned char generator_y[] = {
1087 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1088 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1089 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1090 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1091 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1093 unsigned char x_dst[57], buff[114];
1094 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1);
1095 unsigned char *privkey = NULL, *pubkey;
1096 EVP_MD_CTX *hashctx = NULL;
1099 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1103 pubkey = key->pubkey;
1105 privkey = ecx_key_allocate_privkey(key);
1106 if (privkey == NULL) {
1107 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1111 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1114 hashctx = EVP_MD_CTX_new();
1115 if (hashctx == NULL)
1117 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1119 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1121 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1128 if (s390x_ed448_mul(x_dst, pubkey,
1129 generator_x, generator_y, buff) != 1)
1132 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1134 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1135 EVP_MD_CTX_free(hashctx);
1139 EVP_MD_CTX_free(hashctx);
1143 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1146 const unsigned char *privkey, *pubkey;
1148 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1152 return s390x_x25519_mul(key, pubkey, privkey);
1154 *keylen = X25519_KEYLEN;
1158 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1161 const unsigned char *privkey, *pubkey;
1163 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1167 return s390x_x448_mul(key, pubkey, privkey);
1169 *keylen = X448_KEYLEN;
1173 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1174 unsigned char *sig, size_t *siglen,
1175 const unsigned char *tbs,
1180 unsigned char sig[64];
1181 unsigned char priv[32];
1183 unsigned long long buff[512];
1185 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1189 *siglen = ED25519_SIGSIZE;
1193 if (*siglen < ED25519_SIGSIZE) {
1194 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1198 memset(¶m, 0, sizeof(param));
1199 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1201 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1202 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1206 s390x_flip_endian32(sig, param.ed25519.sig);
1207 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1209 *siglen = ED25519_SIGSIZE;
1213 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1214 unsigned char *sig, size_t *siglen,
1215 const unsigned char *tbs,
1220 unsigned char sig[128];
1221 unsigned char priv[64];
1223 unsigned long long buff[512];
1225 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1229 *siglen = ED448_SIGSIZE;
1233 if (*siglen < ED448_SIGSIZE) {
1234 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1238 memset(¶m, 0, sizeof(param));
1239 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1241 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1242 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1246 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1247 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1248 memcpy(sig, param.ed448.sig, 57);
1249 memcpy(sig + 57, param.ed448.sig + 64, 57);
1251 *siglen = ED448_SIGSIZE;
1255 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1256 const unsigned char *sig,
1258 const unsigned char *tbs,
1263 unsigned char sig[64];
1264 unsigned char pub[32];
1266 unsigned long long buff[512];
1268 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1270 if (siglen != ED25519_SIGSIZE)
1273 memset(¶m, 0, sizeof(param));
1274 s390x_flip_endian32(param.ed25519.sig, sig);
1275 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1276 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1278 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1279 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1282 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1283 const unsigned char *sig,
1285 const unsigned char *tbs,
1290 unsigned char sig[128];
1291 unsigned char pub[64];
1293 unsigned long long buff[512];
1295 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1297 if (siglen != ED448_SIGSIZE)
1300 memset(¶m, 0, sizeof(param));
1301 memcpy(param.ed448.sig, sig, 57);
1302 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1303 memcpy(param.ed448.sig + 64, sig + 57, 57);
1304 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1305 memcpy(param.ed448.pub, edkey->pubkey, 57);
1306 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1308 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1309 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1312 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1314 0, 0, 0, 0, 0, 0, 0,
1315 s390x_pkey_ecx_keygen25519,
1316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1317 s390x_pkey_ecx_derive25519,
1322 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1324 0, 0, 0, 0, 0, 0, 0,
1325 s390x_pkey_ecx_keygen448,
1326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1327 s390x_pkey_ecx_derive448,
1331 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1332 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1334 s390x_pkey_ecd_keygen25519,
1335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1338 s390x_pkey_ecd_digestsign25519,
1339 s390x_pkey_ecd_digestverify25519
1342 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1343 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1345 s390x_pkey_ecd_keygen448,
1346 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1349 s390x_pkey_ecd_digestsign448,
1350 s390x_pkey_ecd_digestverify448
1354 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1357 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1358 return &ecx25519_s390x_pkey_meth;
1360 return &ecx25519_pkey_meth;
1363 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1366 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1367 return &ecx448_s390x_pkey_meth;
1369 return &ecx448_pkey_meth;
1372 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1375 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1376 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1377 && OPENSSL_s390xcap_P.kdsa[0]
1378 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1379 return &ed25519_s390x_pkey_meth;
1381 return &ed25519_pkey_meth;
1384 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1387 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1388 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1389 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1390 return &ed448_s390x_pkey_meth;
1392 return &ed448_pkey_meth;