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