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