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