88787e0db6c749feea8eb99b27f375881075b567
[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 };
652
653 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
654     EVP_PKEY_ED448,
655     EVP_PKEY_ED448,
656     0,
657     "ED448",
658     "OpenSSL ED448 algorithm",
659
660     ecx_pub_decode,
661     ecx_pub_encode,
662     ecx_pub_cmp,
663     ecx_pub_print,
664
665     ecx_priv_decode,
666     ecx_priv_encode,
667     ecx_priv_print,
668
669     ecd_size448,
670     ecx_bits,
671     ecx_security_bits,
672
673     0, 0, 0, 0,
674     ecx_cmp_parameters,
675     0, 0,
676
677     ecx_free,
678     ecd_ctrl,
679     NULL,
680     NULL,
681     ecd_item_verify,
682     ecd_item_sign448,
683     ecd_sig_info_set448,
684
685     NULL,
686     NULL,
687     NULL,
688
689     ecx_set_priv_key,
690     ecx_set_pub_key,
691     ecx_get_priv_key,
692     ecx_get_pub_key,
693 };
694
695 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
696 {
697     return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
698 }
699
700 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
701                                           size_t *keylen,
702                                           const unsigned char **privkey,
703                                           const unsigned char **pubkey)
704 {
705     const ECX_KEY *ecxkey, *peerkey;
706
707     if (ctx->pkey == NULL || ctx->peerkey == NULL) {
708         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
709         return 0;
710     }
711     ecxkey = ctx->pkey->pkey.ecx;
712     peerkey = ctx->peerkey->pkey.ecx;
713     if (ecxkey == NULL || ecxkey->privkey == NULL) {
714         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
715         return 0;
716     }
717     if (peerkey == NULL) {
718         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
719         return 0;
720     }
721     *privkey = ecxkey->privkey;
722     *pubkey = peerkey->pubkey;
723
724     return 1;
725 }
726
727 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
728                                 size_t *keylen)
729 {
730     const unsigned char *privkey, *pubkey;
731
732     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
733             || (key != NULL
734                 && X25519(key, privkey, pubkey) == 0))
735         return 0;
736     *keylen = X25519_KEYLEN;
737     return 1;
738 }
739
740 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
741                               size_t *keylen)
742 {
743     const unsigned char *privkey, *pubkey;
744
745     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
746             || (key != NULL
747                 && X448(key, privkey, pubkey) == 0))
748         return 0;
749     *keylen = X448_KEYLEN;
750     return 1;
751 }
752
753 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
754 {
755     /* Only need to handle peer key for derivation */
756     if (type == EVP_PKEY_CTRL_PEER_KEY)
757         return 1;
758     return -2;
759 }
760
761 static const EVP_PKEY_METHOD ecx25519_pkey_meth = {
762     EVP_PKEY_X25519,
763     0, 0, 0, 0, 0, 0, 0,
764     pkey_ecx_keygen,
765     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
766     pkey_ecx_derive25519,
767     pkey_ecx_ctrl,
768     0
769 };
770
771 static const EVP_PKEY_METHOD ecx448_pkey_meth = {
772     EVP_PKEY_X448,
773     0, 0, 0, 0, 0, 0, 0,
774     pkey_ecx_keygen,
775     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
776     pkey_ecx_derive448,
777     pkey_ecx_ctrl,
778     0
779 };
780
781 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
782                                     size_t *siglen, const unsigned char *tbs,
783                                     size_t tbslen)
784 {
785     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
786
787     if (sig == NULL) {
788         *siglen = ED25519_SIGSIZE;
789         return 1;
790     }
791     if (*siglen < ED25519_SIGSIZE) {
792         ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
793         return 0;
794     }
795
796     if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
797         return 0;
798     *siglen = ED25519_SIGSIZE;
799     return 1;
800 }
801
802 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
803                                   size_t *siglen, const unsigned char *tbs,
804                                   size_t tbslen)
805 {
806     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
807
808     if (sig == NULL) {
809         *siglen = ED448_SIGSIZE;
810         return 1;
811     }
812     if (*siglen < ED448_SIGSIZE) {
813         ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
814         return 0;
815     }
816
817     /*
818      * TODO(3.0): We use NULL for the library context for now. Will need to
819      * change later.
820      */
821     if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
822                    NULL, 0) == 0)
823         return 0;
824     *siglen = ED448_SIGSIZE;
825     return 1;
826 }
827
828 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
829                                       size_t siglen, const unsigned char *tbs,
830                                       size_t tbslen)
831 {
832     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
833
834     if (siglen != ED25519_SIGSIZE)
835         return 0;
836
837     return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
838 }
839
840 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
841                                     size_t siglen, const unsigned char *tbs,
842                                     size_t tbslen)
843 {
844     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
845
846     if (siglen != ED448_SIGSIZE)
847         return 0;
848
849     /*
850      * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
851      * change.
852      */
853     return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
854 }
855
856 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
857 {
858     switch (type) {
859     case EVP_PKEY_CTRL_MD:
860         /* Only NULL allowed as digest */
861         if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
862             return 1;
863         ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
864         return 0;
865
866     case EVP_PKEY_CTRL_DIGESTINIT:
867         return 1;
868     }
869     return -2;
870 }
871
872 static const EVP_PKEY_METHOD ed25519_pkey_meth = {
873     EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
874     0, 0, 0, 0, 0, 0,
875     pkey_ecx_keygen,
876     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
877     pkey_ecd_ctrl,
878     0,
879     pkey_ecd_digestsign25519,
880     pkey_ecd_digestverify25519
881 };
882
883 static const EVP_PKEY_METHOD ed448_pkey_meth = {
884     EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
885     0, 0, 0, 0, 0, 0,
886     pkey_ecx_keygen,
887     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
888     pkey_ecd_ctrl,
889     0,
890     pkey_ecd_digestsign448,
891     pkey_ecd_digestverify448
892 };
893
894 #ifdef S390X_EC_ASM
895 # include "s390x_arch.h"
896 # include "internal/constant_time.h"
897
898 static void s390x_x25519_mod_p(unsigned char u[32])
899 {
900     unsigned char u_red[32];
901     unsigned int c = 0;
902     int i;
903
904     memcpy(u_red, u, sizeof(u_red));
905
906     c += (unsigned int)u_red[31] + 19;
907     u_red[31] = (unsigned char)c;
908     c >>= 8;
909
910     for (i = 30; i >= 0; i--) {
911         c += (unsigned int)u_red[i];
912         u_red[i] = (unsigned char)c;
913         c >>= 8;
914     }
915
916     c = (u_red[0] & 0x80) >> 7;
917     u_red[0] &= 0x7f;
918     constant_time_cond_swap_buff(0 - (unsigned char)c,
919                                  u, u_red, sizeof(u_red));
920 }
921
922 static void s390x_x448_mod_p(unsigned char u[56])
923 {
924     unsigned char u_red[56];
925     unsigned int c = 0;
926     int i;
927
928     memcpy(u_red, u, sizeof(u_red));
929
930     c += (unsigned int)u_red[55] + 1;
931     u_red[55] = (unsigned char)c;
932     c >>= 8;
933
934     for (i = 54; i >= 28; i--) {
935         c += (unsigned int)u_red[i];
936         u_red[i] = (unsigned char)c;
937         c >>= 8;
938     }
939
940     c += (unsigned int)u_red[27] + 1;
941     u_red[27] = (unsigned char)c;
942     c >>= 8;
943
944     for (i = 26; i >= 0; i--) {
945         c += (unsigned int)u_red[i];
946         u_red[i] = (unsigned char)c;
947         c >>= 8;
948     }
949
950     constant_time_cond_swap_buff(0 - (unsigned char)c,
951                                  u, u_red, sizeof(u_red));
952 }
953
954 static int s390x_x25519_mul(unsigned char u_dst[32],
955                             const unsigned char u_src[32],
956                             const unsigned char d_src[32])
957 {
958     union {
959         struct {
960             unsigned char u_dst[32];
961             unsigned char u_src[32];
962             unsigned char d_src[32];
963         } x25519;
964         unsigned long long buff[512];
965     } param;
966     int rc;
967
968     memset(&param, 0, sizeof(param));
969
970     s390x_flip_endian32(param.x25519.u_src, u_src);
971     param.x25519.u_src[0] &= 0x7f;
972     s390x_x25519_mod_p(param.x25519.u_src);
973
974     s390x_flip_endian32(param.x25519.d_src, d_src);
975     param.x25519.d_src[31] &= 248;
976     param.x25519.d_src[0] &= 127;
977     param.x25519.d_src[0] |= 64;
978
979     rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X25519, &param.x25519) ? 0 : 1;
980     if (rc == 1)
981         s390x_flip_endian32(u_dst, param.x25519.u_dst);
982
983     OPENSSL_cleanse(param.x25519.d_src, sizeof(param.x25519.d_src));
984     return rc;
985 }
986
987 static int s390x_x448_mul(unsigned char u_dst[56],
988                           const unsigned char u_src[56],
989                           const unsigned char d_src[56])
990 {
991     union {
992         struct {
993             unsigned char u_dst[64];
994             unsigned char u_src[64];
995             unsigned char d_src[64];
996         } x448;
997         unsigned long long buff[512];
998     } param;
999     int rc;
1000
1001     memset(&param, 0, sizeof(param));
1002
1003     memcpy(param.x448.u_src, u_src, 56);
1004     memcpy(param.x448.d_src, d_src, 56);
1005
1006     s390x_flip_endian64(param.x448.u_src, param.x448.u_src);
1007     s390x_x448_mod_p(param.x448.u_src + 8);
1008
1009     s390x_flip_endian64(param.x448.d_src, param.x448.d_src);
1010     param.x448.d_src[63] &= 252;
1011     param.x448.d_src[8] |= 128;
1012
1013     rc = s390x_pcc(S390X_SCALAR_MULTIPLY_X448, &param.x448) ? 0 : 1;
1014     if (rc == 1) {
1015         s390x_flip_endian64(param.x448.u_dst, param.x448.u_dst);
1016         memcpy(u_dst, param.x448.u_dst, 56);
1017     }
1018
1019     OPENSSL_cleanse(param.x448.d_src, sizeof(param.x448.d_src));
1020     return rc;
1021 }
1022
1023 static int s390x_ed25519_mul(unsigned char x_dst[32],
1024                              unsigned char y_dst[32],
1025                              const unsigned char x_src[32],
1026                              const unsigned char y_src[32],
1027                              const unsigned char d_src[32])
1028 {
1029     union {
1030         struct {
1031             unsigned char x_dst[32];
1032             unsigned char y_dst[32];
1033             unsigned char x_src[32];
1034             unsigned char y_src[32];
1035             unsigned char d_src[32];
1036         } ed25519;
1037         unsigned long long buff[512];
1038     } param;
1039     int rc;
1040
1041     memset(&param, 0, sizeof(param));
1042
1043     s390x_flip_endian32(param.ed25519.x_src, x_src);
1044     s390x_flip_endian32(param.ed25519.y_src, y_src);
1045     s390x_flip_endian32(param.ed25519.d_src, d_src);
1046
1047     rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED25519, &param.ed25519) ? 0 : 1;
1048     if (rc == 1) {
1049         s390x_flip_endian32(x_dst, param.ed25519.x_dst);
1050         s390x_flip_endian32(y_dst, param.ed25519.y_dst);
1051     }
1052
1053     OPENSSL_cleanse(param.ed25519.d_src, sizeof(param.ed25519.d_src));
1054     return rc;
1055 }
1056
1057 static int s390x_ed448_mul(unsigned char x_dst[57],
1058                            unsigned char y_dst[57],
1059                            const unsigned char x_src[57],
1060                            const unsigned char y_src[57],
1061                            const unsigned char d_src[57])
1062 {
1063     union {
1064         struct {
1065             unsigned char x_dst[64];
1066             unsigned char y_dst[64];
1067             unsigned char x_src[64];
1068             unsigned char y_src[64];
1069             unsigned char d_src[64];
1070         } ed448;
1071         unsigned long long buff[512];
1072     } param;
1073     int rc;
1074
1075     memset(&param, 0, sizeof(param));
1076
1077     memcpy(param.ed448.x_src, x_src, 57);
1078     memcpy(param.ed448.y_src, y_src, 57);
1079     memcpy(param.ed448.d_src, d_src, 57);
1080     s390x_flip_endian64(param.ed448.x_src, param.ed448.x_src);
1081     s390x_flip_endian64(param.ed448.y_src, param.ed448.y_src);
1082     s390x_flip_endian64(param.ed448.d_src, param.ed448.d_src);
1083
1084     rc = s390x_pcc(S390X_SCALAR_MULTIPLY_ED448, &param.ed448) ? 0 : 1;
1085     if (rc == 1) {
1086         s390x_flip_endian64(param.ed448.x_dst, param.ed448.x_dst);
1087         s390x_flip_endian64(param.ed448.y_dst, param.ed448.y_dst);
1088         memcpy(x_dst, param.ed448.x_dst, 57);
1089         memcpy(y_dst, param.ed448.y_dst, 57);
1090     }
1091
1092     OPENSSL_cleanse(param.ed448.d_src, sizeof(param.ed448.d_src));
1093     return rc;
1094 }
1095
1096 static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1097 {
1098     static const unsigned char generator[] = {
1099         0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1101         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1102     };
1103     ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
1104     unsigned char *privkey = NULL, *pubkey;
1105
1106     if (key == NULL) {
1107         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1108         goto err;
1109     }
1110
1111     pubkey = key->pubkey;
1112
1113     privkey = ecx_key_allocate_privkey(key);
1114     if (privkey == NULL) {
1115         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1116         goto err;
1117     }
1118
1119     if (RAND_priv_bytes(privkey, X25519_KEYLEN) <= 0)
1120         goto err;
1121
1122     privkey[0] &= 248;
1123     privkey[31] &= 127;
1124     privkey[31] |= 64;
1125
1126     if (s390x_x25519_mul(pubkey, generator, privkey) != 1)
1127         goto err;
1128
1129     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1130     return 1;
1131  err:
1132     ecx_key_free(key);
1133     return 0;
1134 }
1135
1136 static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1137 {
1138     static const unsigned char generator[] = {
1139         0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140         0x00, 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, 0x00, 0x00, 0x00, 0x00,
1143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1144     };
1145     ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
1146     unsigned char *privkey = NULL, *pubkey;
1147
1148     if (key == NULL) {
1149         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1150         goto err;
1151     }
1152
1153     pubkey = key->pubkey;
1154
1155     privkey = ecx_key_allocate_privkey(key);
1156     if (privkey == NULL) {
1157         ECerr(EC_F_S390X_PKEY_ECX_KEYGEN448, ERR_R_MALLOC_FAILURE);
1158         goto err;
1159     }
1160
1161     if (RAND_priv_bytes(privkey, X448_KEYLEN) <= 0)
1162         goto err;
1163
1164     privkey[0] &= 252;
1165     privkey[55] |= 128;
1166
1167     if (s390x_x448_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_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1178 {
1179     static const unsigned char generator_x[] = {
1180         0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95,
1181         0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0,
1182         0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21
1183     };
1184     static const unsigned char generator_y[] = {
1185         0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1186         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1187         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
1188     };
1189     unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
1190     ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
1191     unsigned char *privkey = NULL, *pubkey;
1192     unsigned int sz;
1193
1194     if (key == NULL) {
1195         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1196         goto err;
1197     }
1198
1199     pubkey = key->pubkey;
1200
1201     privkey = ecx_key_allocate_privkey(key);
1202     if (privkey == NULL) {
1203         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN25519, ERR_R_MALLOC_FAILURE);
1204         goto err;
1205     }
1206
1207     if (RAND_priv_bytes(privkey, ED25519_KEYLEN) <= 0)
1208         goto err;
1209
1210     if (!EVP_Digest(privkey, 32, buff, &sz, EVP_sha512(), NULL))
1211         goto err;
1212
1213     buff[0] &= 248;
1214     buff[31] &= 63;
1215     buff[31] |= 64;
1216
1217     if (s390x_ed25519_mul(x_dst, pubkey,
1218                           generator_x, generator_y, buff) != 1)
1219         goto err;
1220
1221     pubkey[31] |= ((x_dst[0] & 0x01) << 7);
1222
1223     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1224     return 1;
1225  err:
1226     ecx_key_free(key);
1227     return 0;
1228 }
1229
1230 static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
1231 {
1232     static const unsigned char generator_x[] = {
1233         0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b,
1234         0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12,
1235         0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47,
1236         0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22,
1237         0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f, 0x00
1238     };
1239     static const unsigned char generator_y[] = {
1240         0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e,
1241         0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a,
1242         0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c,
1243         0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88,
1244         0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
1245     };
1246     unsigned char x_dst[57], buff[114];
1247     ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
1248     unsigned char *privkey = NULL, *pubkey;
1249     EVP_MD_CTX *hashctx = NULL;
1250
1251     if (key == NULL) {
1252         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1253         goto err;
1254     }
1255
1256     pubkey = key->pubkey;
1257
1258     privkey = ecx_key_allocate_privkey(key);
1259     if (privkey == NULL) {
1260         ECerr(EC_F_S390X_PKEY_ECD_KEYGEN448, ERR_R_MALLOC_FAILURE);
1261         goto err;
1262     }
1263
1264     if (RAND_priv_bytes(privkey, ED448_KEYLEN) <= 0)
1265         goto err;
1266
1267     hashctx = EVP_MD_CTX_new();
1268     if (hashctx == NULL)
1269         goto err;
1270     if (EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL) != 1)
1271         goto err;
1272     if (EVP_DigestUpdate(hashctx, privkey, 57) != 1)
1273         goto err;
1274     if (EVP_DigestFinalXOF(hashctx, buff, sizeof(buff)) != 1)
1275         goto err;
1276
1277     buff[0] &= -4;
1278     buff[55] |= 0x80;
1279     buff[56] = 0;
1280
1281     if (s390x_ed448_mul(x_dst, pubkey,
1282                         generator_x, generator_y, buff) != 1)
1283         goto err;
1284
1285     pubkey[56] |= ((x_dst[0] & 0x01) << 7);
1286
1287     EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, key);
1288     EVP_MD_CTX_free(hashctx);
1289     return 1;
1290  err:
1291     ecx_key_free(key);
1292     EVP_MD_CTX_free(hashctx);
1293     return 0;
1294 }
1295
1296 static int s390x_pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
1297                                       size_t *keylen)
1298 {
1299     const unsigned char *privkey, *pubkey;
1300
1301     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1302         return 0;
1303
1304     if (key != NULL)
1305         return s390x_x25519_mul(key, pubkey, privkey);
1306
1307     *keylen = X25519_KEYLEN;
1308     return 1;
1309 }
1310
1311 static int s390x_pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
1312                                       size_t *keylen)
1313 {
1314     const unsigned char *privkey, *pubkey;
1315
1316     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey))
1317         return 0;
1318
1319     if (key != NULL)
1320         return s390x_x448_mul(key, pubkey, privkey);
1321
1322     *keylen = X448_KEYLEN;
1323     return 1;
1324 }
1325
1326 static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
1327                                           unsigned char *sig, size_t *siglen,
1328                                           const unsigned char *tbs,
1329                                           size_t tbslen)
1330 {
1331     union {
1332         struct {
1333             unsigned char sig[64];
1334             unsigned char priv[32];
1335         } ed25519;
1336         unsigned long long buff[512];
1337     } param;
1338     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1339     int rc;
1340
1341     if (sig == NULL) {
1342         *siglen = ED25519_SIGSIZE;
1343         return 1;
1344     }
1345
1346     if (*siglen < ED25519_SIGSIZE) {
1347         ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
1348         return 0;
1349     }
1350
1351     memset(&param, 0, sizeof(param));
1352     memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv));
1353
1354     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, &param.ed25519, tbs, tbslen);
1355     OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv));
1356     if (rc != 0)
1357         return 0;
1358
1359     s390x_flip_endian32(sig, param.ed25519.sig);
1360     s390x_flip_endian32(sig + 32, param.ed25519.sig + 32);
1361
1362     *siglen = ED25519_SIGSIZE;
1363     return 1;
1364 }
1365
1366 static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
1367                                         unsigned char *sig, size_t *siglen,
1368                                         const unsigned char *tbs,
1369                                         size_t tbslen)
1370 {
1371     union {
1372         struct {
1373             unsigned char sig[128];
1374             unsigned char priv[64];
1375         } ed448;
1376         unsigned long long buff[512];
1377     } param;
1378     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1379     int rc;
1380
1381     if (sig == NULL) {
1382         *siglen = ED448_SIGSIZE;
1383         return 1;
1384     }
1385
1386     if (*siglen < ED448_SIGSIZE) {
1387         ECerr(EC_F_S390X_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
1388         return 0;
1389     }
1390
1391     memset(&param, 0, sizeof(param));
1392     memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57);
1393
1394     rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, &param.ed448, tbs, tbslen);
1395     OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv));
1396     if (rc != 0)
1397         return 0;
1398
1399     s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1400     s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1401     memcpy(sig, param.ed448.sig, 57);
1402     memcpy(sig + 57, param.ed448.sig + 64, 57);
1403
1404     *siglen = ED448_SIGSIZE;
1405     return 1;
1406 }
1407
1408 static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
1409                                             const unsigned char *sig,
1410                                             size_t siglen,
1411                                             const unsigned char *tbs,
1412                                             size_t tbslen)
1413 {
1414     union {
1415         struct {
1416             unsigned char sig[64];
1417             unsigned char pub[32];
1418         } ed25519;
1419         unsigned long long buff[512];
1420     } param;
1421     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1422
1423     if (siglen != ED25519_SIGSIZE)
1424         return 0;
1425
1426     memset(&param, 0, sizeof(param));
1427     s390x_flip_endian32(param.ed25519.sig, sig);
1428     s390x_flip_endian32(param.ed25519.sig + 32, sig + 32);
1429     s390x_flip_endian32(param.ed25519.pub, edkey->pubkey);
1430
1431     return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519,
1432                       &param.ed25519, tbs, tbslen) == 0 ? 1 : 0;
1433 }
1434
1435 static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
1436                                           const unsigned char *sig,
1437                                           size_t siglen,
1438                                           const unsigned char *tbs,
1439                                           size_t tbslen)
1440 {
1441     union {
1442         struct {
1443             unsigned char sig[128];
1444             unsigned char pub[64];
1445         } ed448;
1446         unsigned long long buff[512];
1447     } param;
1448     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
1449
1450     if (siglen != ED448_SIGSIZE)
1451         return 0;
1452
1453     memset(&param, 0, sizeof(param));
1454     memcpy(param.ed448.sig, sig, 57);
1455     s390x_flip_endian64(param.ed448.sig, param.ed448.sig);
1456     memcpy(param.ed448.sig + 64, sig + 57, 57);
1457     s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64);
1458     memcpy(param.ed448.pub, edkey->pubkey, 57);
1459     s390x_flip_endian64(param.ed448.pub, param.ed448.pub);
1460
1461     return s390x_kdsa(S390X_EDDSA_VERIFY_ED448,
1462                       &param.ed448, tbs, tbslen) == 0 ? 1 : 0;
1463 }
1464
1465 static const EVP_PKEY_METHOD ecx25519_s390x_pkey_meth = {
1466     EVP_PKEY_X25519,
1467     0, 0, 0, 0, 0, 0, 0,
1468     s390x_pkey_ecx_keygen25519,
1469     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1470     s390x_pkey_ecx_derive25519,
1471     pkey_ecx_ctrl,
1472     0
1473 };
1474
1475 static const EVP_PKEY_METHOD ecx448_s390x_pkey_meth = {
1476     EVP_PKEY_X448,
1477     0, 0, 0, 0, 0, 0, 0,
1478     s390x_pkey_ecx_keygen448,
1479     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1480     s390x_pkey_ecx_derive448,
1481     pkey_ecx_ctrl,
1482     0
1483 };
1484 static const EVP_PKEY_METHOD ed25519_s390x_pkey_meth = {
1485     EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1486     0, 0, 0, 0, 0, 0,
1487     s390x_pkey_ecd_keygen25519,
1488     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1489     pkey_ecd_ctrl,
1490     0,
1491     s390x_pkey_ecd_digestsign25519,
1492     s390x_pkey_ecd_digestverify25519
1493 };
1494
1495 static const EVP_PKEY_METHOD ed448_s390x_pkey_meth = {
1496     EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
1497     0, 0, 0, 0, 0, 0,
1498     s390x_pkey_ecd_keygen448,
1499     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1500     pkey_ecd_ctrl,
1501     0,
1502     s390x_pkey_ecd_digestsign448,
1503     s390x_pkey_ecd_digestverify448
1504 };
1505 #endif
1506
1507 const EVP_PKEY_METHOD *ecx25519_pkey_method(void)
1508 {
1509 #ifdef S390X_EC_ASM
1510     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519))
1511         return &ecx25519_s390x_pkey_meth;
1512 #endif
1513     return &ecx25519_pkey_meth;
1514 }
1515
1516 const EVP_PKEY_METHOD *ecx448_pkey_method(void)
1517 {
1518 #ifdef S390X_EC_ASM
1519     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448))
1520         return &ecx448_s390x_pkey_meth;
1521 #endif
1522     return &ecx448_pkey_meth;
1523 }
1524
1525 const EVP_PKEY_METHOD *ed25519_pkey_method(void)
1526 {
1527 #ifdef S390X_EC_ASM
1528     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
1529         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
1530         && OPENSSL_s390xcap_P.kdsa[0]
1531             & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519))
1532         return &ed25519_s390x_pkey_meth;
1533 #endif
1534     return &ed25519_pkey_meth;
1535 }
1536
1537 const EVP_PKEY_METHOD *ed448_pkey_method(void)
1538 {
1539 #ifdef S390X_EC_ASM
1540     if (OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
1541         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_ED448)
1542         && OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448))
1543         return &ed448_s390x_pkey_meth;
1544 #endif
1545     return &ed448_pkey_meth;
1546 }