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