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