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