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