Add gcry_pubkey_get_sexp.
[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   - Split this up into several files.  For example the curve
51     management and gcry_mpi_ec_new are independent of the actual ECDSA
52     implementation.  This will also help to support optimized versions
53     of some curves.
54
55 */
56
57
58 #include <config.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <errno.h>
63
64 #include "g10lib.h"
65 #include "mpi.h"
66 #include "cipher.h"
67 #include "context.h"
68 #include "ec-context.h"
69 #include "pubkey-internal.h"
70
71 /* Definition of a curve.  */
72 typedef struct
73 {
74   gcry_mpi_t p;         /* Prime specifying the field GF(p).  */
75   gcry_mpi_t a;         /* First coefficient of the Weierstrass equation.  */
76   gcry_mpi_t b;         /* Second coefficient of the Weierstrass equation.  */
77   mpi_point_struct G;   /* Base point (generator).  */
78   gcry_mpi_t n;         /* Order of G.  */
79   const char *name;     /* Name of the curve or NULL.  */
80 } elliptic_curve_t;
81
82
83 typedef struct
84 {
85   elliptic_curve_t E;
86   mpi_point_struct Q; /* Q = [d]G  */
87 } ECC_public_key;
88
89 typedef struct
90 {
91   elliptic_curve_t E;
92   mpi_point_struct Q;
93   gcry_mpi_t d;
94 } ECC_secret_key;
95
96
97 /* This tables defines aliases for curve names.  */
98 static const struct
99 {
100   const char *name;  /* Our name.  */
101   const char *other; /* Other name. */
102 } curve_aliases[] =
103   {
104     { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
105     { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
106     { "NIST P-192", "secp192r1"  },          /* SECP name.  */
107     { "NIST P-192", "nistp192"   },          /* rfc5656.  */
108
109     { "NIST P-224", "secp224r1" },
110     { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
111     { "NIST P-224", "nistp224"   },          /* rfc5656.  */
112
113     { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
114     { "NIST P-256", "prime256v1" },
115     { "NIST P-256", "secp256r1"  },
116     { "NIST P-256", "nistp256"   },          /* rfc5656.  */
117
118     { "NIST P-384", "secp384r1" },
119     { "NIST P-384", "1.3.132.0.34" },
120     { "NIST P-384", "nistp384"   },          /* rfc5656.  */
121
122     { "NIST P-521", "secp521r1" },
123     { "NIST P-521", "1.3.132.0.35" },
124     { "NIST P-521", "nistp521"   },          /* rfc5656.  */
125
126     { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
127     { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
128     { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
129     { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
130     { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
131     { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
132     { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
133
134     { NULL, NULL}
135   };
136
137 typedef struct   {
138   const char *desc;           /* Description of the curve.  */
139   unsigned int nbits;         /* Number of bits.  */
140   unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
141   const char  *p;             /* Order of the prime field.  */
142   const char *a, *b;          /* The coefficients. */
143   const char *n;              /* The order of the base point.  */
144   const char *g_x, *g_y;      /* Base point.  */
145 } ecc_domain_parms_t;
146
147 /* This static table defines all available curves.  */
148 static const ecc_domain_parms_t domain_parms[] =
149   {
150     {
151       "NIST P-192", 192, 1,
152       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
153       "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
154       "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
155       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
156
157       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
158       "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
159     },
160     {
161       "NIST P-224", 224, 1,
162       "0xffffffffffffffffffffffffffffffff000000000000000000000001",
163       "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
164       "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
165       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
166
167       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
168       "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
169     },
170     {
171       "NIST P-256", 256, 1,
172       "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
173       "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
174       "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
175       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
176
177       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
178       "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
179     },
180     {
181       "NIST P-384", 384, 1,
182       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
183       "ffffffff0000000000000000ffffffff",
184       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
185       "ffffffff0000000000000000fffffffc",
186       "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
187       "c656398d8a2ed19d2a85c8edd3ec2aef",
188       "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
189       "581a0db248b0a77aecec196accc52973",
190
191       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
192       "5502f25dbf55296c3a545e3872760ab7",
193       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
194       "0a60b1ce1d7e819d7a431d7c90ea0e5f"
195     },
196     {
197       "NIST P-521", 521, 1,
198       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
199       "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
200       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
201       "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
202       "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
203       "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
204       "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
205       "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
206
207       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
208       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
209       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
210       "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
211     },
212
213     { "brainpoolP160r1", 160, 0,
214       "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
215       "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
216       "0x1e589a8595423412134faa2dbdec95c8d8675e58",
217       "0xe95e4a5f737059dc60df5991d45029409e60fc09",
218       "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
219       "0x1667cb477a1a8ec338f94741669c976316da6321"
220     },
221
222     { "brainpoolP192r1", 192, 0,
223       "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
224       "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
225       "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
226       "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
227       "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
228       "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
229     },
230
231     { "brainpoolP224r1", 224, 0,
232       "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
233       "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
234       "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
235       "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
236       "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
237       "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
238     },
239
240     { "brainpoolP256r1", 256, 0,
241       "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
242       "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
243       "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
244       "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
245       "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
246       "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
247     },
248
249     { "brainpoolP320r1", 320, 0,
250       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
251       "fcd412b1f1b32e27",
252       "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
253       "92f375a97d860eb4",
254       "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
255       "6f5eb4ac8fb1f1a6",
256       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
257       "8691555b44c59311",
258       "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
259       "10af8d0d39e20611",
260       "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
261       "d35245d1692e8ee1"
262     },
263
264     { "brainpoolP384r1", 384, 0,
265       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
266       "acd3a729901d1a71874700133107ec53",
267       "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
268       "8aa5814a503ad4eb04a8c7dd22ce2826",
269       "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
270       "7cb4390295dbc9943ab78696fa504c11",
271       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
272       "cf3ab6af6b7fc3103b883202e9046565",
273       "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
274       "e826e03436d646aaef87b2e247d4af1e",
275       "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
276       "0e4646217791811142820341263c5315"
277     },
278
279     { "brainpoolP512r1", 512, 0,
280       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
281       "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
282       "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
283       "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
284       "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
285       "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
286       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
287       "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
288       "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
289       "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
290       "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
291       "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
292     },
293
294     { NULL, 0, 0, NULL, NULL, NULL, NULL }
295   };
296
297
298 /* Registered progress function and its callback value. */
299 static void (*progress_cb) (void *, const char*, int, int, int);
300 static void *progress_cb_data;
301
302
303 #define point_init(a)  _gcry_mpi_point_init ((a))
304 #define point_free(a)  _gcry_mpi_point_free_parts ((a))
305
306
307 \f
308 /* Local prototypes. */
309 static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
310 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
311 static int check_secret_key (ECC_secret_key * sk);
312 static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
313                             gcry_mpi_t r, gcry_mpi_t s);
314 static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
315                               gcry_mpi_t r, gcry_mpi_t s);
316
317
318 static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
319
320
321
322 \f
323 void
324 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
325                                             int, int, int),
326                                 void *cb_data)
327 {
328   progress_cb = cb;
329   progress_cb_data = cb_data;
330 }
331
332 /* static void */
333 /* progress (int c) */
334 /* { */
335 /*   if (progress_cb) */
336 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
337 /* } */
338
339
340 \f
341
342 /* Set the value from S into D.  */
343 static void
344 point_set (mpi_point_t d, mpi_point_t s)
345 {
346   mpi_set (d->x, s->x);
347   mpi_set (d->y, s->y);
348   mpi_set (d->z, s->z);
349 }
350
351
352 /*
353  * Release a curve object.
354  */
355 static void
356 curve_free (elliptic_curve_t *E)
357 {
358   mpi_free (E->p); E->p = NULL;
359   mpi_free (E->a); E->a = NULL;
360   mpi_free (E->b);  E->b = NULL;
361   point_free (&E->G);
362   mpi_free (E->n);  E->n = NULL;
363 }
364
365
366 /*
367  * Return a copy of a curve object.
368  */
369 static elliptic_curve_t
370 curve_copy (elliptic_curve_t E)
371 {
372   elliptic_curve_t R;
373
374   R.p = mpi_copy (E.p);
375   R.a = mpi_copy (E.a);
376   R.b = mpi_copy (E.b);
377   point_init (&R.G);
378   point_set (&R.G, &E.G);
379   R.n = mpi_copy (E.n);
380
381   return R;
382 }
383
384
385 /* Helper to scan a hex string. */
386 static gcry_mpi_t
387 scanval (const char *string)
388 {
389   gpg_error_t err;
390   gcry_mpi_t val;
391
392   err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
393   if (err)
394     log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
395   return val;
396 }
397
398
399
400 \f
401
402 /****************
403  * Solve the right side of the equation that defines a curve.
404  */
405 static gcry_mpi_t
406 gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
407 {
408   gcry_mpi_t three, x_3, axb, y;
409
410   three = mpi_alloc_set_ui (3);
411   x_3 = mpi_new (0);
412   axb = mpi_new (0);
413   y   = mpi_new (0);
414
415   mpi_powm (x_3, x, three, base->p);
416   mpi_mulm (axb, base->a, x, base->p);
417   mpi_addm (axb, axb, base->b, base->p);
418   mpi_addm (y, x_3, axb, base->p);
419
420   mpi_free (x_3);
421   mpi_free (axb);
422   mpi_free (three);
423   return y; /* The quadratic value of the coordinate if it exist. */
424 }
425
426
427 /* Generate a random secret scalar k with an order of p
428
429    At the beginning this was identical to the code is in elgamal.c.
430    Later imporved by mmr.   Further simplified by wk.  */
431 static gcry_mpi_t
432 gen_k (gcry_mpi_t p, int security_level)
433 {
434   gcry_mpi_t k;
435   unsigned int nbits;
436
437   nbits = mpi_get_nbits (p);
438   k = mpi_snew (nbits);
439   if (DBG_CIPHER)
440     log_debug ("choosing a random k of %u bits at seclevel %d\n",
441                nbits, security_level);
442
443   gcry_mpi_randomize (k, nbits, security_level);
444
445   mpi_mod (k, k, p);  /*  k = k mod p  */
446
447   return k;
448 }
449
450
451 /* Generate the crypto system setup.  This function takes the NAME of
452    a curve or the desired number of bits and stores at R_CURVE the
453    parameters of the named curve or those of a suitable curve.  If
454    R_NBITS is not NULL, the chosen number of bits is stored there.  */
455 static gpg_err_code_t
456 fill_in_curve (unsigned int nbits, const char *name,
457                elliptic_curve_t *curve, unsigned int *r_nbits)
458 {
459   int idx, aliasno;
460   const char *resname = NULL; /* Set to a found curve name.  */
461
462   if (name)
463     {
464       /* First check our native curves.  */
465       for (idx = 0; domain_parms[idx].desc; idx++)
466         if (!strcmp (name, domain_parms[idx].desc))
467           {
468             resname = domain_parms[idx].desc;
469             break;
470           }
471       /* If not found consult the alias table.  */
472       if (!domain_parms[idx].desc)
473         {
474           for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
475             if (!strcmp (name, curve_aliases[aliasno].other))
476               break;
477           if (curve_aliases[aliasno].name)
478             {
479               for (idx = 0; domain_parms[idx].desc; idx++)
480                 if (!strcmp (curve_aliases[aliasno].name,
481                              domain_parms[idx].desc))
482                   {
483                     resname = domain_parms[idx].desc;
484                     break;
485                   }
486             }
487         }
488     }
489   else
490     {
491       for (idx = 0; domain_parms[idx].desc; idx++)
492         if (nbits == domain_parms[idx].nbits)
493           break;
494     }
495   if (!domain_parms[idx].desc)
496     return GPG_ERR_INV_VALUE;
497
498   /* In fips mode we only support NIST curves.  Note that it is
499      possible to bypass this check by specifying the curve parameters
500      directly.  */
501   if (fips_mode () && !domain_parms[idx].fips )
502     return GPG_ERR_NOT_SUPPORTED;
503
504   if (r_nbits)
505     *r_nbits = domain_parms[idx].nbits;
506   curve->p = scanval (domain_parms[idx].p);
507   curve->a = scanval (domain_parms[idx].a);
508   curve->b = scanval (domain_parms[idx].b);
509   curve->n = scanval (domain_parms[idx].n);
510   curve->G.x = scanval (domain_parms[idx].g_x);
511   curve->G.y = scanval (domain_parms[idx].g_y);
512   curve->G.z = mpi_alloc_set_ui (1);
513   curve->name = resname;
514
515   return 0;
516 }
517
518
519 /*
520  * First obtain the setup.  Over the finite field randomize an scalar
521  * secret value, and calculate the public point.
522  */
523 static gpg_err_code_t
524 generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
525               int transient_key,
526               gcry_mpi_t g_x, gcry_mpi_t g_y,
527               gcry_mpi_t q_x, gcry_mpi_t q_y,
528               const char **r_usedcurve)
529 {
530   gpg_err_code_t err;
531   elliptic_curve_t E;
532   gcry_mpi_t d;
533   mpi_point_struct Q;
534   mpi_ec_t ctx;
535   gcry_random_level_t random_level;
536
537   *r_usedcurve = NULL;
538
539   err = fill_in_curve (nbits, name, &E, &nbits);
540   if (err)
541     return err;
542
543   if (DBG_CIPHER)
544     {
545       log_mpidump ("ecgen curve  p", E.p);
546       log_mpidump ("ecgen curve  a", E.a);
547       log_mpidump ("ecgen curve  b", E.b);
548       log_mpidump ("ecgen curve  n", E.n);
549       log_mpidump ("ecgen curve Gx", E.G.x);
550       log_mpidump ("ecgen curve Gy", E.G.y);
551       log_mpidump ("ecgen curve Gz", E.G.z);
552       if (E.name)
553         log_debug   ("ecgen curve used: %s\n", E.name);
554     }
555
556   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
557   d = gen_k (E.n, random_level);
558
559   /* Compute Q.  */
560   point_init (&Q);
561   ctx = _gcry_mpi_ec_p_internal_new (E.p, E.a);
562   _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
563
564   /* Copy the stuff to the key structures. */
565   sk->E.p = mpi_copy (E.p);
566   sk->E.a = mpi_copy (E.a);
567   sk->E.b = mpi_copy (E.b);
568   point_init (&sk->E.G);
569   point_set (&sk->E.G, &E.G);
570   sk->E.n = mpi_copy (E.n);
571   point_init (&sk->Q);
572   point_set (&sk->Q, &Q);
573   sk->d    = mpi_copy (d);
574   /* We also return copies of G and Q in affine coordinates if
575      requested.  */
576   if (g_x && g_y)
577     {
578       if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
579         log_fatal ("ecgen: Failed to get affine coordinates\n");
580     }
581   if (q_x && q_y)
582     {
583       if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
584         log_fatal ("ecgen: Failed to get affine coordinates\n");
585     }
586   _gcry_mpi_ec_free (ctx);
587
588   point_free (&Q);
589   mpi_free (d);
590
591   *r_usedcurve = E.name;
592   curve_free (&E);
593
594   /* Now we can test our keys (this should never fail!).  */
595   test_keys (sk, nbits - 64);
596
597   return 0;
598 }
599
600
601 /*
602  * To verify correct skey it use a random information.
603  * First, encrypt and decrypt this dummy value,
604  * test if the information is recuperated.
605  * Second, test with the sign and verify functions.
606  */
607 static void
608 test_keys (ECC_secret_key *sk, unsigned int nbits)
609 {
610   ECC_public_key pk;
611   gcry_mpi_t test = mpi_new (nbits);
612   mpi_point_struct R_;
613   gcry_mpi_t c = mpi_new (nbits);
614   gcry_mpi_t out = mpi_new (nbits);
615   gcry_mpi_t r = mpi_new (nbits);
616   gcry_mpi_t s = mpi_new (nbits);
617
618   if (DBG_CIPHER)
619     log_debug ("Testing key.\n");
620
621   point_init (&R_);
622
623   pk.E = curve_copy (sk->E);
624   point_init (&pk.Q);
625   point_set (&pk.Q, &sk->Q);
626
627   gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
628
629   if (sign (test, sk, r, s) )
630     log_fatal ("ECDSA operation: sign failed\n");
631
632   if (verify (test, &pk, r, s))
633     {
634       log_fatal ("ECDSA operation: sign, verify failed\n");
635     }
636
637   if (DBG_CIPHER)
638     log_debug ("ECDSA operation: sign, verify ok.\n");
639
640   point_free (&pk.Q);
641   curve_free (&pk.E);
642
643   point_free (&R_);
644   mpi_free (s);
645   mpi_free (r);
646   mpi_free (out);
647   mpi_free (c);
648   mpi_free (test);
649 }
650
651
652 /*
653  * To check the validity of the value, recalculate the correspondence
654  * between the public value and the secret one.
655  */
656 static int
657 check_secret_key (ECC_secret_key * sk)
658 {
659   int rc = 1;
660   mpi_point_struct Q;
661   gcry_mpi_t y_2, y2;
662   mpi_ec_t ctx = NULL;
663
664   point_init (&Q);
665
666   /* ?primarity test of 'p' */
667   /*  (...) //!! */
668   /* G in E(F_p) */
669   y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
670   y2 = mpi_alloc (0);
671   mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
672   if (mpi_cmp (y_2, y2))
673     {
674       if (DBG_CIPHER)
675         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
676       goto leave;
677     }
678   /* G != PaI */
679   if (!mpi_cmp_ui (sk->E.G.z, 0))
680     {
681       if (DBG_CIPHER)
682         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
683       goto leave;
684     }
685
686   ctx = _gcry_mpi_ec_p_internal_new (sk->E.p, sk->E.a);
687
688   _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
689   if (mpi_cmp_ui (Q.z, 0))
690     {
691       if (DBG_CIPHER)
692         log_debug ("check_secret_key: E is not a curve of order n\n");
693       goto leave;
694     }
695   /* pubkey cannot be PaI */
696   if (!mpi_cmp_ui (sk->Q.z, 0))
697     {
698       if (DBG_CIPHER)
699         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
700       goto leave;
701     }
702   /* pubkey = [d]G over E */
703   _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
704   if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
705     {
706       if (DBG_CIPHER)
707         log_debug
708           ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
709       goto leave;
710     }
711   rc = 0; /* Okay.  */
712
713  leave:
714   _gcry_mpi_ec_free (ctx);
715   mpi_free (y2);
716   mpi_free (y_2);
717   point_free (&Q);
718   return rc;
719 }
720
721
722 /*
723  * Return the signature struct (r,s) from the message hash.  The caller
724  * must have allocated R and S.
725  */
726 static gpg_err_code_t
727 sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
728 {
729   gpg_err_code_t err = 0;
730   gcry_mpi_t k, dr, sum, k_1, x;
731   mpi_point_struct I;
732   mpi_ec_t ctx;
733
734   if (DBG_CIPHER)
735     log_mpidump ("ecdsa sign hash  ", input );
736
737   k = NULL;
738   dr = mpi_alloc (0);
739   sum = mpi_alloc (0);
740   k_1 = mpi_alloc (0);
741   x = mpi_alloc (0);
742   point_init (&I);
743
744   mpi_set_ui (s, 0);
745   mpi_set_ui (r, 0);
746
747   ctx = _gcry_mpi_ec_p_internal_new (skey->E.p, skey->E.a);
748
749   while (!mpi_cmp_ui (s, 0)) /* s == 0 */
750     {
751       while (!mpi_cmp_ui (r, 0)) /* r == 0 */
752         {
753           /* Note, that we are guaranteed to enter this loop at least
754              once because r has been intialized to 0.  We can't use a
755              do_while because we want to keep the value of R even if S
756              has to be recomputed.  */
757           mpi_free (k);
758           k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
759           _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
760           if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
761             {
762               if (DBG_CIPHER)
763                 log_debug ("ecc sign: Failed to get affine coordinates\n");
764               err = GPG_ERR_BAD_SIGNATURE;
765               goto leave;
766             }
767           mpi_mod (r, x, skey->E.n);  /* r = x mod n */
768         }
769       mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
770       mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n  */
771       mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
772       mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
773     }
774
775   if (DBG_CIPHER)
776     {
777       log_mpidump ("ecdsa sign result r ", r);
778       log_mpidump ("ecdsa sign result s ", s);
779     }
780
781  leave:
782   _gcry_mpi_ec_free (ctx);
783   point_free (&I);
784   mpi_free (x);
785   mpi_free (k_1);
786   mpi_free (sum);
787   mpi_free (dr);
788   mpi_free (k);
789
790   return err;
791 }
792
793
794 /*
795  * Check if R and S verifies INPUT.
796  */
797 static gpg_err_code_t
798 verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
799 {
800   gpg_err_code_t err = 0;
801   gcry_mpi_t h, h1, h2, x, y;
802   mpi_point_struct Q, Q1, Q2;
803   mpi_ec_t ctx;
804
805   if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
806     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < r < n  failed.  */
807   if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
808     return GPG_ERR_BAD_SIGNATURE; /* Assertion  0 < s < n  failed.  */
809
810   h  = mpi_alloc (0);
811   h1 = mpi_alloc (0);
812   h2 = mpi_alloc (0);
813   x = mpi_alloc (0);
814   y = mpi_alloc (0);
815   point_init (&Q);
816   point_init (&Q1);
817   point_init (&Q2);
818
819   ctx = _gcry_mpi_ec_p_internal_new (pkey->E.p, pkey->E.a);
820
821   /* h  = s^(-1) (mod n) */
822   mpi_invm (h, s, pkey->E.n);
823 /*   log_mpidump ("   h", h); */
824   /* h1 = hash * s^(-1) (mod n) */
825   mpi_mulm (h1, input, h, pkey->E.n);
826 /*   log_mpidump ("  h1", h1); */
827   /* Q1 = [ hash * s^(-1) ]G  */
828   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
829 /*   log_mpidump ("Q1.x", Q1.x); */
830 /*   log_mpidump ("Q1.y", Q1.y); */
831 /*   log_mpidump ("Q1.z", Q1.z); */
832   /* h2 = r * s^(-1) (mod n) */
833   mpi_mulm (h2, r, h, pkey->E.n);
834 /*   log_mpidump ("  h2", h2); */
835   /* Q2 = [ r * s^(-1) ]Q */
836   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
837 /*   log_mpidump ("Q2.x", Q2.x); */
838 /*   log_mpidump ("Q2.y", Q2.y); */
839 /*   log_mpidump ("Q2.z", Q2.z); */
840   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
841   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
842 /*   log_mpidump (" Q.x", Q.x); */
843 /*   log_mpidump (" Q.y", Q.y); */
844 /*   log_mpidump (" Q.z", Q.z); */
845
846   if (!mpi_cmp_ui (Q.z, 0))
847     {
848       if (DBG_CIPHER)
849           log_debug ("ecc verify: Rejected\n");
850       err = GPG_ERR_BAD_SIGNATURE;
851       goto leave;
852     }
853   if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
854     {
855       if (DBG_CIPHER)
856         log_debug ("ecc verify: Failed to get affine coordinates\n");
857       err = GPG_ERR_BAD_SIGNATURE;
858       goto leave;
859     }
860   mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
861   if (mpi_cmp (x, r))   /* x != r */
862     {
863       if (DBG_CIPHER)
864         {
865           log_mpidump ("     x", x);
866           log_mpidump ("     y", y);
867           log_mpidump ("     r", r);
868           log_mpidump ("     s", s);
869           log_debug ("ecc verify: Not verified\n");
870         }
871       err = GPG_ERR_BAD_SIGNATURE;
872       goto leave;
873     }
874   if (DBG_CIPHER)
875     log_debug ("ecc verify: Accepted\n");
876
877  leave:
878   _gcry_mpi_ec_free (ctx);
879   point_free (&Q2);
880   point_free (&Q1);
881   point_free (&Q);
882   mpi_free (y);
883   mpi_free (x);
884   mpi_free (h2);
885   mpi_free (h1);
886   mpi_free (h);
887   return err;
888 }
889
890
891 \f
892 /*********************************************
893  **************  interface  ******************
894  *********************************************/
895 static gcry_mpi_t
896 ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
897 {
898   gpg_error_t err;
899   int pbytes = (mpi_get_nbits (p)+7)/8;
900   size_t n;
901   unsigned char *buf, *ptr;
902   gcry_mpi_t result;
903
904   buf = gcry_xmalloc ( 1 + 2*pbytes );
905   *buf = 04; /* Uncompressed point.  */
906   ptr = buf+1;
907   err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
908   if (err)
909     log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
910   if (n < pbytes)
911     {
912       memmove (ptr+(pbytes-n), ptr, n);
913       memset (ptr, 0, (pbytes-n));
914     }
915   ptr += pbytes;
916   err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
917   if (err)
918     log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
919   if (n < pbytes)
920     {
921       memmove (ptr+(pbytes-n), ptr, n);
922       memset (ptr, 0, (pbytes-n));
923     }
924
925   err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
926   if (err)
927     log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
928   gcry_free (buf);
929
930   return result;
931 }
932
933
934 /* Convert POINT into affine coordinates using the context CTX and
935    return a newly allocated MPI.  If the conversion is not possible
936    NULL is returned.  This function won't print an error message.  */
937 gcry_mpi_t
938 _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx)
939 {
940   gcry_mpi_t g_x, g_y, result;
941
942   g_x = mpi_new (0);
943   g_y = mpi_new (0);
944   if (_gcry_mpi_ec_get_affine (g_x, g_y, point, ectx))
945     result = NULL;
946   else
947     result = ec2os (g_x, g_y, ectx->p);
948   mpi_free (g_x);
949   mpi_free (g_y);
950
951   return result;
952 }
953
954
955 /* RESULT must have been initialized and is set on success to the
956    point given by VALUE.  */
957 static gcry_error_t
958 os2ec (mpi_point_t result, gcry_mpi_t value)
959 {
960   gcry_error_t err;
961   size_t n;
962   unsigned char *buf;
963   gcry_mpi_t x, y;
964
965   n = (mpi_get_nbits (value)+7)/8;
966   buf = gcry_xmalloc (n);
967   err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
968   if (err)
969     {
970       gcry_free (buf);
971       return err;
972     }
973   if (n < 1)
974     {
975       gcry_free (buf);
976       return GPG_ERR_INV_OBJ;
977     }
978   if (*buf != 4)
979     {
980       gcry_free (buf);
981       return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
982     }
983   if ( ((n-1)%2) )
984     {
985       gcry_free (buf);
986       return GPG_ERR_INV_OBJ;
987     }
988   n = (n-1)/2;
989   err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
990   if (err)
991     {
992       gcry_free (buf);
993       return err;
994     }
995   err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
996   gcry_free (buf);
997   if (err)
998     {
999       mpi_free (x);
1000       return err;
1001     }
1002
1003   mpi_set (result->x, x);
1004   mpi_set (result->y, y);
1005   mpi_set_ui (result->z, 1);
1006
1007   mpi_free (x);
1008   mpi_free (y);
1009
1010   return 0;
1011 }
1012
1013
1014 /* Extended version of ecc_generate.  */
1015 static gcry_err_code_t
1016 ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
1017                   const gcry_sexp_t genparms,
1018                   gcry_mpi_t *skey, gcry_mpi_t **retfactors,
1019                   gcry_sexp_t *r_extrainfo)
1020 {
1021   gpg_err_code_t ec;
1022   ECC_secret_key sk;
1023   gcry_mpi_t g_x, g_y, q_x, q_y;
1024   char *curve_name = NULL;
1025   gcry_sexp_t l1;
1026   int transient_key = 0;
1027   const char *usedcurve = NULL;
1028
1029   (void)algo;
1030   (void)evalue;
1031
1032   if (genparms)
1033     {
1034       /* Parse the optional "curve" parameter. */
1035       l1 = gcry_sexp_find_token (genparms, "curve", 0);
1036       if (l1)
1037         {
1038           curve_name = _gcry_sexp_nth_string (l1, 1);
1039           gcry_sexp_release (l1);
1040           if (!curve_name)
1041             return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
1042         }
1043
1044       /* Parse the optional transient-key flag.  */
1045       l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
1046       if (l1)
1047         {
1048           transient_key = 1;
1049           gcry_sexp_release (l1);
1050         }
1051     }
1052
1053   /* NBITS is required if no curve name has been given.  */
1054   if (!nbits && !curve_name)
1055     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
1056
1057   g_x = mpi_new (0);
1058   g_y = mpi_new (0);
1059   q_x = mpi_new (0);
1060   q_y = mpi_new (0);
1061   ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
1062                      &usedcurve);
1063   gcry_free (curve_name);
1064   if (ec)
1065     return ec;
1066   if (usedcurve)  /* Fixme: No error return checking.  */
1067     gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
1068
1069   skey[0] = sk.E.p;
1070   skey[1] = sk.E.a;
1071   skey[2] = sk.E.b;
1072   skey[3] = ec2os (g_x, g_y, sk.E.p);
1073   skey[4] = sk.E.n;
1074   skey[5] = ec2os (q_x, q_y, sk.E.p);
1075   skey[6] = sk.d;
1076
1077   mpi_free (g_x);
1078   mpi_free (g_y);
1079   mpi_free (q_x);
1080   mpi_free (q_y);
1081
1082   point_free (&sk.E.G);
1083   point_free (&sk.Q);
1084
1085   /* Make an empty list of factors.  */
1086   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
1087   if (!*retfactors)
1088     return gpg_err_code_from_syserror ();  /* Fixme: relase mem?  */
1089
1090   if (DBG_CIPHER)
1091     {
1092       log_mpidump ("ecgen result p", skey[0]);
1093       log_mpidump ("ecgen result a", skey[1]);
1094       log_mpidump ("ecgen result b", skey[2]);
1095       log_mpidump ("ecgen result G", skey[3]);
1096       log_mpidump ("ecgen result n", skey[4]);
1097       log_mpidump ("ecgen result Q", skey[5]);
1098       log_mpidump ("ecgen result d", skey[6]);
1099     }
1100
1101   return 0;
1102 }
1103
1104
1105 static gcry_err_code_t
1106 ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
1107               gcry_mpi_t *skey, gcry_mpi_t **retfactors)
1108 {
1109   (void)evalue;
1110   return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
1111 }
1112
1113
1114 /* Return the parameters of the curve NAME in an MPI array.  */
1115 static gcry_err_code_t
1116 ecc_get_param (const char *name, gcry_mpi_t *pkey)
1117 {
1118   gpg_err_code_t err;
1119   unsigned int nbits;
1120   elliptic_curve_t E;
1121   mpi_ec_t ctx;
1122   gcry_mpi_t g_x, g_y;
1123
1124   err = fill_in_curve (0, name, &E, &nbits);
1125   if (err)
1126     return err;
1127
1128   g_x = mpi_new (0);
1129   g_y = mpi_new (0);
1130   ctx = _gcry_mpi_ec_p_internal_new (E.p, E.a);
1131   if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
1132     log_fatal ("ecc get param: Failed to get affine coordinates\n");
1133   _gcry_mpi_ec_free (ctx);
1134   point_free (&E.G);
1135
1136   pkey[0] = E.p;
1137   pkey[1] = E.a;
1138   pkey[2] = E.b;
1139   pkey[3] = ec2os (g_x, g_y, E.p);
1140   pkey[4] = E.n;
1141   pkey[5] = NULL;
1142
1143   mpi_free (g_x);
1144   mpi_free (g_y);
1145
1146   return 0;
1147 }
1148
1149
1150 /* Return the parameters of the curve NAME as an S-expression.  */
1151 static gcry_sexp_t
1152 ecc_get_param_sexp (const char *name)
1153 {
1154   gcry_mpi_t pkey[6];
1155   gcry_sexp_t result;
1156   int i;
1157
1158   if (ecc_get_param (name, pkey))
1159     return NULL;
1160
1161   if (gcry_sexp_build (&result, NULL,
1162                        "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
1163                        pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
1164     result = NULL;
1165
1166   for (i=0; pkey[i]; i++)
1167     gcry_mpi_release (pkey[i]);
1168
1169   return result;
1170 }
1171
1172
1173 /* Return the name matching the parameters in PKEY.  */
1174 static const char *
1175 ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits)
1176 {
1177   gpg_err_code_t err;
1178   elliptic_curve_t E;
1179   int idx;
1180   gcry_mpi_t tmp;
1181   const char *result = NULL;
1182
1183   if (r_nbits)
1184     *r_nbits = 0;
1185
1186   if (!pkey)
1187     {
1188       idx = iterator;
1189       if (idx >= 0 && idx < DIM (domain_parms))
1190         {
1191           result = domain_parms[idx].desc;
1192           if (r_nbits)
1193             *r_nbits = domain_parms[idx].nbits;
1194         }
1195       return result;
1196     }
1197
1198   if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4])
1199     return NULL;
1200
1201   E.p = pkey[0];
1202   E.a = pkey[1];
1203   E.b = pkey[2];
1204   point_init (&E.G);
1205   err = os2ec (&E.G, pkey[3]);
1206   if (err)
1207     {
1208       point_free (&E.G);
1209       return NULL;
1210     }
1211   E.n = pkey[4];
1212
1213   for (idx = 0; domain_parms[idx].desc; idx++)
1214     {
1215       tmp = scanval (domain_parms[idx].p);
1216       if (!mpi_cmp (tmp, E.p))
1217         {
1218           mpi_free (tmp);
1219           tmp = scanval (domain_parms[idx].a);
1220           if (!mpi_cmp (tmp, E.a))
1221             {
1222               mpi_free (tmp);
1223               tmp = scanval (domain_parms[idx].b);
1224               if (!mpi_cmp (tmp, E.b))
1225                 {
1226                   mpi_free (tmp);
1227                   tmp = scanval (domain_parms[idx].n);
1228                   if (!mpi_cmp (tmp, E.n))
1229                     {
1230                       mpi_free (tmp);
1231                       tmp = scanval (domain_parms[idx].g_x);
1232                       if (!mpi_cmp (tmp, E.G.x))
1233                         {
1234                           mpi_free (tmp);
1235                           tmp = scanval (domain_parms[idx].g_y);
1236                           if (!mpi_cmp (tmp, E.G.y))
1237                             {
1238                               result = domain_parms[idx].desc;
1239                               if (r_nbits)
1240                                 *r_nbits = domain_parms[idx].nbits;
1241                               break;
1242                             }
1243                         }
1244                     }
1245                 }
1246             }
1247         }
1248       mpi_free (tmp);
1249     }
1250
1251   point_free (&E.G);
1252
1253   return result;
1254 }
1255
1256
1257 static gcry_err_code_t
1258 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
1259 {
1260   gpg_err_code_t err;
1261   ECC_secret_key sk;
1262
1263   (void)algo;
1264
1265   /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
1266   if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
1267       || !skey[6])
1268     return GPG_ERR_BAD_MPI;
1269
1270   sk.E.p = skey[0];
1271   sk.E.a = skey[1];
1272   sk.E.b = skey[2];
1273   point_init (&sk.E.G);
1274   err = os2ec (&sk.E.G, skey[3]);
1275   if (err)
1276     {
1277       point_free (&sk.E.G);
1278       return err;
1279     }
1280   sk.E.n = skey[4];
1281   point_init (&sk.Q);
1282   err = os2ec (&sk.Q, skey[5]);
1283   if (err)
1284     {
1285       point_free (&sk.E.G);
1286       point_free (&sk.Q);
1287       return err;
1288     }
1289
1290   sk.d = skey[6];
1291
1292   if (check_secret_key (&sk))
1293     {
1294       point_free (&sk.E.G);
1295       point_free (&sk.Q);
1296       return GPG_ERR_BAD_SECKEY;
1297     }
1298   point_free (&sk.E.G);
1299   point_free (&sk.Q);
1300   return 0;
1301 }
1302
1303
1304 static gcry_err_code_t
1305 ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
1306 {
1307   gpg_err_code_t err;
1308   ECC_secret_key sk;
1309
1310   (void)algo;
1311
1312   if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1313       || !skey[6] )
1314     return GPG_ERR_BAD_MPI;
1315
1316   sk.E.p = skey[0];
1317   sk.E.a = skey[1];
1318   sk.E.b = skey[2];
1319   point_init (&sk.E.G);
1320   err = os2ec (&sk.E.G, skey[3]);
1321   if (err)
1322     {
1323       point_free (&sk.E.G);
1324       return err;
1325     }
1326   sk.E.n = skey[4];
1327   /* Note: We don't have any need for Q here.  */
1328   sk.d = skey[6];
1329
1330   resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1331   resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
1332   err = sign (data, &sk, resarr[0], resarr[1]);
1333   if (err)
1334     {
1335       mpi_free (resarr[0]);
1336       mpi_free (resarr[1]);
1337       resarr[0] = NULL; /* Mark array as released.  */
1338     }
1339   point_free (&sk.E.G);
1340   return err;
1341 }
1342
1343
1344 static gcry_err_code_t
1345 ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
1346             int (*cmp)(void *, gcry_mpi_t), void *opaquev)
1347 {
1348   gpg_err_code_t err;
1349   ECC_public_key pk;
1350
1351   (void)algo;
1352   (void)cmp;
1353   (void)opaquev;
1354
1355   if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
1356       || !pkey[3] || !pkey[4] || !pkey[5] )
1357     return GPG_ERR_BAD_MPI;
1358
1359   pk.E.p = pkey[0];
1360   pk.E.a = pkey[1];
1361   pk.E.b = pkey[2];
1362   point_init (&pk.E.G);
1363   err = os2ec (&pk.E.G, pkey[3]);
1364   if (err)
1365     {
1366       point_free (&pk.E.G);
1367       return err;
1368     }
1369   pk.E.n = pkey[4];
1370   point_init (&pk.Q);
1371   err = os2ec (&pk.Q, pkey[5]);
1372   if (err)
1373     {
1374       point_free (&pk.E.G);
1375       point_free (&pk.Q);
1376       return err;
1377     }
1378
1379   err = verify (hash, &pk, data[0], data[1]);
1380
1381   point_free (&pk.E.G);
1382   point_free (&pk.Q);
1383   return err;
1384 }
1385
1386
1387 /* ecdh raw is classic 2-round DH protocol published in 1976.
1388  *
1389  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1390  *
1391  * As with any PK operation, encrypt version uses a public key and
1392  * decrypt -- private.
1393  *
1394  * Symbols used below:
1395  *     G - field generator point
1396  *     d - private long-term scalar
1397  *    dG - public long-term key
1398  *     k - ephemeral scalar
1399  *    kG - ephemeral public key
1400  *   dkG - shared secret
1401  *
1402  * ecc_encrypt_raw description:
1403  *   input:
1404  *     data[0] : private scalar (k)
1405  *   output:
1406  *     result[0] : shared point (kdG)
1407  *     result[1] : generated ephemeral public key (kG)
1408  *
1409  * ecc_decrypt_raw description:
1410  *   input:
1411  *     data[0] : a point kG (ephemeral public key)
1412  *   output:
1413  *     result[0] : shared point (kdG)
1414  */
1415 static gcry_err_code_t
1416 ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
1417                  gcry_mpi_t *pkey, int flags)
1418 {
1419   ECC_public_key pk;
1420   mpi_ec_t ctx;
1421   gcry_mpi_t result[2];
1422   int err;
1423
1424   (void)algo;
1425   (void)flags;
1426
1427   if (!k
1428       || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
1429     return GPG_ERR_BAD_MPI;
1430
1431   pk.E.p = pkey[0];
1432   pk.E.a = pkey[1];
1433   pk.E.b = pkey[2];
1434   point_init (&pk.E.G);
1435   err = os2ec (&pk.E.G, pkey[3]);
1436   if (err)
1437     {
1438       point_free (&pk.E.G);
1439       return err;
1440     }
1441   pk.E.n = pkey[4];
1442   point_init (&pk.Q);
1443   err = os2ec (&pk.Q, pkey[5]);
1444   if (err)
1445     {
1446       point_free (&pk.E.G);
1447       point_free (&pk.Q);
1448       return err;
1449     }
1450
1451   ctx = _gcry_mpi_ec_p_internal_new (pk.E.p, pk.E.a);
1452
1453   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1454   {
1455     mpi_point_struct R;  /* Result that we return.  */
1456     gcry_mpi_t x, y;
1457
1458     x = mpi_new (0);
1459     y = mpi_new (0);
1460
1461     point_init (&R);
1462
1463     /* R = kQ  <=>  R = kdG  */
1464     _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
1465
1466     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1467       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
1468
1469     result[0] = ec2os (x, y, pk.E.p);
1470
1471     /* R = kG */
1472     _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
1473
1474     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1475       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
1476
1477     result[1] = ec2os (x, y, pk.E.p);
1478
1479     mpi_free (x);
1480     mpi_free (y);
1481
1482     point_free (&R);
1483   }
1484
1485   _gcry_mpi_ec_free (ctx);
1486   point_free (&pk.E.G);
1487   point_free (&pk.Q);
1488
1489   if (!result[0] || !result[1])
1490     {
1491       mpi_free (result[0]);
1492       mpi_free (result[1]);
1493       return GPG_ERR_ENOMEM;
1494     }
1495
1496   /* Success.  */
1497   resarr[0] = result[0];
1498   resarr[1] = result[1];
1499
1500   return 0;
1501 }
1502
1503 /*  input:
1504  *     data[0] : a point kG (ephemeral public key)
1505  *   output:
1506  *     resaddr[0] : shared point kdG
1507  *
1508  *  see ecc_encrypt_raw for details.
1509  */
1510 static gcry_err_code_t
1511 ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
1512                  gcry_mpi_t *skey, int flags)
1513 {
1514   ECC_secret_key sk;
1515   mpi_point_struct R;   /* Result that we return.  */
1516   mpi_point_struct kG;
1517   mpi_ec_t ctx;
1518   gcry_mpi_t r;
1519   int err;
1520
1521   (void)algo;
1522   (void)flags;
1523
1524   *result = NULL;
1525
1526   if (!data || !data[0]
1527       || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
1528       || !skey[5] || !skey[6] )
1529     return GPG_ERR_BAD_MPI;
1530
1531   point_init (&kG);
1532   err = os2ec (&kG, data[0]);
1533   if (err)
1534     {
1535       point_free (&kG);
1536       return err;
1537     }
1538
1539
1540   sk.E.p = skey[0];
1541   sk.E.a = skey[1];
1542   sk.E.b = skey[2];
1543   point_init (&sk.E.G);
1544   err = os2ec (&sk.E.G, skey[3]);
1545   if (err)
1546     {
1547       point_free (&kG);
1548       point_free (&sk.E.G);
1549       return err;
1550     }
1551   sk.E.n = skey[4];
1552   point_init (&sk.Q);
1553   err = os2ec (&sk.Q, skey[5]);
1554   if (err)
1555     {
1556       point_free (&kG);
1557       point_free (&sk.E.G);
1558       point_free (&sk.Q);
1559       return err;
1560     }
1561   sk.d = skey[6];
1562
1563   ctx = _gcry_mpi_ec_p_internal_new (sk.E.p, sk.E.a);
1564
1565   /* R = dkG */
1566   point_init (&R);
1567   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
1568
1569   point_free (&kG);
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     y = mpi_new (0);
1577
1578     if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
1579       log_fatal ("ecdh: Failed to get affine coordinates\n");
1580
1581     r = ec2os (x, y, sk.E.p);
1582     mpi_free (x);
1583     mpi_free (y);
1584   }
1585
1586   point_free (&R);
1587   _gcry_mpi_ec_free (ctx);
1588   point_free (&kG);
1589   point_free (&sk.E.G);
1590   point_free (&sk.Q);
1591
1592   if (!r)
1593     return GPG_ERR_ENOMEM;
1594
1595   /* Success.  */
1596
1597   *result = r;
1598
1599   return 0;
1600 }
1601
1602
1603 static unsigned int
1604 ecc_get_nbits (int algo, gcry_mpi_t *pkey)
1605 {
1606   (void)algo;
1607
1608   return mpi_get_nbits (pkey[0]);
1609 }
1610
1611
1612 /* See rsa.c for a description of this function.  */
1613 static gpg_err_code_t
1614 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
1615 {
1616 #define N_COMPONENTS 6
1617   static const char names[N_COMPONENTS+1] = "pabgnq";
1618   gpg_err_code_t ec = 0;
1619   gcry_sexp_t l1;
1620   gcry_mpi_t values[N_COMPONENTS];
1621   int idx;
1622
1623   /* Clear the values for easier error cleanup.  */
1624   for (idx=0; idx < N_COMPONENTS; idx++)
1625     values[idx] = NULL;
1626
1627   /* Fill values with all provided parameters.  */
1628   for (idx=0; idx < N_COMPONENTS; idx++)
1629     {
1630       l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
1631       if (l1)
1632         {
1633           values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1634           gcry_sexp_release (l1);
1635           if (!values[idx])
1636             {
1637               ec = GPG_ERR_INV_OBJ;
1638               goto leave;
1639             }
1640         }
1641     }
1642
1643   /* Check whether a curve parameter is available and use that to fill
1644      in missing values.  */
1645   l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1646   if (l1)
1647     {
1648       char *curve;
1649       gcry_mpi_t tmpvalues[N_COMPONENTS];
1650
1651       for (idx = 0; idx < N_COMPONENTS; idx++)
1652         tmpvalues[idx] = NULL;
1653
1654       curve = _gcry_sexp_nth_string (l1, 1);
1655       gcry_sexp_release (l1);
1656       if (!curve)
1657         {
1658           ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1659           goto leave;
1660         }
1661       ec = ecc_get_param (curve, tmpvalues);
1662       gcry_free (curve);
1663       if (ec)
1664         goto leave;
1665
1666       for (idx = 0; idx < N_COMPONENTS; idx++)
1667         {
1668           if (!values[idx])
1669             values[idx] = tmpvalues[idx];
1670           else
1671             mpi_free (tmpvalues[idx]);
1672         }
1673     }
1674
1675   /* Check that all parameters are known and normalize all MPIs (that
1676      should not be required but we use an internal function later and
1677      thus we better make 100% sure that they are normalized). */
1678   for (idx = 0; idx < N_COMPONENTS; idx++)
1679     if (!values[idx])
1680       {
1681         ec = GPG_ERR_NO_OBJ;
1682         goto leave;
1683       }
1684     else
1685       _gcry_mpi_normalize (values[idx]);
1686
1687   /* Hash them all.  */
1688   for (idx = 0; idx < N_COMPONENTS; idx++)
1689     {
1690       char buf[30];
1691       unsigned char *rawmpi;
1692       unsigned int rawmpilen;
1693
1694       rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
1695       if (!rawmpi)
1696         {
1697           ec = gpg_err_code_from_syserror ();
1698           goto leave;
1699         }
1700       snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1701       gcry_md_write (md, buf, strlen (buf));
1702       gcry_md_write (md, rawmpi, rawmpilen);
1703       gcry_md_write (md, ")", 1);
1704       gcry_free (rawmpi);
1705     }
1706
1707  leave:
1708   for (idx = 0; idx < N_COMPONENTS; idx++)
1709     _gcry_mpi_release (values[idx]);
1710
1711   return ec;
1712 #undef N_COMPONENTS
1713 }
1714
1715
1716 \f
1717 /*
1718    Low-level API helper functions.
1719  */
1720
1721 /* Helper to extract an MPI from key parameters.  */
1722 static gpg_err_code_t
1723 mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name)
1724 {
1725   gcry_err_code_t ec = 0;
1726   gcry_sexp_t l1;
1727
1728   l1 = gcry_sexp_find_token (keyparam, name, 0);
1729   if (l1)
1730     {
1731       *r_a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1732       gcry_sexp_release (l1);
1733       if (!*r_a)
1734         ec = GPG_ERR_INV_OBJ;
1735     }
1736   return ec;
1737 }
1738
1739 /* Helper to extract a point from key parameters.  If no parameter
1740    with NAME is found, the functions tries to find a non-encoded point
1741    by appending ".x", ".y" and ".z" to NAME.  ".z" is in this case
1742    optional and defaults to 1.  */
1743 static gpg_err_code_t
1744 point_from_keyparam (gcry_mpi_point_t *r_a,
1745                      gcry_sexp_t keyparam, const char *name)
1746 {
1747   gcry_err_code_t ec;
1748   gcry_mpi_t a = NULL;
1749   gcry_mpi_point_t point;
1750
1751   ec = mpi_from_keyparam (&a, keyparam, name);
1752   if (ec)
1753     return ec;
1754
1755   if (a)
1756     {
1757       point = gcry_mpi_point_new (0);
1758       ec = os2ec (point, a);
1759       mpi_free (a);
1760       if (ec)
1761         {
1762           gcry_mpi_point_release (point);
1763           return ec;
1764         }
1765     }
1766   else
1767     {
1768       char *tmpname;
1769       gcry_mpi_t x = NULL;
1770       gcry_mpi_t y = NULL;
1771       gcry_mpi_t z = NULL;
1772
1773       tmpname = gcry_malloc (strlen (name) + 2 + 1);
1774       if (!tmpname)
1775         return gpg_err_code_from_syserror ();
1776       strcpy (stpcpy (tmpname, name), ".x");
1777       ec = mpi_from_keyparam (&x, keyparam, tmpname);
1778       if (ec)
1779         {
1780           gcry_free (tmpname);
1781           return ec;
1782         }
1783       strcpy (stpcpy (tmpname, name), ".y");
1784       ec = mpi_from_keyparam (&y, keyparam, tmpname);
1785       if (ec)
1786         {
1787           mpi_free (x);
1788           gcry_free (tmpname);
1789           return ec;
1790         }
1791       strcpy (stpcpy (tmpname, name), ".z");
1792       ec = mpi_from_keyparam (&z, keyparam, tmpname);
1793       if (ec)
1794         {
1795           mpi_free (y);
1796           mpi_free (x);
1797           gcry_free (tmpname);
1798           return ec;
1799         }
1800       if (!z)
1801         z = mpi_set_ui (NULL, 1);
1802       if (x && y)
1803         point = gcry_mpi_point_snatch_set (NULL, x, y, z);
1804       else
1805         {
1806           mpi_free (x);
1807           mpi_free (y);
1808           mpi_free (z);
1809           point = NULL;
1810         }
1811       gcry_free (tmpname);
1812     }
1813
1814   if (point)
1815     *r_a = point;
1816   return 0;
1817 }
1818
1819
1820 /* This function creates a new context for elliptic curve operations.
1821    Either KEYPARAM or CURVENAME must be given.  If both are given and
1822    KEYPARAM has no curve parameter CURVENAME is used to add missing
1823    parameters.  On success 0 is returned and the new context stored at
1824    R_CTX.  On error NULL is stored at R_CTX and an error code is
1825    returned.  The context needs to be released using
1826    gcry_ctx_release.  */
1827 gpg_err_code_t
1828 _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
1829                   gcry_sexp_t keyparam, const char *curvename)
1830 {
1831   gpg_err_code_t errc;
1832   gcry_ctx_t ctx = NULL;
1833   gcry_mpi_t p = NULL;
1834   gcry_mpi_t a = NULL;
1835   gcry_mpi_t b = NULL;
1836   gcry_mpi_point_t G = NULL;
1837   gcry_mpi_t n = NULL;
1838   gcry_mpi_point_t Q = NULL;
1839   gcry_mpi_t d = NULL;
1840   gcry_sexp_t l1;
1841
1842   *r_ctx = NULL;
1843
1844   if (keyparam)
1845     {
1846       errc = mpi_from_keyparam (&p, keyparam, "p");
1847       if (errc)
1848         goto leave;
1849       errc = mpi_from_keyparam (&a, keyparam, "a");
1850       if (errc)
1851         goto leave;
1852       errc = mpi_from_keyparam (&b, keyparam, "b");
1853       if (errc)
1854         goto leave;
1855       errc = point_from_keyparam (&G, keyparam, "g");
1856       if (errc)
1857         goto leave;
1858       errc = mpi_from_keyparam (&n, keyparam, "n");
1859       if (errc)
1860         goto leave;
1861       errc = point_from_keyparam (&Q, keyparam, "q");
1862       if (errc)
1863         goto leave;
1864       errc = mpi_from_keyparam (&d, keyparam, "d");
1865       if (errc)
1866         goto leave;
1867     }
1868
1869
1870   /* Check whether a curve parameter is available and use that to fill
1871      in missing values.  If no curve parameter is available try an
1872      optional provided curvename.  If only the curvename has been
1873      given use that one. */
1874   if (keyparam)
1875     l1 = gcry_sexp_find_token (keyparam, "curve", 5);
1876   else
1877     l1 = NULL;
1878   if (l1 || curvename)
1879     {
1880       char *name;
1881       elliptic_curve_t *E;
1882
1883       if (l1)
1884         {
1885           name = _gcry_sexp_nth_string (l1, 1);
1886           gcry_sexp_release (l1);
1887           if (!name)
1888             {
1889               errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
1890               goto leave;
1891             }
1892         }
1893       else
1894         name = NULL;
1895
1896       E = gcry_calloc (1, sizeof *E);
1897       if (!E)
1898         {
1899           errc = gpg_err_code_from_syserror ();
1900           gcry_free (name);
1901           goto leave;
1902         }
1903
1904       errc = fill_in_curve (0, name? name : curvename, E, NULL);
1905       gcry_free (name);
1906       if (errc)
1907         {
1908           gcry_free (E);
1909           goto leave;
1910         }
1911
1912       if (!p)
1913         {
1914           p = E->p;
1915           E->p = NULL;
1916         }
1917       if (!a)
1918         {
1919           a = E->a;
1920           E->a = NULL;
1921         }
1922       if (!b)
1923         {
1924           b = E->b;
1925           E->b = NULL;
1926         }
1927       if (!G)
1928         {
1929           G = gcry_mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z);
1930           E->G.x = NULL;
1931           E->G.y = NULL;
1932           E->G.z = NULL;
1933         }
1934       if (!n)
1935         {
1936           n = E->n;
1937           E->n = NULL;
1938         }
1939       curve_free (E);
1940       gcry_free (E);
1941     }
1942
1943   errc = _gcry_mpi_ec_p_new (&ctx, p, a);
1944   if (!errc)
1945     {
1946       mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
1947
1948       if (b)
1949         {
1950           ec->b = b;
1951           b = NULL;
1952         }
1953       if (G)
1954         {
1955           ec->G = G;
1956           G = NULL;
1957         }
1958       if (n)
1959         {
1960           ec->n = n;
1961           n = NULL;
1962         }
1963       if (Q)
1964         {
1965           ec->Q = Q;
1966           Q = NULL;
1967         }
1968       if (d)
1969         {
1970           ec->d = d;
1971           d = NULL;
1972         }
1973
1974       *r_ctx = ctx;
1975     }
1976
1977  leave:
1978   mpi_free (p);
1979   mpi_free (a);
1980   mpi_free (b);
1981   gcry_mpi_point_release (G);
1982   mpi_free (n);
1983   gcry_mpi_point_release (Q);
1984   mpi_free (d);
1985   return errc;
1986 }
1987
1988
1989 /* This is the wroker function for gcry_pubkey_get_sexp for ECC
1990    algorithms.  Note that the caller has already stored NULL at
1991    R_SEXP.  */
1992 gpg_err_code_t
1993 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1994 {
1995   gpg_err_code_t rc;
1996   gcry_mpi_t mpi_G = NULL;
1997   gcry_mpi_t mpi_Q = NULL;
1998
1999   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
2000     return GPG_ERR_BAD_CRYPT_CTX;
2001
2002   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
2003     return GPG_ERR_NO_SECKEY;
2004
2005   /* Compute the public point if it is missing.  */
2006   if (!ec->Q && ec->d)
2007     {
2008       ec->Q = gcry_mpi_point_new (0);
2009       _gcry_mpi_ec_mul_point (ec->Q, ec->d, ec->G, ec);
2010     }
2011
2012   /* Encode G and Q.  */
2013   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
2014   if (!mpi_G)
2015     {
2016       rc = GPG_ERR_BROKEN_PUBKEY;
2017       goto leave;
2018     }
2019   if (!ec->Q)
2020     {
2021       rc = GPG_ERR_BAD_CRYPT_CTX;
2022       goto leave;
2023     }
2024   mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
2025   if (!mpi_Q)
2026     {
2027       rc = GPG_ERR_BROKEN_PUBKEY;
2028       goto leave;
2029     }
2030
2031   /* Fixme: We should return a curve name instead of the parameters if
2032      if know that they match a curve.  */
2033
2034   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
2035     {
2036       /* Let's return a private key. */
2037       rc = gpg_err_code
2038         (gcry_sexp_build
2039          (r_sexp, NULL,
2040           "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))",
2041           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d));
2042     }
2043   else if (ec->Q)
2044     {
2045       /* Let's return a public key.  */
2046       rc = gpg_err_code
2047         (gcry_sexp_build
2048          (r_sexp, NULL,
2049           "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))",
2050           ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q));
2051     }
2052   else
2053     rc = GPG_ERR_BAD_CRYPT_CTX;
2054
2055  leave:
2056   mpi_free (mpi_Q);
2057   mpi_free (mpi_G);
2058   return rc;
2059 }
2060
2061
2062 \f
2063 /*
2064      Self-test section.
2065  */
2066
2067
2068 static gpg_err_code_t
2069 selftests_ecdsa (selftest_report_func_t report)
2070 {
2071   const char *what;
2072   const char *errtxt;
2073
2074   what = "low-level";
2075   errtxt = NULL; /*selftest ();*/
2076   if (errtxt)
2077     goto failed;
2078
2079   /* FIXME:  need more tests.  */
2080
2081   return 0; /* Succeeded. */
2082
2083  failed:
2084   if (report)
2085     report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
2086   return GPG_ERR_SELFTEST_FAILED;
2087 }
2088
2089
2090 /* Run a full self-test for ALGO and return 0 on success.  */
2091 static gpg_err_code_t
2092 run_selftests (int algo, int extended, selftest_report_func_t report)
2093 {
2094   gpg_err_code_t ec;
2095
2096   (void)extended;
2097
2098   switch (algo)
2099     {
2100     case GCRY_PK_ECDSA:
2101       ec = selftests_ecdsa (report);
2102       break;
2103     default:
2104       ec = GPG_ERR_PUBKEY_ALGO;
2105       break;
2106
2107     }
2108   return ec;
2109 }
2110
2111
2112
2113 \f
2114 static const char *ecdsa_names[] =
2115   {
2116     "ecdsa",
2117     "ecc",
2118     NULL,
2119   };
2120 static const char *ecdh_names[] =
2121   {
2122     "ecdh",
2123     "ecc",
2124     NULL,
2125   };
2126
2127 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
2128   {
2129     "ECDSA", ecdsa_names,
2130     "pabgnq", "pabgnqd", "", "rs", "pabgnq",
2131     GCRY_PK_USAGE_SIGN,
2132     ecc_generate,
2133     ecc_check_secret_key,
2134     NULL,
2135     NULL,
2136     ecc_sign,
2137     ecc_verify,
2138     ecc_get_nbits
2139   };
2140
2141 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
2142   {
2143     "ECDH", ecdh_names,
2144     "pabgnq", "pabgnqd", "se", "", "pabgnq",
2145     GCRY_PK_USAGE_ENCR,
2146     ecc_generate,
2147     ecc_check_secret_key,
2148     ecc_encrypt_raw,
2149     ecc_decrypt_raw,
2150     NULL,
2151     NULL,
2152     ecc_get_nbits
2153   };
2154
2155
2156 pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
2157   {
2158     run_selftests,
2159     ecc_generate_ext,
2160     compute_keygrip,
2161     ecc_get_param,
2162     ecc_get_curve,
2163     ecc_get_param_sexp
2164   };