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