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