coverity 1462576 Resource leak
[openssl.git] / crypto / ec / ecx_meth.c
1 /*
2  * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved.
3  *
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
8  */
9
10 /*
11  * ECDSA low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <stdio.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"
26 #include "ec_local.h"
27 #include "curve448/curve448_local.h"
28 #include "ecx_backend.h"
29
30 typedef enum {
31     KEY_OP_PUBLIC,
32     KEY_OP_PRIVATE,
33     KEY_OP_KEYGEN
34 } ecx_key_op_t;
35
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)
40 {
41     ECX_KEY *key = NULL;
42     unsigned char *privkey, *pubkey;
43
44     if (op != KEY_OP_KEYGEN) {
45         if (palg != NULL) {
46             int ptype;
47
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);
52                 return 0;
53             }
54         }
55
56         if (p == NULL || plen != KEYLENID(id)) {
57             ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
58             return 0;
59         }
60     }
61
62     key = ecx_key_new(KEYNID2TYPE(id), 1);
63     if (key == NULL) {
64         ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
65         return 0;
66     }
67     pubkey = key->pubkey;
68
69     if (op == KEY_OP_PUBLIC) {
70         memcpy(pubkey, p, plen);
71     } else {
72         privkey = ecx_key_allocate_privkey(key);
73         if (privkey == NULL) {
74             ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
75             goto err;
76         }
77         if (op == KEY_OP_KEYGEN) {
78             if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0)
79                 goto err;
80             if (id == EVP_PKEY_X25519) {
81                 privkey[0] &= 248;
82                 privkey[X25519_KEYLEN - 1] &= 127;
83                 privkey[X25519_KEYLEN - 1] |= 64;
84             } else if (id == EVP_PKEY_X448) {
85                 privkey[0] &= 252;
86                 privkey[X448_KEYLEN - 1] |= 128;
87             }
88         } else {
89             memcpy(privkey, p, KEYLENID(id));
90         }
91         switch (id) {
92         case EVP_PKEY_X25519:
93             X25519_public_from_private(pubkey, privkey);
94             break;
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);
98                 goto err;
99             }
100             break;
101         case EVP_PKEY_X448:
102             X448_public_from_private(pubkey, privkey);
103             break;
104         case EVP_PKEY_ED448:
105             if (!ED448_public_from_private(libctx, pubkey, privkey)) {
106                 ECerr(EC_F_ECX_KEY_OP, EC_R_FAILED_MAKING_PUBLIC_KEY);
107                 goto err;
108             }
109             break;
110         }
111     }
112
113     EVP_PKEY_assign(pkey, id, key);
114     return 1;
115  err:
116     ecx_key_free(key);
117     return 0;
118 }
119
120 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
121 {
122     const ECX_KEY *ecxkey = pkey->pkey.ecx;
123     unsigned char *penc;
124
125     if (ecxkey == NULL) {
126         ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
127         return 0;
128     }
129
130     penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
131     if (penc == NULL) {
132         ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
133         return 0;
134     }
135
136     if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
137                                 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
138         OPENSSL_free(penc);
139         ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
140         return 0;
141     }
142     return 1;
143 }
144
145 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
146 {
147     const unsigned char *p;
148     int pklen;
149     X509_ALGOR *palg;
150
151     if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
152         return 0;
153     return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
154                       KEY_OP_PUBLIC, NULL, NULL);
155 }
156
157 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
158 {
159     const ECX_KEY *akey = a->pkey.ecx;
160     const ECX_KEY *bkey = b->pkey.ecx;
161
162     if (akey == NULL || bkey == NULL)
163         return -2;
164
165     return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
166 }
167
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)
171 {
172     const unsigned char *p;
173     int plen;
174     ASN1_OCTET_STRING *oct = NULL;
175     const X509_ALGOR *palg;
176     int rv;
177
178     if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
179         return 0;
180
181     oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
182     if (oct == NULL) {
183         p = NULL;
184         plen = 0;
185     } else {
186         p = ASN1_STRING_get0_data(oct);
187         plen = ASN1_STRING_length(oct);
188     }
189
190     rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE,
191                     libctx, propq);
192     ASN1_STRING_clear_free(oct);
193     return rv;
194 }
195
196 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
197 {
198     const ECX_KEY *ecxkey = pkey->pkey.ecx;
199     ASN1_OCTET_STRING oct;
200     unsigned char *penc = NULL;
201     int penclen;
202
203     if (ecxkey == NULL || ecxkey->privkey == NULL) {
204         ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
205         return 0;
206     }
207
208     oct.data = ecxkey->privkey;
209     oct.length = KEYLEN(pkey);
210     oct.flags = 0;
211
212     penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
213     if (penclen < 0) {
214         ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
215         return 0;
216     }
217
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);
222         return 0;
223     }
224
225     return 1;
226 }
227
228 static int ecx_size(const EVP_PKEY *pkey)
229 {
230     return KEYLEN(pkey);
231 }
232
233 static int ecx_bits(const EVP_PKEY *pkey)
234 {
235     if (IS25519(pkey->ameth->pkey_id)) {
236         return X25519_BITS;
237     } else if(ISX448(pkey->ameth->pkey_id)) {
238         return X448_BITS;
239     } else {
240         return ED448_BITS;
241     }
242 }
243
244 static int ecx_security_bits(const EVP_PKEY *pkey)
245 {
246     if (IS25519(pkey->ameth->pkey_id)) {
247         return X25519_SECURITY_BITS;
248     } else {
249         return X448_SECURITY_BITS;
250     }
251 }
252
253 static void ecx_free(EVP_PKEY *pkey)
254 {
255     ecx_key_free(pkey->pkey.ecx);
256 }
257
258 /* "parameters" are always equal */
259 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
260 {
261     return 1;
262 }
263
264 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
265                          ASN1_PCTX *ctx, ecx_key_op_t op)
266 {
267     const ECX_KEY *ecxkey = pkey->pkey.ecx;
268     const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
269
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)
273                 return 0;
274             return 1;
275         }
276         if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
277             return 0;
278         if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
279             return 0;
280         if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
281                            indent + 4) == 0)
282             return 0;
283     } else {
284         if (ecxkey == NULL) {
285             if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
286                 return 0;
287             return 1;
288         }
289         if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
290             return 0;
291     }
292     if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
293         return 0;
294
295     if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
296                        indent + 4) == 0)
297         return 0;
298     return 1;
299 }
300
301 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
302                           ASN1_PCTX *ctx)
303 {
304     return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
305 }
306
307 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
308                          ASN1_PCTX *ctx)
309 {
310     return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
311 }
312
313 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
314 {
315     switch (op) {
316
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);
320
321     case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
322         if (pkey->pkey.ecx != NULL) {
323             unsigned char **ppt = arg2;
324
325             *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
326             if (*ppt != NULL)
327                 return KEYLEN(pkey);
328         }
329         return 0;
330
331     default:
332         return -2;
333
334     }
335 }
336
337 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
338 {
339     switch (op) {
340     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
341         /* We currently only support Pure EdDSA which takes no digest */
342         *(int *)arg2 = NID_undef;
343         return 2;
344
345     default:
346         return -2;
347
348     }
349 }
350
351 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
352                             size_t len)
353 {
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);
357 }
358
359 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
360 {
361     return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
362                       KEY_OP_PUBLIC, NULL, NULL);
363 }
364
365 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
366                             size_t *len)
367 {
368     const ECX_KEY *key = pkey->pkey.ecx;
369
370     if (priv == NULL) {
371         *len = KEYLENID(pkey->ameth->pkey_id);
372         return 1;
373     }
374
375     if (key == NULL
376             || key->privkey == NULL
377             || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
378         return 0;
379
380     *len = KEYLENID(pkey->ameth->pkey_id);
381     memcpy(priv, key->privkey, *len);
382
383     return 1;
384 }
385
386 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
387                            size_t *len)
388 {
389     const ECX_KEY *key = pkey->pkey.ecx;
390
391     if (pub == NULL) {
392         *len = KEYLENID(pkey->ameth->pkey_id);
393         return 1;
394     }
395
396     if (key == NULL
397             || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
398         return 0;
399
400     *len = KEYLENID(pkey->ameth->pkey_id);
401     memcpy(pub, key->pubkey, *len);
402
403     return 1;
404 }
405
406 static size_t ecx_pkey_dirty_cnt(const EVP_PKEY *pkey)
407 {
408     /*
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.
411      */
412     return 1;
413 }
414
415 static int ecx_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
416                               EVP_KEYMGMT *to_keymgmt, OPENSSL_CTX *libctx,
417                               const char *propq)
418 {
419     const ECX_KEY *key = from->pkey.ecx;
420     OSSL_PARAM_BLD *tmpl = OSSL_PARAM_BLD_new();
421     OSSL_PARAM *params = NULL;
422     int selection = 0;
423     int rv = 0;
424
425     if (tmpl == NULL)
426         return 0;
427
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))
431         goto err;
432     selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
433
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))
438             goto err;
439         selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
440     }
441
442     params = OSSL_PARAM_BLD_to_param(tmpl);
443
444     /* We export, the provider imports */
445     rv = evp_keymgmt_import(to_keymgmt, to_keydata, selection, params);
446
447  err:
448     OSSL_PARAM_BLD_free(tmpl);
449     OSSL_PARAM_BLD_free_params(params);
450     return rv;
451 }
452
453 static int ecx_generic_import_from(const OSSL_PARAM params[], void *vpctx,
454                                    int keytype)
455 {
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);
459
460     if (ecx == NULL) {
461         ERR_raise(ERR_LIB_DH, ERR_R_MALLOC_FAILURE);
462         return 0;
463     }
464
465     if (!ecx_key_fromdata(ecx, params, 1)
466         || !EVP_PKEY_assign(pkey, keytype, ecx)) {
467         ecx_key_free(ecx);
468         return 0;
469     }
470     return 1;
471 }
472
473 static int x25519_import_from(const OSSL_PARAM params[], void *vpctx)
474 {
475     return ecx_generic_import_from(params, vpctx, EVP_PKEY_X25519);
476 }
477
478 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
479     EVP_PKEY_X25519,
480     EVP_PKEY_X25519,
481     0,
482     "X25519",
483     "OpenSSL X25519 algorithm",
484
485     ecx_pub_decode,
486     ecx_pub_encode,
487     ecx_pub_cmp,
488     ecx_pub_print,
489
490     NULL,
491     ecx_priv_encode,
492     ecx_priv_print,
493
494     ecx_size,
495     ecx_bits,
496     ecx_security_bits,
497
498     0, 0, 0, 0,
499     ecx_cmp_parameters,
500     0, 0,
501
502     ecx_free,
503     ecx_ctrl,
504     NULL,
505     NULL,
506
507     NULL,
508     NULL,
509     NULL,
510
511     NULL,
512     NULL,
513     NULL,
514
515     ecx_set_priv_key,
516     ecx_set_pub_key,
517     ecx_get_priv_key,
518     ecx_get_pub_key,
519     ecx_pkey_dirty_cnt,
520     ecx_pkey_export_to,
521     x25519_import_from,
522
523     ecx_priv_decode_with_libctx
524 };
525
526 static int x448_import_from(const OSSL_PARAM params[], void *vpctx)
527 {
528     return ecx_generic_import_from(params, vpctx, EVP_PKEY_X448);
529 }
530
531 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
532     EVP_PKEY_X448,
533     EVP_PKEY_X448,
534     0,
535     "X448",
536     "OpenSSL X448 algorithm",
537
538     ecx_pub_decode,
539     ecx_pub_encode,
540     ecx_pub_cmp,
541     ecx_pub_print,
542
543     NULL,
544     ecx_priv_encode,
545     ecx_priv_print,
546
547     ecx_size,
548     ecx_bits,
549     ecx_security_bits,
550
551     0, 0, 0, 0,
552     ecx_cmp_parameters,
553     0, 0,
554
555     ecx_free,
556     ecx_ctrl,
557     NULL,
558     NULL,
559
560     NULL,
561     NULL,
562     NULL,
563
564     NULL,
565     NULL,
566     NULL,
567
568     ecx_set_priv_key,
569     ecx_set_pub_key,
570     ecx_get_priv_key,
571     ecx_get_pub_key,
572     ecx_pkey_dirty_cnt,
573     ecx_pkey_export_to,
574     x448_import_from,
575
576     ecx_priv_decode_with_libctx
577 };
578
579 static int ecd_size25519(const EVP_PKEY *pkey)
580 {
581     return ED25519_SIGSIZE;
582 }
583
584 static int ecd_size448(const EVP_PKEY *pkey)
585 {
586     return ED448_SIGSIZE;
587 }
588
589 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
590                            X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
591                            EVP_PKEY *pkey)
592 {
593     const ASN1_OBJECT *obj;
594     int ptype;
595     int nid;
596
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);
602         return 0;
603     }
604
605     if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
606         return 0;
607
608     return 2;
609 }
610
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)
614 {
615     /* Set algorithms identifiers */
616     X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
617     if (alg2)
618         X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
619     /* Algorithm identifiers set: carry on as normal */
620     return 3;
621 }
622
623 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
624                                  const ASN1_STRING *sig)
625 {
626     X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
627                       X509_SIG_INFO_TLS);
628     return 1;
629 }
630
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)
634 {
635     /* Set algorithm identifier */
636     X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
637     if (alg2 != NULL)
638         X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
639     /* Algorithm identifier set: carry on as normal */
640     return 3;
641 }
642
643 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
644                                const ASN1_STRING *sig)
645 {
646     X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
647                       X509_SIG_INFO_TLS);
648     return 1;
649 }
650
651 static int ed25519_import_from(const OSSL_PARAM params[], void *vpctx)
652 {
653     return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED25519);
654 }
655
656 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
657     EVP_PKEY_ED25519,
658     EVP_PKEY_ED25519,
659     0,
660     "ED25519",
661     "OpenSSL ED25519 algorithm",
662
663     ecx_pub_decode,
664     ecx_pub_encode,
665     ecx_pub_cmp,
666     ecx_pub_print,
667
668     NULL,
669     ecx_priv_encode,
670     ecx_priv_print,
671
672     ecd_size25519,
673     ecx_bits,
674     ecx_security_bits,
675
676     0, 0, 0, 0,
677     ecx_cmp_parameters,
678     0, 0,
679
680     ecx_free,
681     ecd_ctrl,
682     NULL,
683     NULL,
684     ecd_item_verify,
685     ecd_item_sign25519,
686     ecd_sig_info_set25519,
687
688     NULL,
689     NULL,
690     NULL,
691
692     ecx_set_priv_key,
693     ecx_set_pub_key,
694     ecx_get_priv_key,
695     ecx_get_pub_key,
696     ecx_pkey_dirty_cnt,
697     ecx_pkey_export_to,
698     ed25519_import_from,
699
700     ecx_priv_decode_with_libctx
701 };
702
703 static int ed448_import_from(const OSSL_PARAM params[], void *vpctx)
704 {
705     return ecx_generic_import_from(params, vpctx, EVP_PKEY_ED448);
706 }
707
708 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
709     EVP_PKEY_ED448,
710     EVP_PKEY_ED448,
711     0,
712     "ED448",
713     "OpenSSL ED448 algorithm",
714
715     ecx_pub_decode,
716     ecx_pub_encode,
717     ecx_pub_cmp,
718     ecx_pub_print,
719
720     NULL,
721     ecx_priv_encode,
722     ecx_priv_print,
723
724     ecd_size448,
725     ecx_bits,
726     ecx_security_bits,
727
728     0, 0, 0, 0,
729     ecx_cmp_parameters,
730     0, 0,
731
732     ecx_free,
733     ecd_ctrl,
734     NULL,
735     NULL,
736     ecd_item_verify,
737     ecd_item_sign448,
738     ecd_sig_info_set448,
739
740     NULL,
741     NULL,
742     NULL,
743
744     ecx_set_priv_key,
745     ecx_set_pub_key,
746     ecx_get_priv_key,
747     ecx_get_pub_key,
748     ecx_pkey_dirty_cnt,
749     ecx_pkey_export_to,
750     ed448_import_from,
751
752     ecx_priv_decode_with_libctx
753 };
754
755 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
756 {
757     return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN,
758                       NULL, NULL);
759 }
760
761 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
762                                           size_t *keylen,
763                                           const unsigned char **privkey,
764                                           const unsigned char **pubkey)
765 {
766     const ECX_KEY *ecxkey, *peerkey;
767
768     if (ctx->pkey == NULL || ctx->peerkey == NULL) {
769         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
770         return 0;
771     }
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);
776         return 0;
777     }
778     if (peerkey == NULL) {
779         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
780         return 0;
781     }
782     *privkey = ecxkey->privkey;
783     *pubkey = peerkey->pubkey;
784
785     return 1;
786 }
787
788 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
789                                 size_t *keylen)
790 {
791     const unsigned char *privkey, *pubkey;
792
793     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
794             || (key != NULL
795                 && X25519(key, privkey, pubkey) == 0))
796         return 0;
797     *keylen = X25519_KEYLEN;
798     return 1;
799 }
800
801 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
802                               size_t *keylen)
803 {
804     const unsigned char *privkey, *pubkey;
805
806     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
807             || (key != NULL
808                 && X448(key, privkey, pubkey) == 0))
809         return 0;
810     *keylen = X448_KEYLEN;
811     return 1;
812 }
813
814 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
815 {
816     /* Only need to handle peer key for derivation */
817     if (type == EVP_PKEY_CTRL_PEER_KEY)
818         return 1;
819     return -2;
820 }
821
822 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
823     EVP_PKEY_X25519,
824     0, 0, 0, 0, 0, 0, 0,
825     pkey_ecx_keygen,
826     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
827     pkey_ecx_derive25519,
828     pkey_ecx_ctrl,
829     0
830 };
831
832 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
833     EVP_PKEY_X448,
834     0, 0, 0, 0, 0, 0, 0,
835     pkey_ecx_keygen,
836     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837     pkey_ecx_derive448,
838     pkey_ecx_ctrl,
839     0
840 };
841
842 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
843                                     size_t *siglen, const unsigned char *tbs,
844                                     size_t tbslen)
845 {
846     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
847
848     if (sig == NULL) {
849         *siglen = ED25519_SIGSIZE;
850         return 1;
851     }
852     if (*siglen < ED25519_SIGSIZE) {
853         ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
854         return 0;
855     }
856
857     if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey, NULL,
858                      NULL) == 0)
859         return 0;
860     *siglen = ED25519_SIGSIZE;
861     return 1;
862 }
863
864 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
865                                   size_t *siglen, const unsigned char *tbs,
866                                   size_t tbslen)
867 {
868     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
869
870     if (sig == NULL) {
871         *siglen = ED448_SIGSIZE;
872         return 1;
873     }
874     if (*siglen < ED448_SIGSIZE) {
875         ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
876         return 0;
877     }
878
879     /*
880      * TODO(3.0): We use NULL for the library context for now. Will need to
881      * change later.
882      */
883     if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
884                    NULL, 0) == 0)
885         return 0;
886     *siglen = ED448_SIGSIZE;
887     return 1;
888 }
889
890 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
891                                       size_t siglen, const unsigned char *tbs,
892                                       size_t tbslen)
893 {
894     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
895
896     if (siglen != ED25519_SIGSIZE)
897         return 0;
898
899     return ED25519_verify(tbs, tbslen, sig, edkey->pubkey, NULL, NULL);
900 }
901
902 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
903                                     size_t siglen, const unsigned char *tbs,
904                                     size_t tbslen)
905 {
906     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
907
908     if (siglen != ED448_SIGSIZE)
909         return 0;
910
911     /*
912      * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
913      * change.
914      */
915     return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
916 }
917
918 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
919 {
920     switch (type) {
921     case EVP_PKEY_CTRL_MD:
922         /* Only NULL allowed as digest */
923         if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
924             return 1;
925         ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
926         return 0;
927
928     case EVP_PKEY_CTRL_DIGESTINIT:
929         return 1;
930     }
931     return -2;
932 }
933
934 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
935     EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
936     0, 0, 0, 0, 0, 0,
937     pkey_ecx_keygen,
938     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
939     pkey_ecd_ctrl,
940     0,
941     pkey_ecd_digestsign25519,
942     pkey_ecd_digestverify25519
943 };
944
945 static const EVP_PKEY_METHOD ed448_pkey_meth = {
946     EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
947     0, 0, 0, 0, 0, 0,
948     pkey_ecx_keygen,
949     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
950     pkey_ecd_ctrl,
951     0,
952     pkey_ecd_digestsign448,
953     pkey_ecd_digestverify448
954 };
955
956 #ifdef S390X_EC_ASM
957 # include "s390x_arch.h"
958
959 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
960 {
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
965     };
966     ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
967     unsigned char *privkey = NULL, *pubkey;
968
969     if (key == NULL) {
970         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
971         goto err;
972     }
973
974     pubkey = key->pubkey;
975
976     privkey = ecx_key_allocate_privkey(key);
977     if (privkey == NULL) {
978         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
979         goto err;
980     }
981
982     if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
983         goto err;
984
985     privkey[0] &= 248;
986     privkey[31] &= 127;
987     privkey[31] |= 64;
988
989     if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
990         goto err;
991
992     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
993     return 1;
994  err:
995     ecx_key_free(key);
996     return 0;
997 }
998
999 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1000 {
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
1007     };
1008     ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
1009     unsigned char *privkey = NULL, *pubkey;
1010
1011     if (key == NULL) {
1012         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1013         goto err;
1014     }
1015
1016     pubkey = key->pubkey;
1017
1018     privkey = ecx_key_allocate_privkey(key);
1019     if (privkey == NULL) {
1020         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1021         goto err;
1022     }
1023
1024     if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1025         goto err;
1026
1027     privkey[0] &= 252;
1028     privkey[55] |= 128;
1029
1030     if (s390x_x448_mul(pubkey, generator, privkey) != 1)
1031         goto err;
1032
1033     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1034     return 1;
1035  err:
1036     ecx_key_free(key);
1037     return 0;
1038 }
1039
1040 static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1041 {
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
1046     };
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,
1051     };
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;
1055     unsigned int sz;
1056
1057     if (key == NULL) {
1058         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1059         goto err;
1060     }
1061
1062     pubkey = key->pubkey;
1063
1064     privkey = ecx_key_allocate_privkey(key);
1065     if (privkey == NULL) {
1066         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1067         goto err;
1068     }
1069
1070     if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1071         goto err;
1072
1073     if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1074         goto err;
1075
1076     buff[0] &= 248;
1077     buff[31] &= 63;
1078     buff[31] |= 64;
1079
1080     if (s390x_ed25519_mul(x_dst, pubkey,
1081                           generator_x, generator_y, buff) != 1)
1082         goto err;
1083
1084     pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1085
1086     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1087     return 1;
1088  err:
1089     ecx_key_free(key);
1090     return 0;
1091 }
1092
1093 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1094 {
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
1101     };
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
1108     };
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;
1113
1114     if (key == NULL) {
1115         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1116         goto err;
1117     }
1118
1119     pubkey = key->pubkey;
1120
1121     privkey = ecx_key_allocate_privkey(key);
1122     if (privkey == NULL) {
1123         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1124         goto err;
1125     }
1126
1127     if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1128         goto err;
1129
1130     hashctx = EVP_MD_CTX_new();
1131     if (hashctx == NULL)
1132         goto err;
1133     if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1134         goto err;
1135     if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1136         goto err;
1137     if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1138         goto err;
1139
1140     buff[0] &= -4;
1141     buff[55] |= 0x80;
1142     buff[56] = 0;
1143
1144     if (s390x_ed448_mul(x_dst, pubkey,
1145                         generator_x, generator_y, buff) != 1)
1146         goto err;
1147
1148     pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1149
1150     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1151     EVP_MD_CTX_free(hashctx);
1152     return 1;
1153  err:
1154     ecx_key_free(key);
1155     EVP_MD_CTX_free(hashctx);
1156     return 0;
1157 }
1158
1159 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1160                                       size_t *keylen)
1161 {
1162     const unsigned char *privkey, *pubkey;
1163
1164     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1165         return 0;
1166
1167     if (key != NULL)
1168         return s390x_x25519_mul(key, pubkey, privkey);
1169
1170     *keylen = X25519_KEYLEN;
1171     return 1;
1172 }
1173
1174 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1175                                       size_t *keylen)
1176 {
1177     const unsigned char *privkey, *pubkey;
1178
1179     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1180         return 0;
1181
1182     if (key != NULL)
1183         return s390x_x448_mul(key, pubkey, privkey);
1184
1185     *keylen = X448_KEYLEN;
1186     return 1;
1187 }
1188
1189 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1190                                           unsigned char *sig, size_t *siglen,
1191                                           const unsigned char *tbs,
1192                                           size_t tbslen)
1193 {
1194     union {
1195         struct {
1196             unsigned char sig[64];
1197             unsigned char priv[32];
1198         } ed25519;
1199         unsigned long long buff[512];
1200     } param;
1201     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1202     int rc;
1203
1204     if (sig == NULL) {
1205         *siglen = ED25519_SIGSIZE;
1206         return 1;
1207     }
1208
1209     if (*siglen < ED25519_SIGSIZE) {
1210         ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1211         return 0;
1212     }
1213
1214     memset(&param, 0, sizeof(param));
1215     memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1216
1217     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1218     OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1219     if (rc != 0)
1220         return 0;
1221
1222     s390x_flip_endian32(sig, param.ed25519.sig);
1223     s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1224
1225     *siglen = ED25519_SIGSIZE;
1226     return 1;
1227 }
1228
1229 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1230                                         unsigned char *sig, size_t *siglen,
1231                                         const unsigned char *tbs,
1232                                         size_t tbslen)
1233 {
1234     union {
1235         struct {
1236             unsigned char sig[128];
1237             unsigned char priv[64];
1238         } ed448;
1239         unsigned long long buff[512];
1240     } param;
1241     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1242     int rc;
1243
1244     if (sig == NULL) {
1245         *siglen = ED448_SIGSIZE;
1246         return 1;
1247     }
1248
1249     if (*siglen < ED448_SIGSIZE) {
1250         ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1251         return 0;
1252     }
1253
1254     memset(&param, 0, sizeof(param));
1255     memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1256
1257     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1258     OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1259     if (rc != 0)
1260         return 0;
1261
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);
1266
1267     *siglen = ED448_SIGSIZE;
1268     return 1;
1269 }
1270
1271 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1272                                             const unsigned char *sig,
1273                                             size_t siglen,
1274                                             const unsigned char *tbs,
1275                                             size_t tbslen)
1276 {
1277     union {
1278         struct {
1279             unsigned char sig[64];
1280             unsigned char pub[32];
1281         } ed25519;
1282         unsigned long long buff[512];
1283     } param;
1284     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1285
1286     if (siglen != ED25519_SIGSIZE)
1287         return 0;
1288
1289     memset(&param, 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);
1293
1294     return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1295                       &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1296 }
1297
1298 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1299                                           const unsigned char *sig,
1300                                           size_t siglen,
1301                                           const unsigned char *tbs,
1302                                           size_t tbslen)
1303 {
1304     union {
1305         struct {
1306             unsigned char sig[128];
1307             unsigned char pub[64];
1308         } ed448;
1309         unsigned long long buff[512];
1310     } param;
1311     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1312
1313     if (siglen != ED448_SIGSIZE)
1314         return 0;
1315
1316     memset(&param, 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);
1323
1324     return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1325                       &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
1326 }
1327
1328 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1329     EVP_PKEY_X25519,
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,
1334     pkey_ecx_ctrl,
1335     0
1336 };
1337
1338 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1339     EVP_PKEY_X448,
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,
1344     pkey_ecx_ctrl,
1345     0
1346 };
1347 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1348     EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1349     0, 0, 0, 0, 0, 0,
1350     s390x_pkey_ecd_keygen25519,
1351     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1352     pkey_ecd_ctrl,
1353     0,
1354     s390x_pkey_ecd_digestsign25519,
1355     s390x_pkey_ecd_digestverify25519
1356 };
1357
1358 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1359     EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1360     0, 0, 0, 0, 0, 0,
1361     s390x_pkey_ecd_keygen448,
1362     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1363     pkey_ecd_ctrl,
1364     0,
1365     s390x_pkey_ecd_digestsign448,
1366     s390x_pkey_ecd_digestverify448
1367 };
1368 #endif
1369
1370 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1371 {
1372 #ifdef S390X_EC_ASM
1373     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1374         return &ecx25519_s390x_pkey_meth;
1375 #endif
1376     return &ecx25519_pkey_meth;
1377 }
1378
1379 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1380 {
1381 #ifdef S390X_EC_ASM
1382     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1383         return &ecx448_s390x_pkey_meth;
1384 #endif
1385     return &ecx448_pkey_meth;
1386 }
1387
1388 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1389 {
1390 #ifdef S390X_EC_ASM
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;
1396 #endif
1397     return &ed25519_pkey_meth;
1398 }
1399
1400 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1401 {
1402 #ifdef S390X_EC_ASM
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;
1407 #endif
1408     return &ed448_pkey_meth;
1409 }