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