ecc: Fix highly unlikely endless loop in sign_ecdsa.
[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   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
412                                      skey->E.p, skey->E.a, skey->E.b);
413
414   /* Two loops to avoid R or S are zero.  This is more of a joke than
415      a real demand because the probability of them being zero is less
416      than any hardware failure.  Some specs however require it.  */
417   do
418     {
419       do
420         {
421           mpi_free (k);
422           k = NULL;
423           if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
424             {
425               /* Use Pornin's method for deterministic DSA.  If this
426                  flag is set, it is expected that HASH is an opaque
427                  MPI with the to be signed hash.  That hash is also
428                  used as h1 from 3.2.a.  */
429               if (!mpi_is_opaque (input))
430                 {
431                   err = GPG_ERR_CONFLICT;
432                   goto leave;
433                 }
434
435               abuf = gcry_mpi_get_opaque (input, &abits);
436               err = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
437                                              abuf, (abits+7)/8,
438                                              hashalgo, extraloops);
439               if (err)
440                 goto leave;
441               extraloops++;
442             }
443           else
444             k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
445
446           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
447           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
448             {
449               if (DBG_CIPHER)
450                 log_debug ("ecc sign: Failed to get affine coordinates\n");
451               err = GPG_ERR_BAD_SIGNATURE;
452               goto leave;
453             }
454           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
455         }
456       while (!mpi_cmp_ui (r, 0));
457
458       mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
459       mpi_addm (sum, hash, dr, skey->E.n);  /* sum = hash + (d*r) mod n  */
460       mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
461       mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
462     }
463   while (!mpi_cmp_ui (s, 0));
464
465   if (DBG_CIPHER)
466     {
467       log_mpidump ("ecdsa sign result r ", r);
468       log_mpidump ("ecdsa sign result s ", s);
469     }
470
471  leave:
472   _gcry_mpi_ec_free (ctx);
473   point_free (&I);
474   mpi_free (x);
475   mpi_free (k_1);
476   mpi_free (sum);
477   mpi_free (dr);
478   mpi_free (k);
479
480   if (hash != input)
481     mpi_free (hash);
482
483   return err;
484 }
485
486
487 /* Verify an ECDSA signature.
488  * Check if R and S verifies INPUT.
489  */
490 static gpg_err_code_t
491 verify_ecdsa (gcry_mpi_t input, ECC_public_key *pkey,
492               gcry_mpi_t r, gcry_mpi_t s)
493 {
494   gpg_err_code_t err = 0;
495   gcry_mpi_t h, h1, h2, x;
496   mpi_point_struct Q, Q1, Q2;
497   mpi_ec_t ctx;
498
499   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
500     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < r < n  failed.  */
501   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
502     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < s < n  failed.  */
503
504   h  = mpi_alloc (0);
505   h1 = mpi_alloc (0);
506   h2 = mpi_alloc (0);
507   x = mpi_alloc (0);
508   point_init (&Q);
509   point_init (&Q1);
510   point_init (&Q2);
511
512   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
513                                      pkey->E.p, pkey->E.a, pkey->E.b);
514
515   /* h  = s^(-1) (mod n) */
516   mpi_invm (h, s, pkey->E.n);
517   /* h1 = hash * s^(-1) (mod n) */
518   mpi_mulm (h1, input, h, pkey->E.n);
519   /* Q1 = [ hash * s^(-1) ]G  */
520   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
521   /* h2 = r * s^(-1) (mod n) */
522   mpi_mulm (h2, r, h, pkey->E.n);
523   /* Q2 = [ r * s^(-1) ]Q */
524   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
525   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
526   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
527
528   if (!mpi_cmp_ui (Q.z, 0))
529     {
530       if (DBG_CIPHER)
531           log_debug ("ecc verify: Rejected\n");
532       err = GPG_ERR_BAD_SIGNATURE;
533       goto leave;
534     }
535   if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
536     {
537       if (DBG_CIPHER)
538         log_debug ("ecc verify: Failed to get affine coordinates\n");
539       err = GPG_ERR_BAD_SIGNATURE;
540       goto leave;
541     }
542   mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
543   if (mpi_cmp (x, r))   /* x != r */
544     {
545       if (DBG_CIPHER)
546         {
547           log_mpidump ("     x", x);
548           log_mpidump ("     r", r);
549           log_mpidump ("     s", s);
550           log_debug ("ecc verify: Not verified\n");
551         }
552       err = GPG_ERR_BAD_SIGNATURE;
553       goto leave;
554     }
555   if (DBG_CIPHER)
556     log_debug ("ecc verify: Accepted\n");
557
558  leave:
559   _gcry_mpi_ec_free (ctx);
560   point_free (&Q2);
561   point_free (&Q1);
562   point_free (&Q);
563   mpi_free (x);
564   mpi_free (h2);
565   mpi_free (h1);
566   mpi_free (h);
567   return err;
568 }
569
570
571 \f
572 static void
573 reverse_buffer (unsigned char *buffer, unsigned int length)
574 {
575   unsigned int tmp, i;
576
577   for (i=0; i < length/2; i++)
578     {
579       tmp = buffer[i];
580       buffer[i] = buffer[length-1-i];
581       buffer[length-1-i] = tmp;
582     }
583 }
584
585
586 /* Encode MPI using the EdDSA scheme.  MINLEN specifies the required
587    length of the buffer in bytes.  On success 0 is returned an a
588    malloced buffer with the encoded point is stored at R_BUFFER; the
589    length of this buffer is stored at R_BUFLEN.  */
590 static gpg_err_code_t
591 eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen,
592                  unsigned char **r_buffer, unsigned int *r_buflen)
593 {
594   unsigned char *rawmpi;
595   unsigned int rawmpilen;
596
597   rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
598   if (!rawmpi)
599     return gpg_err_code_from_syserror ();
600
601   *r_buffer = rawmpi;
602   *r_buflen = rawmpilen;
603   return 0;
604 }
605
606
607 /* Encode (X,Y) using the EdDSA scheme.  MINLEN is the required length
608    in bytes for the result.  On success 0 is returned and a malloced
609    buffer with the encoded point is stored at R_BUFFER; the length of
610    this buffer is stored at R_BUFLEN.  */
611 static gpg_err_code_t
612 eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen,
613                   unsigned char **r_buffer, unsigned int *r_buflen)
614 {
615   unsigned char *rawmpi;
616   unsigned int rawmpilen;
617
618   rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
619   if (!rawmpi)
620     return gpg_err_code_from_syserror ();
621   if (mpi_test_bit (x, 0) && rawmpilen)
622     rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
623
624   *r_buffer = rawmpi;
625   *r_buflen = rawmpilen;
626   return 0;
627 }
628
629 /* Encode POINT using the EdDSA scheme.  X and Y are scratch variables
630    supplied by the caller and CTX is the usual context.  MINLEN is the
631    required length in bytes for the result. On success 0 is returned
632    and a malloced buffer with the encoded point is stored at R_BUFFER;
633    the length of this buffer is stored at R_BUFLEN.  */
634 static gpg_err_code_t
635 eddsa_encodepoint (mpi_point_t point, unsigned int minlen, mpi_ec_t ctx,
636                    gcry_mpi_t x, gcry_mpi_t y,
637                    unsigned char **r_buffer, unsigned int *r_buflen)
638 {
639   if (_gcry_mpi_ec_get_affine (x, y, point, ctx))
640     {
641       log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
642       return GPG_ERR_INTERNAL;
643     }
644   return eddsa_encode_x_y (x, y, minlen, r_buffer, r_buflen);
645 }
646
647
648 /* Decode the EdDSA style encoded PK and set it into RESULT.  LEN is
649    the expected length in bytes of the encoded key and CTX the usual
650    curve context.  If R_ENCPK is not NULL, the encoded PK is stored at
651    that address; this is a new copy to be released by the caller.  In
652    contrast to the supplied PK, this is not an MPI and thus guarnateed
653    to be properly padded.  R_ENCPKLEN received the length of that
654    encoded key.  */
655 static gpg_err_code_t
656 eddsa_decodepoint (gcry_mpi_t pk, unsigned int len, mpi_ec_t ctx,
657                    mpi_point_t result,
658                    unsigned char **r_encpk, unsigned int *r_encpklen)
659 {
660   gpg_err_code_t rc;
661   unsigned char *rawmpi;
662   unsigned int rawmpilen;
663   gcry_mpi_t yy, t, x, p1, p2, p3;
664   int sign;
665
666   if (mpi_is_opaque (pk))
667     {
668       const unsigned char *buf;
669
670       buf = gcry_mpi_get_opaque (pk, &rawmpilen);
671       if (!buf)
672         return GPG_ERR_INV_OBJ;
673       rawmpilen = (rawmpilen + 7)/8;
674
675       /* First check whether the public key has been given in standard
676          uncompressed format.  No need to recover x in this case.
677          Detection is easy: The size of the buffer will be odd and the
678          first byte be 0x04.  */
679       if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2))
680         {
681           gcry_mpi_t y;
682
683           rc = gcry_mpi_scan (&x, GCRYMPI_FMT_STD,
684                               buf+1, (rawmpilen-1)/2, NULL);
685           if (rc)
686             return rc;
687           rc = gcry_mpi_scan (&y, GCRYMPI_FMT_STD,
688                               buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
689           if (rc)
690             {
691               mpi_free (x);
692               return rc;
693             }
694
695           if (r_encpk)
696             {
697               rc = eddsa_encode_x_y (x, y, len, r_encpk, r_encpklen);
698               if (rc)
699                 {
700                   mpi_free (x);
701                   mpi_free (y);
702                   return rc;
703                 }
704             }
705           mpi_snatch (result->x, x);
706           mpi_snatch (result->y, y);
707           mpi_set_ui (result->z, 1);
708           return 0;
709         }
710
711       /* EdDSA compressed point.  */
712       rawmpi = gcry_malloc (rawmpilen? rawmpilen:1);
713       if (!rawmpi)
714         return gpg_err_code_from_syserror ();
715       memcpy (rawmpi, buf, rawmpilen);
716       reverse_buffer (rawmpi, rawmpilen);
717     }
718   else
719     {
720       /* Note: Without using an opaque MPI it is not reliable possible
721          to find out whether the public key has been given in
722          uncompressed format.  Thus we expect EdDSA format here.  */
723       rawmpi = _gcry_mpi_get_buffer (pk, len, &rawmpilen, NULL);
724       if (!rawmpi)
725         return gpg_err_code_from_syserror ();
726     }
727
728   if (rawmpilen)
729     {
730       sign = !!(rawmpi[0] & 0x80);
731       rawmpi[0] &= 0x7f;
732     }
733   else
734     sign = 0;
735   _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
736   if (r_encpk)
737     {
738       /* Revert to little endian.  */
739       if (sign && rawmpilen)
740         rawmpi[0] |= 0x80;
741       reverse_buffer (rawmpi, rawmpilen);
742       *r_encpk = rawmpi;
743       if (r_encpklen)
744         *r_encpklen = rawmpilen;
745     }
746   else
747     gcry_free (rawmpi);
748
749   /* Now recover X.  */
750   /* t = (y^2-1) · ((b*y^2+1)^{p-2} mod p) */
751   x = mpi_new (0);
752   yy = mpi_new (0);
753   mpi_mul (yy, result->y, result->y);
754   t = mpi_copy (yy);
755   mpi_mul (t, t, ctx->b);
756   mpi_add_ui (t, t, 1);
757   p2 = mpi_copy (ctx->p);
758   mpi_sub_ui (p2, p2, 2);
759   mpi_powm (t, t, p2, ctx->p);
760
761   mpi_sub_ui (yy, yy, 1);
762   mpi_mul (t, yy, t);
763
764   /* x = t^{(p+3)/8} mod p */
765   p3 = mpi_copy (ctx->p);
766   mpi_add_ui (p3, p3, 3);
767   mpi_fdiv_q (p3, p3, mpi_const (MPI_C_EIGHT));
768   mpi_powm (x, t, p3, ctx->p);
769
770   /* (x^2 - t) % p != 0 ? x = (x*(2^{(p-1)/4} mod p)) % p */
771   mpi_mul (yy, x, x);
772   mpi_subm (yy, yy, t, ctx->p);
773   if (mpi_cmp_ui (yy, 0))
774     {
775       p1 = mpi_copy (ctx->p);
776       mpi_sub_ui (p1, p1, 1);
777       mpi_fdiv_q (p1, p1, mpi_const (MPI_C_FOUR));
778       mpi_powm (yy, mpi_const (MPI_C_TWO), p1, ctx->p);
779       mpi_mulm (x, x, yy, ctx->p);
780     }
781   else
782     p1 = NULL;
783
784   /* is_odd(x) ? x = p-x */
785   if (mpi_test_bit (x, 0))
786     mpi_sub (x, ctx->p, x);
787
788   /* lowbit(x) != highbit(input) ?  x = p-x */
789   if (mpi_test_bit (x, 0) != sign)
790     mpi_sub (x, ctx->p, x);
791
792   mpi_set (result->x, x);
793   mpi_set_ui (result->z, 1);
794
795   gcry_mpi_release (x);
796   gcry_mpi_release (yy);
797   gcry_mpi_release (t);
798   gcry_mpi_release (p3);
799   gcry_mpi_release (p2);
800   gcry_mpi_release (p1);
801
802   return 0;
803 }
804
805
806 /* Ed25519 version of the key generation.  */
807 static gpg_err_code_t
808 eddsa_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
809                     gcry_random_level_t random_level)
810 {
811   gpg_err_code_t rc;
812   int b = 256/8;             /* The only size we currently support.  */
813   gcry_mpi_t a, x, y;
814   mpi_point_struct Q;
815   char *dbuf;
816   size_t dlen;
817   gcry_buffer_t hvec[1];
818   unsigned char *hash_d = NULL;
819
820   point_init (&Q);
821   memset (hvec, 0, sizeof hvec);
822
823   a = mpi_snew (0);
824   x = mpi_new (0);
825   y = mpi_new (0);
826
827   /* Generate a secret.  */
828   hash_d = gcry_malloc_secure (2*b);
829   if (!hash_d)
830     {
831       rc = gpg_error_from_syserror ();
832       goto leave;
833     }
834   dlen = b;
835   dbuf = gcry_random_bytes_secure (dlen, random_level);
836
837   /* Compute the A value.  */
838   hvec[0].data = dbuf;
839   hvec[0].len = dlen;
840   rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
841   if (rc)
842     goto leave;
843   sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
844   dbuf = NULL;
845   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
846   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
847   hash_d[31] &= 0xf8;
848   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
849   gcry_free (hash_d); hash_d = NULL;
850   /* log_printmpi ("ecgen         a", a); */
851
852   /* Compute Q.  */
853   _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
854   if (DBG_CIPHER)
855     log_printpnt ("ecgen      pk", &Q, ctx);
856
857   /* Copy the stuff to the key structures. */
858   sk->E.model = E->model;
859   sk->E.dialect = E->dialect;
860   sk->E.p = mpi_copy (E->p);
861   sk->E.a = mpi_copy (E->a);
862   sk->E.b = mpi_copy (E->b);
863   point_init (&sk->E.G);
864   point_set (&sk->E.G, &E->G);
865   sk->E.n = mpi_copy (E->n);
866   point_init (&sk->Q);
867   point_set (&sk->Q, &Q);
868
869  leave:
870   gcry_mpi_release (a);
871   gcry_mpi_release (x);
872   gcry_mpi_release (y);
873   gcry_free (hash_d);
874   return rc;
875 }
876
877
878 /* Compute an EdDSA signature. See:
879  *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
880  *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
881  *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
882  *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
883  *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
884  *
885  * Despite that this function requires the specification of a hash
886  * algorithm, we only support what has been specified by the paper.
887  * This may change in the future.  Note that we don't check the used
888  * curve; the user is responsible to use Ed25519.
889  *
890  * Return the signature struct (r,s) from the message hash.  The caller
891  * must have allocated R_R and S.
892  */
893 static gpg_err_code_t
894 sign_eddsa (gcry_mpi_t input, ECC_secret_key *skey,
895             gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
896 {
897   int rc;
898   mpi_ec_t ctx = NULL;
899   int b = 256/8;             /* The only size we currently support.  */
900   unsigned int tmp;
901   unsigned char hash_d[64];  /* Fixme: malloc in secure memory */
902   unsigned char digest[64];
903   gcry_buffer_t hvec[3];
904   const void *mbuf;
905   size_t mlen;
906   unsigned char *rawmpi = NULL;
907   unsigned int rawmpilen;
908   unsigned char *encpk = NULL; /* Encoded public key.  */
909   unsigned int encpklen;
910   mpi_point_struct I;          /* Intermediate value.  */
911   mpi_point_struct Q;          /* Public key.  */
912   gcry_mpi_t a, x, y, r;
913
914   memset (hvec, 0, sizeof hvec);
915
916   if (!mpi_is_opaque (input))
917     return GPG_ERR_INV_DATA;
918   if (hashalgo != GCRY_MD_SHA512)
919     return GPG_ERR_DIGEST_ALGO;
920
921   /* Initialize some helpers.  */
922   point_init (&I);
923   point_init (&Q);
924   a = mpi_snew (0);
925   x = mpi_new (0);
926   y = mpi_new (0);
927   r = mpi_new (0);
928   ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect,
929                                      skey->E.p, skey->E.a, skey->E.b);
930
931   /* Hash the secret key.  We clear DIGEST so we can use it to left
932      pad the key with zeroes for hashing.  */
933   rawmpi = _gcry_mpi_get_buffer (skey->d, 0, &rawmpilen, NULL);
934   if (!rawmpi)
935     {
936       rc = gpg_err_code_from_syserror ();
937       goto leave;
938     }
939   memset (digest, 0, b);
940   hvec[0].data = digest;
941   hvec[0].off = 0;
942   hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
943   hvec[1].data = rawmpi;
944   hvec[1].off = 0;
945   hvec[1].len = rawmpilen;
946   rc = _gcry_md_hash_buffers (hashalgo, 0, hash_d, hvec, 2);
947   gcry_free (rawmpi); rawmpi = NULL;
948   if (rc)
949     goto leave;
950
951   /* Compute the A value (this modifies hash_d).  */
952   reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
953   hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
954   hash_d[31] &= 0xf8;
955   _gcry_mpi_set_buffer (a, hash_d, 32, 0);
956   /* log_printmpi ("     a", a); */
957
958   /* Compute the public key if it has not been supplied as optional
959      parameter.  */
960   if (pk)
961     {
962       rc = eddsa_decodepoint (pk, b, ctx, &Q,  &encpk, &encpklen);
963       if (rc)
964         goto leave;
965       if (DBG_CIPHER)
966         log_printhex ("* e_pk", encpk, encpklen);
967       if (!_gcry_mpi_ec_curve_point (&Q, ctx))
968         {
969           rc = GPG_ERR_BROKEN_PUBKEY;
970           goto leave;
971         }
972     }
973   else
974     {
975       _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
976       rc = eddsa_encodepoint (&Q, b, ctx, x, y, &encpk, &encpklen);
977       if (rc)
978         goto leave;
979       if (DBG_CIPHER)
980         log_printhex ("  e_pk", encpk, encpklen);
981     }
982
983   /* Compute R.  */
984   mbuf = gcry_mpi_get_opaque (input, &tmp);
985   mlen = (tmp +7)/8;
986   if (DBG_CIPHER)
987     log_printhex ("     m", mbuf, mlen);
988
989   hvec[0].data = hash_d;
990   hvec[0].off  = 32;
991   hvec[0].len  = 32;
992   hvec[1].data = (char*)mbuf;
993   hvec[1].len  = mlen;
994   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
995   if (rc)
996     goto leave;
997   reverse_buffer (digest, 64);
998   if (DBG_CIPHER)
999     log_printhex ("     r", digest, 64);
1000   _gcry_mpi_set_buffer (r, digest, 64, 0);
1001   _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
1002   if (DBG_CIPHER)
1003     log_printpnt ("   r", &I, ctx);
1004
1005   /* Convert R into affine coordinates and apply encoding.  */
1006   rc = eddsa_encodepoint (&I, b, ctx, x, y, &rawmpi, &rawmpilen);
1007   if (rc)
1008     goto leave;
1009   if (DBG_CIPHER)
1010     log_printhex ("   e_r", rawmpi, rawmpilen);
1011
1012   /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
1013   hvec[0].data = rawmpi;  /* (this is R) */
1014   hvec[0].off  = 0;
1015   hvec[0].len  = rawmpilen;
1016   hvec[1].data = encpk;
1017   hvec[1].off  = 0;
1018   hvec[1].len  = encpklen;
1019   hvec[2].data = (char*)mbuf;
1020   hvec[2].off  = 0;
1021   hvec[2].len  = mlen;
1022   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1023   if (rc)
1024     goto leave;
1025
1026   /* No more need for RAWMPI thus we now transfer it to R_R.  */
1027   gcry_mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
1028   rawmpi = NULL;
1029
1030   reverse_buffer (digest, 64);
1031   if (DBG_CIPHER)
1032     log_printhex (" H(R+)", digest, 64);
1033   _gcry_mpi_set_buffer (s, digest, 64, 0);
1034   mpi_mulm (s, s, a, skey->E.n);
1035   mpi_addm (s, s, r, skey->E.n);
1036   rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
1037   if (rc)
1038     goto leave;
1039   if (DBG_CIPHER)
1040     log_printhex ("   e_s", rawmpi, rawmpilen);
1041   gcry_mpi_set_opaque (s, rawmpi, rawmpilen*8);
1042   rawmpi = NULL;
1043
1044   rc = 0;
1045
1046  leave:
1047   gcry_mpi_release (a);
1048   gcry_mpi_release (x);
1049   gcry_mpi_release (y);
1050   gcry_mpi_release (r);
1051   _gcry_mpi_ec_free (ctx);
1052   point_free (&I);
1053   point_free (&Q);
1054   gcry_free (encpk);
1055   gcry_free (rawmpi);
1056   return rc;
1057 }
1058
1059
1060 /* Verify an EdDSA signature.  See sign_eddsa for the reference.
1061  * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
1062  * parameters and PK is the EdDSA style encoded public key.
1063  */
1064 static gpg_err_code_t
1065 verify_eddsa (gcry_mpi_t input, ECC_public_key *pkey,
1066               gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo, gcry_mpi_t pk)
1067 {
1068   int rc;
1069   mpi_ec_t ctx = NULL;
1070   int b = 256/8;               /* The only size we currently support.  */
1071   unsigned int tmp;
1072   mpi_point_struct Q;          /* Public key.  */
1073   unsigned char *encpk = NULL; /* Encoded public key.  */
1074   unsigned int encpklen;
1075   const void *mbuf, *rbuf;
1076   unsigned char *tbuf = NULL;
1077   size_t mlen, rlen;
1078   unsigned int tlen;
1079   unsigned char digest[64];
1080   gcry_buffer_t hvec[3];
1081   gcry_mpi_t h, s;
1082   mpi_point_struct Ia, Ib;
1083
1084   if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
1085     return GPG_ERR_INV_DATA;
1086   if (hashalgo != GCRY_MD_SHA512)
1087     return GPG_ERR_DIGEST_ALGO;
1088
1089   point_init (&Q);
1090   point_init (&Ia);
1091   point_init (&Ib);
1092   h = mpi_new (0);
1093   s = mpi_new (0);
1094
1095   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect,
1096                                      pkey->E.p, pkey->E.a, pkey->E.b);
1097
1098   /* Decode and check the public key.  */
1099   rc = eddsa_decodepoint (pk, b, ctx, &Q, &encpk, &encpklen);
1100   if (rc)
1101     goto leave;
1102   if (!_gcry_mpi_ec_curve_point (&Q, ctx))
1103     {
1104       rc = GPG_ERR_BROKEN_PUBKEY;
1105       goto leave;
1106     }
1107   if (DBG_CIPHER)
1108     log_printhex ("  e_pk", encpk, encpklen);
1109   if (encpklen != b)
1110     {
1111       rc = GPG_ERR_INV_LENGTH;
1112       goto leave;
1113     }
1114
1115   /* Convert the other input parameters.  */
1116   mbuf = gcry_mpi_get_opaque (input, &tmp);
1117   mlen = (tmp +7)/8;
1118   if (DBG_CIPHER)
1119     log_printhex ("     m", mbuf, mlen);
1120   rbuf = gcry_mpi_get_opaque (r_in, &tmp);
1121   rlen = (tmp +7)/8;
1122   if (DBG_CIPHER)
1123     log_printhex ("     r", rbuf, rlen);
1124   if (rlen != b)
1125     {
1126       rc = GPG_ERR_INV_LENGTH;
1127       goto leave;
1128     }
1129
1130   /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
1131   hvec[0].data = (char*)rbuf;
1132   hvec[0].off  = 0;
1133   hvec[0].len  = rlen;
1134   hvec[1].data = encpk;
1135   hvec[1].off  = 0;
1136   hvec[1].len  = encpklen;
1137   hvec[2].data = (char*)mbuf;
1138   hvec[2].off  = 0;
1139   hvec[2].len  = mlen;
1140   rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
1141   if (rc)
1142     goto leave;
1143   reverse_buffer (digest, 64);
1144   if (DBG_CIPHER)
1145     log_printhex (" H(R+)", digest, 64);
1146   _gcry_mpi_set_buffer (h, digest, 64, 0);
1147
1148   /* According to the paper the best way for verification is:
1149          encodepoint(sG - h·Q) = encodepoint(r)
1150      because we don't need to decode R. */
1151   {
1152     void *sbuf;
1153     unsigned int slen;
1154
1155     sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
1156     slen = (tmp +7)/8;
1157     reverse_buffer (sbuf, slen);
1158     if (DBG_CIPHER)
1159       log_printhex ("     s", sbuf, slen);
1160     _gcry_mpi_set_buffer (s, sbuf, slen, 0);
1161     gcry_free (sbuf);
1162     if (slen != b)
1163       {
1164         rc = GPG_ERR_INV_LENGTH;
1165         goto leave;
1166       }
1167   }
1168
1169   _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx);
1170   _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx);
1171   _gcry_mpi_neg (Ib.x, Ib.x);
1172   _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx);
1173   rc = eddsa_encodepoint (&Ia, b, ctx, s, h, &tbuf, &tlen);
1174   if (rc)
1175     goto leave;
1176   if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
1177     {
1178       if (DBG_CIPHER)
1179         log_debug ("eddsa verify: Not verified\n");
1180       rc = GPG_ERR_BAD_SIGNATURE;
1181       goto leave;
1182     }
1183
1184   if (DBG_CIPHER)
1185     log_debug ("eddsa verify: Accepted\n");
1186   rc = 0;
1187
1188  leave:
1189   gcry_free (encpk);
1190   gcry_free (tbuf);
1191   _gcry_mpi_ec_free (ctx);
1192   gcry_mpi_release (s);
1193   gcry_mpi_release (h);
1194   point_free (&Ia);
1195   point_free (&Ib);
1196   point_free (&Q);
1197   return rc;
1198 }
1199
1200
1201 \f
1202 /*********************************************
1203  **************  interface  ******************
1204  *********************************************/
1205
1206 static gcry_err_code_t
1207 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1208               const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
1209 {
1210   gpg_err_code_t rc;
1211   elliptic_curve_t E;
1212   ECC_secret_key sk;
1213   gcry_mpi_t x = NULL;
1214   gcry_mpi_t y = NULL;
1215   char *curve_name = NULL;
1216   gcry_sexp_t l1;
1217   int transient_key = 0;
1218   gcry_random_level_t random_level;
1219   mpi_ec_t ctx = NULL;
1220   gcry_sexp_t curve_info = NULL;
1221   gcry_mpi_t base = NULL;
1222   gcry_mpi_t public = NULL;
1223   gcry_mpi_t secret = NULL;
1224
1225   (void)algo;
1226   (void)evalue;
1227
1228   memset (&E, 0, sizeof E);
1229   memset (&sk, 0, sizeof sk);
1230
1231   if (genparms)
1232     {
1233       /* Parse the optional "curve" parameter. */
1234       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1235       if (l1)
1236         {
1237           curve_name = _gcry_sexp_nth_string (l1, 1);
1238           gcry_sexp_release (l1);
1239           if (!curve_name)
1240             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1241         }
1242
1243       /* Parse the optional transient-key flag.  */
1244       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1245       if (l1)
1246         {
1247           transient_key = 1;
1248           gcry_sexp_release (l1);
1249         }
1250     }
1251
1252   /* NBITS is required if no curve name has been given.  */
1253   if (!nbits && !curve_name)
1254     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1255
1256   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
1257   gcry_free (curve_name); curve_name = NULL;
1258   if (rc)
1259     goto leave;
1260
1261   if (DBG_CIPHER)
1262     {
1263       log_debug ("ecgen curve info: %s/%s\n",
1264                  _gcry_ecc_model2str (E.model),
1265                  _gcry_ecc_dialect2str (E.dialect));
1266       if (E.name)
1267         log_debug ("ecgen curve used: %s\n", E.name);
1268       log_printmpi ("ecgen curve   p", E.p);
1269       log_printmpi ("ecgen curve   a", E.a);
1270       log_printmpi ("ecgen curve   b", E.b);
1271       log_printmpi ("ecgen curve   n", E.n);
1272       log_printpnt ("ecgen curve G", &E.G, NULL);
1273     }
1274
1275   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
1276   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, E.p, E.a, E.b);
1277   x = mpi_new (0);
1278   y = mpi_new (0);
1279
1280   switch (E.dialect)
1281     {
1282     case ECC_DIALECT_STANDARD:
1283       rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
1284       break;
1285     case ECC_DIALECT_ED25519:
1286       rc = eddsa_generate_key (&sk, &E, ctx, random_level);
1287       break;
1288     default:
1289       rc = GPG_ERR_INTERNAL;
1290       break;
1291     }
1292   if (rc)
1293     goto leave;
1294
1295   /* Copy data to the result.  */
1296   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
1297     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
1298   base = _gcry_ecc_ec2os (x, y, sk.E.p);
1299   if (sk.E.dialect == ECC_DIALECT_ED25519)
1300     {
1301       unsigned char *encpk;
1302       unsigned int encpklen;
1303
1304       rc = eddsa_encodepoint (&sk.Q, 256/8, ctx, x, y, &encpk, &encpklen);
1305       if (rc)
1306         return rc;
1307       public = mpi_new (0);
1308       gcry_mpi_set_opaque (public, encpk, encpklen*8);
1309       encpk = NULL;
1310     }
1311   else
1312     {
1313       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
1314         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
1315       public = _gcry_ecc_ec2os (x, y, sk.E.p);
1316     }
1317   secret = sk.d; sk.d = NULL;
1318   if (E.name)
1319     {
1320       rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
1321       if (rc)
1322         goto leave;
1323     }
1324
1325   rc = gcry_sexp_build (r_skey, NULL,
1326                         "(key-data"
1327                         " (public-key"
1328                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
1329                         " (private-key"
1330                         "  (ecc%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
1331                         " )",
1332                         curve_info,
1333                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
1334                         curve_info,
1335                         sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret);
1336   if (rc)
1337     goto leave;
1338
1339   if (DBG_CIPHER)
1340     {
1341       log_printmpi ("ecgen result  p", sk.E.p);
1342       log_printmpi ("ecgen result  a", sk.E.a);
1343       log_printmpi ("ecgen result  b", sk.E.b);
1344       log_printmpi ("ecgen result  G", base);
1345       log_printmpi ("ecgen result  n", sk.E.n);
1346       log_printmpi ("ecgen result  Q", public);
1347       log_printmpi ("ecgen result  d", secret);
1348     }
1349
1350  leave:
1351   mpi_free (secret);
1352   mpi_free (public);
1353   mpi_free (base);
1354   {
1355     _gcry_ecc_curve_free (&sk.E);
1356     point_free (&sk.Q);
1357     mpi_free (sk.d);
1358   }
1359   _gcry_ecc_curve_free (&E);
1360   mpi_free (x);
1361   mpi_free (y);
1362   _gcry_mpi_ec_free (ctx);
1363   gcry_sexp_release (curve_info);
1364   return rc;
1365 }
1366
1367
1368 static gcry_err_code_t
1369 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1370 {
1371   gpg_err_code_t err;
1372   ECC_secret_key sk;
1373
1374   (void)algo;
1375
1376   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1377   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1378       || !skey[6])
1379     return GPG_ERR_BAD_MPI;
1380
1381   sk.E.model = MPI_EC_WEIERSTRASS;
1382   sk.E.p = skey[0];
1383   sk.E.a = skey[1];
1384   sk.E.b = skey[2];
1385   point_init (&sk.E.G);
1386   err = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1387   if (err)
1388     {
1389       point_free (&sk.E.G);
1390       return err;
1391     }
1392   sk.E.n = skey[4];
1393   point_init (&sk.Q);
1394   err = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1395   if (err)
1396     {
1397       point_free (&sk.E.G);
1398       point_free (&sk.Q);
1399       return err;
1400     }
1401
1402   {
1403     const unsigned char *buf;
1404     unsigned int n;
1405
1406     gcry_assert (mpi_is_opaque (skey[6]));
1407
1408     buf = gcry_mpi_get_opaque (skey[6], &n);
1409     if (!buf)
1410       err = GPG_ERR_INV_OBJ;
1411     else
1412       {
1413         n = (n + 7)/8;
1414         sk.d = NULL;
1415         err = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1416         if (!err)
1417           {
1418             if (check_secret_key (&sk))
1419               err = GPG_ERR_BAD_SECKEY;
1420             gcry_mpi_release (sk.d);
1421             sk.d = NULL;
1422           }
1423       }
1424   }
1425
1426   point_free (&sk.E.G);
1427   point_free (&sk.Q);
1428   return err;
1429 }
1430
1431
1432 static gcry_err_code_t
1433 ecc_sign (int algo, gcry_sexp_t *r_result, gcry_mpi_t data, gcry_mpi_t *skey,
1434           int flags, int hashalgo)
1435 {
1436   gpg_err_code_t rc;
1437   ECC_secret_key sk;
1438   gcry_mpi_t r, s;
1439
1440   (void)algo;
1441
1442   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1443       || !skey[6] )
1444     return GPG_ERR_BAD_MPI;
1445
1446   sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1447                 ? MPI_EC_TWISTEDEDWARDS
1448                 : MPI_EC_WEIERSTRASS);
1449   sk.E.p = skey[0];
1450   sk.E.a = skey[1];
1451   sk.E.b = skey[2];
1452   point_init (&sk.E.G);
1453   sk.Q.x = NULL;
1454   sk.Q.y = NULL;
1455   sk.Q.z = NULL;
1456   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1457   if (rc)
1458     {
1459       point_free (&sk.E.G);
1460       return rc;
1461     }
1462   sk.E.n = skey[4];
1463
1464   r = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1465   s = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1466
1467   {
1468     const unsigned char *buf;
1469     unsigned int n;
1470
1471     gcry_assert (mpi_is_opaque (skey[6]));
1472
1473     buf = gcry_mpi_get_opaque (skey[6], &n);
1474     if (!buf)
1475       rc = GPG_ERR_INV_OBJ;
1476     else
1477       {
1478         n = (n + 7)/8;
1479         sk.d = NULL;
1480         rc = gcry_mpi_scan (&sk.d, GCRYMPI_FMT_USG, buf, n, NULL);
1481         if (!rc)
1482           {
1483             if ((flags & PUBKEY_FLAG_EDDSA))
1484               {
1485                 rc = sign_eddsa (data, &sk, r, s, hashalgo, skey[5]);
1486                 if (!rc)
1487                   rc = gcry_sexp_build (r_result, NULL,
1488                                         "(sig-val(eddsa(r%M)(s%M)))", r, s);
1489               }
1490             else
1491               {
1492                 rc = sign_ecdsa (data, &sk, r, s, flags, hashalgo);
1493                 if (!rc)
1494                   rc = gcry_sexp_build (r_result, NULL,
1495                                         "(sig-val(ecdsa(r%M)(s%M)))", r, s);
1496               }
1497             gcry_mpi_release (sk.d);
1498             sk.d = NULL;
1499           }
1500       }
1501   }
1502
1503   mpi_free (r);
1504   mpi_free (s);
1505   point_free (&sk.E.G);
1506   if (sk.Q.x)
1507     point_free (&sk.Q);
1508   return rc;
1509 }
1510
1511
1512 static gcry_err_code_t
1513 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1514             int (*cmp)(void *, gcry_mpi_t), void *opaquev,
1515             int flags, int hashalgo)
1516 {
1517   gpg_err_code_t err;
1518   ECC_public_key pk;
1519
1520   (void)algo;
1521   (void)cmp;
1522   (void)opaquev;
1523
1524   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1525       || !pkey[3] || !pkey[4] || !pkey[5] )
1526     return GPG_ERR_BAD_MPI;
1527
1528   pk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
1529                 ? MPI_EC_TWISTEDEDWARDS
1530                 : MPI_EC_WEIERSTRASS);
1531   pk.E.p = pkey[0];
1532   pk.E.a = pkey[1];
1533   pk.E.b = pkey[2];
1534   point_init (&pk.E.G);
1535   err = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1536   if (err)
1537     {
1538       point_free (&pk.E.G);
1539       return err;
1540     }
1541   pk.E.n = pkey[4];
1542
1543   if ((flags & PUBKEY_FLAG_EDDSA))
1544     {
1545       pk.Q.x = NULL;
1546       pk.Q.y = NULL;
1547       pk.Q.z = NULL;
1548
1549       err = verify_eddsa (hash, &pk, data[0], data[1], hashalgo, pkey[5]);
1550     }
1551   else
1552     {
1553       point_init (&pk.Q);
1554       err = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1555       if (err)
1556         {
1557           point_free (&pk.E.G);
1558           point_free (&pk.Q);
1559           return err;
1560         }
1561
1562       if (mpi_is_opaque (hash))
1563         {
1564           const void *abuf;
1565           unsigned int abits, qbits;
1566           gcry_mpi_t a;
1567
1568           qbits = mpi_get_nbits (pk.E.n);
1569
1570           abuf = gcry_mpi_get_opaque (hash, &abits);
1571           err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1572           if (!err)
1573             {
1574               if (abits > qbits)
1575                 gcry_mpi_rshift (a, a, abits - qbits);
1576
1577               err = verify_ecdsa (a, &pk, data[0], data[1]);
1578               gcry_mpi_release (a);
1579             }
1580         }
1581       else
1582         err = verify_ecdsa (hash, &pk, data[0], data[1]);
1583     }
1584
1585   point_free (&pk.E.G);
1586   point_free (&pk.Q);
1587   return err;
1588 }
1589
1590
1591 /* ecdh raw is classic 2-round DH protocol published in 1976.
1592  *
1593  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1594  *
1595  * As with any PK operation, encrypt version uses a public key and
1596  * decrypt -- private.
1597  *
1598  * Symbols used below:
1599  *     G - field generator point
1600  *     d - private long-term scalar
1601  *    dG - public long-term key
1602  *     k - ephemeral scalar
1603  *    kG - ephemeral public key
1604  *   dkG - shared secret
1605  *
1606  * ecc_encrypt_raw description:
1607  *   input:
1608  *     data[0] : private scalar (k)
1609  *   output: A new S-expression with the parameters:
1610  *     s : shared point (kdG)
1611  *     e : generated ephemeral public key (kG)
1612  *
1613  * ecc_decrypt_raw description:
1614  *   input:
1615  *     data[0] : a point kG (ephemeral public key)
1616  *   output:
1617  *     result[0] : shared point (kdG)
1618  */
1619 static gcry_err_code_t
1620 ecc_encrypt_raw (int algo, gcry_sexp_t *r_result, gcry_mpi_t k,
1621                  gcry_mpi_t *pkey, int flags)
1622 {
1623   gpg_err_code_t rc;
1624   ECC_public_key pk;
1625   mpi_ec_t ctx;
1626   gcry_mpi_t s, e;
1627
1628   (void)algo;
1629   (void)flags;
1630
1631   if (!k
1632       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1633     return GPG_ERR_BAD_MPI;
1634
1635   pk.E.model = MPI_EC_WEIERSTRASS;
1636   pk.E.p = pkey[0];
1637   pk.E.a = pkey[1];
1638   pk.E.b = pkey[2];
1639   point_init (&pk.E.G);
1640   rc = _gcry_ecc_os2ec (&pk.E.G, pkey[3]);
1641   if (rc)
1642     {
1643       point_free (&pk.E.G);
1644       return rc;
1645     }
1646   pk.E.n = pkey[4];
1647   point_init (&pk.Q);
1648   rc = _gcry_ecc_os2ec (&pk.Q, pkey[5]);
1649   if (rc)
1650     {
1651       point_free (&pk.E.G);
1652       point_free (&pk.Q);
1653       return rc;
1654     }
1655
1656   ctx = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect,
1657                                      pk.E.p, pk.E.a, pk.E.b);
1658   s = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1659   e = mpi_alloc (mpi_get_nlimbs (pk.E.p));
1660
1661   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1662   {
1663     mpi_point_struct R;  /* Result that we return.  */
1664     gcry_mpi_t x, y;
1665
1666     x = mpi_new (0);
1667     y = mpi_new (0);
1668
1669     point_init (&R);
1670
1671     /* R = kQ  <=>  R = kdG  */
1672     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1673
1674     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1675       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1676     s = _gcry_ecc_ec2os (x, y, pk.E.p);
1677
1678     /* R = kG */
1679     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1680
1681     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1682       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1683     e = _gcry_ecc_ec2os (x, y, pk.E.p);
1684
1685     mpi_free (x);
1686     mpi_free (y);
1687
1688     point_free (&R);
1689   }
1690
1691   _gcry_mpi_ec_free (ctx);
1692   point_free (&pk.E.G);
1693   point_free (&pk.Q);
1694
1695   rc = gcry_sexp_build (r_result, NULL, "(enc-val(ecdh(s%m)(e%m)))", s, e);
1696   mpi_free (s);
1697   mpi_free (e);
1698
1699   return rc;
1700 }
1701
1702 /*  input:
1703  *     data[0] : a point kG (ephemeral public key)
1704  *   output:
1705  *     resaddr[0] : shared point kdG
1706  *
1707  *  see ecc_encrypt_raw for details.
1708  */
1709 static gcry_err_code_t
1710 ecc_decrypt_raw (int algo, gcry_sexp_t *r_plain, gcry_mpi_t *data,
1711                  gcry_mpi_t *skey, int flags,
1712                  enum pk_encoding encoding, int hash_algo,
1713                  unsigned char *label, size_t labellen)
1714 {
1715   gpg_err_code_t rc;
1716   ECC_secret_key sk;
1717   mpi_point_struct R;   /* Result that we return.  */
1718   mpi_point_struct kG;
1719   mpi_ec_t ctx;
1720   gcry_mpi_t r;
1721
1722   (void)algo;
1723   (void)flags;
1724   (void)encoding;
1725   (void)hash_algo;
1726   (void)label;
1727   (void)labellen;
1728
1729   if (!data || !data[0]
1730       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1731       || !skey[5] || !skey[6] )
1732     return GPG_ERR_BAD_MPI;
1733
1734   point_init (&kG);
1735   rc = _gcry_ecc_os2ec (&kG, data[0]);
1736   if (rc)
1737     {
1738       point_free (&kG);
1739       return rc;
1740     }
1741
1742   sk.E.model = MPI_EC_WEIERSTRASS;
1743   sk.E.p = skey[0];
1744   sk.E.a = skey[1];
1745   sk.E.b = skey[2];
1746   point_init (&sk.E.G);
1747   rc = _gcry_ecc_os2ec (&sk.E.G, skey[3]);
1748   if (rc)
1749     {
1750       point_free (&kG);
1751       point_free (&sk.E.G);
1752       return rc;
1753     }
1754   sk.E.n = skey[4];
1755   point_init (&sk.Q);
1756   rc = _gcry_ecc_os2ec (&sk.Q, skey[5]);
1757   if (rc)
1758     {
1759       point_free (&kG);
1760       point_free (&sk.E.G);
1761       point_free (&sk.Q);
1762       return rc;
1763     }
1764   sk.d = skey[6];
1765
1766   ctx = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect,
1767                                      sk.E.p, sk.E.a, sk.E.b);
1768
1769   /* R = dkG */
1770   point_init (&R);
1771   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1772
1773   point_free (&kG);
1774
1775   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1776   {
1777     gcry_mpi_t x, y;
1778
1779     x = mpi_new (0);
1780     y = mpi_new (0);
1781
1782     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1783       log_fatal ("ecdh: Failed to get affine coordinates\n");
1784
1785     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1786     if (!r)
1787       rc = gpg_err_code_from_syserror ();
1788     else
1789       rc = 0;
1790     mpi_free (x);
1791     mpi_free (y);
1792   }
1793
1794   point_free (&R);
1795   _gcry_mpi_ec_free (ctx);
1796   point_free (&kG);
1797   point_free (&sk.E.G);
1798   point_free (&sk.Q);
1799
1800   if (!rc)
1801     rc = gcry_sexp_build (r_plain, NULL, "(value %m)", r);
1802   mpi_free (r);
1803   return rc;
1804 }
1805
1806
1807 static unsigned int
1808 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1809 {
1810   (void)algo;
1811
1812   return mpi_get_nbits (pkey[0]);
1813 }
1814
1815
1816 /* See rsa.c for a description of this function.  */
1817 static gpg_err_code_t
1818 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1819 {
1820 #define N_COMPONENTS 6
1821   static const char names[N_COMPONENTS+1] = "pabgnq";
1822   gpg_err_code_t ec = 0;
1823   gcry_sexp_t l1;
1824   gcry_mpi_t values[N_COMPONENTS];
1825   int idx;
1826
1827   /* Clear the values for easier error cleanup.  */
1828   for (idx=0; idx < N_COMPONENTS; idx++)
1829     values[idx] = NULL;
1830
1831   /* Fill values with all provided parameters.  */
1832   for (idx=0; idx < N_COMPONENTS; idx++)
1833     {
1834       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1835       if (l1)
1836         {
1837           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1838           gcry_sexp_release (l1);
1839           if (!values[idx])
1840             {
1841               ec = GPG_ERR_INV_OBJ;
1842               goto leave;
1843             }
1844         }
1845     }
1846
1847   /* Check whether a curve parameter is available and use that to fill
1848      in missing values.  */
1849   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1850   if (l1)
1851     {
1852       char *curve;
1853       gcry_mpi_t tmpvalues[N_COMPONENTS];
1854
1855       for (idx = 0; idx < N_COMPONENTS; idx++)
1856         tmpvalues[idx] = NULL;
1857
1858       curve = _gcry_sexp_nth_string (l1, 1);
1859       gcry_sexp_release (l1);
1860       if (!curve)
1861         {
1862           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1863           goto leave;
1864         }
1865       ec = _gcry_ecc_get_param (curve, tmpvalues);
1866       gcry_free (curve);
1867       if (ec)
1868         goto leave;
1869
1870       for (idx = 0; idx < N_COMPONENTS; idx++)
1871         {
1872           if (!values[idx])
1873             values[idx] = tmpvalues[idx];
1874           else
1875             mpi_free (tmpvalues[idx]);
1876         }
1877     }
1878
1879   /* Check that all parameters are known and normalize all MPIs (that
1880      should not be required but we use an internal function later and
1881      thus we better make 100% sure that they are normalized). */
1882   for (idx = 0; idx < N_COMPONENTS; idx++)
1883     if (!values[idx])
1884       {
1885         ec = GPG_ERR_NO_OBJ;
1886         goto leave;
1887       }
1888     else
1889       _gcry_mpi_normalize (values[idx]);
1890
1891   /* Hash them all.  */
1892   for (idx = 0; idx < N_COMPONENTS; idx++)
1893     {
1894       char buf[30];
1895       unsigned char *rawmpi;
1896       unsigned int rawmpilen;
1897
1898       rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1899       if (!rawmpi)
1900         {
1901           ec = gpg_err_code_from_syserror ();
1902           goto leave;
1903         }
1904       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1905       gcry_md_write (md, buf, strlen (buf));
1906       gcry_md_write (md, rawmpi, rawmpilen);
1907       gcry_md_write (md, ")", 1);
1908       gcry_free (rawmpi);
1909     }
1910
1911  leave:
1912   for (idx = 0; idx < N_COMPONENTS; idx++)
1913     _gcry_mpi_release (values[idx]);
1914
1915   return ec;
1916 #undef N_COMPONENTS
1917 }
1918
1919
1920 \f
1921 /*
1922    Low-level API helper functions.
1923  */
1924
1925 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1926    algorithms.  Note that the caller has already stored NULL at
1927    R_SEXP.  */
1928 gpg_err_code_t
1929 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1930 {
1931   gpg_err_code_t rc;
1932   gcry_mpi_t mpi_G = NULL;
1933   gcry_mpi_t mpi_Q = NULL;
1934
1935   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1936     return GPG_ERR_BAD_CRYPT_CTX;
1937
1938   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1939     return GPG_ERR_NO_SECKEY;
1940
1941   /* Compute the public point if it is missing.  */
1942   if (!ec->Q && ec->d)
1943     {
1944       ec->Q = gcry_mpi_point_new (0);
1945       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
1946     }
1947
1948   /* Encode G and Q.  */
1949   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1950   if (!mpi_G)
1951     {
1952       rc = GPG_ERR_BROKEN_PUBKEY;
1953       goto leave;
1954     }
1955   if (!ec->Q)
1956     {
1957       rc = GPG_ERR_BAD_CRYPT_CTX;
1958       goto leave;
1959     }
1960   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1961   if (!mpi_Q)
1962     {
1963       rc = GPG_ERR_BROKEN_PUBKEY;
1964       goto leave;
1965     }
1966
1967   /* Fixme: We should return a curve name instead of the parameters if
1968      if know that they match a curve.  */
1969
1970   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1971     {
1972       /* Let's return a private key. */
1973       rc = gcry_sexp_build
1974         (r_sexp, NULL,
1975          "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1976          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d);
1977     }
1978   else if (ec->Q)
1979     {
1980       /* Let's return a public key.  */
1981       rc = gcry_sexp_build
1982         (r_sexp, NULL,
1983          "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1984          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q);
1985     }
1986   else
1987     rc = GPG_ERR_BAD_CRYPT_CTX;
1988
1989  leave:
1990   mpi_free (mpi_Q);
1991   mpi_free (mpi_G);
1992   return rc;
1993 }
1994
1995
1996 \f
1997 /*
1998      Self-test section.
1999  */
2000
2001
2002 static gpg_err_code_t
2003 selftests_ecdsa (selftest_report_func_t report)
2004 {
2005   const char *what;
2006   const char *errtxt;
2007
2008   what = "low-level";
2009   errtxt = NULL; /*selftest ();*/
2010   if (errtxt)
2011     goto failed;
2012
2013   /* FIXME:  need more tests.  */
2014
2015   return 0; /* Succeeded. */
2016
2017  failed:
2018   if (report)
2019     report ("pubkey", GCRY_PK_ECC, what, errtxt);
2020   return GPG_ERR_SELFTEST_FAILED;
2021 }
2022
2023
2024 /* Run a full self-test for ALGO and return 0 on success.  */
2025 static gpg_err_code_t
2026 run_selftests (int algo, int extended, selftest_report_func_t report)
2027 {
2028   (void)extended;
2029
2030   if (algo != GCRY_PK_ECC)
2031     return GPG_ERR_PUBKEY_ALGO;
2032
2033   return selftests_ecdsa (report);
2034 }
2035
2036
2037
2038 \f
2039 static const char *ecc_names[] =
2040   {
2041     "ecc",
2042     "ecdsa",
2043     "ecdh",
2044     "eddsa",
2045     NULL,
2046   };
2047
2048 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
2049   {
2050     GCRY_PK_ECC, { 0, 0 },
2051     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
2052     "ECC", ecc_names,
2053     "pabgnq", "pabgnqd", "sw", "rs", "pabgnq",
2054     ecc_generate,
2055     ecc_check_secret_key,
2056     ecc_encrypt_raw,
2057     ecc_decrypt_raw,
2058     ecc_sign,
2059     ecc_verify,
2060     ecc_get_nbits,
2061     run_selftests,
2062     compute_keygrip,
2063     _gcry_ecc_get_param,
2064     _gcry_ecc_get_curve,
2065     _gcry_ecc_get_param_sexp
2066   };