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