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 <openssl/rand.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"
31 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
33 const ECX_KEY *ecxkey = pkey->pkey.ecx;
37 ERR_raise(ERR_LIB_EC, EC_R_INVALID_KEY);
41 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
43 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
47 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
48 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
50 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
56 static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey)
58 const unsigned char *p;
64 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
66 ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id,
67 KEY_OP_PUBLIC, NULL, NULL);
70 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
75 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
77 const ECX_KEY *akey = a->pkey.ecx;
78 const ECX_KEY *bkey = b->pkey.ecx;
80 if (akey == NULL || bkey == NULL)
83 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
86 static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8,
87 OSSL_LIB_CTX *libctx, const char *propq)
90 ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq);
94 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
100 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
102 const ECX_KEY *ecxkey = pkey->pkey.ecx;
103 ASN1_OCTET_STRING oct;
104 unsigned char *penc = NULL;
107 if (ecxkey == NULL || ecxkey->privkey == NULL) {
108 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
112 oct.data = ecxkey->privkey;
113 oct.length = KEYLEN(pkey);
116 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
118 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
122 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
123 V_ASN1_UNDEF, NULL, penc, penclen)) {
124 OPENSSL_clear_free(penc, penclen);
125 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
132 static int ecx_size(const EVP_PKEY *pkey)
137 static int ecx_bits(const EVP_PKEY *pkey)
139 if (IS25519(pkey->ameth->pkey_id)) {
141 } else if(ISX448(pkey->ameth->pkey_id)) {
148 static int ecx_security_bits(const EVP_PKEY *pkey)
150 if (IS25519(pkey->ameth->pkey_id)) {
151 return X25519_SECURITY_BITS;
153 return X448_SECURITY_BITS;
157 static void ecx_free(EVP_PKEY *pkey)
159 ossl_ecx_key_free(pkey->pkey.ecx);
162 /* "parameters" are always equal */
163 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
168 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
169 ASN1_PCTX *ctx, ecx_key_op_t op)
171 const ECX_KEY *ecxkey = pkey->pkey.ecx;
172 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
174 if (op == KEY_OP_PRIVATE) {
175 if (ecxkey == NULL || ecxkey->privkey == NULL) {
176 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
180 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
182 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
184 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
188 if (ecxkey == NULL) {
189 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
193 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
196 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
199 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
205 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
208 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
211 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
214 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
217 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
221 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: {
222 ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id,
223 KEY_OP_PUBLIC, NULL, NULL);
226 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
231 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
232 if (pkey->pkey.ecx != NULL) {
233 unsigned char **ppt = arg2;
235 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
247 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
250 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
251 /* We currently only support Pure EdDSA which takes no digest */
252 *(int *)arg2 = NID_undef;
261 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
264 OSSL_LIB_CTX *libctx = NULL;
267 if (pkey->keymgmt != NULL)
268 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
270 ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id,
271 KEY_OP_PRIVATE, libctx, NULL);
274 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
280 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
282 OSSL_LIB_CTX *libctx = NULL;
285 if (pkey->keymgmt != NULL)
286 libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt));
288 ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id,
289 KEY_OP_PUBLIC, libctx, NULL);
292 EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx);
298 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
301 const ECX_KEY *key = pkey->pkey.ecx;
304 *len = KEYLENID(pkey->ameth->pkey_id);
309 || key->privkey == NULL
310 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
313 *len = KEYLENID(pkey->ameth->pkey_id);
314 memcpy(priv, key->privkey, *len);
319 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
322 const ECX_KEY *key = pkey->pkey.ecx;
325 *len = KEYLENID(pkey->ameth->pkey_id);
330 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
333 *len = KEYLENID(pkey->ameth->pkey_id);
334 memcpy(pub, key->pubkey, *len);
339 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
342 * We provide no mechanism to "update" an ECX key once it has been set,
343 * therefore we do not have to maintain a dirty count.
348 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
349 OSSL_FUNC_keymgmt_import_fn *importer,
350 OSSL_LIB_CTX *libctx, const char *propq)
352 const ECX_KEY *key = from->pkey.ecx;
353 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
354 OSSL_PARAM *params = NULL;
361 /* A key must at least have a public part */
362 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
363 key->pubkey, key->keylen))
365 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
367 if (key->privkey != NULL) {
368 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
369 OSSL_PKEY_PARAM_PRIV_KEY,
370 key->privkey, key->keylen))
372 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
375 params = OSSL_PARAM_BLD_to_param(tmpl);
377 /* We export, the provider imports */
378 rv = importer(to_keydata, selection, params);
381 OSSL_PARAM_BLD_free(tmpl);
382 OSSL_PARAM_free(params);
386 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
389 EVP_PKEY_CTX *pctx = vpctx;
390 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
391 ECX_KEY *ecx = ossl_ecx_key_new(pctx->libctx, KEYNID2TYPE(keytype), 0,
395 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
399 if (!ossl_ecx_key_fromdata(ecx, params, 1)
400 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
401 ossl_ecx_key_free(ecx);
407 static int ecx_pkey_copy(EVP_PKEY *to, EVP_PKEY *from)
409 ECX_KEY *ecx = from->pkey.ecx, *dupkey = NULL;
413 dupkey = ossl_ecx_key_dup(ecx, OSSL_KEYMGMT_SELECT_ALL);
418 ret = EVP_PKEY_assign(to, from->type, dupkey);
420 ossl_ecx_key_free(dupkey);
424 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
426 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
429 const EVP_PKEY_ASN1_METHOD ossl_ecx25519_asn1_meth = {
434 "OpenSSL X25519 algorithm",
478 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
480 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
483 const EVP_PKEY_ASN1_METHOD ossl_ecx448_asn1_meth = {
488 "OpenSSL X448 algorithm",
532 static int ecd_size25519(const EVP_PKEY *pkey)
534 return ED25519_SIGSIZE;
537 static int ecd_size448(const EVP_PKEY *pkey)
539 return ED448_SIGSIZE;
542 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
543 const void *asn, const X509_ALGOR *sigalg,
544 const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
546 const ASN1_OBJECT *obj;
550 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
551 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
552 nid = OBJ_obj2nid(obj);
553 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
554 ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING);
558 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
564 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
566 X509_ALGOR *alg1, X509_ALGOR *alg2,
567 ASN1_BIT_STRING *str)
569 /* Set algorithms identifiers */
570 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
572 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
573 /* Algorithm identifiers set: carry on as normal */
577 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
578 const ASN1_STRING *sig)
580 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
585 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
587 X509_ALGOR *alg1, X509_ALGOR *alg2,
588 ASN1_BIT_STRING *str)
590 /* Set algorithm identifier */
591 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
593 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
594 /* Algorithm identifier set: carry on as normal */
598 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
599 const ASN1_STRING *sig)
601 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
606 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
608 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
611 const EVP_PKEY_ASN1_METHOD ossl_ed25519_asn1_meth = {
616 "OpenSSL ED25519 algorithm",
641 ecd_sig_info_set25519,
659 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
661 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
664 const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = {
669 "OpenSSL ED448 algorithm",
712 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
714 ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id,
715 KEY_OP_PUBLIC, NULL, NULL);
718 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx);
724 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
726 const unsigned char **privkey,
727 const unsigned char **pubkey)
729 const ECX_KEY *ecxkey, *peerkey;
731 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
732 ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
735 ecxkey = ctx->pkey->pkey.ecx;
736 peerkey = EVP_PKEY_get0(ctx->peerkey);
737 if (ecxkey == NULL || ecxkey->privkey == NULL) {
738 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
741 if (peerkey == NULL) {
742 ERR_raise(ERR_LIB_EC, EC_R_INVALID_PEER_KEY);
745 *privkey = ecxkey->privkey;
746 *pubkey = peerkey->pubkey;
751 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
754 const unsigned char *privkey, *pubkey;
756 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
758 && ossl_x25519(key, privkey, pubkey) == 0))
760 *keylen = X25519_KEYLEN;
764 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
767 const unsigned char *privkey, *pubkey;
769 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
771 && ossl_x448(key, privkey, pubkey) == 0))
773 *keylen = X448_KEYLEN;
777 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
779 /* Only need to handle peer key for derivation */
780 if (type == EVP_PKEY_CTRL_PEER_KEY)
785 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
789 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
790 pkey_ecx_derive25519,
795 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
805 static int pkey_ecd_digestsign25519(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 = ED25519_SIGSIZE;
815 if (*siglen < ED25519_SIGSIZE) {
816 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
820 if (ossl_ed25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
823 *siglen = ED25519_SIGSIZE;
827 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, 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;
834 *siglen = ED448_SIGSIZE;
837 if (*siglen < ED448_SIGSIZE) {
838 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
842 if (ossl_ed448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey,
843 edkey->privkey, NULL, 0, edkey->propq) == 0)
845 *siglen = ED448_SIGSIZE;
849 static int pkey_ecd_digestverify25519(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 != ED25519_SIGSIZE)
858 return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey,
859 edkey->libctx, edkey->propq);
862 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
863 size_t siglen, const unsigned char *tbs,
866 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
868 if (siglen != ED448_SIGSIZE)
871 return ossl_ed448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey,
872 NULL, 0, edkey->propq);
875 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
878 case EVP_PKEY_CTRL_MD:
879 /* Only NULL allowed as digest */
880 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
882 ERR_raise(ERR_LIB_EC, EC_R_INVALID_DIGEST_TYPE);
885 case EVP_PKEY_CTRL_DIGESTINIT:
891 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
892 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
895 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
898 pkey_ecd_digestsign25519,
899 pkey_ecd_digestverify25519
902 static const EVP_PKEY_METHOD ed448_pkey_meth = {
903 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
909 pkey_ecd_digestsign448,
910 pkey_ecd_digestverify448
914 # include "s390x_arch.h"
916 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
918 static const unsigned char generator[] = {
919 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
923 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1,
925 unsigned char *privkey = NULL, *pubkey;
928 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
932 pubkey = key->pubkey;
934 privkey = ossl_ecx_key_allocate_privkey(key);
935 if (privkey == NULL) {
936 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
940 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN, 0) <= 0)
947 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
950 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
953 ossl_ecx_key_free(key);
957 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
959 static const unsigned char generator[] = {
960 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
962 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
963 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
964 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
966 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1,
968 unsigned char *privkey = NULL, *pubkey;
971 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
975 pubkey = key->pubkey;
977 privkey = ossl_ecx_key_allocate_privkey(key);
978 if (privkey == NULL) {
979 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
983 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN, 0) <= 0)
989 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
992 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
995 ossl_ecx_key_free(key);
999 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1001 static const unsigned char generator_x[] = {
1002 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1003 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1004 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1006 static const unsigned char generator_y[] = {
1007 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1008 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1009 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1011 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1012 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED25519, 1,
1014 unsigned char *privkey = NULL, *pubkey;
1020 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1024 pubkey = key->pubkey;
1026 privkey = ossl_ecx_key_allocate_privkey(key);
1027 if (privkey == NULL) {
1028 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1032 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED25519_KEYLEN, 0) <= 0)
1035 md = EVP_MD_fetch(ctx->libctx, "SHA512", ctx->propquery);
1039 rv = EVP_Digest(privkey, 32, buff, &sz, md, NULL);
1048 if (s390x_ed25519_mul(x_dst, pubkey,
1049 generator_x, generator_y, buff) != 1)
1052 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1054 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1057 ossl_ecx_key_free(key);
1061 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1063 static const unsigned char generator_x[] = {
1064 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1065 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1066 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1067 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1068 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1070 static const unsigned char generator_y[] = {
1071 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1072 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1073 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1074 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1075 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1077 unsigned char x_dst[57], buff[114];
1078 ECX_KEY *key = ossl_ecx_key_new(ctx->libctx, ECX_KEY_TYPE_ED448, 1,
1080 unsigned char *privkey = NULL, *pubkey;
1081 EVP_MD_CTX *hashctx = NULL;
1086 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1090 pubkey = key->pubkey;
1092 privkey = ossl_ecx_key_allocate_privkey(key);
1093 if (privkey == NULL) {
1094 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE);
1098 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN, 0) <= 0)
1101 hashctx = EVP_MD_CTX_new();
1102 if (hashctx == NULL)
1105 md = EVP_MD_fetch(ctx->libctx, "SHAKE256", ctx->propquery);
1109 rv = EVP_DigestInit_ex(hashctx, md, NULL);
1114 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1116 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1123 if (s390x_ed448_mul(x_dst, pubkey,
1124 generator_x, generator_y, buff) != 1)
1127 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1129 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1130 EVP_MD_CTX_free(hashctx);
1133 ossl_ecx_key_free(key);
1134 EVP_MD_CTX_free(hashctx);
1138 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1141 const unsigned char *privkey, *pubkey;
1143 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1147 return s390x_x25519_mul(key, pubkey, privkey);
1149 *keylen = X25519_KEYLEN;
1153 static int s390x_pkey_ecx_derive448(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_x448_mul(key, pubkey, privkey);
1164 *keylen = X448_KEYLEN;
1168 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1169 unsigned char *sig, size_t *siglen,
1170 const unsigned char *tbs,
1175 unsigned char sig[64];
1176 unsigned char priv[32];
1178 unsigned long long buff[512];
1180 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1184 *siglen = ED25519_SIGSIZE;
1188 if (*siglen < ED25519_SIGSIZE) {
1189 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1193 memset(¶m, 0, sizeof(param));
1194 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1196 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1197 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1201 s390x_flip_endian32(sig, param.ed25519.sig);
1202 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1204 *siglen = ED25519_SIGSIZE;
1208 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1209 unsigned char *sig, size_t *siglen,
1210 const unsigned char *tbs,
1215 unsigned char sig[128];
1216 unsigned char priv[64];
1218 unsigned long long buff[512];
1220 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1224 *siglen = ED448_SIGSIZE;
1228 if (*siglen < ED448_SIGSIZE) {
1229 ERR_raise(ERR_LIB_EC, EC_R_BUFFER_TOO_SMALL);
1233 memset(¶m, 0, sizeof(param));
1234 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1236 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1237 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1241 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1242 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1243 memcpy(sig, param.ed448.sig, 57);
1244 memcpy(sig + 57, param.ed448.sig + 64, 57);
1246 *siglen = ED448_SIGSIZE;
1250 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1251 const unsigned char *sig,
1253 const unsigned char *tbs,
1258 unsigned char sig[64];
1259 unsigned char pub[32];
1261 unsigned long long buff[512];
1263 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1265 if (siglen != ED25519_SIGSIZE)
1268 memset(¶m, 0, sizeof(param));
1269 s390x_flip_endian32(param.ed25519.sig, sig);
1270 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1271 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1273 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1274 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1277 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1278 const unsigned char *sig,
1280 const unsigned char *tbs,
1285 unsigned char sig[128];
1286 unsigned char pub[64];
1288 unsigned long long buff[512];
1290 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1292 if (siglen != ED448_SIGSIZE)
1295 memset(¶m, 0, sizeof(param));
1296 memcpy(param.ed448.sig, sig, 57);
1297 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1298 memcpy(param.ed448.sig + 64, sig + 57, 57);
1299 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1300 memcpy(param.ed448.pub, edkey->pubkey, 57);
1301 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1303 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1304 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1307 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1309 0, 0, 0, 0, 0, 0, 0,
1310 s390x_pkey_ecx_keygen25519,
1311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1312 s390x_pkey_ecx_derive25519,
1317 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1319 0, 0, 0, 0, 0, 0, 0,
1320 s390x_pkey_ecx_keygen448,
1321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1322 s390x_pkey_ecx_derive448,
1326 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1327 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1329 s390x_pkey_ecd_keygen25519,
1330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1333 s390x_pkey_ecd_digestsign25519,
1334 s390x_pkey_ecd_digestverify25519
1337 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1338 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1340 s390x_pkey_ecd_keygen448,
1341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1344 s390x_pkey_ecd_digestsign448,
1345 s390x_pkey_ecd_digestverify448
1349 const EVP_PKEY_METHOD *ossl_ecx25519_pkey_method(void)
1352 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1353 return &ecx25519_s390x_pkey_meth;
1355 return &ecx25519_pkey_meth;
1358 const EVP_PKEY_METHOD *ossl_ecx448_pkey_method(void)
1361 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1362 return &ecx448_s390x_pkey_meth;
1364 return &ecx448_pkey_meth;
1367 const EVP_PKEY_METHOD *ossl_ed25519_pkey_method(void)
1370 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1371 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1372 && OPENSSL_s390xcap_P.kdsa[0]
1373 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1374 return &ed25519_s390x_pkey_meth;
1376 return &ed25519_pkey_meth;
1379 const EVP_PKEY_METHOD *ossl_ed448_pkey_method(void)
1382 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1383 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1384 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1385 return &ed448_s390x_pkey_meth;
1387 return &ed448_pkey_meth;