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 <openssl/x509.h>
18 #include <openssl/ec.h>
19 #include <openssl/rand.h>
20 #include <openssl/core_names.h>
21 #include <openssl/param_build.h>
22 #include "internal/cryptlib.h"
23 #include "internal/provider.h"
24 #include "crypto/asn1.h"
25 #include "crypto/evp.h"
26 #include "crypto/ecx.h"
28 #include "curve448/curve448_local.h"
29 #include "ecx_backend.h"
37 /* Setup EVP_PKEY using public, private or generation */
38 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
39 const unsigned char *p, int plen, ecx_key_op_t op,
40 OSSL_LIB_CTX *libctx, const char *propq)
43 unsigned char *privkey, *pubkey;
45 if (op != KEY_OP_KEYGEN) {
49 /* Algorithm parameters must be absent */
50 X509_ALGOR_get0(NULL, &ptype, NULL, palg);
51 if (ptype != V_ASN1_UNDEF) {
52 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
57 if (p == NULL || plen != KEYLENID(id)) {
58 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
63 key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq);
65 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
70 if (op == KEY_OP_PUBLIC) {
71 memcpy(pubkey, p, plen);
73 privkey = ossl_ecx_key_allocate_privkey(key);
74 if (privkey == NULL) {
75 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
78 if (op == KEY_OP_KEYGEN) {
79 if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id)) <= 0)
81 if (id == EVP_PKEY_X25519) {
83 privkey[X25519_KEYLEN - 1] &= 127;
84 privkey[X25519_KEYLEN - 1] |= 64;
85 } else if (id == EVP_PKEY_X448) {
87 privkey[X448_KEYLEN - 1] |= 128;
90 memcpy(privkey, p, KEYLENID(id));
92 if (!ossl_ecx_public_from_private(key)) {
93 ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY);
98 EVP_PKEY_assign(pkey, id, key);
101 ossl_ecx_key_free(key);
105 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
107 const ECX_KEY *ecxkey = pkey->pkey.ecx;
110 if (ecxkey == NULL) {
111 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
115 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
117 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
121 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
122 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
124 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
130 static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
132 const unsigned char *p;
136 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
138 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
139 KEY_OP_PUBLIC, NULL, NULL);
142 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
144 const ECX_KEY *akey = a->pkey.ecx;
145 const ECX_KEY *bkey = b->pkey.ecx;
147 if (akey == NULL || bkey == NULL)
150 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
153 static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
154 OSSL_LIB_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 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
192 oct.data = ecxkey->privkey;
193 oct.length = KEYLEN(pkey);
196 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
198 ERR_raise(ERR_LIB_EC, 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 ERR_raise(ERR_LIB_EC, 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 ossl_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 OSSL_LIB_CTX *libctx = NULL;
340 if (pkey->keymgmt != NULL)
341 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
343 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
344 KEY_OP_PRIVATE, libctx, NULL);
347 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
349 OSSL_LIB_CTX *libctx = NULL;
351 if (pkey->keymgmt != NULL)
352 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
354 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
355 KEY_OP_PUBLIC, libctx, NULL);
358 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
361 const ECX_KEY *key = pkey->pkey.ecx;
364 *len = KEYLENID(pkey->ameth->pkey_id);
369 || key->privkey == NULL
370 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
373 *len = KEYLENID(pkey->ameth->pkey_id);
374 memcpy(priv, key->privkey, *len);
379 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
382 const ECX_KEY *key = pkey->pkey.ecx;
385 *len = KEYLENID(pkey->ameth->pkey_id);
390 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
393 *len = KEYLENID(pkey->ameth->pkey_id);
394 memcpy(pub, key->pubkey, *len);
399 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
402 * We provide no mechanism to "update" an ECX key once it has been set,
403 * therefore we do not have to maintain a dirty count.
408 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
409 EVP_KEYMGMT *to_keymgmt, OSSL_LIB_CTX *libctx,
412 const ECX_KEY *key = from->pkey.ecx;
413 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
414 OSSL_PARAM *params = NULL;
421 /* A key must at least have a public part */
422 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
423 key->pubkey, key->keylen))
425 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
427 if (key->privkey != NULL) {
428 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
429 OSSL_PKEY_PARAM_PRIV_KEY,
430 key->privkey, key->keylen))
432 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
435 params = OSSL_PARAM_BLD_to_param(tmpl);
437 /* We export, the provider imports */
438 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
441 OSSL_PARAM_BLD_free(tmpl);
442 OSSL_PARAM_BLD_free_params(params);
446 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
449 EVP_PKEY_CTX *pctx = vpctx;
450 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
451 ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0,
455 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
459 if (!ossl_ecx_key_fromdata(ecx, params, 1)
460 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
461 ossl_ecx_key_free(ecx);
467 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
469 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
472 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
477 "OpenSSL X25519 algorithm",
520 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
522 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
525 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
530 "OpenSSL X448 algorithm",
573 static int ecd_size25519(const EVP_PKEY *pkey)
575 return ED25519_SIGSIZE;
578 static int ecd_size448(const EVP_PKEY *pkey)
580 return ED448_SIGSIZE;
583 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
584 const void *asn, const X509_ALGOR *sigalg,
585 const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
587 const ASN1_OBJECT *obj;
591 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
592 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
593 nid = OBJ_obj2nid(obj);
594 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
595 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
599 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
605 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
607 X509_ALGOR *alg1, X509_ALGOR *alg2,
608 ASN1_BIT_STRING *str)
610 /* Set algorithms identifiers */
611 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
613 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
614 /* Algorithm identifiers set: carry on as normal */
618 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
619 const ASN1_STRING *sig)
621 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
626 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
628 X509_ALGOR *alg1, X509_ALGOR *alg2,
629 ASN1_BIT_STRING *str)
631 /* Set algorithm identifier */
632 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
634 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
635 /* Algorithm identifier set: carry on as normal */
639 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
640 const ASN1_STRING *sig)
642 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
647 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
649 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
652 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
657 "OpenSSL ED25519 algorithm",
682 ecd_sig_info_set25519,
699 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
701 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
704 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
709 "OpenSSL ED448 algorithm",
751 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
753 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
757 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
759 const unsigned char **privkey,
760 const unsigned char **pubkey)
762 const ECX_KEY *ecxkey, *peerkey;
764 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
765 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
768 ecxkey = ctx->pkey->pkey.ecx;
769 peerkey = ctx->peerkey->pkey.ecx;
770 if (ecxkey == NULL || ecxkey->privkey == NULL) {
771 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
774 if (peerkey == NULL) {
775 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY);
778 *privkey = ecxkey->privkey;
779 *pubkey = peerkey->pubkey;
784 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
787 const unsigned char *privkey, *pubkey;
789 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
791 && X25519(key, privkey, pubkey) == 0))
793 *keylen = X25519_KEYLEN;
797 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
800 const unsigned char *privkey, *pubkey;
802 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
804 && X448(key, privkey, pubkey) == 0))
806 *keylen = X448_KEYLEN;
810 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
812 /* Only need to handle peer key for derivation */
813 if (type == EVP_PKEY_CTRL_PEER_KEY)
818 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
823 pkey_ecx_derive25519,
828 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
832 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
838 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
839 size_t *siglen, const unsigned char *tbs,
842 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
845 *siglen = ED25519_SIGSIZE;
848 if (*siglen < ED25519_SIGSIZE) {
849 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
853 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
856 *siglen = ED25519_SIGSIZE;
860 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
861 size_t *siglen, const unsigned char *tbs,
864 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
867 *siglen = ED448_SIGSIZE;
870 if (*siglen < ED448_SIGSIZE) {
871 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
875 if (ED448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
876 NULL, 0, edkey->propq) == 0)
878 *siglen = ED448_SIGSIZE;
882 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
883 size_t siglen, const unsigned char *tbs,
886 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
888 if (siglen != ED25519_SIGSIZE)
891 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey,
892 edkey->libctx, edkey->propq);
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)
904 return ED448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, NULL, 0,
908 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
911 case EVP_PKEY_CTRL_MD:
912 /* Only NULL allowed as digest */
913 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
915 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE);
918 case EVP_PKEY_CTRL_DIGESTINIT:
924 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
925 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
931 pkey_ecd_digestsign25519,
932 pkey_ecd_digestverify25519
935 static const EVP_PKEY_METHOD ed448_pkey_meth = {
936 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
939 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
942 pkey_ecd_digestsign448,
943 pkey_ecd_digestverify448
947 # include "s390x_arch.h"
949 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
951 static const unsigned char generator[] = {
952 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
953 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
956 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1,
958 unsigned char *privkey = NULL, *pubkey;
961 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
965 pubkey = key->pubkey;
967 privkey = ossl_ecx_key_allocate_privkey(key);
968 if (privkey == NULL) {
969 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
973 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN) <= 0)
980 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
983 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
986 ossl_ecx_key_free(key);
990 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
992 static const unsigned char generator[] = {
993 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
999 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1,
1001 unsigned char *privkey = NULL, *pubkey;
1004 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1008 pubkey = key->pubkey;
1010 privkey = ossl_ecx_key_allocate_privkey(key);
1011 if (privkey == NULL) {
1012 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1016 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN) <= 0)
1022 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1025 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1028 ossl_ecx_key_free(key);
1032 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1034 static const unsigned char generator_x[] = {
1035 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1036 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1037 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1039 static const unsigned char generator_y[] = {
1040 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1041 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1042 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1044 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1045 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1047 unsigned char *privkey = NULL, *pubkey;
1051 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1055 pubkey = key->pubkey;
1057 privkey = ossl_ecx_key_allocate_privkey(key);
1058 if (privkey == NULL) {
1059 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1063 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN) <= 0)
1066 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1073 if (s390x_ed25519_mul(x_dst, pubkey,
1074 generator_x, generator_y, buff) != 1)
1077 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1079 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1082 ossl_ecx_key_free(key);
1086 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1088 static const unsigned char generator_x[] = {
1089 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1090 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1091 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1092 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1093 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1095 static const unsigned char generator_y[] = {
1096 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1097 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1098 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1099 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1100 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1102 unsigned char x_dst[57], buff[114];
1103 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1,
1105 unsigned char *privkey = NULL, *pubkey;
1106 EVP_MD_CTX *hashctx = NULL;
1109 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1113 pubkey = key->pubkey;
1115 privkey = ossl_ecx_key_allocate_privkey(key);
1116 if (privkey == NULL) {
1117 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1121 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN) <= 0)
1124 hashctx = EVP_MD_CTX_new();
1125 if (hashctx == NULL)
1127 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1129 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1131 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1138 if (s390x_ed448_mul(x_dst, pubkey,
1139 generator_x, generator_y, buff) != 1)
1142 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1144 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1145 EVP_MD_CTX_free(hashctx);
1148 ossl_ecx_key_free(key);
1149 EVP_MD_CTX_free(hashctx);
1153 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1156 const unsigned char *privkey, *pubkey;
1158 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1162 return s390x_x25519_mul(key, pubkey, privkey);
1164 *keylen = X25519_KEYLEN;
1168 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1171 const unsigned char *privkey, *pubkey;
1173 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1177 return s390x_x448_mul(key, pubkey, privkey);
1179 *keylen = X448_KEYLEN;
1183 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1184 unsigned char *sig, size_t *siglen,
1185 const unsigned char *tbs,
1190 unsigned char sig[64];
1191 unsigned char priv[32];
1193 unsigned long long buff[512];
1195 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1199 *siglen = ED25519_SIGSIZE;
1203 if (*siglen < ED25519_SIGSIZE) {
1204 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1208 memset(¶m, 0, sizeof(param));
1209 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1211 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1212 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1216 s390x_flip_endian32(sig, param.ed25519.sig);
1217 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1219 *siglen = ED25519_SIGSIZE;
1223 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1224 unsigned char *sig, size_t *siglen,
1225 const unsigned char *tbs,
1230 unsigned char sig[128];
1231 unsigned char priv[64];
1233 unsigned long long buff[512];
1235 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1239 *siglen = ED448_SIGSIZE;
1243 if (*siglen < ED448_SIGSIZE) {
1244 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1248 memset(¶m, 0, sizeof(param));
1249 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1251 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1252 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1256 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1257 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1258 memcpy(sig, param.ed448.sig, 57);
1259 memcpy(sig + 57, param.ed448.sig + 64, 57);
1261 *siglen = ED448_SIGSIZE;
1265 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1266 const unsigned char *sig,
1268 const unsigned char *tbs,
1273 unsigned char sig[64];
1274 unsigned char pub[32];
1276 unsigned long long buff[512];
1278 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1280 if (siglen != ED25519_SIGSIZE)
1283 memset(¶m, 0, sizeof(param));
1284 s390x_flip_endian32(param.ed25519.sig, sig);
1285 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1286 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1288 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1289 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1292 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1293 const unsigned char *sig,
1295 const unsigned char *tbs,
1300 unsigned char sig[128];
1301 unsigned char pub[64];
1303 unsigned long long buff[512];
1305 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1307 if (siglen != ED448_SIGSIZE)
1310 memset(¶m, 0, sizeof(param));
1311 memcpy(param.ed448.sig, sig, 57);
1312 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1313 memcpy(param.ed448.sig + 64, sig + 57, 57);
1314 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1315 memcpy(param.ed448.pub, edkey->pubkey, 57);
1316 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1318 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1319 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1322 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1324 0, 0, 0, 0, 0, 0, 0,
1325 s390x_pkey_ecx_keygen25519,
1326 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1327 s390x_pkey_ecx_derive25519,
1332 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1334 0, 0, 0, 0, 0, 0, 0,
1335 s390x_pkey_ecx_keygen448,
1336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1337 s390x_pkey_ecx_derive448,
1341 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1342 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1344 s390x_pkey_ecd_keygen25519,
1345 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1348 s390x_pkey_ecd_digestsign25519,
1349 s390x_pkey_ecd_digestverify25519
1352 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1353 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1355 s390x_pkey_ecd_keygen448,
1356 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1359 s390x_pkey_ecd_digestsign448,
1360 s390x_pkey_ecd_digestverify448
1364 const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void)
1367 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1368 return &ecx25519_s390x_pkey_meth;
1370 return &ecx25519_pkey_meth;
1373 const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void)
1376 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1377 return &ecx448_s390x_pkey_meth;
1379 return &ecx448_pkey_meth;
1382 const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void)
1385 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1386 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1387 && OPENSSL_s390xcap_P.kdsa[0]
1388 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1389 return &ed25519_s390x_pkey_meth;
1391 return &ed25519_pkey_meth;
1394 const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void)
1397 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1398 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1399 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1400 return &ed448_s390x_pkey_meth;
1402 return &ed448_pkey_meth;