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(KEYNID2TYPE(id), 1);
64 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
69 if (op == KEY_OP_PUBLIC) {
70 memcpy(pubkey, p, plen);
72 privkey = ecx_key_allocate_privkey(key);
73 if (privkey == NULL) {
74 ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
77 if (op == KEY_OP_KEYGEN) {
78 if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
80 if (id == EVP_PKEY_X25519) {
82 privkey[X25519_KEYLEN - 1] &= 127;
83 privkey[X25519_KEYLEN - 1] |= 64;
84 } else if (id == EVP_PKEY_X448) {
86 privkey[X448_KEYLEN - 1] |= 128;
89 memcpy(privkey, p, KEYLENID(id));
93 X25519_public_from_private(pubkey, privkey);
95 case EVP_PKEY_ED25519:
96 if (!ED25519_public_from_private(libctx, pubkey, privkey)) {
97 ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
102 X448_public_from_private(pubkey, privkey);
105 if (!ED448_public_from_private(libctx, pubkey, privkey)) {
106 ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
113 EVP_PKEY_assign(pkey, id, key);
120 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
122 const ECX_KEY *ecxkey = pkey->pkey.ecx;
125 if (ecxkey == NULL) {
126 ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
130 penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
132 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
136 if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
137 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
139 ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
145 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
147 const unsigned char *p;
151 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
153 return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
154 KEY_OP_PUBLIC, NULL, NULL);
157 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
159 const ECX_KEY *akey = a->pkey.ecx;
160 const ECX_KEY *bkey = b->pkey.ecx;
162 if (akey == NULL || bkey == NULL)
165 return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
168 static int ecx_priv_decode_with_libctx(EVP_PKEY *pkey,
169 const PKCS8_PRIV_KEY_INFO *p8,
170 OPENSSL_CTX *libctx, const char *propq)
172 const unsigned char *p;
174 ASN1_OCTET_STRING *oct = NULL;
175 const X509_ALGOR *palg;
178 if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
181 oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
186 p = ASN1_STRING_get0_data(oct);
187 plen = ASN1_STRING_length(oct);
190 rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE,
192 ASN1_STRING_clear_free(oct);
196 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
198 const ECX_KEY *ecxkey = pkey->pkey.ecx;
199 ASN1_OCTET_STRING oct;
200 unsigned char *penc = NULL;
203 if (ecxkey == NULL || ecxkey->privkey == NULL) {
204 ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
208 oct.data = ecxkey->privkey;
209 oct.length = KEYLEN(pkey);
212 penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
214 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
218 if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
219 V_ASN1_UNDEF, NULL, penc, penclen)) {
220 OPENSSL_clear_free(penc, penclen);
221 ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
228 static int ecx_size(const EVP_PKEY *pkey)
233 static int ecx_bits(const EVP_PKEY *pkey)
235 if (IS25519(pkey->ameth->pkey_id)) {
237 } else if(ISX448(pkey->ameth->pkey_id)) {
244 static int ecx_security_bits(const EVP_PKEY *pkey)
246 if (IS25519(pkey->ameth->pkey_id)) {
247 return X25519_SECURITY_BITS;
249 return X448_SECURITY_BITS;
253 static void ecx_free(EVP_PKEY *pkey)
255 ecx_key_free(pkey->pkey.ecx);
258 /* "parameters" are always equal */
259 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
264 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
265 ASN1_PCTX *ctx, ecx_key_op_t op)
267 const ECX_KEY *ecxkey = pkey->pkey.ecx;
268 const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
270 if (op == KEY_OP_PRIVATE) {
271 if (ecxkey == NULL || ecxkey->privkey == NULL) {
272 if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
276 if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
278 if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
280 if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
284 if (ecxkey == NULL) {
285 if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
289 if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
292 if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
295 if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
301 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
304 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
307 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
310 return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
313 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
317 case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
318 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
319 KEY_OP_PUBLIC, NULL, NULL);
321 case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
322 if (pkey->pkey.ecx != NULL) {
323 unsigned char **ppt = arg2;
325 *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
337 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
340 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
341 /* We currently only support Pure EdDSA which takes no digest */
342 *(int *)arg2 = NID_undef;
351 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
354 /* TODO(3.0): We should pass a libctx here */
355 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
356 KEY_OP_PRIVATE, NULL, NULL);
359 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
361 return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
362 KEY_OP_PUBLIC, NULL, NULL);
365 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
368 const ECX_KEY *key = pkey->pkey.ecx;
371 *len = KEYLENID(pkey->ameth->pkey_id);
376 || key->privkey == NULL
377 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
380 *len = KEYLENID(pkey->ameth->pkey_id);
381 memcpy(priv, key->privkey, *len);
386 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
389 const ECX_KEY *key = pkey->pkey.ecx;
392 *len = KEYLENID(pkey->ameth->pkey_id);
397 || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
400 *len = KEYLENID(pkey->ameth->pkey_id);
401 memcpy(pub, key->pubkey, *len);
406 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
409 * We provide no mechanism to "update" an ECX key once it has been set,
410 * therefore we do not have to maintain a dirty count.
415 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
416 EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
419 const ECX_KEY *key = from->pkey.ecx;
420 OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
421 OSSL_PARAM *params = NULL;
428 /* A key must at least have a public part */
429 if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
430 key->pubkey, key->keylen))
432 selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
434 if (key->privkey != NULL) {
435 if (!OSSL_PARAM_BLD_push_octet_string(tmpl,
436 OSSL_PKEY_PARAM_PRIV_KEY,
437 key->privkey, key->keylen))
439 selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
442 params = OSSL_PARAM_BLD_to_param(tmpl);
444 /* We export, the provider imports */
445 rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
448 OSSL_PARAM_BLD_free(tmpl);
449 OSSL_PARAM_BLD_free_params(params);
453 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
456 EVP_PKEY_CTX *pctx = vpctx;
457 EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx);
458 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
461 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
465 if (!ecx_key_fromdata(ecx, params, 1)
466 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
473 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
475 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
478 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
483 "OpenSSL X25519 algorithm",
523 ecx_priv_decode_with_libctx
526 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
528 return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
531 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
536 "OpenSSL X448 algorithm",
576 ecx_priv_decode_with_libctx
579 static int ecd_size25519(const EVP_PKEY *pkey)
581 return ED25519_SIGSIZE;
584 static int ecd_size448(const EVP_PKEY *pkey)
586 return ED448_SIGSIZE;
589 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
590 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
593 const ASN1_OBJECT *obj;
597 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
598 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
599 nid = OBJ_obj2nid(obj);
600 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
601 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
605 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
611 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
612 X509_ALGOR *alg1, X509_ALGOR *alg2,
613 ASN1_BIT_STRING *str)
615 /* Set algorithms identifiers */
616 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
618 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
619 /* Algorithm identifiers set: carry on as normal */
623 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
624 const ASN1_STRING *sig)
626 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
631 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
632 X509_ALGOR *alg1, X509_ALGOR *alg2,
633 ASN1_BIT_STRING *str)
635 /* Set algorithm identifier */
636 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
638 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
639 /* Algorithm identifier set: carry on as normal */
643 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
644 const ASN1_STRING *sig)
646 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
651 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
653 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
656 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
661 "OpenSSL ED25519 algorithm",
686 ecd_sig_info_set25519,
700 ecx_priv_decode_with_libctx
703 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
705 return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
708 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
713 "OpenSSL ED448 algorithm",
752 ecx_priv_decode_with_libctx
755 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
757 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
761 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
763 const unsigned char **privkey,
764 const unsigned char **pubkey)
766 const ECX_KEY *ecxkey, *peerkey;
768 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
769 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
772 ecxkey = ctx->pkey->pkey.ecx;
773 peerkey = ctx->peerkey->pkey.ecx;
774 if (ecxkey == NULL || ecxkey->privkey == NULL) {
775 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
778 if (peerkey == NULL) {
779 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
782 *privkey = ecxkey->privkey;
783 *pubkey = peerkey->pubkey;
788 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
791 const unsigned char *privkey, *pubkey;
793 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
795 && X25519(key, privkey, pubkey) == 0))
797 *keylen = X25519_KEYLEN;
801 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
804 const unsigned char *privkey, *pubkey;
806 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
808 && X448(key, privkey, pubkey) == 0))
810 *keylen = X448_KEYLEN;
814 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
816 /* Only need to handle peer key for derivation */
817 if (type == EVP_PKEY_CTRL_PEER_KEY)
822 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
826 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
827 pkey_ecx_derive25519,
832 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
842 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
843 size_t *siglen, const unsigned char *tbs,
846 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
849 *siglen = ED25519_SIGSIZE;
852 if (*siglen < ED25519_SIGSIZE) {
853 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
857 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
860 *siglen = ED25519_SIGSIZE;
864 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
865 size_t *siglen, const unsigned char *tbs,
868 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
871 *siglen = ED448_SIGSIZE;
874 if (*siglen < ED448_SIGSIZE) {
875 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
880 * TODO(3.0): We use NULL for the library context for now. Will need to
883 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
886 *siglen = ED448_SIGSIZE;
890 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
891 size_t siglen, const unsigned char *tbs,
894 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
896 if (siglen != ED25519_SIGSIZE)
899 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
902 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
903 size_t siglen, const unsigned char *tbs,
906 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
908 if (siglen != ED448_SIGSIZE)
912 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
915 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
918 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
921 case EVP_PKEY_CTRL_MD:
922 /* Only NULL allowed as digest */
923 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
925 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
928 case EVP_PKEY_CTRL_DIGESTINIT:
934 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
935 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
938 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
941 pkey_ecd_digestsign25519,
942 pkey_ecd_digestverify25519
945 static const EVP_PKEY_METHOD ed448_pkey_meth = {
946 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
949 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
952 pkey_ecd_digestsign448,
953 pkey_ecd_digestverify448
957 # include "s390x_arch.h"
959 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
961 static const unsigned char generator[] = {
962 0x09, 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 = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
967 unsigned char *privkey = NULL, *pubkey;
970 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
974 pubkey = key->pubkey;
976 privkey = ecx_key_allocate_privkey(key);
977 if (privkey == NULL) {
978 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
982 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
989 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
992 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
999 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1001 static const unsigned char generator[] = {
1002 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1008 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1009 unsigned char *privkey = NULL, *pubkey;
1012 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1016 pubkey = key->pubkey;
1018 privkey = ecx_key_allocate_privkey(key);
1019 if (privkey == NULL) {
1020 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1024 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1030 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1033 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1040 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1042 static const unsigned char generator_x[] = {
1043 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1044 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1045 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1047 static const unsigned char generator_y[] = {
1048 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1049 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1050 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1052 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1053 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1054 unsigned char *privkey = NULL, *pubkey;
1058 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1062 pubkey = key->pubkey;
1064 privkey = ecx_key_allocate_privkey(key);
1065 if (privkey == NULL) {
1066 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1070 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1073 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1080 if (s390x_ed25519_mul(x_dst, pubkey,
1081 generator_x, generator_y, buff) != 1)
1084 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1086 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1093 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1095 static const unsigned char generator_x[] = {
1096 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1097 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1098 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1099 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1100 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1102 static const unsigned char generator_y[] = {
1103 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1104 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1105 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1106 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1107 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1109 unsigned char x_dst[57], buff[114];
1110 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1111 unsigned char *privkey = NULL, *pubkey;
1112 EVP_MD_CTX *hashctx = NULL;
1115 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1119 pubkey = key->pubkey;
1121 privkey = ecx_key_allocate_privkey(key);
1122 if (privkey == NULL) {
1123 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1127 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1130 hashctx = EVP_MD_CTX_new();
1131 if (hashctx == NULL)
1133 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1135 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1137 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1144 if (s390x_ed448_mul(x_dst, pubkey,
1145 generator_x, generator_y, buff) != 1)
1148 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1150 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1151 EVP_MD_CTX_free(hashctx);
1155 EVP_MD_CTX_free(hashctx);
1159 static int s390x_pkey_ecx_derive25519(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_x25519_mul(key, pubkey, privkey);
1170 *keylen = X25519_KEYLEN;
1174 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1177 const unsigned char *privkey, *pubkey;
1179 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1183 return s390x_x448_mul(key, pubkey, privkey);
1185 *keylen = X448_KEYLEN;
1189 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1190 unsigned char *sig, size_t *siglen,
1191 const unsigned char *tbs,
1196 unsigned char sig[64];
1197 unsigned char priv[32];
1199 unsigned long long buff[512];
1201 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1205 *siglen = ED25519_SIGSIZE;
1209 if (*siglen < ED25519_SIGSIZE) {
1210 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1214 memset(¶m, 0, sizeof(param));
1215 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1217 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1218 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1222 s390x_flip_endian32(sig, param.ed25519.sig);
1223 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1225 *siglen = ED25519_SIGSIZE;
1229 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1230 unsigned char *sig, size_t *siglen,
1231 const unsigned char *tbs,
1236 unsigned char sig[128];
1237 unsigned char priv[64];
1239 unsigned long long buff[512];
1241 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1245 *siglen = ED448_SIGSIZE;
1249 if (*siglen < ED448_SIGSIZE) {
1250 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1254 memset(¶m, 0, sizeof(param));
1255 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1257 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1258 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1262 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1263 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1264 memcpy(sig, param.ed448.sig, 57);
1265 memcpy(sig + 57, param.ed448.sig + 64, 57);
1267 *siglen = ED448_SIGSIZE;
1271 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1272 const unsigned char *sig,
1274 const unsigned char *tbs,
1279 unsigned char sig[64];
1280 unsigned char pub[32];
1282 unsigned long long buff[512];
1284 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1286 if (siglen != ED25519_SIGSIZE)
1289 memset(¶m, 0, sizeof(param));
1290 s390x_flip_endian32(param.ed25519.sig, sig);
1291 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1292 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1294 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1295 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1298 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1299 const unsigned char *sig,
1301 const unsigned char *tbs,
1306 unsigned char sig[128];
1307 unsigned char pub[64];
1309 unsigned long long buff[512];
1311 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1313 if (siglen != ED448_SIGSIZE)
1316 memset(¶m, 0, sizeof(param));
1317 memcpy(param.ed448.sig, sig, 57);
1318 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1319 memcpy(param.ed448.sig + 64, sig + 57, 57);
1320 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1321 memcpy(param.ed448.pub, edkey->pubkey, 57);
1322 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1324 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1325 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1328 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1330 0, 0, 0, 0, 0, 0, 0,
1331 s390x_pkey_ecx_keygen25519,
1332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1333 s390x_pkey_ecx_derive25519,
1338 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1340 0, 0, 0, 0, 0, 0, 0,
1341 s390x_pkey_ecx_keygen448,
1342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1343 s390x_pkey_ecx_derive448,
1347 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1348 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1350 s390x_pkey_ecd_keygen25519,
1351 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1354 s390x_pkey_ecd_digestsign25519,
1355 s390x_pkey_ecd_digestverify25519
1358 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1359 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1361 s390x_pkey_ecd_keygen448,
1362 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1365 s390x_pkey_ecd_digestsign448,
1366 s390x_pkey_ecd_digestverify448
1370 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1373 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1374 return &ecx25519_s390x_pkey_meth;
1376 return &ecx25519_pkey_meth;
1379 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1382 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1383 return &ecx448_s390x_pkey_meth;
1385 return &ecx448_pkey_meth;
1388 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1391 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1392 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1393 && OPENSSL_s390xcap_P.kdsa[0]
1394 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1395 return &ed25519_s390x_pkey_meth;
1397 return &ed25519_pkey_meth;
1400 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1403 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1404 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1405 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1406 return &ed448_s390x_pkey_meth;
1408 return &ed448_pkey_meth;