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