clearing the ecx private key memory
[openssl.git] / crypto / ec / ecx_meth.c
1 /*
2  * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/x509.h>
13 #include <openssl/ec.h>
14 #include <openssl/rand.h>
15 #include "internal/asn1_int.h"
16 #include "internal/evp_int.h"
17 #include "ec_lcl.h"
18 #include "curve448/curve448_lcl.h"
19
20 #define X25519_BITS          253
21 #define X25519_SECURITY_BITS 128
22
23 #define ED25519_SIGSIZE      64
24
25 #define X448_BITS            448
26 #define ED448_BITS           456
27 #define X448_SECURITY_BITS   224
28
29 #define ED448_SIGSIZE        114
30
31 #define ISX448(id)      ((id) == EVP_PKEY_X448)
32 #define IS25519(id)     ((id) == EVP_PKEY_X25519 || (id) == EVP_PKEY_ED25519)
33 #define KEYLENID(id)    (IS25519(id) ? X25519_KEYLEN \
34                                      : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
35                                                               : ED448_KEYLEN))
36 #define KEYLEN(p)       KEYLENID((p)->ameth->pkey_id)
37
38
39 typedef enum {
40     KEY_OP_PUBLIC,
41     KEY_OP_PRIVATE,
42     KEY_OP_KEYGEN
43 } ecx_key_op_t;
44
45 /* Setup EVP_PKEY using public, private or generation */
46 static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
47                       const unsigned char *p, int plen, ecx_key_op_t op)
48 {
49     ECX_KEY *key = NULL;
50     unsigned char *privkey, *pubkey;
51
52     if (op != KEY_OP_KEYGEN) {
53         if (palg != NULL) {
54             int ptype;
55
56             /* Algorithm parameters must be absent */
57             X509_ALGOR_get0(NULL, &ptype, NULL, palg);
58             if (ptype != V_ASN1_UNDEF) {
59                 ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
60                 return 0;
61             }
62         }
63
64         if (p == NULL || plen != KEYLENID(id)) {
65             ECerr(EC_F_ECX_KEY_OP, EC_R_INVALID_ENCODING);
66             return 0;
67         }
68     }
69
70     key = OPENSSL_zalloc(sizeof(*key));
71     if (key == NULL) {
72         ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
73         return 0;
74     }
75     pubkey = key->pubkey;
76
77     if (op == KEY_OP_PUBLIC) {
78         memcpy(pubkey, p, plen);
79     } else {
80         privkey = key->privkey = OPENSSL_secure_malloc(KEYLENID(id));
81         if (privkey == NULL) {
82             ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
83             goto err;
84         }
85         if (op == KEY_OP_KEYGEN) {
86             if (RAND_priv_bytes(privkey, KEYLENID(id)) <= 0) {
87                 OPENSSL_secure_free(privkey);
88                 key->privkey = NULL;
89                 goto err;
90             }
91             if (id == EVP_PKEY_X25519) {
92                 privkey[0] &= 248;
93                 privkey[X25519_KEYLEN - 1] &= 127;
94                 privkey[X25519_KEYLEN - 1] |= 64;
95             } else if (id == EVP_PKEY_X448) {
96                 privkey[0] &= 252;
97                 privkey[X448_KEYLEN - 1] |= 128;
98             }
99         } else {
100             memcpy(privkey, p, KEYLENID(id));
101         }
102         switch (id) {
103         case EVP_PKEY_X25519:
104             X25519_public_from_private(pubkey, privkey);
105             break;
106         case EVP_PKEY_ED25519:
107             ED25519_public_from_private(pubkey, privkey);
108             break;
109         case EVP_PKEY_X448:
110             X448_public_from_private(pubkey, privkey);
111             break;
112         case EVP_PKEY_ED448:
113             /*
114              * TODO(3.0): We set the library context to NULL for now. This will
115              * need to change.
116              */
117             ED448_public_from_private(NULL, pubkey, privkey);
118             break;
119         }
120     }
121
122     EVP_PKEY_assign(pkey, id, key);
123     return 1;
124  err:
125     OPENSSL_free(key);
126     return 0;
127 }
128
129 static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
130 {
131     const ECX_KEY *ecxkey = pkey->pkey.ecx;
132     unsigned char *penc;
133
134     if (ecxkey == NULL) {
135         ECerr(EC_F_ECX_PUB_ENCODE, EC_R_INVALID_KEY);
136         return 0;
137     }
138
139     penc = OPENSSL_memdup(ecxkey->pubkey, KEYLEN(pkey));
140     if (penc == NULL) {
141         ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
142         return 0;
143     }
144
145     if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
146                                 V_ASN1_UNDEF, NULL, penc, KEYLEN(pkey))) {
147         OPENSSL_free(penc);
148         ECerr(EC_F_ECX_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
149         return 0;
150     }
151     return 1;
152 }
153
154 static int ecx_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
155 {
156     const unsigned char *p;
157     int pklen;
158     X509_ALGOR *palg;
159
160     if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
161         return 0;
162     return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen,
163                       KEY_OP_PUBLIC);
164 }
165
166 static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
167 {
168     const ECX_KEY *akey = a->pkey.ecx;
169     const ECX_KEY *bkey = b->pkey.ecx;
170
171     if (akey == NULL || bkey == NULL)
172         return -2;
173
174     return CRYPTO_memcmp(akey->pubkey, bkey->pubkey, KEYLEN(a)) == 0;
175 }
176
177 static int ecx_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
178 {
179     const unsigned char *p;
180     int plen;
181     ASN1_OCTET_STRING *oct = NULL;
182     const X509_ALGOR *palg;
183     int rv;
184
185     if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
186         return 0;
187
188     oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
189     if (oct == NULL) {
190         p = NULL;
191         plen = 0;
192     } else {
193         p = ASN1_STRING_get0_data(oct);
194         plen = ASN1_STRING_length(oct);
195     }
196
197     rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE);
198     ASN1_STRING_clear_free(oct);
199     return rv;
200 }
201
202 static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
203 {
204     const ECX_KEY *ecxkey = pkey->pkey.ecx;
205     ASN1_OCTET_STRING oct;
206     unsigned char *penc = NULL;
207     int penclen;
208
209     if (ecxkey == NULL || ecxkey->privkey == NULL) {
210         ECerr(EC_F_ECX_PRIV_ENCODE, EC_R_INVALID_PRIVATE_KEY);
211         return 0;
212     }
213
214     oct.data = ecxkey->privkey;
215     oct.length = KEYLEN(pkey);
216     oct.flags = 0;
217
218     penclen = i2d_ASN1_OCTET_STRING(&oct, &penc);
219     if (penclen < 0) {
220         ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
221         return 0;
222     }
223
224     if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
225                          V_ASN1_UNDEF, NULL, penc, penclen)) {
226         OPENSSL_clear_free(penc, penclen);
227         ECerr(EC_F_ECX_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
228         return 0;
229     }
230
231     return 1;
232 }
233
234 static int ecx_size(const EVP_PKEY *pkey)
235 {
236     return KEYLEN(pkey);
237 }
238
239 static int ecx_bits(const EVP_PKEY *pkey)
240 {
241     if (IS25519(pkey->ameth->pkey_id)) {
242         return X25519_BITS;
243     } else if(ISX448(pkey->ameth->pkey_id)) {
244         return X448_BITS;
245     } else {
246         return ED448_BITS;
247     }
248 }
249
250 static int ecx_security_bits(const EVP_PKEY *pkey)
251 {
252     if (IS25519(pkey->ameth->pkey_id)) {
253         return X25519_SECURITY_BITS;
254     } else {
255         return X448_SECURITY_BITS;
256     }
257 }
258
259 static void ecx_free(EVP_PKEY *pkey)
260 {
261     if (pkey->pkey.ecx != NULL)
262         OPENSSL_secure_clear_free(pkey->pkey.ecx->privkey, KEYLEN(pkey));
263     OPENSSL_free(pkey->pkey.ecx);
264 }
265
266 /* "parameters" are always equal */
267 static int ecx_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
268 {
269     return 1;
270 }
271
272 static int ecx_key_print(BIO *bp, const EVP_PKEY *pkey, int indent,
273                          ASN1_PCTX *ctx, ecx_key_op_t op)
274 {
275     const ECX_KEY *ecxkey = pkey->pkey.ecx;
276     const char *nm = OBJ_nid2ln(pkey->ameth->pkey_id);
277
278     if (op == KEY_OP_PRIVATE) {
279         if (ecxkey == NULL || ecxkey->privkey == NULL) {
280             if (BIO_printf(bp, "%*s<INVALID PRIVATE KEY>\n", indent, "") <= 0)
281                 return 0;
282             return 1;
283         }
284         if (BIO_printf(bp, "%*s%s Private-Key:\n", indent, "", nm) <= 0)
285             return 0;
286         if (BIO_printf(bp, "%*spriv:\n", indent, "") <= 0)
287             return 0;
288         if (ASN1_buf_print(bp, ecxkey->privkey, KEYLEN(pkey),
289                            indent + 4) == 0)
290             return 0;
291     } else {
292         if (ecxkey == NULL) {
293             if (BIO_printf(bp, "%*s<INVALID PUBLIC KEY>\n", indent, "") <= 0)
294                 return 0;
295             return 1;
296         }
297         if (BIO_printf(bp, "%*s%s Public-Key:\n", indent, "", nm) <= 0)
298             return 0;
299     }
300     if (BIO_printf(bp, "%*spub:\n", indent, "") <= 0)
301         return 0;
302
303     if (ASN1_buf_print(bp, ecxkey->pubkey, KEYLEN(pkey),
304                        indent + 4) == 0)
305         return 0;
306     return 1;
307 }
308
309 static int ecx_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
310                           ASN1_PCTX *ctx)
311 {
312     return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PRIVATE);
313 }
314
315 static int ecx_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
316                          ASN1_PCTX *ctx)
317 {
318     return ecx_key_print(bp, pkey, indent, ctx, KEY_OP_PUBLIC);
319 }
320
321 static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
322 {
323     switch (op) {
324
325     case ASN1_PKEY_CTRL_SET1_TLS_ENCPT:
326         return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1,
327                           KEY_OP_PUBLIC);
328
329     case ASN1_PKEY_CTRL_GET1_TLS_ENCPT:
330         if (pkey->pkey.ecx != NULL) {
331             unsigned char **ppt = arg2;
332
333             *ppt = OPENSSL_memdup(pkey->pkey.ecx->pubkey, KEYLEN(pkey));
334             if (*ppt != NULL)
335                 return KEYLEN(pkey);
336         }
337         return 0;
338
339     default:
340         return -2;
341
342     }
343 }
344
345 static int ecd_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
346 {
347     switch (op) {
348     case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
349         /* We currently only support Pure EdDSA which takes no digest */
350         *(int *)arg2 = NID_undef;
351         return 2;
352
353     default:
354         return -2;
355
356     }
357 }
358
359 static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv,
360                             size_t len)
361 {
362     return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len,
363                        KEY_OP_PRIVATE);
364 }
365
366 static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len)
367 {
368     return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len,
369                       KEY_OP_PUBLIC);
370 }
371
372 static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv,
373                             size_t *len)
374 {
375     const ECX_KEY *key = pkey->pkey.ecx;
376
377     if (priv == NULL) {
378         *len = KEYLENID(pkey->ameth->pkey_id);
379         return 1;
380     }
381
382     if (key == NULL
383             || key->privkey == NULL
384             || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
385         return 0;
386
387     *len = KEYLENID(pkey->ameth->pkey_id);
388     memcpy(priv, key->privkey, *len);
389
390     return 1;
391 }
392
393 static int ecx_get_pub_key(const EVP_PKEY *pkey, unsigned char *pub,
394                            size_t *len)
395 {
396     const ECX_KEY *key = pkey->pkey.ecx;
397
398     if (pub == NULL) {
399         *len = KEYLENID(pkey->ameth->pkey_id);
400         return 1;
401     }
402
403     if (key == NULL
404             || *len < (size_t)KEYLENID(pkey->ameth->pkey_id))
405         return 0;
406
407     *len = KEYLENID(pkey->ameth->pkey_id);
408     memcpy(pub, key->pubkey, *len);
409
410     return 1;
411 }
412
413 const EVP_PKEY_ASN1_METHOD ecx25519_asn1_meth = {
414     EVP_PKEY_X25519,
415     EVP_PKEY_X25519,
416     0,
417     "X25519",
418     "OpenSSL X25519 algorithm",
419
420     ecx_pub_decode,
421     ecx_pub_encode,
422     ecx_pub_cmp,
423     ecx_pub_print,
424
425     ecx_priv_decode,
426     ecx_priv_encode,
427     ecx_priv_print,
428
429     ecx_size,
430     ecx_bits,
431     ecx_security_bits,
432
433     0, 0, 0, 0,
434     ecx_cmp_parameters,
435     0, 0,
436
437     ecx_free,
438     ecx_ctrl,
439     NULL,
440     NULL,
441
442     NULL,
443     NULL,
444     NULL,
445
446     NULL,
447     NULL,
448     NULL,
449
450     ecx_set_priv_key,
451     ecx_set_pub_key,
452     ecx_get_priv_key,
453     ecx_get_pub_key,
454 };
455
456 const EVP_PKEY_ASN1_METHOD ecx448_asn1_meth = {
457     EVP_PKEY_X448,
458     EVP_PKEY_X448,
459     0,
460     "X448",
461     "OpenSSL X448 algorithm",
462
463     ecx_pub_decode,
464     ecx_pub_encode,
465     ecx_pub_cmp,
466     ecx_pub_print,
467
468     ecx_priv_decode,
469     ecx_priv_encode,
470     ecx_priv_print,
471
472     ecx_size,
473     ecx_bits,
474     ecx_security_bits,
475
476     0, 0, 0, 0,
477     ecx_cmp_parameters,
478     0, 0,
479
480     ecx_free,
481     ecx_ctrl,
482     NULL,
483     NULL,
484
485     NULL,
486     NULL,
487     NULL,
488
489     NULL,
490     NULL,
491     NULL,
492
493     ecx_set_priv_key,
494     ecx_set_pub_key,
495     ecx_get_priv_key,
496     ecx_get_pub_key,
497 };
498
499 static int ecd_size25519(const EVP_PKEY *pkey)
500 {
501     return ED25519_SIGSIZE;
502 }
503
504 static int ecd_size448(const EVP_PKEY *pkey)
505 {
506     return ED448_SIGSIZE;
507 }
508
509 static int ecd_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
510                            X509_ALGOR *sigalg, ASN1_BIT_STRING *str,
511                            EVP_PKEY *pkey)
512 {
513     const ASN1_OBJECT *obj;
514     int ptype;
515     int nid;
516
517     /* Sanity check: make sure it is ED25519/ED448 with absent parameters */
518     X509_ALGOR_get0(&obj, &ptype, NULL, sigalg);
519     nid = OBJ_obj2nid(obj);
520     if ((nid != NID_ED25519 && nid != NID_ED448) || ptype != V_ASN1_UNDEF) {
521         ECerr(EC_F_ECD_ITEM_VERIFY, EC_R_INVALID_ENCODING);
522         return 0;
523     }
524
525     if (!EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey))
526         return 0;
527
528     return 2;
529 }
530
531 static int ecd_item_sign25519(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
532                               X509_ALGOR *alg1, X509_ALGOR *alg2,
533                               ASN1_BIT_STRING *str)
534 {
535     /* Set algorithms identifiers */
536     X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
537     if (alg2)
538         X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL);
539     /* Algorithm identifiers set: carry on as normal */
540     return 3;
541 }
542
543 static int ecd_sig_info_set25519(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
544                                  const ASN1_STRING *sig)
545 {
546     X509_SIG_INFO_set(siginf, NID_undef, NID_ED25519, X25519_SECURITY_BITS,
547                       X509_SIG_INFO_TLS);
548     return 1;
549 }
550
551 static int ecd_item_sign448(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
552                             X509_ALGOR *alg1, X509_ALGOR *alg2,
553                             ASN1_BIT_STRING *str)
554 {
555     /* Set algorithm identifier */
556     X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
557     if (alg2 != NULL)
558         X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ED448), V_ASN1_UNDEF, NULL);
559     /* Algorithm identifier set: carry on as normal */
560     return 3;
561 }
562
563 static int ecd_sig_info_set448(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
564                                const ASN1_STRING *sig)
565 {
566     X509_SIG_INFO_set(siginf, NID_undef, NID_ED448, X448_SECURITY_BITS,
567                       X509_SIG_INFO_TLS);
568     return 1;
569 }
570
571
572 const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = {
573     EVP_PKEY_ED25519,
574     EVP_PKEY_ED25519,
575     0,
576     "ED25519",
577     "OpenSSL ED25519 algorithm",
578
579     ecx_pub_decode,
580     ecx_pub_encode,
581     ecx_pub_cmp,
582     ecx_pub_print,
583
584     ecx_priv_decode,
585     ecx_priv_encode,
586     ecx_priv_print,
587
588     ecd_size25519,
589     ecx_bits,
590     ecx_security_bits,
591
592     0, 0, 0, 0,
593     ecx_cmp_parameters,
594     0, 0,
595
596     ecx_free,
597     ecd_ctrl,
598     NULL,
599     NULL,
600     ecd_item_verify,
601     ecd_item_sign25519,
602     ecd_sig_info_set25519,
603
604     NULL,
605     NULL,
606     NULL,
607
608     ecx_set_priv_key,
609     ecx_set_pub_key,
610     ecx_get_priv_key,
611     ecx_get_pub_key,
612 };
613
614 const EVP_PKEY_ASN1_METHOD ed448_asn1_meth = {
615     EVP_PKEY_ED448,
616     EVP_PKEY_ED448,
617     0,
618     "ED448",
619     "OpenSSL ED448 algorithm",
620
621     ecx_pub_decode,
622     ecx_pub_encode,
623     ecx_pub_cmp,
624     ecx_pub_print,
625
626     ecx_priv_decode,
627     ecx_priv_encode,
628     ecx_priv_print,
629
630     ecd_size448,
631     ecx_bits,
632     ecx_security_bits,
633
634     0, 0, 0, 0,
635     ecx_cmp_parameters,
636     0, 0,
637
638     ecx_free,
639     ecd_ctrl,
640     NULL,
641     NULL,
642     ecd_item_verify,
643     ecd_item_sign448,
644     ecd_sig_info_set448,
645
646     NULL,
647     NULL,
648     NULL,
649
650     ecx_set_priv_key,
651     ecx_set_pub_key,
652     ecx_get_priv_key,
653     ecx_get_pub_key,
654 };
655
656 static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
657 {
658     return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN);
659 }
660
661 static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
662                                           size_t *keylen,
663                                           const unsigned char **privkey,
664                                           const unsigned char **pubkey)
665 {
666     const ECX_KEY *ecxkey, *peerkey;
667
668     if (ctx->pkey == NULL || ctx->peerkey == NULL) {
669         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_KEYS_NOT_SET);
670         return 0;
671     }
672     ecxkey = ctx->pkey->pkey.ecx;
673     peerkey = ctx->peerkey->pkey.ecx;
674     if (ecxkey == NULL || ecxkey->privkey == NULL) {
675         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PRIVATE_KEY);
676         return 0;
677     }
678     if (peerkey == NULL) {
679         ECerr(EC_F_VALIDATE_ECX_DERIVE, EC_R_INVALID_PEER_KEY);
680         return 0;
681     }
682     *privkey = ecxkey->privkey;
683     *pubkey = peerkey->pubkey;
684
685     return 1;
686 }
687
688 static int pkey_ecx_derive25519(EVP_PKEY_CTX *ctx, unsigned char *key,
689                                 size_t *keylen)
690 {
691     const unsigned char *privkey, *pubkey;
692
693     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
694             || (key != NULL
695                 && X25519(key, privkey, pubkey) == 0))
696         return 0;
697     *keylen = X25519_KEYLEN;
698     return 1;
699 }
700
701 static int pkey_ecx_derive448(EVP_PKEY_CTX *ctx, unsigned char *key,
702                               size_t *keylen)
703 {
704     const unsigned char *privkey, *pubkey;
705
706     if (!validate_ecx_derive(ctx, key, keylen, &privkey, &pubkey)
707             || (key != NULL
708                 && X448(key, privkey, pubkey) == 0))
709         return 0;
710     *keylen = X448_KEYLEN;
711     return 1;
712 }
713
714 static int pkey_ecx_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
715 {
716     /* Only need to handle peer key for derivation */
717     if (type == EVP_PKEY_CTRL_PEER_KEY)
718         return 1;
719     return -2;
720 }
721
722 const EVP_PKEY_METHOD ecx25519_pkey_meth = {
723     EVP_PKEY_X25519,
724     0, 0, 0, 0, 0, 0, 0,
725     pkey_ecx_keygen,
726     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
727     pkey_ecx_derive25519,
728     pkey_ecx_ctrl,
729     0
730 };
731
732 const EVP_PKEY_METHOD ecx448_pkey_meth = {
733     EVP_PKEY_X448,
734     0, 0, 0, 0, 0, 0, 0,
735     pkey_ecx_keygen,
736     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
737     pkey_ecx_derive448,
738     pkey_ecx_ctrl,
739     0
740 };
741
742 static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
743                                     size_t *siglen, const unsigned char *tbs,
744                                     size_t tbslen)
745 {
746     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
747
748     if (sig == NULL) {
749         *siglen = ED25519_SIGSIZE;
750         return 1;
751     }
752     if (*siglen < ED25519_SIGSIZE) {
753         ECerr(EC_F_PKEY_ECD_DIGESTSIGN25519, EC_R_BUFFER_TOO_SMALL);
754         return 0;
755     }
756
757     if (ED25519_sign(sig, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0)
758         return 0;
759     *siglen = ED25519_SIGSIZE;
760     return 1;
761 }
762
763 static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
764                                   size_t *siglen, const unsigned char *tbs,
765                                   size_t tbslen)
766 {
767     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
768
769     if (sig == NULL) {
770         *siglen = ED448_SIGSIZE;
771         return 1;
772     }
773     if (*siglen < ED448_SIGSIZE) {
774         ECerr(EC_F_PKEY_ECD_DIGESTSIGN448, EC_R_BUFFER_TOO_SMALL);
775         return 0;
776     }
777
778     /*
779      * TODO(3.0): We use NULL for the library context for now. Will need to
780      * change later.
781      */
782     if (ED448_sign(NULL, sig, tbs, tbslen, edkey->pubkey, edkey->privkey,
783                    NULL, 0) == 0)
784         return 0;
785     *siglen = ED448_SIGSIZE;
786     return 1;
787 }
788
789 static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
790                                       size_t siglen, const unsigned char *tbs,
791                                       size_t tbslen)
792 {
793     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
794
795     if (siglen != ED25519_SIGSIZE)
796         return 0;
797
798     return ED25519_verify(tbs, tbslen, sig, edkey->pubkey);
799 }
800
801 static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
802                                     size_t siglen, const unsigned char *tbs,
803                                     size_t tbslen)
804 {
805     const ECX_KEY *edkey = EVP_MD_CTX_pkey_ctx(ctx)->pkey->pkey.ecx;
806
807     if (siglen != ED448_SIGSIZE)
808         return 0;
809
810     /*
811      * TODO(3.0): We send NULL for the OPENSSL_CTX for now. This will need to
812      * change.
813      */
814     return ED448_verify(NULL, tbs, tbslen, sig, edkey->pubkey, NULL, 0);
815 }
816
817 static int pkey_ecd_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
818 {
819     switch (type) {
820     case EVP_PKEY_CTRL_MD:
821         /* Only NULL allowed as digest */
822         if (p2 == NULL || (const EVP_MD *)p2 == EVP_md_null())
823             return 1;
824         ECerr(EC_F_PKEY_ECD_CTRL, EC_R_INVALID_DIGEST_TYPE);
825         return 0;
826
827     case EVP_PKEY_CTRL_DIGESTINIT:
828         return 1;
829     }
830     return -2;
831 }
832
833 const EVP_PKEY_METHOD ed25519_pkey_meth = {
834     EVP_PKEY_ED25519, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
835     0, 0, 0, 0, 0, 0,
836     pkey_ecx_keygen,
837     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
838     pkey_ecd_ctrl,
839     0,
840     pkey_ecd_digestsign25519,
841     pkey_ecd_digestverify25519
842 };
843
844 const EVP_PKEY_METHOD ed448_pkey_meth = {
845     EVP_PKEY_ED448, EVP_PKEY_FLAG_SIGCTX_CUSTOM,
846     0, 0, 0, 0, 0, 0,
847     pkey_ecx_keygen,
848     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
849     pkey_ecd_ctrl,
850     0,
851     pkey_ecd_digestsign448,
852     pkey_ecd_digestverify448
853 };