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