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