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