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