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