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