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