pk: Move s-expr creation for genkey to the modules.
[libgcrypt.git] / cipher / ecc.c
1 /* ecc.c  -  Elliptic Curve Cryptography
2  * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
3  * Copyright (C) 2013 g10 Code GmbH
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /* This code is originally based on the Patch 0.1.6 for the gnupg
22    1.4.x branch as retrieved on 2007-03-21 from
23    http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
24    The original authors are:
25      Written by
26       Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
27       Ramiro Moreno Chiral <ramiro at eup.udl.es>
28      Maintainers
29       Sergi Blanch i Torne
30       Ramiro Moreno Chiral
31       Mikael Mylnikov (mmr)
32   For use in Libgcrypt the code has been heavily modified and cleaned
33   up. In fact there is not much left of the orginally code except for
34   some variable names and the text book implementaion of the sign and
35   verification algorithms.  The arithmetic functions have entirely
36   been rewritten and moved to mpi/ec.c.
37
38   ECDH encrypt and decrypt code written by Andrey Jivsov,
39 */
40
41
42 /* TODO:
43
44   - If we support point compression we need to uncompress before
45     computing the keygrip
46
47   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
48     special case in mpi_powm or check whether mpi_mulm is faster.
49
50 */
51
52
53 #include <config.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <errno.h>
58
59 #include "g10lib.h"
60 #include "mpi.h"
61 #include "cipher.h"
62 #include "context.h"
63 #include "ec-context.h"
64 #include "pubkey-internal.h"
65 #include "ecc-common.h"
66
67
68 /* Registered progress function and its callback value. */
69 static void (*progress_cb) (void *, const char*, int, int, int);
70 static void *progress_cb_data;
71
72
73 #define point_init(a)  _gcry_mpi_point_init ((a))
74 #define point_free(a)  _gcry_mpi_point_free_parts ((a))
75
76 \f
77 /* Local prototypes. */
78 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
79 static int check_secret_key (ECC_secret_key * sk);
80 static gpg_err_code_t sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey,
81                                   gcry_mpi_t r, gcry_mpi_t s,
82                                   int flags, int hashalgo);
83 static gpg_err_code_t verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey,
84                                     gcry_mpi_t r, gcry_mpi_t s);
85
86 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
87
88
89
90 \f
91 void
92 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
93                                             int, int, int),
94                                 void *cb_data)
95 {
96   progress_cb = cb;
97   progress_cb_data = cb_data;
98 }
99
100 /* static void */
101 /* progress (int c) */
102 /* { */
103 /*   if (progress_cb) */
104 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
105 /* } */
106
107
108 \f
109
110 /*
111  * Solve the right side of the Weierstrass equation.
112  */
113 static gcry_mpi_t
114 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
115 {
116   gcry_mpi_t three, x_3, axb, y;
117
118   three = mpi_alloc_set_ui (3);
119   x_3 = mpi_new (0);
120   axb = mpi_new (0);
121   y   = mpi_new (0);
122
123   mpi_powm (x_3, x, three, base->p);
124   mpi_mulm (axb, base->a, x, base->p);
125   mpi_addm (axb, axb, base->b, base->p);
126   mpi_addm (y, x_3, axb, base->p);
127
128   mpi_free (x_3);
129   mpi_free (axb);
130   mpi_free (three);
131   return y; /* The quadratic value of the coordinate if it exist. */
132 }
133
134
135 /* Standard version of the key generation.  */
136 static gpg_err_code_t
137 nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
138                    gcry_random_level_t random_level, unsigned int nbits)
139 {
140   mpi_point_struct Q;
141
142   point_init (&Q);
143
144   /* Generate a secret.  */
145   sk->d = _gcry_dsa_gen_k (E->n, random_level);
146
147   /* Compute Q.  */
148   _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
149
150   /* Copy the stuff to the key structures. */
151   sk->E.model = E->model;
152   sk->E.dialect = E->dialect;
153   sk->E.p = mpi_copy (E->p);
154   sk->E.a = mpi_copy (E->a);
155   sk->E.b = mpi_copy (E->b);
156   point_init (&sk->E.G);
157   point_set (&sk->E.G, &E->G);
158   sk->E.n = mpi_copy (E->n);
159   point_init (&sk->Q);
160
161   /* We want the Q=(x,y) be a "compliant key" in terms of the
162    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
163    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
164    * end up with the min(y,p-y) as the y coordinate.  Such a public
165    * key allows the most efficient compression: y can simply be
166    * dropped because we know that it's a minimum of the two
167    * possibilities without any loss of security.  */
168   {
169     gcry_mpi_t x, y, p_y;
170     const unsigned int pbits = mpi_get_nbits (E->p);
171
172     x = mpi_new (pbits);
173     y = mpi_new (pbits);
174     p_y = mpi_new (pbits);
175
176     if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
177       log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
178
179     mpi_sub (p_y, E->p, y);     /* p_y = p - y */
180
181     if (mpi_cmp (p_y, y) < 0)   /* p - y < p */
182       {
183         /* We need to end up with -Q; this assures that new Q's y is
184            the smallest one */
185         mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
186         gcry_mpi_point_snatch_set (&sk->Q, x, p_y, mpi_alloc_set_ui (1));
187
188       if (DBG_CIPHER)
189         log_debug ("ecgen converted Q to a compliant point\n");
190       }
191     else /* p - y >= p */
192       {
193         /* No change is needed exactly 50% of the time: just copy. */
194         point_set (&sk->Q, &Q);
195         if (DBG_CIPHER)
196           log_debug ("ecgen didn't need to convert Q to a compliant point\n");
197
198         mpi_free (p_y);
199         mpi_free (x);
200       }
201     mpi_free (y);
202   }
203
204   /* Now we can test our keys (this should never fail!).  */
205   test_keys (sk, nbits - 64);
206
207   return 0;
208 }
209
210
211 /*
212  * To verify correct skey it use a random information.
213  * First, encrypt and decrypt this dummy value,
214  * test if the information is recuperated.
215  * Second, test with the sign and verify functions.
216  */
217 static void
218 test_keys (ECC_secret_key *sk, unsigned int nbits)
219 {
220   ECC_public_key pk;
221   gcry_mpi_t test = mpi_new (nbits);
222   mpi_point_struct R_;
223   gcry_mpi_t c = mpi_new (nbits);
224   gcry_mpi_t out = mpi_new (nbits);
225   gcry_mpi_t r = mpi_new (nbits);
226   gcry_mpi_t s = mpi_new (nbits);
227
228   if (DBG_CIPHER)
229     log_debug ("Testing key.\n");
230
231   point_init (&R_);
232
233   pk.E = _gcry_ecc_curve_copy (sk->E);
234   point_init (&pk.Q);
235   point_set (&pk.Q, &sk->Q);
236
237   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
238
239   if (sign_ecdsa (test, sk, r, s, 0, 0) )
240     log_fatal ("ECDSA operation: sign failed\n");
241
242   if (verify_ecdsa (test, &pk, r, s))
243     {
244       log_fatal ("ECDSA operation: sign, verify failed\n");
245     }
246
247   if (DBG_CIPHER)
248     log_debug ("ECDSA operation: sign, verify ok.\n");
249
250   point_free (&pk.Q);
251   _gcry_ecc_curve_free (&pk.E);
252
253   point_free (&R_);
254   mpi_free (s);
255   mpi_free (r);
256   mpi_free (out);
257   mpi_free (c);
258   mpi_free (test);
259 }
260
261
262 /*
263  * To check the validity of the value, recalculate the correspondence
264  * between the public value and the secret one.
265  */
266 static int
267 check_secret_key (ECC_secret_key * sk)
268 {
269   int rc = 1;
270   mpi_point_struct Q;
271   gcry_mpi_t y_2, y2;
272   gcry_mpi_t x1, x2;
273   mpi_ec_t ctx = NULL;
274
275   point_init (&Q);
276
277   /* ?primarity test of 'p' */
278   /*  (...) //!! */
279   /* G in E(F_p) */
280   y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
281   y2 = mpi_alloc (0);
282   x1 = mpi_alloc (0);
283   x2 = mpi_alloc (0);
284   mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
285   if (mpi_cmp (y_2, y2))
286     {
287       if (DBG_CIPHER)
288         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
289       goto leave;
290     }
291   /* G != PaI */
292   if (!mpi_cmp_ui (sk->E.G.z, 0))
293     {
294       if (DBG_CIPHER)
295         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
296       goto leave;
297     }
298
299   ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect,
300                                      sk->E.p, sk->E.a, sk->E.b);
301
302   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
303   if (mpi_cmp_ui (Q.z, 0))
304     {
305       if (DBG_CIPHER)
306         log_debug ("check_secret_key: E is not a curve of order n\n");
307       goto leave;
308     }
309   /* pubkey cannot be PaI */
310   if (!mpi_cmp_ui (sk->Q.z, 0))
311     {
312       if (DBG_CIPHER)
313         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
314       goto leave;
315     }
316   /* pubkey = [d]G over E */
317   _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
318
319   if (_gcry_mpi_ec_get_affine (x1, y_2, &Q, ctx))
320     {
321       if (DBG_CIPHER)
322         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
323       goto leave;
324     }
325
326   /* Fast path for loaded secret keys - Q is already in affine coordinates */
327   if (!mpi_cmp_ui (sk->Q.z, 1))
328     {
329       if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y_2, sk->Q.y))
330         {
331           if (DBG_CIPHER)
332             log_debug
333               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
334           goto leave;
335         }
336     }
337   else
338     {
339       if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ctx))
340         {
341           if (DBG_CIPHER)
342             log_debug ("Bad check: Q can not be a Point at Infinity!\n");
343           goto leave;
344         }
345
346       if (mpi_cmp (x1, x2) || mpi_cmp (y_2, y2))
347         {
348           if (DBG_CIPHER)
349             log_debug
350               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
351           goto leave;
352         }
353     }
354   rc = 0; /* Okay.  */
355
356  leave:
357   _gcry_mpi_ec_free (ctx);
358   mpi_free (x2);
359   mpi_free (x1);
360   mpi_free (y2);
361   mpi_free (y_2);
362   point_free (&Q);
363   return rc;
364 }
365
366
367 /* Compute an ECDSA signature.
368  * Return the signature struct (r,s) from the message hash.  The caller
369  * must have allocated R and S.
370  */
371 static gpg_err_code_t
372 sign_ecdsa (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s,
373             int flags, int hashalgo)
374 {
375   gpg_err_code_t err = 0;
376   int extraloops = 0;
377   gcry_mpi_t k, dr, sum, k_1, x;
378   mpi_point_struct I;
379   gcry_mpi_t hash;
380   const void *abuf;
381   unsigned int abits, qbits;
382   mpi_ec_t ctx;
383
384   if (DBG_CIPHER)
385     log_mpidump ("ecdsa sign hash  ", input );
386
387   qbits = mpi_get_nbits (skey->E.n);
388
389   /* Convert the INPUT into an MPI if needed.  */
390   if (mpi_is_opaque (input))
391     {
392       abuf = gcry_mpi_get_opaque (input, &abits);
393       err = gpg_err_code (gcry_mpi_scan (&hash, GCRYMPI_FMT_USG,
394                                          abuf, (abits+7)/8, NULL));
395       if (err)
396         return err;
397       if (abits > qbits)
398         gcry_mpi_rshift (hash, hash, abits - qbits);
399     }
400   else
401     hash = input;
402
403
404   k = NULL;
405   dr = mpi_alloc (0);
406   sum = mpi_alloc (0);
407   k_1 = mpi_alloc (0);
408   x = mpi_alloc (0);
409   point_init (&I);
410
411   mpi_set_ui (s, 0);
412   mpi_set_ui (r, 0);
413
414   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
415                                      skey->E.p, skey->E.a, skey->E.b);
416
417   while (!mpi_cmp_ui (s, 0)) /* s == 0 */
418     {
419       while (!mpi_cmp_ui (r, 0)) /* r == 0 */
420         {
421           /* Note, that we are guaranteed to enter this loop at least
422              once because r has been intialized to 0.  We can't use a
423              do_while because we want to keep the value of R even if S
424              has to be recomputed.  */
425
426           mpi_free (k);
427           k = NULL;
428           if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
429             {
430               /* Use Pornin's method for deterministic DSA.  If this
431                  flag is set, it is expected that HASH is an opaque
432                  MPI with the to be signed hash.  That hash is also
433                  used as h1 from 3.2.a.  */
434               if (!mpi_is_opaque (input))
435                 {
436                   err = GPG_ERR_CONFLICT;
437                   goto leave;
438                 }
439
440               abuf = gcry_mpi_get_opaque (input, &abits);
441               err = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
442                                              abuf, (abits+7)/8,
443                                              hashalgo, extraloops);
444               if (err)
445                 goto leave;
446               extraloops++;
447             }
448           else
449             k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
450
451           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
452           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
453             {
454               if (DBG_CIPHER)
455                 log_debug ("ecc sign: Failed to get affine coordinates\n");
456               err = GPG_ERR_BAD_SIGNATURE;
457               goto leave;
458             }
459           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
460         }
461       mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
462       mpi_addm (sum, hash, dr, skey->E.n);  /* sum = hash + (d*r) mod n  */
463       mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
464       mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
465     }
466
467   if (DBG_CIPHER)
468     {
469       log_mpidump ("ecdsa sign result r ", r);
470       log_mpidump ("ecdsa sign result s ", s);
471     }
472
473  leave:
474   _gcry_mpi_ec_free (ctx);
475   point_free (&I);
476   mpi_free (x);
477   mpi_free (k_1);
478   mpi_free (sum);
479   mpi_free (dr);
480   mpi_free (k);
481
482   if (hash != input)
483     mpi_free (hash);
484
485   return err;
486 }
487
488
489 /* Verify an ECDSA signature.
490  * Check if R and S verifies INPUT.
491  */
492 static gpg_err_code_t
493 verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey,
494               gcry_mpi_t r, gcry_mpi_t s)
495 {
496   gpg_err_code_t err = 0;
497   gcry_mpi_t h, h1, h2, x;
498   mpi_point_struct Q, Q1, Q2;
499   mpi_ec_t ctx;
500
501   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
502     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < r < n  failed.  */
503   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
504     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < s < n  failed.  */
505
506   h  = mpi_alloc (0);
507   h1 = mpi_alloc (0);
508   h2 = mpi_alloc (0);
509   x = mpi_alloc (0);
510   point_init (&Q);
511   point_init (&Q1);
512   point_init (&Q2);
513
514   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
515                                      pkey->E.p, pkey->E.a, pkey->E.b);
516
517   /* h  = s^(-1) (mod n) */
518   mpi_invm (h, s, pkey->E.n);
519   /* h1 = hash * s^(-1) (mod n) */
520   mpi_mulm (h1, input, h, pkey->E.n);
521   /* Q1 = [ hash * s^(-1) ]G  */
522   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
523   /* h2 = r * s^(-1) (mod n) */
524   mpi_mulm (h2, r, h, pkey->E.n);
525   /* Q2 = [ r * s^(-1) ]Q */
526   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
527   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
528   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
529
530   if (!mpi_cmp_ui (Q.z, 0))
531     {
532       if (DBG_CIPHER)
533           log_debug ("ecc verify: Rejected\n");
534       err = GPG_ERR_BAD_SIGNATURE;
535       goto leave;
536     }
537   if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
538     {
539       if (DBG_CIPHER)
540         log_debug ("ecc verify: Failed to get affine coordinates\n");
541       err = GPG_ERR_BAD_SIGNATURE;
542       goto leave;
543     }
544   mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
545   if (mpi_cmp (x, r))   /* x != r */
546     {
547       if (DBG_CIPHER)
548         {
549           log_mpidump ("     x", x);
550           log_mpidump ("     r", r);
551           log_mpidump ("     s", s);
552           log_debug ("ecc verify: Not verified\n");
553         }
554       err = GPG_ERR_BAD_SIGNATURE;
555       goto leave;
556     }
557   if (DBG_CIPHER)
558     log_debug ("ecc verify: Accepted\n");
559
560  leave:
561   _gcry_mpi_ec_free (ctx);
562   point_free (&Q2);
563   point_free (&Q1);
564   point_free (&Q);
565   mpi_free (x);
566   mpi_free (h2);
567   mpi_free (h1);
568   mpi_free (h);
569   return err;
570 }
571
572
573 \f
574 static void
575 reverse_buffer (unsigned char *buffer, unsigned int length)
576 {
577   unsigned int tmp, i;
578
579   for (i=0; i < length/2; i++)
580     {
581       tmp = buffer[i];
582       buffer[i] = buffer[length-1-i];
583       buffer[length-1-i] = tmp;
584     }
585 }
586
587
588 /* Encode MPI using the EdDSA scheme.  MINLEN specifies the required
589    length of the buffer in bytes.  On success 0 is returned an a
590    malloced buffer with the encoded point is stored at R_BUFFER; the
591    length of this buffer is stored at R_BUFLEN.  */
592 static gpg_err_code_t
593 eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen,
594                  unsigned char **r_buffer, unsigned int *r_buflen)
595 {
596   unsigned char *rawmpi;
597   unsigned int rawmpilen;
598
599   rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
600   if (!rawmpi)
601     return gpg_err_code_from_syserror ();
602
603   *r_buffer = rawmpi;
604   *r_buflen = rawmpilen;
605   return 0;
606 }
607
608
609 /* Encode POINT using the EdDSA scheme.  X and Y are scratch variables
610    supplied by the caller and CTX is the usual context.  MINLEN is the
611    required length in bytes for the result. On success 0 is returned
612    an a malloced buffer with the encoded point is stored at R_BUFFER;
613    the length of this buffer is stored at R_BUFLEN.  */
614 static gpg_err_code_t
615 eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx,
616                    gcry_mpi_t x, gcry_mpi_t y,
617                    unsigned char **r_buffer, unsigned int *r_buflen)
618 {
619   unsigned char *rawmpi;
620   unsigned int rawmpilen;
621
622   if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
623     {
624       log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
625       return GPG_ERR_INTERNAL;
626     }
627   rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
628   if (!rawmpi)
629     return gpg_err_code_from_syserror ();
630   if (mpi_test_bit (x, 0) && rawmpilen)
631     rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
632
633   *r_buffer = rawmpi;
634   *r_buflen = rawmpilen;
635   return 0;
636 }
637
638
639 /* Decode the EdDSA style encoded PK and set it into RESULT.  LEN is
640    the expected length in bytes of the encoded key and CTX the usual
641    curve context.  If R_ENCPK is not NULL, the encoded PK is stored at
642    that address; this is a new copy to be release by the caller.  In
643    contrast to the supplied PK, this is not an MPI and thus guarnteed
644    to be properly padded.  R_ENCPKLEN received the length of that
645    encoded key.  */
646 static gpg_err_code_t
647 eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx,
648                    mpi_point_t result,
649                    unsigned char **r_encpk, unsigned int *r_encpklen)
650 {
651   unsigned char *rawmpi;
652   unsigned int rawmpilen;
653   gcry_mpi_t yy, t, x, p1, p2, p3;
654   int sign;
655
656   if (mpi_is_opaque (pk))
657     {
658       const void *buf;
659
660       buf = gcry_mpi_get_opaque (pk, &rawmpilen);
661       if (!buf)
662         return GPG_ERR_INV_OBJ;
663       rawmpilen = (rawmpilen + 7)/8;
664       rawmpi = gcry_malloc (rawmpilen? rawmpilen:1);
665       if (!rawmpi)
666         return gpg_err_code_from_syserror ();
667       memcpy (rawmpi, buf, rawmpilen);
668       reverse_buffer (rawmpi, rawmpilen);
669     }
670   else
671     {
672       rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL);
673       if (!rawmpi)
674         return gpg_err_code_from_syserror ();
675     }
676
677   if (rawmpilen)
678     {
679       sign = !!(rawmpi[0] & 0x80);
680       rawmpi[0] &= 0x7f;
681     }
682   else
683     sign = 0;
684   _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
685   if (r_encpk)
686     {
687       /* Revert to little endian.  */
688       if (sign && rawmpilen)
689         rawmpi[0] |= 0x80;
690       reverse_buffer (rawmpi, rawmpilen);
691       *r_encpk = rawmpi;
692       if (r_encpklen)
693         *r_encpklen = rawmpilen;
694     }
695   else
696     gcry_free (rawmpi);
697
698   /* Now recover X.  */
699   /* t = (y^2-1) · ((b*y^2+1)^{p-2} mod p) */
700   x = mpi_new (0);
701   yy = mpi_new (0);
702   mpi_mul (yy, result->y, result->y);
703   t = mpi_copy (yy);
704   mpi_mul (t, t, ctx->b);
705   mpi_add_ui (t, t, 1);
706   p2 = mpi_copy (ctx->p);
707   mpi_sub_ui (p2, p2, 2);
708   mpi_powm (t, t, p2, ctx->p);
709
710   mpi_sub_ui (yy, yy, 1);
711   mpi_mul (t, yy, t);
712
713   /* x = t^{(p+3)/8} mod p */
714   p3 = mpi_copy (ctx->p);
715   mpi_add_ui (p3, p3, 3);
716   mpi_fdiv_q (p3, p3, mpi_const (MPI_C_EIGHT));
717   mpi_powm (x, t, p3, ctx->p);
718
719   /* (x^2 - t) % p != 0 ? x = (x*(2^{(p-1)/4} mod p)) % p */
720   mpi_mul (yy, x, x);
721   mpi_subm (yy, yy, t, ctx->p);
722   if (mpi_cmp_ui (yy, 0))
723     {
724       p1 = mpi_copy (ctx->p);
725       mpi_sub_ui (p1, p1, 1);
726       mpi_fdiv_q (p1, p1, mpi_const (MPI_C_FOUR));
727       mpi_powm (yy, mpi_const (MPI_C_TWO), p1, ctx->p);
728       mpi_mulm (x, x, yy, ctx->p);
729     }
730   else
731     p1 = NULL;
732
733   /* is_odd(x) ? x = p-x */
734   if (mpi_test_bit (x, 0))
735     mpi_sub (x, ctx->p, x);
736
737   /* lowbit(x) != highbit(input) ?  x = p-x */
738   if (mpi_test_bit (x, 0) != sign)
739     mpi_sub (x, ctx->p, x);
740
741   mpi_set (result->x, x);
742   mpi_set_ui (result->z, 1);
743
744   gcry_mpi_release (x);
745   gcry_mpi_release (yy);
746   gcry_mpi_release (t);
747   gcry_mpi_release (p3);
748   gcry_mpi_release (p2);
749   gcry_mpi_release (p1);
750
751   return 0;
752 }
753
754
755 /* Ed25519 version of the key generation.  */
756 static gpg_err_code_t
757 eddsa_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
758                     gcry_random_level_t random_level)
759 {
760   gpg_err_code_t rc;
761   int b = 256/8;             /* The only size we currently support.  */
762   gcry_mpi_t a, x, y;
763   mpi_point_struct Q;
764   char *dbuf;
765   size_t dlen;
766   gcry_buffer_t hvec[1];
767   unsigned char *hash_d = NULL;
768
769   point_init (&Q);
770   memset (hvec, 0, sizeof hvec);
771
772   a = mpi_snew (0);
773   x = mpi_new (0);
774   y = mpi_new (0);
775
776   /* Generate a secret.  */
777   hash_d = gcry_malloc_secure (2*b);
778   if (!hash_d)
779     {
780       rc = gpg_error_from_syserror ();
781       goto leave;
782     }
783   dlen = b;
784   dbuf = gcry_random_bytes_secure (dlen, random_level);
785
786   /* Compute the A value.  */
787   hvec[0].data = dbuf;
788   hvec[0].len = dlen;
789   rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
790   if (rc)
791     goto leave;
792   sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
793   dbuf = NULL;
794   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
795   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
796   hash_d[31] &= 0xf8;
797   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
798   gcry_free (hash_d); hash_d = NULL;
799   /* log_printmpi ("ecgen         a", a); */
800
801   /* Compute Q.  */
802   _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
803   if (DBG_CIPHER)
804     log_printpnt ("ecgen      pk", &Q, ctx);
805
806   /* Copy the stuff to the key structures. */
807   sk->E.model = E->model;
808   sk->E.dialect = E->dialect;
809   sk->E.p = mpi_copy (E->p);
810   sk->E.a = mpi_copy (E->a);
811   sk->E.b = mpi_copy (E->b);
812   point_init (&sk->E.G);
813   point_set (&sk->E.G, &E->G);
814   sk->E.n = mpi_copy (E->n);
815   point_init (&sk->Q);
816   point_set (&sk->Q, &Q);
817
818  leave:
819   gcry_mpi_release (a);
820   gcry_mpi_release (x);
821   gcry_mpi_release (y);
822   gcry_free (hash_d);
823   return rc;
824 }
825
826
827 /* Compute an EdDSA signature. See:
828  *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
829  *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
830  *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
831  *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
832  *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
833  *
834  * Despite that this function requires the specification of a hash
835  * algorithm, we only support what has been specified by the paper.
836  * This may change in the future.  Note that we don't check the used
837  * curve; the user is responsible to use Ed25519.
838  *
839  * Return the signature struct (r,s) from the message hash.  The caller
840  * must have allocated R_R and S.
841  */
842 static gpg_err_code_t
843 sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
844             gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
845 {
846   int rc;
847   mpi_ec_t ctx = NULL;
848   int b = 256/8;             /* The only size we currently support.  */
849   unsigned int tmp;
850   unsigned char hash_d[64];  /* Fixme: malloc in secure memory */
851   unsigned char digest[64];
852   gcry_buffer_t hvec[3];
853   const void *mbuf;
854   size_t mlen;
855   unsigned char *rawmpi = NULL;
856   unsigned int rawmpilen;
857   unsigned char *encpk = NULL; /* Encoded public key.  */
858   unsigned int encpklen;
859   mpi_point_struct I;          /* Intermediate value.  */
860   mpi_point_struct Q;          /* Public key.  */
861   gcry_mpi_t a, x, y, r;
862
863   memset (hvec, 0, sizeof hvec);
864
865   if (!mpi_is_opaque (input))
866     return GPG_ERR_INV_DATA;
867   if (hashalgo != GCRY_MD_SHA512)
868     return GPG_ERR_DIGEST_ALGO;
869
870   /* Initialize some helpers.  */
871   point_init (&I);
872   point_init (&Q);
873   a = mpi_snew (0);
874   x = mpi_new (0);
875   y = mpi_new (0);
876   r = mpi_new (0);
877   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
878                                      skey->E.p, skey->E.a, skey->E.b);
879
880   /* Hash the secret key.  We clear DIGEST so we can use it to left
881      pad the key with zeroes for hashing.  */
882   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
883   if (!rawmpi)
884     {
885       rc = gpg_err_code_from_syserror ();
886       goto leave;
887     }
888   memset (digest, 0, b);
889   hvec[0].data = digest;
890   hvec[0].off = 0;
891   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
892   hvec[1].data = rawmpi;
893   hvec[1].off = 0;
894   hvec[1].len = rawmpilen;
895   rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2);
896   gcry_free (rawmpi); rawmpi = NULL;
897   if (rc)
898     goto leave;
899
900   /* Compute the A value (this modifies hash_d).  */
901   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
902   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
903   hash_d[31] &= 0xf8;
904   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
905   /* log_printmpi ("     a", a); */
906
907   /* Compute the public key if it has not been supplied as optional
908      parameter.  */
909   if (pk)
910     {
911       rc = eddsa_decodepoint (pk, b, ctx, &Q,  &encpk, &encpklen);
912       if (rc)
913         goto leave;
914       if (DBG_CIPHER)
915         log_printhex ("* e_pk", encpk, encpklen);
916       if (!_gcry_mpi_ec_curve_point (&Q, ctx))
917         {
918           rc = GPG_ERR_BROKEN_PUBKEY;
919           goto leave;
920         }
921     }
922   else
923     {
924       _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
925       rc = eddsa_encodepoint (&Q, b, ctx, x, y, &encpk, &encpklen);
926       if (rc)
927         goto leave;
928       if (DBG_CIPHER)
929         log_printhex ("  e_pk", encpk, encpklen);
930     }
931
932   /* Compute R.  */
933   mbuf = gcry_mpi_get_opaque (input, &tmp);
934   mlen = (tmp +7)/8;
935   if (DBG_CIPHER)
936     log_printhex ("     m", mbuf, mlen);
937
938   hvec[0].data = hash_d;
939   hvec[0].off  = 32;
940   hvec[0].len  = 32;
941   hvec[1].data = (char*)mbuf;
942   hvec[1].len  = mlen;
943   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
944   if (rc)
945     goto leave;
946   reverse_buffer (digest, 64);
947   if (DBG_CIPHER)
948     log_printhex ("     r", digest, 64);
949   _gcry_mpi_set_buffer (r, digest, 64, 0);
950   _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
951   if (DBG_CIPHER)
952     log_printpnt ("   r", &I, ctx);
953
954   /* Convert R into affine coordinates and apply encoding.  */
955   rc = eddsa_encodepoint (&I, b, ctx, x, y, &rawmpi, &rawmpilen);
956   if (rc)
957     goto leave;
958   if (DBG_CIPHER)
959     log_printhex ("   e_r", rawmpi, rawmpilen);
960
961   /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
962   hvec[0].data = rawmpi;  /* (this is R) */
963   hvec[0].off  = 0;
964   hvec[0].len  = rawmpilen;
965   hvec[1].data = encpk;
966   hvec[1].off  = 0;
967   hvec[1].len  = encpklen;
968   hvec[2].data = (char*)mbuf;
969   hvec[2].off  = 0;
970   hvec[2].len  = mlen;
971   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
972   if (rc)
973     goto leave;
974
975   /* No more need for RAWMPI thus we now transfer it to R_R.  */
976   gcry_mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
977   rawmpi = NULL;
978
979   reverse_buffer (digest, 64);
980   if (DBG_CIPHER)
981     log_printhex (" H(R+)", digest, 64);
982   _gcry_mpi_set_buffer (s, digest, 64, 0);
983   mpi_mulm (s, s, a, skey->E.n);
984   mpi_addm (s, s, r, skey->E.n);
985   rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
986   if (rc)
987     goto leave;
988   if (DBG_CIPHER)
989     log_printhex ("   e_s", rawmpi, rawmpilen);
990   gcry_mpi_set_opaque (s, rawmpi, rawmpilen*8);
991   rawmpi = NULL;
992
993   rc = 0;
994
995  leave:
996   gcry_mpi_release (a);
997   gcry_mpi_release (x);
998   gcry_mpi_release (y);
999   gcry_mpi_release (r);
1000   _gcry_mpi_ec_free (ctx);
1001   point_free (&I);
1002   point_free (&Q);
1003   gcry_free (encpk);
1004   gcry_free (rawmpi);
1005   return rc;
1006 }
1007
1008
1009 /* Verify an EdDSA signature.  See sign_eddsa for the reference.
1010  * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
1011  * parameters and PK is the EdDSA style encoded public key.
1012  */
1013 static gpg_err_code_t
1014 verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
1015               gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo, gcry_mpi_t pk)
1016 {
1017   int rc;
1018   mpi_ec_t ctx = NULL;
1019   int b = 256/8;               /* The only size we currently support.  */
1020   unsigned int tmp;
1021   mpi_point_struct Q;          /* Public key.  */
1022   unsigned char *encpk = NULL; /* Encoded public key.  */
1023   unsigned int encpklen;
1024   const void *mbuf, *rbuf;
1025   unsigned char *tbuf = NULL;
1026   size_t mlen, rlen;
1027   unsigned int tlen;
1028   unsigned char digest[64];
1029   gcry_buffer_t hvec[3];
1030   gcry_mpi_t h, s;
1031   mpi_point_struct Ia, Ib;
1032
1033   if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
1034     return GPG_ERR_INV_DATA;
1035   if (hashalgo != GCRY_MD_SHA512)
1036     return GPG_ERR_DIGEST_ALGO;
1037
1038   point_init (&Q);
1039   point_init (&Ia);
1040   point_init (&Ib);
1041   h = mpi_new (0);
1042   s = mpi_new (0);
1043
1044   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
1045                                      pkey->E.p, pkey->E.a, pkey->E.b);
1046
1047   /* Decode and check the public key.  */
1048   rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen);
1049   if (rc)
1050     goto leave;
1051   if (!_gcry_mpi_ec_curve_point (&Q, ctx))
1052     {
1053       rc = GPG_ERR_BROKEN_PUBKEY;
1054       goto leave;
1055     }
1056   if (DBG_CIPHER)
1057     log_printhex ("  e_pk", encpk, encpklen);
1058   if (encpklen != b)
1059     {
1060       rc = GPG_ERR_INV_LENGTH;
1061       goto leave;
1062     }
1063
1064   /* Convert the other input parameters.  */
1065   mbuf = gcry_mpi_get_opaque (input, &tmp);
1066   mlen = (tmp +7)/8;
1067   if (DBG_CIPHER)
1068     log_printhex ("     m", mbuf, mlen);
1069   rbuf = gcry_mpi_get_opaque (r_in, &tmp);
1070   rlen = (tmp +7)/8;
1071   if (DBG_CIPHER)
1072     log_printhex ("     r", rbuf, rlen);
1073   if (rlen != b)
1074     {
1075       rc = GPG_ERR_INV_LENGTH;
1076       goto leave;
1077     }
1078
1079   /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
1080   hvec[0].data = (char*)rbuf;
1081   hvec[0].off  = 0;
1082   hvec[0].len  = rlen;
1083   hvec[1].data = encpk;
1084   hvec[1].off  = 0;
1085   hvec[1].len  = encpklen;
1086   hvec[2].data = (char*)mbuf;
1087   hvec[2].off  = 0;
1088   hvec[2].len  = mlen;
1089   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1090   if (rc)
1091     goto leave;
1092   reverse_buffer (digest, 64);
1093   if (DBG_CIPHER)
1094     log_printhex (" H(R+)", digest, 64);
1095   _gcry_mpi_set_buffer (h, digest, 64, 0);
1096
1097   /* According to the paper the best way for verification is:
1098          encodepoint(sG - h·Q) = encodepoint(r)
1099      because we don't need to decode R. */
1100   {
1101     void *sbuf;
1102     unsigned int slen;
1103
1104     sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
1105     slen = (tmp +7)/8;
1106     reverse_buffer (sbuf, slen);
1107     if (DBG_CIPHER)
1108       log_printhex ("     s", sbuf, slen);
1109     _gcry_mpi_set_buffer (s, sbuf, slen, 0);
1110     gcry_free (sbuf);
1111     if (slen != b)
1112       {
1113         rc = GPG_ERR_INV_LENGTH;
1114         goto leave;
1115       }
1116   }
1117
1118   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
1119   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
1120   _gcry_mpi_neg (Ib.x, Ib.x);
1121   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
1122   rc = eddsa_encodepoint (&Ia, b, ctx, s, h, &tbuf, &tlen);
1123   if (rc)
1124     goto leave;
1125   if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
1126     {
1127       if (DBG_CIPHER)
1128         log_debug ("eddsa verify: Not verified\n");
1129       rc = GPG_ERR_BAD_SIGNATURE;
1130       goto leave;
1131     }
1132
1133   if (DBG_CIPHER)
1134     log_debug ("eddsa verify: Accepted\n");
1135   rc = 0;
1136
1137  leave:
1138   gcry_free (encpk);
1139   gcry_free (tbuf);
1140   _gcry_mpi_ec_free (ctx);
1141   gcry_mpi_release (s);
1142   gcry_mpi_release (h);
1143   point_free (&Ia);
1144   point_free (&Ib);
1145   point_free (&Q);
1146   return rc;
1147 }
1148
1149
1150 \f
1151 /*********************************************
1152  **************  interface  ******************
1153  *********************************************/
1154
1155 static gcry_err_code_t
1156 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1157               const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
1158 {
1159   gpg_err_code_t rc;
1160   elliptic_curve_t E;
1161   ECC_secret_key sk;
1162   gcry_mpi_t x = NULL;
1163   gcry_mpi_t y = NULL;
1164   char *curve_name = NULL;
1165   gcry_sexp_t l1;
1166   int transient_key = 0;
1167   gcry_random_level_t random_level;
1168   mpi_ec_t ctx = NULL;
1169   gcry_sexp_t curve_info = NULL;
1170   gcry_mpi_t base = NULL;
1171   gcry_mpi_t public = NULL;
1172   gcry_mpi_t secret = NULL;
1173
1174   (void)algo;
1175   (void)evalue;
1176
1177   memset (&E, 0, sizeof E);
1178   memset (&sk, 0, sizeof sk);
1179
1180   if (genparms)
1181     {
1182       /* Parse the optional "curve" parameter. */
1183       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1184       if (l1)
1185         {
1186           curve_name = _gcry_sexp_nth_string (l1, 1);
1187           gcry_sexp_release (l1);
1188           if (!curve_name)
1189             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1190         }
1191
1192       /* Parse the optional transient-key flag.  */
1193       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1194       if (l1)
1195         {
1196           transient_key = 1;
1197           gcry_sexp_release (l1);
1198         }
1199     }
1200
1201   /* NBITS is required if no curve name has been given.  */
1202   if (!nbits && !curve_name)
1203     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1204
1205   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
1206   gcry_free (curve_name); curve_name = NULL;
1207   if (rc)
1208     goto leave;
1209
1210   if (DBG_CIPHER)
1211     {
1212       log_debug ("ecgen curve info: %s/%s\n",
1213                  _gcry_ecc_model2str (E.model),
1214                  _gcry_ecc_dialect2str (E.dialect));
1215       if (E.name)
1216         log_debug ("ecgen curve used: %s\n", E.name);
1217       log_printmpi ("ecgen curve   p", E.p);
1218       log_printmpi ("ecgen curve   a", E.a);
1219       log_printmpi ("ecgen curve   b", E.b);
1220       log_printmpi ("ecgen curve   n", E.n);
1221       log_printpnt ("ecgen curve G", &E.G, NULL);
1222     }
1223
1224   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
1225   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
1226   x = mpi_new (0);
1227   y = mpi_new (0);
1228
1229   switch (E.dialect)
1230     {
1231     case ECC_DIALECT_STANDARD:
1232       rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
1233       break;
1234     case ECC_DIALECT_ED25519:
1235       rc = eddsa_generate_key (&sk, &E, ctx, random_level);
1236       break;
1237     default:
1238       rc = GPG_ERR_INTERNAL;
1239       break;
1240     }
1241   if (rc)
1242     goto leave;
1243
1244   /* Copy data to the result.  */
1245   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
1246     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
1247   base = _gcry_ecc_ec2os (x, y, sk.E.p);
1248   if (sk.E.dialect == ECC_DIALECT_ED25519)
1249     {
1250       unsigned char *encpk;
1251       unsigned int encpklen;
1252
1253       rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
1254       if (rc)
1255         return rc;
1256       public = mpi_new (0);
1257       gcry_mpi_set_opaque (public, encpk, encpklen*8);
1258       encpk = NULL;
1259     }
1260   else
1261     {
1262       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
1263         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
1264       public = _gcry_ecc_ec2os (x, y, sk.E.p);
1265     }
1266   secret = sk.d; sk.d = NULL;
1267   if (E.name)
1268     {
1269       rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
1270       if (rc)
1271         goto leave;
1272     }
1273
1274   rc = gcry_err_code (gcry_sexp_build
1275                       (r_skey, NULL,
1276                        "(key-data"
1277                        " (public-key"
1278                        "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
1279                        " (private-key"
1280                        "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
1281                        " )",
1282                        curve_info,
1283                        sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
1284                        curve_info,
1285                        sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret));
1286   if (rc)
1287     goto leave;
1288
1289   if (DBG_CIPHER)
1290     {
1291       log_printmpi ("ecgen result  p", sk.E.p);
1292       log_printmpi ("ecgen result  a", sk.E.a);
1293       log_printmpi ("ecgen result  b", sk.E.b);
1294       log_printmpi ("ecgen result  G", base);
1295       log_printmpi ("ecgen result  n", sk.E.n);
1296       log_printmpi ("ecgen result  Q", public);
1297       log_printmpi ("ecgen result  d", secret);
1298     }
1299
1300  leave:
1301   mpi_free (secret);
1302   mpi_free (public);
1303   mpi_free (base);
1304   {
1305     _gcry_ecc_curve_free (&sk.E);
1306     point_free (&sk.Q);
1307     mpi_free (sk.d);
1308   }
1309   _gcry_ecc_curve_free (&E);
1310   mpi_free (x);
1311   mpi_free (y);
1312   _gcry_mpi_ec_free (ctx);
1313   gcry_sexp_release (curve_info);
1314   return rc;
1315 }
1316
1317
1318 static gcry_err_code_t
1319 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1320 {
1321   gpg_err_code_t err;
1322   ECC_secret_key sk;
1323
1324   (void)algo;
1325
1326   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1327   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1328       || !skey[6])
1329     return GPG_ERR_BAD_MPI;
1330
1331   sk.E.model = MPI_EC_WEIERSTRASS;
1332   sk.E.p = skey[0];
1333   sk.E.a = skey[1];
1334   sk.E.b = skey[2];
1335   point_init (&sk.E.G);
1336   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1337   if (err)
1338     {
1339       point_free (&sk.E.G);
1340       return err;
1341     }
1342   sk.E.n = skey[4];
1343   point_init (&sk.Q);
1344   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1345   if (err)
1346     {
1347       point_free (&sk.E.G);
1348       point_free (&sk.Q);
1349       return err;
1350     }
1351
1352   {
1353     const unsigned char *buf;
1354     unsigned int n;
1355
1356     gcry_assert (mpi_is_opaque (skey[6]));
1357
1358     buf = gcry_mpi_get_opaque (skey[6], &n);
1359     if (!buf)
1360       err = GPG_ERR_INV_OBJ;
1361     else
1362       {
1363         n = (n + 7)/8;
1364         sk.d = NULL;
1365         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1366         if (!err)
1367           {
1368             if (check_secret_key (&sk))
1369               err = GPG_ERR_BAD_SECKEY;
1370             gcry_mpi_release (sk.d);
1371             sk.d = NULL;
1372           }
1373       }
1374   }
1375
1376   point_free (&sk.E.G);
1377   point_free (&sk.Q);
1378   return err;
1379 }
1380
1381
1382 static gcry_err_code_t
1383 ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey,
1384           int flags, int hashalgo)
1385 {
1386   gpg_err_code_t rc;
1387   ECC_secret_key sk;
1388   gcry_mpi_t r, s;
1389
1390   (void)algo;
1391
1392   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1393       || !skey[6] )
1394     return GPG_ERR_BAD_MPI;
1395
1396   sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1397                 ? MPI_EC_TWISTEDEDWARDS
1398                 : MPI_EC_WEIERSTRASS);
1399   sk.E.p = skey[0];
1400   sk.E.a = skey[1];
1401   sk.E.b = skey[2];
1402   point_init (&sk.E.G);
1403   sk.Q.x = NULL;
1404   sk.Q.y = NULL;
1405   sk.Q.z = NULL;
1406   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1407   if (rc)
1408     {
1409       point_free (&sk.E.G);
1410       return rc;
1411     }
1412   sk.E.n = skey[4];
1413
1414   r = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1415   s = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1416
1417   {
1418     const unsigned char *buf;
1419     unsigned int n;
1420
1421     gcry_assert (mpi_is_opaque (skey[6]));
1422
1423     buf = gcry_mpi_get_opaque (skey[6], &n);
1424     if (!buf)
1425       rc = GPG_ERR_INV_OBJ;
1426     else
1427       {
1428         n = (n + 7)/8;
1429         sk.d = NULL;
1430         rc = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1431         if (!rc)
1432           {
1433             if ((flags & PUBKEY_FLAG_EDDSA))
1434               {
1435                 rc = sign_eddsa (data, &sk, r, s, hashalgo, skey[5]);
1436                 if (!rc)
1437                   rc = gcry_err_code (gcry_sexp_build
1438                                       (r_result, NULL,
1439                                        "(sig-val(eddsa(r%M)(s%M)))", r, s));
1440               }
1441             else
1442               {
1443                 rc = sign_ecdsa (data, &sk, r, s, flags, hashalgo);
1444                 if (!rc)
1445                   rc = gcry_err_code (gcry_sexp_build
1446                                       (r_result, NULL,
1447                                        "(sig-val(ecdsa(r%M)(s%M)))", r, s));
1448               }
1449             gcry_mpi_release (sk.d);
1450             sk.d = NULL;
1451           }
1452       }
1453   }
1454
1455   mpi_free (r);
1456   mpi_free (s);
1457   point_free (&sk.E.G);
1458   if (sk.Q.x)
1459     point_free (&sk.Q);
1460   return rc;
1461 }
1462
1463
1464 static gcry_err_code_t
1465 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1466             int (*cmp)(void *, gcry_mpi_t), void *opaquev,
1467             int flags, int hashalgo)
1468 {
1469   gpg_err_code_t err;
1470   ECC_public_key pk;
1471
1472   (void)algo;
1473   (void)cmp;
1474   (void)opaquev;
1475
1476   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1477       || !pkey[3] || !pkey[4] || !pkey[5] )
1478     return GPG_ERR_BAD_MPI;
1479
1480   pk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1481                 ? MPI_EC_TWISTEDEDWARDS
1482                 : MPI_EC_WEIERSTRASS);
1483   pk.E.p = pkey[0];
1484   pk.E.a = pkey[1];
1485   pk.E.b = pkey[2];
1486   point_init (&pk.E.G);
1487   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1488   if (err)
1489     {
1490       point_free (&pk.E.G);
1491       return err;
1492     }
1493   pk.E.n = pkey[4];
1494
1495   if ((flags & PUBKEY_FLAG_EDDSA))
1496     {
1497       pk.Q.x = NULL;
1498       pk.Q.y = NULL;
1499       pk.Q.z = NULL;
1500
1501       err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]);
1502     }
1503   else
1504     {
1505       point_init (&pk.Q);
1506       err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1507       if (err)
1508         {
1509           point_free (&pk.E.G);
1510           point_free (&pk.Q);
1511           return err;
1512         }
1513
1514       if (mpi_is_opaque (hash))
1515         {
1516           const void *abuf;
1517           unsigned int abits, qbits;
1518           gcry_mpi_t a;
1519
1520           qbits = mpi_get_nbits (pk.E.n);
1521
1522           abuf = gcry_mpi_get_opaque (hash, &abits);
1523           err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1524           if (!err)
1525             {
1526               if (abits > qbits)
1527                 gcry_mpi_rshift (a, a, abits - qbits);
1528
1529               err = verify_ecdsa (a, &pk, data[0], data[1]);
1530               gcry_mpi_release (a);
1531             }
1532         }
1533       else
1534         err = verify_ecdsa (hash, &pk, data[0], data[1]);
1535     }
1536
1537   point_free (&pk.E.G);
1538   point_free (&pk.Q);
1539   return err;
1540 }
1541
1542
1543 /* ecdh raw is classic 2-round DH protocol published in 1976.
1544  *
1545  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1546  *
1547  * As with any PK operation, encrypt version uses a public key and
1548  * decrypt -- private.
1549  *
1550  * Symbols used below:
1551  *     G - field generator point
1552  *     d - private long-term scalar
1553  *    dG - public long-term key
1554  *     k - ephemeral scalar
1555  *    kG - ephemeral public key
1556  *   dkG - shared secret
1557  *
1558  * ecc_encrypt_raw description:
1559  *   input:
1560  *     data[0] : private scalar (k)
1561  *   output: A new S-expression with the parameters:
1562  *     s : shared point (kdG)
1563  *     e : generated ephemeral public key (kG)
1564  *
1565  * ecc_decrypt_raw description:
1566  *   input:
1567  *     data[0] : a point kG (ephemeral public key)
1568  *   output:
1569  *     result[0] : shared point (kdG)
1570  */
1571 static gcry_err_code_t
1572 ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
1573                  gcry_mpi_t *pkey, int flags)
1574 {
1575   gpg_err_code_t rc;
1576   ECC_public_key pk;
1577   mpi_ec_t ctx;
1578   gcry_mpi_t s, e;
1579
1580   (void)algo;
1581   (void)flags;
1582
1583   if (!k
1584       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1585     return GPG_ERR_BAD_MPI;
1586
1587   pk.E.model = MPI_EC_WEIERSTRASS;
1588   pk.E.p = pkey[0];
1589   pk.E.a = pkey[1];
1590   pk.E.b = pkey[2];
1591   point_init (&pk.E.G);
1592   rc = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1593   if (rc)
1594     {
1595       point_free (&pk.E.G);
1596       return rc;
1597     }
1598   pk.E.n = pkey[4];
1599   point_init (&pk.Q);
1600   rc = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1601   if (rc)
1602     {
1603       point_free (&pk.E.G);
1604       point_free (&pk.Q);
1605       return rc;
1606     }
1607
1608   ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
1609                                      pk.E.p, pk.E.a, pk.E.b);
1610   s = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1611   e = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1612
1613   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1614   {
1615     mpi_point_struct R;  /* Result that we return.  */
1616     gcry_mpi_t x, y;
1617
1618     x = mpi_new (0);
1619     y = mpi_new (0);
1620
1621     point_init (&R);
1622
1623     /* R = kQ  <=>  R = kdG  */
1624     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1625
1626     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1627       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1628     s = _gcry_ecc_ec2os (x, y, pk.E.p);
1629
1630     /* R = kG */
1631     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1632
1633     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1634       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1635     e = _gcry_ecc_ec2os (x, y, pk.E.p);
1636
1637     mpi_free (x);
1638     mpi_free (y);
1639
1640     point_free (&R);
1641   }
1642
1643   _gcry_mpi_ec_free (ctx);
1644   point_free (&pk.E.G);
1645   point_free (&pk.Q);
1646
1647   rc = gcry_err_code (gcry_sexp_build (r_result, NULL,
1648                                        "(enc-val(ecdh(s%m)(e%m)))",
1649                                        s, e));
1650   mpi_free (s);
1651   mpi_free (e);
1652
1653   return rc;
1654 }
1655
1656 /*  input:
1657  *     data[0] : a point kG (ephemeral public key)
1658  *   output:
1659  *     resaddr[0] : shared point kdG
1660  *
1661  *  see ecc_encrypt_raw for details.
1662  */
1663 static gcry_err_code_t
1664 ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
1665                  gcry_mpi_t *skey, int flags)
1666 {
1667   ECC_secret_key sk;
1668   mpi_point_struct R;   /* Result that we return.  */
1669   mpi_point_struct kG;
1670   mpi_ec_t ctx;
1671   gcry_mpi_t r;
1672   int err;
1673
1674   (void)algo;
1675   (void)flags;
1676
1677   *result = NULL;
1678
1679   if (!data || !data[0]
1680       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1681       || !skey[5] || !skey[6] )
1682     return GPG_ERR_BAD_MPI;
1683
1684   point_init (&kG);
1685   err = _gcry_ecc_os2ec (&kG, data[0]);
1686   if (err)
1687     {
1688       point_free (&kG);
1689       return err;
1690     }
1691
1692   sk.E.model = MPI_EC_WEIERSTRASS;
1693   sk.E.p = skey[0];
1694   sk.E.a = skey[1];
1695   sk.E.b = skey[2];
1696   point_init (&sk.E.G);
1697   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1698   if (err)
1699     {
1700       point_free (&kG);
1701       point_free (&sk.E.G);
1702       return err;
1703     }
1704   sk.E.n = skey[4];
1705   point_init (&sk.Q);
1706   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1707   if (err)
1708     {
1709       point_free (&kG);
1710       point_free (&sk.E.G);
1711       point_free (&sk.Q);
1712       return err;
1713     }
1714   sk.d = skey[6];
1715
1716   ctx = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
1717                                      sk.E.p, sk.E.a, sk.E.b);
1718
1719   /* R = dkG */
1720   point_init (&R);
1721   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1722
1723   point_free (&kG);
1724
1725   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1726   {
1727     gcry_mpi_t x, y;
1728
1729     x = mpi_new (0);
1730     y = mpi_new (0);
1731
1732     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1733       log_fatal ("ecdh: Failed to get affine coordinates\n");
1734
1735     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1736     mpi_free (x);
1737     mpi_free (y);
1738   }
1739
1740   point_free (&R);
1741   _gcry_mpi_ec_free (ctx);
1742   point_free (&kG);
1743   point_free (&sk.E.G);
1744   point_free (&sk.Q);
1745
1746   if (!r)
1747     return GPG_ERR_ENOMEM;
1748
1749   /* Success.  */
1750
1751   *result = r;
1752
1753   return 0;
1754 }
1755
1756
1757 static unsigned int
1758 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1759 {
1760   (void)algo;
1761
1762   return mpi_get_nbits (pkey[0]);
1763 }
1764
1765
1766 /* See rsa.c for a description of this function.  */
1767 static gpg_err_code_t
1768 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1769 {
1770 #define N_COMPONENTS 6
1771   static const char names[N_COMPONENTS+1] = "pabgnq";
1772   gpg_err_code_t ec = 0;
1773   gcry_sexp_t l1;
1774   gcry_mpi_t values[N_COMPONENTS];
1775   int idx;
1776
1777   /* Clear the values for easier error cleanup.  */
1778   for (idx=0; idx < N_COMPONENTS; idx++)
1779     values[idx] = NULL;
1780
1781   /* Fill values with all provided parameters.  */
1782   for (idx=0; idx < N_COMPONENTS; idx++)
1783     {
1784       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1785       if (l1)
1786         {
1787           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1788           gcry_sexp_release (l1);
1789           if (!values[idx])
1790             {
1791               ec = GPG_ERR_INV_OBJ;
1792               goto leave;
1793             }
1794         }
1795     }
1796
1797   /* Check whether a curve parameter is available and use that to fill
1798      in missing values.  */
1799   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1800   if (l1)
1801     {
1802       char *curve;
1803       gcry_mpi_t tmpvalues[N_COMPONENTS];
1804
1805       for (idx = 0; idx < N_COMPONENTS; idx++)
1806         tmpvalues[idx] = NULL;
1807
1808       curve = _gcry_sexp_nth_string (l1, 1);
1809       gcry_sexp_release (l1);
1810       if (!curve)
1811         {
1812           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1813           goto leave;
1814         }
1815       ec = _gcry_ecc_get_param (curve, tmpvalues);
1816       gcry_free (curve);
1817       if (ec)
1818         goto leave;
1819
1820       for (idx = 0; idx < N_COMPONENTS; idx++)
1821         {
1822           if (!values[idx])
1823             values[idx] = tmpvalues[idx];
1824           else
1825             mpi_free (tmpvalues[idx]);
1826         }
1827     }
1828
1829   /* Check that all parameters are known and normalize all MPIs (that
1830      should not be required but we use an internal function later and
1831      thus we better make 100% sure that they are normalized). */
1832   for (idx = 0; idx < N_COMPONENTS; idx++)
1833     if (!values[idx])
1834       {
1835         ec = GPG_ERR_NO_OBJ;
1836         goto leave;
1837       }
1838     else
1839       _gcry_mpi_normalize (values[idx]);
1840
1841   /* Hash them all.  */
1842   for (idx = 0; idx < N_COMPONENTS; idx++)
1843     {
1844       char buf[30];
1845       unsigned char *rawmpi;
1846       unsigned int rawmpilen;
1847
1848       rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1849       if (!rawmpi)
1850         {
1851           ec = gpg_err_code_from_syserror ();
1852           goto leave;
1853         }
1854       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1855       gcry_md_write (md, buf, strlen (buf));
1856       gcry_md_write (md, rawmpi, rawmpilen);
1857       gcry_md_write (md, ")", 1);
1858       gcry_free (rawmpi);
1859     }
1860
1861  leave:
1862   for (idx = 0; idx < N_COMPONENTS; idx++)
1863     _gcry_mpi_release (values[idx]);
1864
1865   return ec;
1866 #undef N_COMPONENTS
1867 }
1868
1869
1870 \f
1871 /*
1872    Low-level API helper functions.
1873  */
1874
1875 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1876    algorithms.  Note that the caller has already stored NULL at
1877    R_SEXP.  */
1878 gpg_err_code_t
1879 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1880 {
1881   gpg_err_code_t rc;
1882   gcry_mpi_t mpi_G = NULL;
1883   gcry_mpi_t mpi_Q = NULL;
1884
1885   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1886     return GPG_ERR_BAD_CRYPT_CTX;
1887
1888   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1889     return GPG_ERR_NO_SECKEY;
1890
1891   /* Compute the public point if it is missing.  */
1892   if (!ec->Q && ec->d)
1893     {
1894       ec->Q = gcry_mpi_point_new (0);
1895       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
1896     }
1897
1898   /* Encode G and Q.  */
1899   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1900   if (!mpi_G)
1901     {
1902       rc = GPG_ERR_BROKEN_PUBKEY;
1903       goto leave;
1904     }
1905   if (!ec->Q)
1906     {
1907       rc = GPG_ERR_BAD_CRYPT_CTX;
1908       goto leave;
1909     }
1910   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1911   if (!mpi_Q)
1912     {
1913       rc = GPG_ERR_BROKEN_PUBKEY;
1914       goto leave;
1915     }
1916
1917   /* Fixme: We should return a curve name instead of the parameters if
1918      if know that they match a curve.  */
1919
1920   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1921     {
1922       /* Let's return a private key. */
1923       rc = gpg_err_code
1924         (gcry_sexp_build
1925          (r_sexp, NULL,
1926           "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1927           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d));
1928     }
1929   else if (ec->Q)
1930     {
1931       /* Let's return a public key.  */
1932       rc = gpg_err_code
1933         (gcry_sexp_build
1934          (r_sexp, NULL,
1935           "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1936           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q));
1937     }
1938   else
1939     rc = GPG_ERR_BAD_CRYPT_CTX;
1940
1941  leave:
1942   mpi_free (mpi_Q);
1943   mpi_free (mpi_G);
1944   return rc;
1945 }
1946
1947
1948 \f
1949 /*
1950      Self-test section.
1951  */
1952
1953
1954 static gpg_err_code_t
1955 selftests_ecdsa (selftest_report_func_t report)
1956 {
1957   const char *what;
1958   const char *errtxt;
1959
1960   what = "low-level";
1961   errtxt = NULL; /*selftest ();*/
1962   if (errtxt)
1963     goto failed;
1964
1965   /* FIXME:  need more tests.  */
1966
1967   return 0; /* Succeeded. */
1968
1969  failed:
1970   if (report)
1971     report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
1972   return GPG_ERR_SELFTEST_FAILED;
1973 }
1974
1975
1976 /* Run a full self-test for ALGO and return 0 on success.  */
1977 static gpg_err_code_t
1978 run_selftests (int algo, int extended, selftest_report_func_t report)
1979 {
1980   gpg_err_code_t ec;
1981
1982   (void)extended;
1983
1984   switch (algo)
1985     {
1986     case GCRY_PK_ECDSA:
1987       ec = selftests_ecdsa (report);
1988       break;
1989     default:
1990       ec = GPG_ERR_PUBKEY_ALGO;
1991       break;
1992
1993     }
1994   return ec;
1995 }
1996
1997
1998
1999 \f
2000 static const char *ecdsa_names[] =
2001   {
2002     "ecdsa",
2003     "eddsa",
2004     "ecc",
2005     NULL,
2006   };
2007 static const char *ecdh_names[] =
2008   {
2009     "ecdh",
2010     "ecc",
2011     NULL,
2012   };
2013
2014 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
2015   {
2016     GCRY_PK_ECDSA, { 0, 0 },
2017     GCRY_PK_USAGE_SIGN,
2018     "ECDSA", ecdsa_names,
2019     "pabgnq", "pabgnqd", "", "rs", "pabgnq",
2020     ecc_generate,
2021     ecc_check_secret_key,
2022     NULL,
2023     NULL,
2024     ecc_sign,
2025     ecc_verify,
2026     ecc_get_nbits,
2027     run_selftests,
2028     compute_keygrip,
2029     _gcry_ecc_get_param,
2030     _gcry_ecc_get_curve,
2031     _gcry_ecc_get_param_sexp
2032   };
2033
2034 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
2035   {
2036     GCRY_PK_ECDH, { 0, 0 },
2037     GCRY_PK_USAGE_ENCR,
2038     "ECDH", ecdh_names,
2039     "pabgnq", "pabgnqd", "se", "", "pabgnq",
2040     ecc_generate,
2041     ecc_check_secret_key,
2042     ecc_encrypt_raw,
2043     ecc_decrypt_raw,
2044     NULL,
2045     NULL,
2046     ecc_get_nbits,
2047     run_selftests,
2048     compute_keygrip,
2049     _gcry_ecc_get_param,
2050     _gcry_ecc_get_curve,
2051     _gcry_ecc_get_param_sexp
2052   };