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