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