ecc: Fix some memory leaks
[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 static const char *ecc_names[] =
69   {
70     "ecc",
71     "ecdsa",
72     "ecdh",
73     "eddsa",
74     "gost",
75     NULL,
76   };
77
78
79 /* Registered progress function and its callback value. */
80 static void (*progress_cb) (void *, const char*, int, int, int);
81 static void *progress_cb_data;
82
83
84 \f
85 /* Local prototypes. */
86 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
87 static int check_secret_key (ECC_secret_key * sk);
88 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
89 static unsigned int ecc_get_nbits (gcry_sexp_t parms);
90
91
92
93 \f
94 void
95 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
96                                             int, int, int),
97                                 void *cb_data)
98 {
99   progress_cb = cb;
100   progress_cb_data = cb_data;
101 }
102
103 /* static void */
104 /* progress (int c) */
105 /* { */
106 /*   if (progress_cb) */
107 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
108 /* } */
109
110
111 \f
112
113 /*
114  * Solve the right side of the Weierstrass equation.
115  */
116 static gcry_mpi_t
117 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
118 {
119   gcry_mpi_t three, x_3, axb, y;
120
121   three = mpi_alloc_set_ui (3);
122   x_3 = mpi_new (0);
123   axb = mpi_new (0);
124   y   = mpi_new (0);
125
126   mpi_powm (x_3, x, three, base->p);
127   mpi_mulm (axb, base->a, x, base->p);
128   mpi_addm (axb, axb, base->b, base->p);
129   mpi_addm (y, x_3, axb, base->p);
130
131   mpi_free (x_3);
132   mpi_free (axb);
133   mpi_free (three);
134   return y; /* The quadratic value of the coordinate if it exist. */
135 }
136
137
138 /* Standard version of the key generation.  */
139 static gpg_err_code_t
140 nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
141                    gcry_random_level_t random_level, unsigned int nbits)
142 {
143   mpi_point_struct Q;
144
145   point_init (&Q);
146
147   /* Generate a secret.  */
148   sk->d = _gcry_dsa_gen_k (E->n, random_level);
149
150   /* Compute Q.  */
151   _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
152
153   /* Copy the stuff to the key structures. */
154   sk->E.model = E->model;
155   sk->E.dialect = E->dialect;
156   sk->E.p = mpi_copy (E->p);
157   sk->E.a = mpi_copy (E->a);
158   sk->E.b = mpi_copy (E->b);
159   point_init (&sk->E.G);
160   point_set (&sk->E.G, &E->G);
161   sk->E.n = mpi_copy (E->n);
162   point_init (&sk->Q);
163
164   /* We want the Q=(x,y) be a "compliant key" in terms of the
165    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
166    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
167    * end up with the min(y,p-y) as the y coordinate.  Such a public
168    * key allows the most efficient compression: y can simply be
169    * dropped because we know that it's a minimum of the two
170    * possibilities without any loss of security.  */
171   {
172     gcry_mpi_t x, y, negative;
173     const unsigned int pbits = mpi_get_nbits (E->p);
174
175     x = mpi_new (pbits);
176     y = mpi_new (pbits);
177     negative = mpi_new (pbits);
178
179     if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
180       log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
181
182     if (E->model == MPI_EC_WEIERSTRASS)
183       mpi_sub (negative, E->p, y);      /* negative = p - y */
184     else
185       mpi_sub (negative, E->p, x);      /* negative = p - x */
186
187     if (mpi_cmp (negative, y) < 0)   /* p - y < p */
188       {
189         /* We need to end up with -Q; this assures that new Q's y is
190            the smallest one */
191         mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
192         if (E->model == MPI_EC_WEIERSTRASS)
193           gcry_mpi_point_snatch_set (&sk->Q, x, negative, mpi_alloc_set_ui (1));
194         else
195           gcry_mpi_point_snatch_set (&sk->Q, negative, y, mpi_alloc_set_ui (1));
196
197         if (DBG_CIPHER)
198           log_debug ("ecgen converted Q to a compliant point\n");
199       }
200     else /* p - y >= p */
201       {
202         /* No change is needed exactly 50% of the time: just copy. */
203         point_set (&sk->Q, &Q);
204         if (DBG_CIPHER)
205           log_debug ("ecgen didn't need to convert Q to a compliant point\n");
206
207         mpi_free (negative);
208         if (E->model == MPI_EC_WEIERSTRASS)
209           mpi_free (x);
210         else
211           mpi_free (y);
212       }
213
214     if (E->model == MPI_EC_WEIERSTRASS)
215       mpi_free (y);
216     else
217       mpi_free (x);
218   }
219
220   point_free (&Q);
221   /* Now we can test our keys (this should never fail!).  */
222   test_keys (sk, nbits - 64);
223
224   return 0;
225 }
226
227
228 /*
229  * To verify correct skey it use a random information.
230  * First, encrypt and decrypt this dummy value,
231  * test if the information is recuperated.
232  * Second, test with the sign and verify functions.
233  */
234 static void
235 test_keys (ECC_secret_key *sk, unsigned int nbits)
236 {
237   ECC_public_key pk;
238   gcry_mpi_t test = mpi_new (nbits);
239   mpi_point_struct R_;
240   gcry_mpi_t c = mpi_new (nbits);
241   gcry_mpi_t out = mpi_new (nbits);
242   gcry_mpi_t r = mpi_new (nbits);
243   gcry_mpi_t s = mpi_new (nbits);
244
245   if (DBG_CIPHER)
246     log_debug ("Testing key.\n");
247
248   point_init (&R_);
249
250   pk.E = _gcry_ecc_curve_copy (sk->E);
251   point_init (&pk.Q);
252   point_set (&pk.Q, &sk->Q);
253
254   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
255
256   if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) )
257     log_fatal ("ECDSA operation: sign failed\n");
258
259   if (_gcry_ecc_ecdsa_verify (test, &pk, r, s))
260     {
261       log_fatal ("ECDSA operation: sign, verify failed\n");
262     }
263
264   if (DBG_CIPHER)
265     log_debug ("ECDSA operation: sign, verify ok.\n");
266
267   point_free (&pk.Q);
268   _gcry_ecc_curve_free (&pk.E);
269
270   point_free (&R_);
271   mpi_free (s);
272   mpi_free (r);
273   mpi_free (out);
274   mpi_free (c);
275   mpi_free (test);
276 }
277
278
279 /*
280  * To check the validity of the value, recalculate the correspondence
281  * between the public value and the secret one.
282  */
283 static int
284 check_secret_key (ECC_secret_key * sk)
285 {
286   int rc = 1;
287   mpi_point_struct Q;
288   gcry_mpi_t y_2, y2;
289   gcry_mpi_t x1, x2;
290   mpi_ec_t ctx = NULL;
291
292   point_init (&Q);
293
294   /* ?primarity test of 'p' */
295   /*  (...) //!! */
296   /* G in E(F_p) */
297   y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
298   y2 = mpi_alloc (0);
299   x1 = mpi_alloc (0);
300   x2 = mpi_alloc (0);
301   mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
302   if (mpi_cmp (y_2, y2))
303     {
304       if (DBG_CIPHER)
305         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
306       goto leave;
307     }
308   /* G != PaI */
309   if (!mpi_cmp_ui (sk->E.G.z, 0))
310     {
311       if (DBG_CIPHER)
312         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
313       goto leave;
314     }
315
316   ctx = _gcry_mpi_ec_p_internal_new (sk->E.model, sk->E.dialect, 0,
317                                      sk->E.p, sk->E.a, sk->E.b);
318
319   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
320   if (mpi_cmp_ui (Q.z, 0))
321     {
322       if (DBG_CIPHER)
323         log_debug ("check_secret_key: E is not a curve of order n\n");
324       goto leave;
325     }
326   /* pubkey cannot be PaI */
327   if (!mpi_cmp_ui (sk->Q.z, 0))
328     {
329       if (DBG_CIPHER)
330         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
331       goto leave;
332     }
333   /* pubkey = [d]G over E */
334   _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
335
336   if (_gcry_mpi_ec_get_affine (x1, y_2, &Q, ctx))
337     {
338       if (DBG_CIPHER)
339         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
340       goto leave;
341     }
342
343   /* Fast path for loaded secret keys - Q is already in affine coordinates */
344   if (!mpi_cmp_ui (sk->Q.z, 1))
345     {
346       if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y_2, sk->Q.y))
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   else
355     {
356       if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ctx))
357         {
358           if (DBG_CIPHER)
359             log_debug ("Bad check: Q can not be a Point at Infinity!\n");
360           goto leave;
361         }
362
363       if (mpi_cmp (x1, x2) || mpi_cmp (y_2, y2))
364         {
365           if (DBG_CIPHER)
366             log_debug
367               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
368           goto leave;
369         }
370     }
371   rc = 0; /* Okay.  */
372
373  leave:
374   _gcry_mpi_ec_free (ctx);
375   mpi_free (x2);
376   mpi_free (x1);
377   mpi_free (y2);
378   mpi_free (y_2);
379   point_free (&Q);
380   return rc;
381 }
382
383
384 \f
385 /*********************************************
386  **************  interface  ******************
387  *********************************************/
388
389 static gcry_err_code_t
390 ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
391 {
392   gpg_err_code_t rc;
393   unsigned int nbits;
394   elliptic_curve_t E;
395   ECC_secret_key sk;
396   gcry_mpi_t x = NULL;
397   gcry_mpi_t y = NULL;
398   char *curve_name = NULL;
399   gcry_sexp_t l1;
400   gcry_random_level_t random_level;
401   mpi_ec_t ctx = NULL;
402   gcry_sexp_t curve_info = NULL;
403   gcry_sexp_t curve_flags = NULL;
404   gcry_mpi_t base = NULL;
405   gcry_mpi_t public = NULL;
406   gcry_mpi_t secret = NULL;
407   int flags = 0;
408
409   memset (&E, 0, sizeof E);
410   memset (&sk, 0, sizeof sk);
411
412   rc = _gcry_pk_util_get_nbits (genparms, &nbits);
413   if (rc)
414     return rc;
415
416   /* Parse the optional "curve" parameter. */
417   l1 = gcry_sexp_find_token (genparms, "curve", 0);
418   if (l1)
419     {
420       curve_name = _gcry_sexp_nth_string (l1, 1);
421       gcry_sexp_release (l1);
422       if (!curve_name)
423         return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
424     }
425
426   /* Parse the optional flags list.  */
427   l1 = gcry_sexp_find_token (genparms, "flags", 0);
428   if (l1)
429     {
430       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
431       gcry_sexp_release (l1);
432       if (rc)
433         goto leave;
434     }
435
436   /* Parse the deprecated optional transient-key flag.  */
437   l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
438   if (l1)
439     {
440       flags |= PUBKEY_FLAG_TRANSIENT_KEY;
441       gcry_sexp_release (l1);
442     }
443
444   /* NBITS is required if no curve name has been given.  */
445   if (!nbits && !curve_name)
446     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
447
448   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
449   gcry_free (curve_name); curve_name = NULL;
450   if (rc)
451     goto leave;
452
453   if (DBG_CIPHER)
454     {
455       log_debug ("ecgen curve info: %s/%s\n",
456                  _gcry_ecc_model2str (E.model),
457                  _gcry_ecc_dialect2str (E.dialect));
458       if (E.name)
459         log_debug ("ecgen curve used: %s\n", E.name);
460       log_printmpi ("ecgen curve   p", E.p);
461       log_printmpi ("ecgen curve   a", E.a);
462       log_printmpi ("ecgen curve   b", E.b);
463       log_printmpi ("ecgen curve   n", E.n);
464       log_printpnt ("ecgen curve G", &E.G, NULL);
465     }
466
467   if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
468     random_level = GCRY_STRONG_RANDOM;
469   else
470     random_level = GCRY_VERY_STRONG_RANDOM;
471
472   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, 0, E.p, E.a, E.b);
473   x = mpi_new (0);
474   y = mpi_new (0);
475
476   if ((flags & PUBKEY_FLAG_EDDSA))
477     rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, random_level);
478   else
479     rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
480   if (rc)
481     goto leave;
482
483   /* Copy data to the result.  */
484   if (_gcry_mpi_ec_get_affine (x, y, &sk.E.G, ctx))
485     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
486   base = _gcry_ecc_ec2os (x, y, sk.E.p);
487   if (sk.E.dialect == ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_NOCOMP))
488     {
489       unsigned char *encpk;
490       unsigned int encpklen;
491
492       rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, x, y, &encpk, &encpklen);
493       if (rc)
494         return rc;
495       public = mpi_new (0);
496       gcry_mpi_set_opaque (public, encpk, encpklen*8);
497       encpk = NULL;
498     }
499   else
500     {
501       if (_gcry_mpi_ec_get_affine (x, y, &sk.Q, ctx))
502         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
503       public = _gcry_ecc_ec2os (x, y, sk.E.p);
504     }
505   secret = sk.d; sk.d = NULL;
506   if (E.name)
507     {
508       rc = gcry_sexp_build (&curve_info, NULL, "(curve %s)", E.name);
509       if (rc)
510         goto leave;
511     }
512
513   if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA))
514     {
515       rc = gcry_sexp_build
516         (&curve_flags, NULL,
517          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
518          "(flags param eddsa)" :
519          ((flags & PUBKEY_FLAG_PARAM))?
520          "(flags param)" :
521          "(flags eddsa)");
522       if (rc)
523         goto leave;
524     }
525
526   if ((flags & PUBKEY_FLAG_PARAM) && E.name)
527     rc = gcry_sexp_build (r_skey, NULL,
528                           "(key-data"
529                           " (public-key"
530                           "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))"
531                           " (private-key"
532                           "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
533                           " )",
534                           curve_info, curve_flags,
535                           sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
536                           curve_info, curve_flags,
537                           sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret);
538   else
539     rc = gcry_sexp_build (r_skey, NULL,
540                           "(key-data"
541                           " (public-key"
542                           "  (ecc%S%S(q%m)))"
543                           " (private-key"
544                           "  (ecc%S%S(q%m)(d%m)))"
545                           " )",
546                           curve_info, curve_flags,
547                           public,
548                           curve_info, curve_flags,
549                           public, secret);
550   if (rc)
551     goto leave;
552
553   if (DBG_CIPHER)
554     {
555       log_printmpi ("ecgen result  p", sk.E.p);
556       log_printmpi ("ecgen result  a", sk.E.a);
557       log_printmpi ("ecgen result  b", sk.E.b);
558       log_printmpi ("ecgen result  G", base);
559       log_printmpi ("ecgen result  n", sk.E.n);
560       log_printmpi ("ecgen result  Q", public);
561       log_printmpi ("ecgen result  d", secret);
562       if ((flags & PUBKEY_FLAG_EDDSA))
563         log_debug ("ecgen result  using Ed25519+EdDSA\n");
564     }
565
566  leave:
567   mpi_free (secret);
568   mpi_free (public);
569   mpi_free (base);
570   {
571     _gcry_ecc_curve_free (&sk.E);
572     point_free (&sk.Q);
573     mpi_free (sk.d);
574   }
575   _gcry_ecc_curve_free (&E);
576   mpi_free (x);
577   mpi_free (y);
578   _gcry_mpi_ec_free (ctx);
579   gcry_sexp_release (curve_flags);
580   gcry_sexp_release (curve_info);
581   return rc;
582 }
583
584
585 static gcry_err_code_t
586 ecc_check_secret_key (gcry_sexp_t keyparms)
587 {
588   gcry_err_code_t rc;
589   gcry_sexp_t l1 = NULL;
590   char *curvename = NULL;
591   gcry_mpi_t mpi_g = NULL;
592   gcry_mpi_t mpi_q = NULL;
593   ECC_secret_key sk;
594
595   memset (&sk, 0, sizeof sk);
596
597   /*
598    * Extract the key.
599    */
600   rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d",
601                                  &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
602                                  &mpi_q, &sk.d, NULL);
603   if (rc)
604     goto leave;
605   if (mpi_g)
606     {
607       point_init (&sk.E.G);
608       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
609       if (rc)
610         goto leave;
611     }
612   /* Add missing parameters using the optional curve parameter.  */
613   gcry_sexp_release (l1);
614   l1 = gcry_sexp_find_token (keyparms, "curve", 5);
615   if (l1)
616     {
617       curvename = gcry_sexp_nth_string (l1, 1);
618       if (curvename)
619         {
620           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
621           if (rc)
622             return rc;
623         }
624     }
625   /* Guess required fields if a curve parameter has not been given.
626      FIXME: This is a crude hacks.  We need to fix that.  */
627   if (!curvename)
628     {
629       sk.E.model = MPI_EC_WEIERSTRASS;
630       sk.E.dialect = ECC_DIALECT_STANDARD;
631     }
632   if (DBG_CIPHER)
633     {
634       log_debug ("ecc_testkey inf: %s/%s\n",
635                  _gcry_ecc_model2str (sk.E.model),
636                  _gcry_ecc_dialect2str (sk.E.dialect));
637       if (sk.E.name)
638         log_debug  ("ecc_testkey nam: %s\n", sk.E.name);
639       log_printmpi ("ecc_testkey   p", sk.E.p);
640       log_printmpi ("ecc_testkey   a", sk.E.a);
641       log_printmpi ("ecc_testkey   b", sk.E.b);
642       log_printpnt ("ecc_testkey g",   &sk.E.G, NULL);
643       log_printmpi ("ecc_testkey   n", sk.E.n);
644       log_printmpi ("ecc_testkey   q", mpi_q);
645       if (!fips_mode ())
646         log_printmpi ("ecc_testkey   d", sk.d);
647     }
648   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d)
649     {
650       rc = GPG_ERR_NO_OBJ;
651       goto leave;
652     }
653
654   if (mpi_q)
655     {
656       point_init (&sk.Q);
657       rc = _gcry_ecc_os2ec (&sk.Q, mpi_q);
658       if (rc)
659         goto leave;
660     }
661   else
662     {
663       /* The current test requires Q.  */
664       rc = GPG_ERR_NO_OBJ;
665       goto leave;
666     }
667
668   if (check_secret_key (&sk))
669     rc = GPG_ERR_BAD_SECKEY;
670
671  leave:
672   gcry_mpi_release (sk.E.p);
673   gcry_mpi_release (sk.E.a);
674   gcry_mpi_release (sk.E.b);
675   gcry_mpi_release (mpi_g);
676   point_free (&sk.E.G);
677   gcry_mpi_release (sk.E.n);
678   gcry_mpi_release (mpi_q);
679   point_free (&sk.Q);
680   gcry_mpi_release (sk.d);
681   gcry_free (curvename);
682   gcry_sexp_release (l1);
683   if (DBG_CIPHER)
684     log_debug ("ecc_testkey   => %s\n", gpg_strerror (rc));
685   return rc;
686 }
687
688
689 static gcry_err_code_t
690 ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
691 {
692   gcry_err_code_t rc;
693   struct pk_encoding_ctx ctx;
694   gcry_mpi_t data = NULL;
695   gcry_sexp_t l1 = NULL;
696   char *curvename = NULL;
697   gcry_mpi_t mpi_g = NULL;
698   gcry_mpi_t mpi_q = NULL;
699   ECC_secret_key sk;
700   gcry_mpi_t sig_r = NULL;
701   gcry_mpi_t sig_s = NULL;
702
703   memset (&sk, 0, sizeof sk);
704
705   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, 0);
706
707   /* Extract the data.  */
708   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
709   if (rc)
710     goto leave;
711   if (DBG_CIPHER)
712     log_mpidump ("ecc_sign   data", data);
713
714   /*
715    * Extract the key.
716    */
717   if ((ctx.flags & PUBKEY_FLAG_PARAM))
718     rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d",
719                                    &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
720                                    &mpi_q, &sk.d, NULL);
721   else
722     rc = _gcry_sexp_extract_param (keyparms, NULL, "/q?+d",
723                                    &mpi_q, &sk.d, NULL);
724   if (rc)
725     goto leave;
726   if (mpi_g)
727     {
728       point_init (&sk.E.G);
729       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
730       if (rc)
731         goto leave;
732     }
733   /* Add missing parameters using the optional curve parameter.  */
734   gcry_sexp_release (l1);
735   l1 = gcry_sexp_find_token (keyparms, "curve", 5);
736   if (l1)
737     {
738       curvename = gcry_sexp_nth_string (l1, 1);
739       if (curvename)
740         {
741           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
742           if (rc)
743             return rc;
744         }
745     }
746   /* Guess required fields if a curve parameter has not been given.
747      FIXME: This is a crude hacks.  We need to fix that.  */
748   if (!curvename)
749     {
750       sk.E.model = ((ctx.flags & PUBKEY_FLAG_EDDSA)
751                     ? MPI_EC_TWISTEDEDWARDS
752                     : MPI_EC_WEIERSTRASS);
753       sk.E.dialect = ((ctx.flags & PUBKEY_FLAG_EDDSA)
754                       ? ECC_DIALECT_ED25519
755                       : ECC_DIALECT_STANDARD);
756     }
757   if (DBG_CIPHER)
758     {
759       log_debug ("ecc_sign   info: %s/%s%s\n",
760                  _gcry_ecc_model2str (sk.E.model),
761                  _gcry_ecc_dialect2str (sk.E.dialect),
762                  (ctx.flags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
763       if (sk.E.name)
764         log_debug  ("ecc_sign   name: %s\n", sk.E.name);
765       log_printmpi ("ecc_sign      p", sk.E.p);
766       log_printmpi ("ecc_sign      a", sk.E.a);
767       log_printmpi ("ecc_sign      b", sk.E.b);
768       log_printpnt ("ecc_sign    g",   &sk.E.G, NULL);
769       log_printmpi ("ecc_sign      n", sk.E.n);
770       log_printmpi ("ecc_sign      q", mpi_q);
771       if (!fips_mode ())
772         log_printmpi ("ecc_sign      d", sk.d);
773     }
774   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d)
775     {
776       rc = GPG_ERR_NO_OBJ;
777       goto leave;
778     }
779
780
781   sig_r = gcry_mpi_new (0);
782   sig_s = gcry_mpi_new (0);
783   if ((ctx.flags & PUBKEY_FLAG_EDDSA))
784     {
785       /* EdDSA requires the public key.  */
786       rc = _gcry_ecc_eddsa_sign (data, &sk, sig_r, sig_s, ctx.hash_algo, mpi_q);
787       if (!rc)
788         rc = gcry_sexp_build (r_sig, NULL,
789                               "(sig-val(eddsa(r%M)(s%M)))", sig_r, sig_s);
790     }
791   else if ((ctx.flags & PUBKEY_FLAG_GOST))
792     {
793       rc = _gcry_ecc_gost_sign (data, &sk, sig_r, sig_s);
794       if (!rc)
795         rc = gcry_sexp_build (r_sig, NULL,
796                               "(sig-val(gost(r%M)(s%M)))", sig_r, sig_s);
797     }
798   else
799     {
800       rc = _gcry_ecc_ecdsa_sign (data, &sk, sig_r, sig_s,
801                                  ctx.flags, ctx.hash_algo);
802       if (!rc)
803         rc = gcry_sexp_build (r_sig, NULL,
804                               "(sig-val(ecdsa(r%M)(s%M)))", sig_r, sig_s);
805     }
806
807
808  leave:
809   gcry_mpi_release (sk.E.p);
810   gcry_mpi_release (sk.E.a);
811   gcry_mpi_release (sk.E.b);
812   gcry_mpi_release (mpi_g);
813   point_free (&sk.E.G);
814   gcry_mpi_release (sk.E.n);
815   gcry_mpi_release (mpi_q);
816   point_free (&sk.Q);
817   gcry_mpi_release (sk.d);
818   gcry_mpi_release (sig_r);
819   gcry_mpi_release (sig_s);
820   gcry_free (curvename);
821   gcry_mpi_release (data);
822   gcry_sexp_release (l1);
823   _gcry_pk_util_free_encoding_ctx (&ctx);
824   if (DBG_CIPHER)
825     log_debug ("ecc_sign      => %s\n", gpg_strerror (rc));
826   return rc;
827 }
828
829
830 static gcry_err_code_t
831 ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
832 {
833   gcry_err_code_t rc;
834   struct pk_encoding_ctx ctx;
835   gcry_sexp_t l1 = NULL;
836   char *curvename = NULL;
837   gcry_mpi_t mpi_g = NULL;
838   gcry_mpi_t mpi_q = NULL;
839   gcry_mpi_t sig_r = NULL;
840   gcry_mpi_t sig_s = NULL;
841   gcry_mpi_t data = NULL;
842   ECC_public_key pk;
843   int sigflags;
844
845   memset (&pk, 0, sizeof pk);
846   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
847                                    ecc_get_nbits (s_keyparms));
848
849   /* Extract the data.  */
850   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
851   if (rc)
852     goto leave;
853   if (DBG_CIPHER)
854     log_mpidump ("ecc_verify data", data);
855
856   /*
857    * Extract the signature value.
858    */
859   rc = _gcry_pk_util_preparse_sigval (s_sig, ecc_names, &l1, &sigflags);
860   if (rc)
861     goto leave;
862   rc = _gcry_sexp_extract_param (l1, NULL,
863                                  (sigflags & PUBKEY_FLAG_EDDSA)? "/rs":"rs",
864                                  &sig_r, &sig_s, NULL);
865   if (rc)
866     goto leave;
867   if (DBG_CIPHER)
868     {
869       log_mpidump ("ecc_verify  s_r", sig_r);
870       log_mpidump ("ecc_verify  s_s", sig_s);
871     }
872   if ((ctx.flags & PUBKEY_FLAG_EDDSA) ^ (sigflags & PUBKEY_FLAG_EDDSA))
873     {
874       rc = GPG_ERR_CONFLICT; /* Inconsistent use of flag/algoname.  */
875       goto leave;
876     }
877
878
879   /*
880    * Extract the key.
881    */
882   if ((ctx.flags & PUBKEY_FLAG_PARAM))
883     rc = _gcry_sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?/q",
884                                    &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
885                                    &mpi_q, NULL);
886   else
887     rc = _gcry_sexp_extract_param (s_keyparms, NULL, "/q",
888                                    &mpi_q, NULL);
889   if (rc)
890     goto leave;
891   if (mpi_g)
892     {
893       point_init (&pk.E.G);
894       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
895       if (rc)
896         goto leave;
897     }
898   /* Add missing parameters using the optional curve parameter.  */
899   gcry_sexp_release (l1);
900   l1 = gcry_sexp_find_token (s_keyparms, "curve", 5);
901   if (l1)
902     {
903       curvename = gcry_sexp_nth_string (l1, 1);
904       if (curvename)
905         {
906           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
907           if (rc)
908             return rc;
909         }
910     }
911   /* Guess required fields if a curve parameter has not been given.
912      FIXME: This is a crude hacks.  We need to fix that.  */
913   if (!curvename)
914     {
915       pk.E.model = ((sigflags & PUBKEY_FLAG_EDDSA)
916                     ? MPI_EC_TWISTEDEDWARDS
917                     : MPI_EC_WEIERSTRASS);
918       pk.E.dialect = ((sigflags & PUBKEY_FLAG_EDDSA)
919                       ? ECC_DIALECT_ED25519
920                       : ECC_DIALECT_STANDARD);
921     }
922
923   if (DBG_CIPHER)
924     {
925       log_debug ("ecc_verify info: %s/%s%s\n",
926                  _gcry_ecc_model2str (pk.E.model),
927                  _gcry_ecc_dialect2str (pk.E.dialect),
928                  (sigflags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
929       if (pk.E.name)
930         log_debug  ("ecc_verify name: %s\n", pk.E.name);
931       log_printmpi ("ecc_verify    p", pk.E.p);
932       log_printmpi ("ecc_verify    a", pk.E.a);
933       log_printmpi ("ecc_verify    b", pk.E.b);
934       log_printpnt ("ecc_verify  g",   &pk.E.G, NULL);
935       log_printmpi ("ecc_verify    n", pk.E.n);
936       log_printmpi ("ecc_verify    q", mpi_q);
937     }
938   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q)
939     {
940       rc = GPG_ERR_NO_OBJ;
941       goto leave;
942     }
943
944
945   /*
946    * Verify the signature.
947    */
948   if ((sigflags & PUBKEY_FLAG_EDDSA))
949     {
950       rc = _gcry_ecc_eddsa_verify (data, &pk, sig_r, sig_s,
951                                    ctx.hash_algo, mpi_q);
952     }
953   else if ((sigflags & PUBKEY_FLAG_GOST))
954     {
955       point_init (&pk.Q);
956       rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
957       if (rc)
958         goto leave;
959
960       rc = _gcry_ecc_gost_verify (data, &pk, sig_r, sig_s);
961     }
962   else
963     {
964       point_init (&pk.Q);
965       if (pk.E.dialect == ECC_DIALECT_ED25519)
966         {
967           mpi_ec_t ec;
968
969           /* Fixme: Factor the curve context setup out of eddsa_verify
970              and ecdsa_verify. So that we don't do it twice.  */
971           ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
972                                             pk.E.p, pk.E.a, pk.E.b);
973
974           rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &pk.Q, NULL, NULL);
975           _gcry_mpi_ec_free (ec);
976         }
977       else
978         {
979           rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
980         }
981       if (rc)
982         goto leave;
983
984       if (mpi_is_opaque (data))
985         {
986           const void *abuf;
987           unsigned int abits, qbits;
988           gcry_mpi_t a;
989
990           qbits = mpi_get_nbits (pk.E.n);
991
992           abuf = gcry_mpi_get_opaque (data, &abits);
993           rc = gpg_err_code (gcry_mpi_scan (&a, GCRYMPI_FMT_USG,
994                                             abuf, (abits+7)/8, NULL));
995           if (!rc)
996             {
997               if (abits > qbits)
998                 gcry_mpi_rshift (a, a, abits - qbits);
999
1000               rc = _gcry_ecc_ecdsa_verify (a, &pk, sig_r, sig_s);
1001               gcry_mpi_release (a);
1002             }
1003         }
1004       else
1005         rc = _gcry_ecc_ecdsa_verify (data, &pk, sig_r, sig_s);
1006     }
1007
1008  leave:
1009   gcry_mpi_release (pk.E.p);
1010   gcry_mpi_release (pk.E.a);
1011   gcry_mpi_release (pk.E.b);
1012   gcry_mpi_release (mpi_g);
1013   point_free (&pk.E.G);
1014   gcry_mpi_release (pk.E.n);
1015   gcry_mpi_release (mpi_q);
1016   point_free (&pk.Q);
1017   gcry_mpi_release (data);
1018   gcry_mpi_release (sig_r);
1019   gcry_mpi_release (sig_s);
1020   gcry_free (curvename);
1021   gcry_sexp_release (l1);
1022   _gcry_pk_util_free_encoding_ctx (&ctx);
1023   if (DBG_CIPHER)
1024     log_debug ("ecc_verify    => %s\n", rc?gpg_strerror (rc):"Good");
1025   return rc;
1026 }
1027
1028
1029 /* ecdh raw is classic 2-round DH protocol published in 1976.
1030  *
1031  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1032  *
1033  * As with any PK operation, encrypt version uses a public key and
1034  * decrypt -- private.
1035  *
1036  * Symbols used below:
1037  *     G - field generator point
1038  *     d - private long-term scalar
1039  *    dG - public long-term key
1040  *     k - ephemeral scalar
1041  *    kG - ephemeral public key
1042  *   dkG - shared secret
1043  *
1044  * ecc_encrypt_raw description:
1045  *   input:
1046  *     data[0] : private scalar (k)
1047  *   output: A new S-expression with the parameters:
1048  *     s : shared point (kdG)
1049  *     e : generated ephemeral public key (kG)
1050  *
1051  * ecc_decrypt_raw description:
1052  *   input:
1053  *     data[0] : a point kG (ephemeral public key)
1054  *   output:
1055  *     result[0] : shared point (kdG)
1056  */
1057 static gcry_err_code_t
1058 ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
1059 {
1060   gcry_err_code_t rc;
1061   struct pk_encoding_ctx ctx;
1062   gcry_sexp_t l1 = NULL;
1063   char *curvename = NULL;
1064   gcry_mpi_t mpi_g = NULL;
1065   gcry_mpi_t mpi_q = NULL;
1066   gcry_mpi_t mpi_s = NULL;
1067   gcry_mpi_t mpi_e = NULL;
1068   gcry_mpi_t data = NULL;
1069   ECC_public_key pk;
1070   mpi_ec_t ec = NULL;
1071
1072   memset (&pk, 0, sizeof pk);
1073   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
1074                                    ecc_get_nbits (keyparms));
1075
1076   /*
1077    * Extract the data.
1078    */
1079   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
1080   if (rc)
1081     goto leave;
1082   if (DBG_CIPHER)
1083     log_mpidump ("ecc_encrypt data", data);
1084   if (mpi_is_opaque (data))
1085     {
1086       rc = GPG_ERR_INV_DATA;
1087       goto leave;
1088     }
1089
1090
1091   /*
1092    * Extract the key.
1093    */
1094   rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+q",
1095                                  &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
1096                                  &mpi_q, NULL);
1097   if (rc)
1098     goto leave;
1099   if (mpi_g)
1100     {
1101       point_init (&pk.E.G);
1102       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
1103       if (rc)
1104         goto leave;
1105     }
1106   /* Add missing parameters using the optional curve parameter.  */
1107   gcry_sexp_release (l1);
1108   l1 = gcry_sexp_find_token (keyparms, "curve", 5);
1109   if (l1)
1110     {
1111       curvename = gcry_sexp_nth_string (l1, 1);
1112       if (curvename)
1113         {
1114           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
1115           if (rc)
1116             return rc;
1117         }
1118     }
1119   /* Guess required fields if a curve parameter has not been given.  */
1120   if (!curvename)
1121     {
1122       pk.E.model = MPI_EC_WEIERSTRASS;
1123       pk.E.dialect = ECC_DIALECT_STANDARD;
1124     }
1125
1126   if (DBG_CIPHER)
1127     {
1128       log_debug ("ecc_encrypt info: %s/%s\n",
1129                  _gcry_ecc_model2str (pk.E.model),
1130                  _gcry_ecc_dialect2str (pk.E.dialect));
1131       if (pk.E.name)
1132         log_debug  ("ecc_encrypt name: %s\n", pk.E.name);
1133       log_printmpi ("ecc_encrypt    p", pk.E.p);
1134       log_printmpi ("ecc_encrypt    a", pk.E.a);
1135       log_printmpi ("ecc_encrypt    b", pk.E.b);
1136       log_printpnt ("ecc_encrypt  g",   &pk.E.G, NULL);
1137       log_printmpi ("ecc_encrypt    n", pk.E.n);
1138       log_printmpi ("ecc_encrypt    q", mpi_q);
1139     }
1140   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q)
1141     {
1142       rc = GPG_ERR_NO_OBJ;
1143       goto leave;
1144     }
1145
1146   /* Convert the public key.  */
1147   if (mpi_q)
1148     {
1149       point_init (&pk.Q);
1150       rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
1151       if (rc)
1152         goto leave;
1153     }
1154
1155   /* Compute the encrypted value.  */
1156   ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
1157                                     pk.E.p, pk.E.a, pk.E.b);
1158
1159   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1160   {
1161     mpi_point_struct R;  /* Result that we return.  */
1162     gcry_mpi_t x, y;
1163
1164     x = mpi_new (0);
1165     y = mpi_new (0);
1166
1167     point_init (&R);
1168
1169     /* R = kQ  <=>  R = kdG  */
1170     _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
1171
1172     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1173       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1174     mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
1175
1176     /* R = kG */
1177     _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
1178
1179     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1180       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1181     mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
1182
1183     mpi_free (x);
1184     mpi_free (y);
1185
1186     point_free (&R);
1187   }
1188
1189   rc = gcry_sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))",
1190                         mpi_s, mpi_e);
1191
1192  leave:
1193   gcry_mpi_release (pk.E.p);
1194   gcry_mpi_release (pk.E.a);
1195   gcry_mpi_release (pk.E.b);
1196   gcry_mpi_release (mpi_g);
1197   point_free (&pk.E.G);
1198   gcry_mpi_release (pk.E.n);
1199   gcry_mpi_release (mpi_q);
1200   point_free (&pk.Q);
1201   gcry_mpi_release (data);
1202   gcry_mpi_release (mpi_s);
1203   gcry_mpi_release (mpi_e);
1204   gcry_free (curvename);
1205   _gcry_mpi_ec_free (ec);
1206   _gcry_pk_util_free_encoding_ctx (&ctx);
1207   if (DBG_CIPHER)
1208     log_debug ("ecc_encrypt    => %s\n", gpg_strerror (rc));
1209   return rc;
1210 }
1211
1212
1213 /*  input:
1214  *     data[0] : a point kG (ephemeral public key)
1215  *   output:
1216  *     resaddr[0] : shared point kdG
1217  *
1218  *  see ecc_encrypt_raw for details.
1219  */
1220 static gcry_err_code_t
1221 ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
1222 {
1223   gpg_err_code_t rc;
1224   struct pk_encoding_ctx ctx;
1225   gcry_sexp_t l1 = NULL;
1226   gcry_mpi_t data_e = NULL;
1227   ECC_secret_key sk;
1228   gcry_mpi_t mpi_g = NULL;
1229   char *curvename = NULL;
1230   mpi_ec_t ec = NULL;
1231   mpi_point_struct kG;
1232   mpi_point_struct R;
1233   gcry_mpi_t r = NULL;
1234
1235   memset (&sk, 0, sizeof sk);
1236   point_init (&kG);
1237   point_init (&R);
1238
1239   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
1240                                    ecc_get_nbits (keyparms));
1241
1242   /*
1243    * Extract the data.
1244    */
1245   rc = _gcry_pk_util_preparse_encval (s_data, ecc_names, &l1, &ctx);
1246   if (rc)
1247     goto leave;
1248   rc = _gcry_sexp_extract_param (l1, NULL, "e", &data_e, NULL);
1249   if (rc)
1250     goto leave;
1251   if (DBG_CIPHER)
1252     log_printmpi ("ecc_decrypt  d_e", data_e);
1253   if (mpi_is_opaque (data_e))
1254     {
1255       rc = GPG_ERR_INV_DATA;
1256       goto leave;
1257     }
1258
1259   /*
1260    * Extract the key.
1261    */
1262   rc = _gcry_sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+d",
1263                                  &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
1264                                  &sk.d, NULL);
1265   if (rc)
1266     goto leave;
1267   if (mpi_g)
1268     {
1269       point_init (&sk.E.G);
1270       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
1271       if (rc)
1272         goto leave;
1273     }
1274   /* Add missing parameters using the optional curve parameter.  */
1275   gcry_sexp_release (l1);
1276   l1 = gcry_sexp_find_token (keyparms, "curve", 5);
1277   if (l1)
1278     {
1279       curvename = gcry_sexp_nth_string (l1, 1);
1280       if (curvename)
1281         {
1282           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
1283           if (rc)
1284             return rc;
1285         }
1286     }
1287   /* Guess required fields if a curve parameter has not been given.  */
1288   if (!curvename)
1289     {
1290       sk.E.model = MPI_EC_WEIERSTRASS;
1291       sk.E.dialect = ECC_DIALECT_STANDARD;
1292     }
1293   if (DBG_CIPHER)
1294     {
1295       log_debug ("ecc_decrypt info: %s/%s\n",
1296                  _gcry_ecc_model2str (sk.E.model),
1297                  _gcry_ecc_dialect2str (sk.E.dialect));
1298       if (sk.E.name)
1299         log_debug  ("ecc_decrypt name: %s\n", sk.E.name);
1300       log_printmpi ("ecc_decrypt    p", sk.E.p);
1301       log_printmpi ("ecc_decrypt    a", sk.E.a);
1302       log_printmpi ("ecc_decrypt    b", sk.E.b);
1303       log_printpnt ("ecc_decrypt  g",   &sk.E.G, NULL);
1304       log_printmpi ("ecc_decrypt    n", sk.E.n);
1305       if (!fips_mode ())
1306         log_printmpi ("ecc_decrypt    d", sk.d);
1307     }
1308   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d)
1309     {
1310       rc = GPG_ERR_NO_OBJ;
1311       goto leave;
1312     }
1313
1314
1315   /*
1316    * Compute the plaintext.
1317    */
1318   rc = _gcry_ecc_os2ec (&kG, data_e);
1319   if (rc)
1320     {
1321       point_free (&kG);
1322       return rc;
1323     }
1324
1325   ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0,
1326                                     sk.E.p, sk.E.a, sk.E.b);
1327
1328   /* R = dkG */
1329   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
1330
1331   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1332   {
1333     gcry_mpi_t x, y;
1334
1335     x = mpi_new (0);
1336     y = mpi_new (0);
1337
1338     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1339       log_fatal ("ecdh: Failed to get affine coordinates\n");
1340
1341     r = _gcry_ecc_ec2os (x, y, sk.E.p);
1342     if (!r)
1343       rc = gpg_err_code_from_syserror ();
1344     else
1345       rc = 0;
1346     mpi_free (x);
1347     mpi_free (y);
1348   }
1349   if (DBG_CIPHER)
1350     log_printmpi ("ecc_decrypt  res", r);
1351
1352   if (!rc)
1353     rc = gcry_sexp_build (r_plain, NULL, "(value %m)", r);
1354
1355  leave:
1356   point_free (&R);
1357   point_free (&kG);
1358   gcry_mpi_release (r);
1359   gcry_mpi_release (sk.E.p);
1360   gcry_mpi_release (sk.E.a);
1361   gcry_mpi_release (sk.E.b);
1362   gcry_mpi_release (mpi_g);
1363   point_free (&sk.E.G);
1364   gcry_mpi_release (sk.E.n);
1365   gcry_mpi_release (sk.d);
1366   gcry_mpi_release (data_e);
1367   gcry_free (curvename);
1368   gcry_sexp_release (l1);
1369   _gcry_mpi_ec_free (ec);
1370   _gcry_pk_util_free_encoding_ctx (&ctx);
1371   if (DBG_CIPHER)
1372     log_debug ("ecc_decrypt    => %s\n", gpg_strerror (rc));
1373   return rc;
1374 }
1375
1376
1377 /* Return the number of bits for the key described by PARMS.  On error
1378  * 0 is returned.  The format of PARMS starts with the algorithm name;
1379  * for example:
1380  *
1381  *   (ecc
1382  *     (p <mpi>)
1383  *     (a <mpi>)
1384  *     (b <mpi>)
1385  *     (g <mpi>)
1386  *     (n <mpi>)
1387  *     (q <mpi>))
1388  *
1389  * More parameters may be given currently P is needed.  FIXME: We
1390  * need allow for a "curve" parameter.
1391  */
1392 static unsigned int
1393 ecc_get_nbits (gcry_sexp_t parms)
1394 {
1395   gcry_sexp_t l1;
1396   gcry_mpi_t p;
1397   unsigned int nbits = 0;
1398   char *curve;
1399
1400   l1 = gcry_sexp_find_token (parms, "p", 1);
1401   if (!l1)
1402     { /* Parameter P not found - check whether we have "curve".  */
1403       l1 = gcry_sexp_find_token (parms, "curve", 5);
1404       if (!l1)
1405         return 0; /* Neither P nor CURVE found.  */
1406
1407       curve = _gcry_sexp_nth_string (l1, 1);
1408       gcry_sexp_release (l1);
1409       if (!curve)
1410         return 0;  /* No curve name given (or out of core). */
1411
1412       if (_gcry_ecc_fill_in_curve (0, curve, NULL, &nbits))
1413         nbits = 0;
1414       gcry_free (curve);
1415     }
1416   else
1417     {
1418       p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1419       gcry_sexp_release (l1);
1420       if (p)
1421         {
1422           nbits = mpi_get_nbits (p);
1423           gcry_mpi_release (p);
1424         }
1425     }
1426   return nbits;
1427 }
1428
1429
1430 /* See rsa.c for a description of this function.  */
1431 static gpg_err_code_t
1432 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
1433 {
1434 #define N_COMPONENTS 6
1435   static const char names[N_COMPONENTS+1] = "pabgnq";
1436   gpg_err_code_t rc;
1437   gcry_sexp_t l1;
1438   gcry_mpi_t values[N_COMPONENTS];
1439   int idx;
1440   char *curvename = NULL;
1441   int flags = 0;
1442   enum gcry_mpi_ec_models model = 0;
1443   enum ecc_dialects dialect = 0;
1444
1445   /* Clear the values first.  */
1446   for (idx=0; idx < N_COMPONENTS; idx++)
1447     values[idx] = NULL;
1448
1449
1450   /* Look for flags. */
1451   l1 = gcry_sexp_find_token (keyparms, "flags", 0);
1452   if (l1)
1453     {
1454       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
1455       if (rc)
1456         goto leave;
1457     }
1458
1459   /* Extract the parameters.  */
1460   if ((flags & PUBKEY_FLAG_PARAM))
1461     {
1462       if ((flags & PUBKEY_FLAG_EDDSA))
1463         rc = _gcry_sexp_extract_param (keyparms, NULL, "p?a?b?g?n?/q",
1464                                        &values[0], &values[1], &values[2],
1465                                        &values[3], &values[4], &values[5],
1466                                        NULL);
1467       else
1468         rc = _gcry_sexp_extract_param (keyparms, NULL, "p?a?b?g?n?q",
1469                                        &values[0], &values[1], &values[2],
1470                                        &values[3], &values[4], &values[5],
1471                                        NULL);
1472     }
1473   else
1474     {
1475       if ((flags & PUBKEY_FLAG_EDDSA))
1476         rc = _gcry_sexp_extract_param (keyparms, NULL, "/q",
1477                                        &values[5], NULL);
1478       else
1479         rc = _gcry_sexp_extract_param (keyparms, NULL, "q",
1480                                        &values[5], NULL);
1481     }
1482   if (rc)
1483     goto leave;
1484
1485   /* Check whether a curve parameter is available and use that to fill
1486      in missing values.  */
1487   gcry_sexp_release (l1);
1488   l1 = gcry_sexp_find_token (keyparms, "curve", 5);
1489   if (l1)
1490     {
1491       curvename = gcry_sexp_nth_string (l1, 1);
1492       if (curvename)
1493         {
1494           rc = _gcry_ecc_update_curve_param (curvename,
1495                                              &model, &dialect,
1496                                              &values[0], &values[1], &values[2],
1497                                              &values[3], &values[4]);
1498           if (rc)
1499             return rc;
1500         }
1501     }
1502
1503   /* Guess required fields if a curve parameter has not been given.
1504      FIXME: This is a crude hacks.  We need to fix that.  */
1505   if (!curvename)
1506     {
1507       model = ((flags & PUBKEY_FLAG_EDDSA)
1508                ? MPI_EC_TWISTEDEDWARDS
1509                : MPI_EC_WEIERSTRASS);
1510       dialect = ((flags & PUBKEY_FLAG_EDDSA)
1511                  ? ECC_DIALECT_ED25519
1512                  : ECC_DIALECT_STANDARD);
1513     }
1514
1515   /* Check that all parameters are known and normalize all MPIs (that
1516      should not be required but we use an internal function later and
1517      thus we better make 100% sure that they are normalized). */
1518   for (idx = 0; idx < N_COMPONENTS; idx++)
1519     if (!values[idx])
1520       {
1521         rc = GPG_ERR_NO_OBJ;
1522         goto leave;
1523       }
1524     else
1525       _gcry_mpi_normalize (values[idx]);
1526
1527   /* Uncompress the public key with the exception of EdDSA where
1528      compression is the default and we thus compute the keygrip using
1529      the compressed version.  Because we don't support any non-eddsa
1530      compression, the only thing we need to do is to compress
1531      EdDSA.  */
1532   if ((flags & PUBKEY_FLAG_EDDSA))
1533     {
1534       if (dialect == ECC_DIALECT_ED25519)
1535         rc = _gcry_ecc_eddsa_ensure_compact (values[5], 256);
1536       else
1537         rc = GPG_ERR_NOT_IMPLEMENTED;
1538       if (rc)
1539         goto leave;
1540     }
1541
1542   /* Hash them all.  */
1543   for (idx = 0; idx < N_COMPONENTS; idx++)
1544     {
1545       char buf[30];
1546
1547       if (mpi_is_opaque (values[idx]))
1548         {
1549           const unsigned char *raw;
1550           unsigned int n;
1551
1552           raw = gcry_mpi_get_opaque (values[idx], &n);
1553           n = (n + 7)/8;
1554           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], n);
1555           gcry_md_write (md, buf, strlen (buf));
1556           gcry_md_write (md, raw, n);
1557           gcry_md_write (md, ")", 1);
1558         }
1559       else
1560         {
1561           unsigned char *rawmpi;
1562           unsigned int rawmpilen;
1563
1564           rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1565           if (!rawmpi)
1566             {
1567               rc = gpg_err_code_from_syserror ();
1568               goto leave;
1569             }
1570           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1571           gcry_md_write (md, buf, strlen (buf));
1572           gcry_md_write (md, rawmpi, rawmpilen);
1573           gcry_md_write (md, ")", 1);
1574           gcry_free (rawmpi);
1575         }
1576     }
1577
1578  leave:
1579   gcry_free (curvename);
1580   gcry_sexp_release (l1);
1581   for (idx = 0; idx < N_COMPONENTS; idx++)
1582     _gcry_mpi_release (values[idx]);
1583
1584   return rc;
1585 #undef N_COMPONENTS
1586 }
1587
1588
1589 \f
1590 /*
1591    Low-level API helper functions.
1592  */
1593
1594 /* This is the worker function for gcry_pubkey_get_sexp for ECC
1595    algorithms.  Note that the caller has already stored NULL at
1596    R_SEXP.  */
1597 gpg_err_code_t
1598 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1599 {
1600   gpg_err_code_t rc;
1601   gcry_mpi_t mpi_G = NULL;
1602   gcry_mpi_t mpi_Q = NULL;
1603
1604   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
1605     return GPG_ERR_BAD_CRYPT_CTX;
1606
1607   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1608     return GPG_ERR_NO_SECKEY;
1609
1610   /* Compute the public point if it is missing.  */
1611   if (!ec->Q && ec->d)
1612     ec->Q = _gcry_ecc_compute_public (NULL, ec);
1613
1614   /* Encode G and Q.  */
1615   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1616   if (!mpi_G)
1617     {
1618       rc = GPG_ERR_BROKEN_PUBKEY;
1619       goto leave;
1620     }
1621   if (!ec->Q)
1622     {
1623       rc = GPG_ERR_BAD_CRYPT_CTX;
1624       goto leave;
1625     }
1626
1627   if (ec->dialect == ECC_DIALECT_ED25519)
1628     {
1629       unsigned char *encpk;
1630       unsigned int encpklen;
1631
1632       rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
1633                                         &encpk, &encpklen);
1634       if (rc)
1635         goto leave;
1636       mpi_Q = gcry_mpi_set_opaque (NULL, encpk, encpklen*8);
1637       encpk = NULL;
1638     }
1639   else
1640     {
1641       mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
1642     }
1643   if (!mpi_Q)
1644     {
1645       rc = GPG_ERR_BROKEN_PUBKEY;
1646       goto leave;
1647     }
1648
1649   /* Fixme: We should return a curve name instead of the parameters if
1650      if know that they match a curve.  */
1651
1652   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
1653     {
1654       /* Let's return a private key. */
1655       rc = gcry_sexp_build
1656         (r_sexp, NULL,
1657          "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
1658          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d);
1659     }
1660   else if (ec->Q)
1661     {
1662       /* Let's return a public key.  */
1663       rc = gcry_sexp_build
1664         (r_sexp, NULL,
1665          "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
1666          ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q);
1667     }
1668   else
1669     rc = GPG_ERR_BAD_CRYPT_CTX;
1670
1671  leave:
1672   mpi_free (mpi_Q);
1673   mpi_free (mpi_G);
1674   return rc;
1675 }
1676
1677
1678 \f
1679 /*
1680      Self-test section.
1681  */
1682
1683
1684 static gpg_err_code_t
1685 selftests_ecdsa (selftest_report_func_t report)
1686 {
1687   const char *what;
1688   const char *errtxt;
1689
1690   what = "low-level";
1691   errtxt = NULL; /*selftest ();*/
1692   if (errtxt)
1693     goto failed;
1694
1695   /* FIXME:  need more tests.  */
1696
1697   return 0; /* Succeeded. */
1698
1699  failed:
1700   if (report)
1701     report ("pubkey", GCRY_PK_ECC, what, errtxt);
1702   return GPG_ERR_SELFTEST_FAILED;
1703 }
1704
1705
1706 /* Run a full self-test for ALGO and return 0 on success.  */
1707 static gpg_err_code_t
1708 run_selftests (int algo, int extended, selftest_report_func_t report)
1709 {
1710   (void)extended;
1711
1712   if (algo != GCRY_PK_ECC)
1713     return GPG_ERR_PUBKEY_ALGO;
1714
1715   return selftests_ecdsa (report);
1716 }
1717
1718
1719
1720 \f
1721 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
1722   {
1723     GCRY_PK_ECC, { 0, 0 },
1724     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
1725     "ECC", ecc_names,
1726     "pabgnq", "pabgnqd", "sw", "rs", "pabgnq",
1727     ecc_generate,
1728     ecc_check_secret_key,
1729     ecc_encrypt_raw,
1730     ecc_decrypt_raw,
1731     ecc_sign,
1732     ecc_verify,
1733     ecc_get_nbits,
1734     run_selftests,
1735     compute_keygrip,
1736     _gcry_ecc_get_param,
1737     _gcry_ecc_get_curve,
1738     _gcry_ecc_get_param_sexp
1739   };