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