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