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, propq);
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_ex(libctx, 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,
446 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
450 if (!ecx_key_fromdata(ecx, params, 1)
451 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
458 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
460 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
463 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
468 "OpenSSL X25519 algorithm",
508 ecx_priv_decode_with_libctx
511 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
513 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
516 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
521 "OpenSSL X448 algorithm",
561 ecx_priv_decode_with_libctx
564 static int ecd_size25519(const EVP_PKEY *pkey)
566 return ED25519_SIGSIZE;
569 static int ecd_size448(const EVP_PKEY *pkey)
571 return ED448_SIGSIZE;
574 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
575 const void *asn, const X509_ALGOR *sigalg,
576 const ASN1_BIT_STRING *str, EVP_PKEY *pkey)
578 const ASN1_OBJECT *obj;
582 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
583 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
584 nid = OBJ_obj2nid(obj);
585 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
586 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
590 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
596 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
598 X509_ALGOR *alg1, X509_ALGOR *alg2,
599 ASN1_BIT_STRING *str)
601 /* Set algorithms identifiers */
602 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
604 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
605 /* Algorithm identifiers set: carry on as normal */
609 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
610 const ASN1_STRING *sig)
612 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
617 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it,
619 X509_ALGOR *alg1, X509_ALGOR *alg2,
620 ASN1_BIT_STRING *str)
622 /* Set algorithm identifier */
623 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
625 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
626 /* Algorithm identifier set: carry on as normal */
630 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
631 const ASN1_STRING *sig)
633 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
638 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
640 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
643 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
648 "OpenSSL ED25519 algorithm",
673 ecd_sig_info_set25519,
687 ecx_priv_decode_with_libctx
690 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
692 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
695 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
700 "OpenSSL ED448 algorithm",
739 ecx_priv_decode_with_libctx
742 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
744 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
748 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
750 const unsigned char **privkey,
751 const unsigned char **pubkey)
753 const ECX_KEY *ecxkey, *peerkey;
755 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
756 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
759 ecxkey = ctx->pkey->pkey.ecx;
760 peerkey = ctx->peerkey->pkey.ecx;
761 if (ecxkey == NULL || ecxkey->privkey == NULL) {
762 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
765 if (peerkey == NULL) {
766 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
769 *privkey = ecxkey->privkey;
770 *pubkey = peerkey->pubkey;
775 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
778 const unsigned char *privkey, *pubkey;
780 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
782 && X25519(key, privkey, pubkey) == 0))
784 *keylen = X25519_KEYLEN;
788 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
791 const unsigned char *privkey, *pubkey;
793 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
795 && X448(key, privkey, pubkey) == 0))
797 *keylen = X448_KEYLEN;
801 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
803 /* Only need to handle peer key for derivation */
804 if (type == EVP_PKEY_CTRL_PEER_KEY)
809 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
814 pkey_ecx_derive25519,
819 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
829 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
830 size_t *siglen, const unsigned char *tbs,
833 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
836 *siglen = ED25519_SIGSIZE;
839 if (*siglen < ED25519_SIGSIZE) {
840 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
844 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
847 *siglen = ED25519_SIGSIZE;
851 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
852 size_t *siglen, const unsigned char *tbs,
855 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
858 *siglen = ED448_SIGSIZE;
861 if (*siglen < ED448_SIGSIZE) {
862 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
866 if (ED448_sign(edkey->libctx, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
867 NULL, 0, edkey->propq) == 0)
869 *siglen = ED448_SIGSIZE;
873 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
874 size_t siglen, const unsigned char *tbs,
877 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
879 if (siglen != ED25519_SIGSIZE)
882 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey,
883 edkey->libctx, edkey->propq);
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)
895 return ED448_verify(edkey->libctx, tbs, tbslen, sig, edkey->pubkey, NULL, 0,
899 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
902 case EVP_PKEY_CTRL_MD:
903 /* Only NULL allowed as digest */
904 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
906 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
909 case EVP_PKEY_CTRL_DIGESTINIT:
915 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
916 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
919 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
922 pkey_ecd_digestsign25519,
923 pkey_ecd_digestverify25519
926 static const EVP_PKEY_METHOD ed448_pkey_meth = {
927 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
930 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
933 pkey_ecd_digestsign448,
934 pkey_ecd_digestverify448
938 # include "s390x_arch.h"
940 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
942 static const unsigned char generator[] = {
943 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
947 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X25519, 1,
949 unsigned char *privkey = NULL, *pubkey;
952 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
956 pubkey = key->pubkey;
958 privkey = ecx_key_allocate_privkey(key);
959 if (privkey == NULL) {
960 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
964 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X25519_KEYLEN) <= 0)
971 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
974 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
981 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
983 static const unsigned char generator[] = {
984 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986 0x00, 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
990 ECX_KEY *key = ecx_key_new(ctx->libctx, ECX_KEY_TYPE_X448, 1,
992 unsigned char *privkey = NULL, *pubkey;
995 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
999 pubkey = key->pubkey;
1001 privkey = ecx_key_allocate_privkey(key);
1002 if (privkey == NULL) {
1003 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1007 if (RAND_priv_bytes_ex(ctx->libctx, privkey, X448_KEYLEN) <= 0)
1013 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1016 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1023 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1025 static const unsigned char generator_x[] = {
1026 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1027 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1028 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1030 static const unsigned char generator_y[] = {
1031 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1032 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1033 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1035 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1036 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_ex(ctx->libctx, 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,
1096 unsigned char *privkey = NULL, *pubkey;
1097 EVP_MD_CTX *hashctx = NULL;
1100 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1104 pubkey = key->pubkey;
1106 privkey = ecx_key_allocate_privkey(key);
1107 if (privkey == NULL) {
1108 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1112 if (RAND_priv_bytes_ex(ctx->libctx, privkey, ED448_KEYLEN) <= 0)
1115 hashctx = EVP_MD_CTX_new();
1116 if (hashctx == NULL)
1118 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1120 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1122 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1129 if (s390x_ed448_mul(x_dst, pubkey,
1130 generator_x, generator_y, buff) != 1)
1133 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1135 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1136 EVP_MD_CTX_free(hashctx);
1140 EVP_MD_CTX_free(hashctx);
1144 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1147 const unsigned char *privkey, *pubkey;
1149 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1153 return s390x_x25519_mul(key, pubkey, privkey);
1155 *keylen = X25519_KEYLEN;
1159 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1162 const unsigned char *privkey, *pubkey;
1164 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1168 return s390x_x448_mul(key, pubkey, privkey);
1170 *keylen = X448_KEYLEN;
1174 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1175 unsigned char *sig, size_t *siglen,
1176 const unsigned char *tbs,
1181 unsigned char sig[64];
1182 unsigned char priv[32];
1184 unsigned long long buff[512];
1186 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1190 *siglen = ED25519_SIGSIZE;
1194 if (*siglen < ED25519_SIGSIZE) {
1195 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1199 memset(¶m, 0, sizeof(param));
1200 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1202 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1203 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1207 s390x_flip_endian32(sig, param.ed25519.sig);
1208 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1210 *siglen = ED25519_SIGSIZE;
1214 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1215 unsigned char *sig, size_t *siglen,
1216 const unsigned char *tbs,
1221 unsigned char sig[128];
1222 unsigned char priv[64];
1224 unsigned long long buff[512];
1226 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1230 *siglen = ED448_SIGSIZE;
1234 if (*siglen < ED448_SIGSIZE) {
1235 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1239 memset(¶m, 0, sizeof(param));
1240 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1242 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1243 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1247 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1248 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1249 memcpy(sig, param.ed448.sig, 57);
1250 memcpy(sig + 57, param.ed448.sig + 64, 57);
1252 *siglen = ED448_SIGSIZE;
1256 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1257 const unsigned char *sig,
1259 const unsigned char *tbs,
1264 unsigned char sig[64];
1265 unsigned char pub[32];
1267 unsigned long long buff[512];
1269 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1271 if (siglen != ED25519_SIGSIZE)
1274 memset(¶m, 0, sizeof(param));
1275 s390x_flip_endian32(param.ed25519.sig, sig);
1276 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1277 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1279 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1280 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1283 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1284 const unsigned char *sig,
1286 const unsigned char *tbs,
1291 unsigned char sig[128];
1292 unsigned char pub[64];
1294 unsigned long long buff[512];
1296 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1298 if (siglen != ED448_SIGSIZE)
1301 memset(¶m, 0, sizeof(param));
1302 memcpy(param.ed448.sig, sig, 57);
1303 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1304 memcpy(param.ed448.sig + 64, sig + 57, 57);
1305 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1306 memcpy(param.ed448.pub, edkey->pubkey, 57);
1307 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1309 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1310 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1313 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1315 0, 0, 0, 0, 0, 0, 0,
1316 s390x_pkey_ecx_keygen25519,
1317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1318 s390x_pkey_ecx_derive25519,
1323 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1325 0, 0, 0, 0, 0, 0, 0,
1326 s390x_pkey_ecx_keygen448,
1327 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1328 s390x_pkey_ecx_derive448,
1332 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1333 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1335 s390x_pkey_ecd_keygen25519,
1336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1339 s390x_pkey_ecd_digestsign25519,
1340 s390x_pkey_ecd_digestverify25519
1343 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1344 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1346 s390x_pkey_ecd_keygen448,
1347 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1350 s390x_pkey_ecd_digestsign448,
1351 s390x_pkey_ecd_digestverify448
1355 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1358 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1359 return &ecx25519_s390x_pkey_meth;
1361 return &ecx25519_pkey_meth;
1364 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1367 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1368 return &ecx448_s390x_pkey_meth;
1370 return &ecx448_pkey_meth;
1373 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1376 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1377 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1378 && OPENSSL_s390xcap_P.kdsa[0]
1379 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1380 return &ed25519_s390x_pkey_meth;
1382 return &ed25519_pkey_meth;
1385 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1388 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1389 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1390 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1391 return &ed448_s390x_pkey_meth;
1393 return &ed448_pkey_meth;