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