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