2 * Copyright 2006-2018 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 *key,
456 EVP_PKEY *pkey = key;
457 ECX_KEY *ecx = ecx_key_new(KEYNID2TYPE(keytype), 0);
460 ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
464 if (!ecx_key_fromdata(ecx, params, 1)
465 || !EVP_PKEY_assign(pkey, keytype, ecx)) {
472 static int x25519_import_from(const OSSL_PARAM params[], void *key)
474 return ecx_generic_import_from(params, key, EVP_PKEY_X25519);
477 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
482 "OpenSSL X25519 algorithm",
522 ecx_priv_decode_with_libctx
525 static int x448_import_from(const OSSL_PARAM params[], void *key)
527 return ecx_generic_import_from(params, key, EVP_PKEY_X448);
530 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
535 "OpenSSL X448 algorithm",
575 ecx_priv_decode_with_libctx
578 static int ecd_size25519(const EVP_PKEY *pkey)
580 return ED25519_SIGSIZE;
583 static int ecd_size448(const EVP_PKEY *pkey)
585 return ED448_SIGSIZE;
588 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
589 X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
592 const ASN1_OBJECT *obj;
596 /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
597 X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
598 nid = OBJ_obj2nid(obj);
599 if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
600 ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
604 if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
610 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
611 X509_ALGOR *alg1, X509_ALGOR *alg2,
612 ASN1_BIT_STRING *str)
614 /* Set algorithms identifiers */
615 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
617 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
618 /* Algorithm identifiers set: carry on as normal */
622 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
623 const ASN1_STRING *sig)
625 X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
630 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
631 X509_ALGOR *alg1, X509_ALGOR *alg2,
632 ASN1_BIT_STRING *str)
634 /* Set algorithm identifier */
635 X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
637 X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
638 /* Algorithm identifier set: carry on as normal */
642 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
643 const ASN1_STRING *sig)
645 X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
650 static int ed25519_import_from(const OSSL_PARAM params[], void *key)
652 return ecx_generic_import_from(params, key, EVP_PKEY_ED25519);
655 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
660 "OpenSSL ED25519 algorithm",
685 ecd_sig_info_set25519,
699 ecx_priv_decode_with_libctx
702 static int ed448_import_from(const OSSL_PARAM params[], void *key)
704 return ecx_generic_import_from(params, key, EVP_PKEY_ED448);
707 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
712 "OpenSSL ED448 algorithm",
751 ecx_priv_decode_with_libctx
754 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
756 return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
760 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
762 const unsigned char **privkey,
763 const unsigned char **pubkey)
765 const ECX_KEY *ecxkey, *peerkey;
767 if (ctx->pkey == NULL || ctx->peerkey == NULL) {
768 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
771 ecxkey = ctx->pkey->pkey.ecx;
772 peerkey = ctx->peerkey->pkey.ecx;
773 if (ecxkey == NULL || ecxkey->privkey == NULL) {
774 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
777 if (peerkey == NULL) {
778 ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
781 *privkey = ecxkey->privkey;
782 *pubkey = peerkey->pubkey;
787 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
790 const unsigned char *privkey, *pubkey;
792 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
794 && X25519(key, privkey, pubkey) == 0))
796 *keylen = X25519_KEYLEN;
800 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
803 const unsigned char *privkey, *pubkey;
805 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
807 && X448(key, privkey, pubkey) == 0))
809 *keylen = X448_KEYLEN;
813 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
815 /* Only need to handle peer key for derivation */
816 if (type == EVP_PKEY_CTRL_PEER_KEY)
821 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
826 pkey_ecx_derive25519,
831 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
841 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
842 size_t *siglen, const unsigned char *tbs,
845 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
848 *siglen = ED25519_SIGSIZE;
851 if (*siglen < ED25519_SIGSIZE) {
852 ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
856 if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
859 *siglen = ED25519_SIGSIZE;
863 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
864 size_t *siglen, const unsigned char *tbs,
867 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
870 *siglen = ED448_SIGSIZE;
873 if (*siglen < ED448_SIGSIZE) {
874 ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
879 * TODO(3.0): We use NULL for the library context for now. Will need to
882 if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
885 *siglen = ED448_SIGSIZE;
889 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
890 size_t siglen, const unsigned char *tbs,
893 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
895 if (siglen != ED25519_SIGSIZE)
898 return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
901 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
902 size_t siglen, const unsigned char *tbs,
905 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
907 if (siglen != ED448_SIGSIZE)
911 * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
914 return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
917 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
920 case EVP_PKEY_CTRL_MD:
921 /* Only NULL allowed as digest */
922 if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
924 ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
927 case EVP_PKEY_CTRL_DIGESTINIT:
933 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
934 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
940 pkey_ecd_digestsign25519,
941 pkey_ecd_digestverify25519
944 static const EVP_PKEY_METHOD ed448_pkey_meth = {
945 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
948 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
951 pkey_ecd_digestsign448,
952 pkey_ecd_digestverify448
956 # include "s390x_arch.h"
958 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
960 static const unsigned char generator[] = {
961 0x09, 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
965 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
966 unsigned char *privkey = NULL, *pubkey;
969 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
973 pubkey = key->pubkey;
975 privkey = ecx_key_allocate_privkey(key);
976 if (privkey == NULL) {
977 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
981 if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
988 if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
991 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
998 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1000 static const unsigned char generator[] = {
1001 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1002 0x00, 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
1007 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1008 unsigned char *privkey = NULL, *pubkey;
1011 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1015 pubkey = key->pubkey;
1017 privkey = ecx_key_allocate_privkey(key);
1018 if (privkey == NULL) {
1019 ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1023 if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1029 if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1032 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1039 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1041 static const unsigned char generator_x[] = {
1042 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1043 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1044 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1046 static const unsigned char generator_y[] = {
1047 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1048 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1049 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1051 unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1052 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
1053 unsigned char *privkey = NULL, *pubkey;
1057 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1061 pubkey = key->pubkey;
1063 privkey = ecx_key_allocate_privkey(key);
1064 if (privkey == NULL) {
1065 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1069 if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1072 if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1079 if (s390x_ed25519_mul(x_dst, pubkey,
1080 generator_x, generator_y, buff) != 1)
1083 pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1085 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1092 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1094 static const unsigned char generator_x[] = {
1095 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1096 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1097 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1098 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1099 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1101 static const unsigned char generator_y[] = {
1102 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1103 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1104 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1105 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1106 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1108 unsigned char x_dst[57], buff[114];
1109 ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
1110 unsigned char *privkey = NULL, *pubkey;
1111 EVP_MD_CTX *hashctx = NULL;
1114 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1118 pubkey = key->pubkey;
1120 privkey = ecx_key_allocate_privkey(key);
1121 if (privkey == NULL) {
1122 ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1126 if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1129 hashctx = EVP_MD_CTX_new();
1130 if (hashctx == NULL)
1132 if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1134 if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1136 if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1143 if (s390x_ed448_mul(x_dst, pubkey,
1144 generator_x, generator_y, buff) != 1)
1147 pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1149 EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1150 EVP_MD_CTX_free(hashctx);
1154 EVP_MD_CTX_free(hashctx);
1158 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1161 const unsigned char *privkey, *pubkey;
1163 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1167 return s390x_x25519_mul(key, pubkey, privkey);
1169 *keylen = X25519_KEYLEN;
1173 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1176 const unsigned char *privkey, *pubkey;
1178 if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1182 return s390x_x448_mul(key, pubkey, privkey);
1184 *keylen = X448_KEYLEN;
1188 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1189 unsigned char *sig, size_t *siglen,
1190 const unsigned char *tbs,
1195 unsigned char sig[64];
1196 unsigned char priv[32];
1198 unsigned long long buff[512];
1200 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1204 *siglen = ED25519_SIGSIZE;
1208 if (*siglen < ED25519_SIGSIZE) {
1209 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1213 memset(¶m, 0, sizeof(param));
1214 memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1216 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen);
1217 OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1221 s390x_flip_endian32(sig, param.ed25519.sig);
1222 s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1224 *siglen = ED25519_SIGSIZE;
1228 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1229 unsigned char *sig, size_t *siglen,
1230 const unsigned char *tbs,
1235 unsigned char sig[128];
1236 unsigned char priv[64];
1238 unsigned long long buff[512];
1240 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1244 *siglen = ED448_SIGSIZE;
1248 if (*siglen < ED448_SIGSIZE) {
1249 ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1253 memset(¶m, 0, sizeof(param));
1254 memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1256 rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen);
1257 OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1261 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1262 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1263 memcpy(sig, param.ed448.sig, 57);
1264 memcpy(sig + 57, param.ed448.sig + 64, 57);
1266 *siglen = ED448_SIGSIZE;
1270 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1271 const unsigned char *sig,
1273 const unsigned char *tbs,
1278 unsigned char sig[64];
1279 unsigned char pub[32];
1281 unsigned long long buff[512];
1283 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1285 if (siglen != ED25519_SIGSIZE)
1288 memset(¶m, 0, sizeof(param));
1289 s390x_flip_endian32(param.ed25519.sig, sig);
1290 s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1291 s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1293 return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1294 ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1297 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1298 const unsigned char *sig,
1300 const unsigned char *tbs,
1305 unsigned char sig[128];
1306 unsigned char pub[64];
1308 unsigned long long buff[512];
1310 const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1312 if (siglen != ED448_SIGSIZE)
1315 memset(¶m, 0, sizeof(param));
1316 memcpy(param.ed448.sig, sig, 57);
1317 s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1318 memcpy(param.ed448.sig + 64, sig + 57, 57);
1319 s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1320 memcpy(param.ed448.pub, edkey->pubkey, 57);
1321 s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1323 return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1324 ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0;
1327 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1329 0, 0, 0, 0, 0, 0, 0,
1330 s390x_pkey_ecx_keygen25519,
1331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1332 s390x_pkey_ecx_derive25519,
1337 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1339 0, 0, 0, 0, 0, 0, 0,
1340 s390x_pkey_ecx_keygen448,
1341 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1342 s390x_pkey_ecx_derive448,
1346 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1347 EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1349 s390x_pkey_ecd_keygen25519,
1350 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1353 s390x_pkey_ecd_digestsign25519,
1354 s390x_pkey_ecd_digestverify25519
1357 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1358 EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1360 s390x_pkey_ecd_keygen448,
1361 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1364 s390x_pkey_ecd_digestsign448,
1365 s390x_pkey_ecd_digestverify448
1369 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1372 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1373 return &ecx25519_s390x_pkey_meth;
1375 return &ecx25519_pkey_meth;
1378 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1381 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1382 return &ecx448_s390x_pkey_meth;
1384 return &ecx448_pkey_meth;
1387 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1390 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1391 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1392 && OPENSSL_s390xcap_P.kdsa[0]
1393 & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1394 return &ed25519_s390x_pkey_meth;
1396 return &ed25519_pkey_meth;
1399 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1402 if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1403 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1404 && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1405 return &ed448_s390x_pkey_meth;
1407 return &ed448_pkey_meth;