2 * Copyright 2006-2021 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 <openssl/x509.h>
18 #include <openssl/ec.h>
19 #include <openssl/core_names.h>
20 #include <openssl/param_build.h>
21 #include "internal/cryptlib.h"
22 #include "internal/provider.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"
30 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
32 const ECX_KEY *ecxkey = pkey->pkey.ecx;
36 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
40 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
42 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
46 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
47 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
49 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
55 static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
57 const unsigned char *p;
63 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
65 ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id,
66 KEY_OP_PUBLIC, NULL, NULL);
69 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
74 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
76 const ECX_KEY *akey = a->pkey.ecx;
77 const ECX_KEY *bkey = b->pkey.ecx;
79 if (akey == NULL || bkey == NULL)
82 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
85 static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
86 OSSL_LIB_CTX *libctx, const char *propq)
89 ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq);
93 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
99 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
101 const ECX_KEY *ecxkey = pkey->pkey.ecx;
102 ASN1_OCTET_STRING oct;
103 unsigned char *penc = NULL;
106 if (ecxkey == NULL || ecxkey->privkey == NULL) {
107 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
111 oct.data = ecxkey->privkey;
112 oct.length = KEYLEN(pkey);
115 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
117 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
121 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
122 V_ASN1_UNDEF, NULL, penc, penclen)) {
123 OPENSSL_clear_free(penc, penclen);
124 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
131 static int ecx_size(const EVP_PKEY *pkey)
136 static int ecx_bits(const EVP_PKEY *pkey)
138 if (IS25519(pkey->ameth->pkey_id)) {
140 } else if(ISX448(pkey->ameth->pkey_id)) {
147 static int ecx_security_bits(const EVP_PKEY *pkey)
149 if (IS25519(pkey->ameth->pkey_id)) {
150 return X25519_SECURITY_BITS;
152 return X448_SECURITY_BITS;
156 static void ecx_free(EVP_PKEY *pkey)
158 ossl_ecx_key_free(pkey->pkey.ecx);
161 /* "parameters" are always equal */
162 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
167 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
168 ASN1_PCTX *ctx, ecx_key_op_t op)
170 const ECX_KEY *ecxkey = pkey->pkey.ecx;
171 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
173 if (op == KEY_OP_PRIVATE) {
174 if (ecxkey == NULL || ecxkey->privkey == NULL) {
175 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
179 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
181 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
183 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
187 if (ecxkey == NULL) {
188 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
192 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
195 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
198 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
204 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
207 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
210 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
213 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
216 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
220 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: {
221 ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id,
222 KEY_OP_PUBLIC, NULL, NULL);
225 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
230 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
231 if (pkey->pkey.ecx != NULL) {
232 unsigned char **ppt = arg2;
234 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
246 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
249 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
250 /* We currently only support Pure EdDSA which takes no digest */
251 *(int *)arg2 = NID_undef;
260 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
263 OSSL_LIB_CTX *libctx = NULL;
266 if (pkey->keymgmt != NULL)
267 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
269 ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id,
270 KEY_OP_PRIVATE, libctx, NULL);
273 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
279 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
281 OSSL_LIB_CTX *libctx = NULL;
284 if (pkey->keymgmt != NULL)
285 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
287 ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id,
288 KEY_OP_PUBLIC, libctx, NULL);
291 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
297 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
300 const ECX_KEY *key = pkey->pkey.ecx;
303 *len = KEYLENID(pkey->ameth->pkey_id);
308 || key->privkey == NULL
309 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
312 *len = KEYLENID(pkey->ameth->pkey_id);
313 memcpy(priv, key->privkey, *len);
318 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
321 const ECX_KEY *key = pkey->pkey.ecx;
324 *len = KEYLENID(pkey->ameth->pkey_id);
329 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
332 *len = KEYLENID(pkey->ameth->pkey_id);
333 memcpy(pub, key->pubkey, *len);
338 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
341 * We provide no mechanism to "update" an ECX key once it has been set,
342 * therefore we do not have to maintain a dirty count.
347 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
348 EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx,
351 const ECX_KEY *key = from->pkey.ecx;
352 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
353 OSSL_PARAM *params = NULL;
360 /* A key must at least have a public part */
361 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
362 key->pubkey, key->keylen))
364 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
366 if (key->privkey != NULL) {
367 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
368 OSSL_PKEY_PARAM_PRIV_KEY,
369 key->privkey, key->keylen))
371 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
374 params = OSSL_PARAM_BLD_to_param(tmpl);
376 /* We export, the provider imports */
377 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
380 OSSL_PARAM_BLD_free(tmpl);
381 OSSL_PARAM_BLD_free_params(params);
385 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
388 EVP_PKEY_CTX *pctx = vpctx;
389 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
390 ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0,
394 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
398 if (!ossl_ecx_key_fromdata(ecx, params, 1)
399 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
400 ossl_ecx_key_free(ecx);
406 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
408 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
411 const EVP_PKEY_ASN1_METHOD ossl_ecx25519_asn1_meth = {
416 "OpenSSL X25519 algorithm",
459 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
461 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
464 const EVP_PKEY_ASN1_METHOD ossl_ecx448_asn1_meth = {
469 "OpenSSL X448 algorithm",
512 static int ecd_size25519(const EVP_PKEY *pkey)
514 return ED25519_SIGSIZE;
517 static int ecd_size448(const EVP_PKEY *pkey)
519 return ED448_SIGSIZE;
522 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
523 const void *asn, const X509_ALGOR *sigalg,
524 const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
526 const ASN1_OBJECT *obj;
530 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
531 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
532 nid = OBJ_obj2nid(obj);
533 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
534 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
538 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
544 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
546 X509_ALGOR *alg1, X509_ALGOR *alg2,
547 ASN1_BIT_STRING *str)
549 /* Set algorithms identifiers */
550 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
552 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
553 /* Algorithm identifiers set: carry on as normal */
557 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
558 const ASN1_STRING *sig)
560 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
565 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
567 X509_ALGOR *alg1, X509_ALGOR *alg2,
568 ASN1_BIT_STRING *str)
570 /* Set algorithm identifier */
571 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
573 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
574 /* Algorithm identifier set: carry on as normal */
578 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
579 const ASN1_STRING *sig)
581 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
586 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
588 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
591 const EVP_PKEY_ASN1_METHOD ossl_ed25519_asn1_meth = {
596 "OpenSSL ED25519 algorithm",
621 ecd_sig_info_set25519,
638 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
640 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
643 const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = {
648 "OpenSSL ED448 algorithm",
690 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
692 ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id,
693 KEY_OP_PUBLIC, NULL, NULL);
696 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx);
702 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
704 const unsigned char **privkey,
705 const unsigned char **pubkey)
707 const ECX_KEY *ecxkey, *peerkey;
709 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
710 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
713 ecxkey = ctx->pkey->pkey.ecx;
714 peerkey = EVP_PKEY_get0(ctx->peerkey);
715 if (ecxkey == NULL || ecxkey->privkey == NULL) {
716 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
719 if (peerkey == NULL) {
720 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY);
723 *privkey = ecxkey->privkey;
724 *pubkey = peerkey->pubkey;
729 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
732 const unsigned char *privkey, *pubkey;
734 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
736 && ossl_x25519(key, privkey, pubkey) == 0))
738 *keylen = X25519_KEYLEN;
742 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
745 const unsigned char *privkey, *pubkey;
747 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
749 && ossl_x448(key, privkey, pubkey) == 0))
751 *keylen = X448_KEYLEN;
755 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
757 /* Only need to handle peer key for derivation */
758 if (type == EVP_PKEY_CTRL_PEER_KEY)
763 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
767 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
768 pkey_ecx_derive25519,
773 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
777 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
783 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
784 size_t *siglen, const unsigned char *tbs,
787 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
790 *siglen = ED25519_SIGSIZE;
793 if (*siglen < ED25519_SIGSIZE) {
794 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
798 if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
801 *siglen = ED25519_SIGSIZE;
805 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
806 size_t *siglen, const unsigned char *tbs,
809 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
812 *siglen = ED448_SIGSIZE;
815 if (*siglen < ED448_SIGSIZE) {
816 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
820 if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey,
821 edkey->privkey, NULL, 0, edkey->propq) == 0)
823 *siglen = ED448_SIGSIZE;
827 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
828 size_t siglen, const unsigned char *tbs,
831 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
833 if (siglen != ED25519_SIGSIZE)
836 return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
837 edkey->libctx, edkey->propq);
840 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
841 size_t siglen, const unsigned char *tbs,
844 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
846 if (siglen != ED448_SIGSIZE)
849 return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey,
850 NULL, 0, edkey->propq);
853 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
856 case EVP_PKEY_CTRL_MD:
857 /* Only NULL allowed as digest */
858 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
860 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE);
863 case EVP_PKEY_CTRL_DIGESTINIT:
869 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
870 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
873 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
876 pkey_ecd_digestsign25519,
877 pkey_ecd_digestverify25519
880 static const EVP_PKEY_METHOD ed448_pkey_meth = {
881 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
884 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
887 pkey_ecd_digestsign448,
888 pkey_ecd_digestverify448
892 # include "s390x_arch.h"
894 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
896 static const unsigned char generator[] = {
897 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
898 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
899 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
901 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1,
903 unsigned char *privkey = NULL, *pubkey;
906 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
910 pubkey = key->pubkey;
912 privkey = ossl_ecx_key_allocate_privkey(key);
913 if (privkey == NULL) {
914 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
918 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN) <= 0)
925 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
928 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
931 ossl_ecx_key_free(key);
935 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
937 static const unsigned char generator[] = {
938 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
939 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
944 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1,
946 unsigned char *privkey = NULL, *pubkey;
949 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
953 pubkey = key->pubkey;
955 privkey = ossl_ecx_key_allocate_privkey(key);
956 if (privkey == NULL) {
957 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
961 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN) <= 0)
967 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
970 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
973 ossl_ecx_key_free(key);
977 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
979 static const unsigned char generator_x[] = {
980 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
981 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
982 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
984 static const unsigned char generator_y[] = {
985 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
986 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
987 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
989 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
990 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1,
992 unsigned char *privkey = NULL, *pubkey;
998 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1002 pubkey = key->pubkey;
1004 privkey = ossl_ecx_key_allocate_privkey(key);
1005 if (privkey == NULL) {
1006 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1010 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN) <= 0)
1013 md = EVP_MD_fetch(ctx->libctx, "SHA512", ctx->propquery);
1017 rv = EVP_Digest(privkey, 32, buff, &sz, md, NULL);
1026 if (s390x_ed25519_mul(x_dst, pubkey,
1027 generator_x, generator_y, buff) != 1)
1030 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1032 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1035 ossl_ecx_key_free(key);
1039 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1041 static const unsigned char generator_x[] = {
1042 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1043 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1044 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1045 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1046 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1048 static const unsigned char generator_y[] = {
1049 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1050 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1051 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1052 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1053 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1055 unsigned char x_dst[57], buff[114];
1056 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1,
1058 unsigned char *privkey = NULL, *pubkey;
1059 EVP_MD_CTX *hashctx = NULL;
1064 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1068 pubkey = key->pubkey;
1070 privkey = ossl_ecx_key_allocate_privkey(key);
1071 if (privkey == NULL) {
1072 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1076 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN) <= 0)
1079 hashctx = EVP_MD_CTX_new();
1080 if (hashctx == NULL)
1083 md = EVP_MD_fetch(ctx->libctx, "SHAKE256", ctx->propquery);
1087 rv = EVP_DigestInit_ex(hashctx, md, NULL);
1092 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1094 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1101 if (s390x_ed448_mul(x_dst, pubkey,
1102 generator_x, generator_y, buff) != 1)
1105 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1107 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1108 EVP_MD_CTX_free(hashctx);
1111 ossl_ecx_key_free(key);
1112 EVP_MD_CTX_free(hashctx);
1116 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1119 const unsigned char *privkey, *pubkey;
1121 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1125 return s390x_x25519_mul(key, pubkey, privkey);
1127 *keylen = X25519_KEYLEN;
1131 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1134 const unsigned char *privkey, *pubkey;
1136 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1140 return s390x_x448_mul(key, pubkey, privkey);
1142 *keylen = X448_KEYLEN;
1146 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1147 unsigned char *sig, size_t *siglen,
1148 const unsigned char *tbs,
1153 unsigned char sig[64];
1154 unsigned char priv[32];
1156 unsigned long long buff[512];
1158 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1162 *siglen = ED25519_SIGSIZE;
1166 if (*siglen < ED25519_SIGSIZE) {
1167 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1171 memset(¶m, 0, sizeof(param));
1172 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1174 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1175 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1179 s390x_flip_endian32(sig, param.ed25519.sig);
1180 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1182 *siglen = ED25519_SIGSIZE;
1186 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1187 unsigned char *sig, size_t *siglen,
1188 const unsigned char *tbs,
1193 unsigned char sig[128];
1194 unsigned char priv[64];
1196 unsigned long long buff[512];
1198 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1202 *siglen = ED448_SIGSIZE;
1206 if (*siglen < ED448_SIGSIZE) {
1207 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1211 memset(¶m, 0, sizeof(param));
1212 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1214 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1215 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1219 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1220 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1221 memcpy(sig, param.ed448.sig, 57);
1222 memcpy(sig + 57, param.ed448.sig + 64, 57);
1224 *siglen = ED448_SIGSIZE;
1228 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1229 const unsigned char *sig,
1231 const unsigned char *tbs,
1236 unsigned char sig[64];
1237 unsigned char pub[32];
1239 unsigned long long buff[512];
1241 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1243 if (siglen != ED25519_SIGSIZE)
1246 memset(¶m, 0, sizeof(param));
1247 s390x_flip_endian32(param.ed25519.sig, sig);
1248 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1249 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1251 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1252 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1255 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1256 const unsigned char *sig,
1258 const unsigned char *tbs,
1263 unsigned char sig[128];
1264 unsigned char pub[64];
1266 unsigned long long buff[512];
1268 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1270 if (siglen != ED448_SIGSIZE)
1273 memset(¶m, 0, sizeof(param));
1274 memcpy(param.ed448.sig, sig, 57);
1275 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1276 memcpy(param.ed448.sig + 64, sig + 57, 57);
1277 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1278 memcpy(param.ed448.pub, edkey->pubkey, 57);
1279 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1281 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1282 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1285 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1287 0, 0, 0, 0, 0, 0, 0,
1288 s390x_pkey_ecx_keygen25519,
1289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1290 s390x_pkey_ecx_derive25519,
1295 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1297 0, 0, 0, 0, 0, 0, 0,
1298 s390x_pkey_ecx_keygen448,
1299 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1300 s390x_pkey_ecx_derive448,
1304 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1305 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1307 s390x_pkey_ecd_keygen25519,
1308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1311 s390x_pkey_ecd_digestsign25519,
1312 s390x_pkey_ecd_digestverify25519
1315 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1316 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1318 s390x_pkey_ecd_keygen448,
1319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1322 s390x_pkey_ecd_digestsign448,
1323 s390x_pkey_ecd_digestverify448
1327 const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void)
1330 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1331 return &ecx25519_s390x_pkey_meth;
1333 return &ecx25519_pkey_meth;
1336 const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void)
1339 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1340 return &ecx448_s390x_pkey_meth;
1342 return &ecx448_pkey_meth;
1345 const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void)
1348 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1349 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1350 && OPENSSL_s390xcap_P.kdsa[0]
1351 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1352 return &ed25519_s390x_pkey_meth;
1354 return &ed25519_pkey_meth;
1357 const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void)
1360 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1361 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1362 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1363 return &ed448_s390x_pkey_meth;
1365 return &ed448_pkey_meth;