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