ecc: Fix some memory leaks
[libgcrypt.git] / cipher / ecc-curves.c
1 /* ecc-curves.c  -  Elliptic Curve parameter mangement
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 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30 #include "context.h"
31 #include "ec-context.h"
32 #include "pubkey-internal.h"
33 #include "ecc-common.h"
34
35
36 /* This tables defines aliases for curve names.  */
37 static const struct
38 {
39   const char *name;  /* Our name.  */
40   const char *other; /* Other name. */
41 } curve_aliases[] =
42   {
43     { "Ed25519",    "1.3.6.1.4.1.3029.1.5.1" },
44
45     { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
46     { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
47     { "NIST P-192", "secp192r1"  },          /* SECP name.  */
48     { "NIST P-192", "nistp192"   },          /* rfc5656.  */
49
50     { "NIST P-224", "secp224r1" },
51     { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
52     { "NIST P-224", "nistp224"   },          /* rfc5656.  */
53
54     { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
55     { "NIST P-256", "prime256v1" },
56     { "NIST P-256", "secp256r1"  },
57     { "NIST P-256", "nistp256"   },          /* rfc5656.  */
58
59     { "NIST P-384", "secp384r1" },
60     { "NIST P-384", "1.3.132.0.34" },
61     { "NIST P-384", "nistp384"   },          /* rfc5656.  */
62
63     { "NIST P-521", "secp521r1" },
64     { "NIST P-521", "1.3.132.0.35" },
65     { "NIST P-521", "nistp521"   },          /* rfc5656.  */
66
67     { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
68     { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
69     { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
70     { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
71     { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
72     { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
73     { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
74
75     { NULL, NULL}
76   };
77
78
79 typedef struct
80 {
81   const char *desc;           /* Description of the curve.  */
82   unsigned int nbits;         /* Number of bits.  */
83   unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
84
85   /* The model describing this curve.  This is mainly used to select
86      the group equation. */
87   enum gcry_mpi_ec_models model;
88
89   /* The actual ECC dialect used.  This is used for curve specific
90      optimizations and to select encodings etc. */
91   enum ecc_dialects dialect;
92
93   const char *p;              /* The prime defining the field.  */
94   const char *a, *b;          /* The coefficients.  For Twisted Edwards
95                                  Curves b is used for d.  */
96   const char *n;              /* The order of the base point.  */
97   const char *g_x, *g_y;      /* Base point.  */
98 } ecc_domain_parms_t;
99
100
101 /* This static table defines all available curves.  */
102 static const ecc_domain_parms_t domain_parms[] =
103   {
104     {
105       /* (-x^2 + y^2 = 1 + dx^2y^2) */
106       "Ed25519", 256, 0,
107       MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519,
108       "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
109       "-0x01",
110       "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
111       "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
112       "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
113       "0x6666666666666666666666666666666666666666666666666666666666666658"
114     },
115     {
116       "NIST P-192", 192, 1,
117       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
118       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
119       "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
120       "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
121       "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
122
123       "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
124       "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
125     },
126     {
127       "NIST P-224", 224, 1,
128       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
129       "0xffffffffffffffffffffffffffffffff000000000000000000000001",
130       "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
131       "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
132       "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
133
134       "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
135       "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
136     },
137     {
138       "NIST P-256", 256, 1,
139       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
140       "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
141       "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
142       "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
143       "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
144
145       "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
146       "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
147     },
148     {
149       "NIST P-384", 384, 1,
150       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
151       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
152       "ffffffff0000000000000000ffffffff",
153       "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
154       "ffffffff0000000000000000fffffffc",
155       "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
156       "c656398d8a2ed19d2a85c8edd3ec2aef",
157       "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
158       "581a0db248b0a77aecec196accc52973",
159
160       "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
161       "5502f25dbf55296c3a545e3872760ab7",
162       "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
163       "0a60b1ce1d7e819d7a431d7c90ea0e5f"
164     },
165     {
166       "NIST P-521", 521, 1,
167       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
168       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
169       "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
170       "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
171       "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
172       "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
173       "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
174       "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
175       "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
176
177       "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
178       "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
179       "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
180       "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
181     },
182
183     { "brainpoolP160r1", 160, 0,
184       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
185       "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
186       "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
187       "0x1e589a8595423412134faa2dbdec95c8d8675e58",
188       "0xe95e4a5f737059dc60df5991d45029409e60fc09",
189       "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
190       "0x1667cb477a1a8ec338f94741669c976316da6321"
191     },
192
193     { "brainpoolP192r1", 192, 0,
194       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
195       "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
196       "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
197       "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
198       "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
199       "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
200       "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
201     },
202
203     { "brainpoolP224r1", 224, 0,
204       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
205       "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
206       "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
207       "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
208       "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
209       "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
210       "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
211     },
212
213     { "brainpoolP256r1", 256, 0,
214       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
215       "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
216       "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
217       "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
218       "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
219       "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
220       "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
221     },
222
223     { "brainpoolP320r1", 320, 0,
224       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
225       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
226       "fcd412b1f1b32e27",
227       "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
228       "92f375a97d860eb4",
229       "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
230       "6f5eb4ac8fb1f1a6",
231       "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
232       "8691555b44c59311",
233       "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
234       "10af8d0d39e20611",
235       "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
236       "d35245d1692e8ee1"
237     },
238
239     { "brainpoolP384r1", 384, 0,
240       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
241       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
242       "acd3a729901d1a71874700133107ec53",
243       "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
244       "8aa5814a503ad4eb04a8c7dd22ce2826",
245       "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
246       "7cb4390295dbc9943ab78696fa504c11",
247       "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
248       "cf3ab6af6b7fc3103b883202e9046565",
249       "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
250       "e826e03436d646aaef87b2e247d4af1e",
251       "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
252       "0e4646217791811142820341263c5315"
253     },
254
255     { "brainpoolP512r1", 512, 0,
256       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
257       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
258       "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
259       "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
260       "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
261       "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
262       "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
263       "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
264       "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
265       "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
266       "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
267       "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
268       "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
269     },
270     {
271       "GOST2001-test", 256, 0,
272       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
273       "0x8000000000000000000000000000000000000000000000000000000000000431",
274       "0x0000000000000000000000000000000000000000000000000000000000000007",
275       "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e",
276       "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3",
277
278       "0x0000000000000000000000000000000000000000000000000000000000000002",
279       "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8",
280     },
281
282     {
283       "GOST2012-test", 511, 0,
284       MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
285       "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
286       "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373",
287       "0x0000000000000000000000000000000000000000000000000000000000000007",
288       "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4"
289       "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc",
290       "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
291       "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df",
292
293       "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762"
294       "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a",
295       "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2"
296       "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e",
297     },
298
299     { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
300   };
301
302
303
304 \f
305 /* Return a copy of POINT.  */
306 static gcry_mpi_point_t
307 point_copy (gcry_mpi_point_t point)
308 {
309   gcry_mpi_point_t newpoint;
310
311   if (point)
312     {
313       newpoint = gcry_mpi_point_new (0);
314       point_set (newpoint, point);
315     }
316   else
317     newpoint = NULL;
318   return newpoint;
319 }
320
321
322 /* Helper to scan a hex string. */
323 static gcry_mpi_t
324 scanval (const char *string)
325 {
326   gpg_error_t err;
327   gcry_mpi_t val;
328
329   err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
330   if (err)
331     log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
332   return val;
333 }
334
335
336 /* Return the index of the domain_parms table for a curve with NAME.
337    Return -1 if not found.  */
338 static int
339 find_domain_parms_idx (const char *name)
340 {
341   int idx, aliasno;
342
343   /* First check our native curves.  */
344   for (idx = 0; domain_parms[idx].desc; idx++)
345     if (!strcmp (name, domain_parms[idx].desc))
346       return idx;
347
348   /* If not found consult the alias table.  */
349   if (!domain_parms[idx].desc)
350     {
351       for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
352         if (!strcmp (name, curve_aliases[aliasno].other))
353           break;
354       if (curve_aliases[aliasno].name)
355         {
356           for (idx = 0; domain_parms[idx].desc; idx++)
357             if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc))
358               return idx;
359         }
360     }
361
362   return -1;
363 }
364
365
366 /* Generate the crypto system setup.  This function takes the NAME of
367    a curve or the desired number of bits and stores at R_CURVE the
368    parameters of the named curve or those of a suitable curve.  If
369    R_NBITS is not NULL, the chosen number of bits is stored there.
370    NULL may be given for R_CURVE, if the value is not required and for
371    example only a quick test for availability is desired.  Note that
372    the curve fields should be initialized to zero because fields which
373    are not NULL are skipped.  */
374 gpg_err_code_t
375 _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
376                          elliptic_curve_t *curve, unsigned int *r_nbits)
377 {
378   int idx;
379   const char *resname = NULL; /* Set to a found curve name.  */
380
381   if (name)
382     idx = find_domain_parms_idx (name);
383   else
384     {
385       for (idx = 0; domain_parms[idx].desc; idx++)
386         if (nbits == domain_parms[idx].nbits
387             && domain_parms[idx].model == MPI_EC_WEIERSTRASS)
388           break;
389       if (!domain_parms[idx].desc)
390         idx = -1;
391     }
392   if (idx < 0)
393     return GPG_ERR_UNKNOWN_CURVE;
394
395   resname = domain_parms[idx].desc;
396
397   /* In fips mode we only support NIST curves.  Note that it is
398      possible to bypass this check by specifying the curve parameters
399      directly.  */
400   if (fips_mode () && !domain_parms[idx].fips )
401     return GPG_ERR_NOT_SUPPORTED;
402
403   switch (domain_parms[idx].model)
404     {
405     case MPI_EC_WEIERSTRASS:
406     case MPI_EC_TWISTEDEDWARDS:
407       break;
408     case MPI_EC_MONTGOMERY:
409       return GPG_ERR_NOT_SUPPORTED;
410     default:
411       return GPG_ERR_BUG;
412     }
413
414
415   if (r_nbits)
416     *r_nbits = domain_parms[idx].nbits;
417
418   if (curve)
419     {
420       curve->model = domain_parms[idx].model;
421       curve->dialect = domain_parms[idx].dialect;
422       if (!curve->p)
423         curve->p = scanval (domain_parms[idx].p);
424       if (!curve->a)
425         curve->a = scanval (domain_parms[idx].a);
426       if (!curve->b)
427         curve->b = scanval (domain_parms[idx].b);
428       if (!curve->n)
429         curve->n = scanval (domain_parms[idx].n);
430       if (!curve->G.x)
431         curve->G.x = scanval (domain_parms[idx].g_x);
432       if (!curve->G.y)
433         curve->G.y = scanval (domain_parms[idx].g_y);
434       if (!curve->G.z)
435         curve->G.z = mpi_alloc_set_ui (1);
436       if (!curve->name)
437         curve->name = resname;
438     }
439
440   return 0;
441 }
442
443
444 /* Give the name of the curve NAME, store the curve parameters into P,
445    A, B, G, and N if they pint to NULL value.  Note that G is returned
446    in standard uncompressed format.  Also update MODEL and DIALECT if
447    they are not NULL. */
448 gpg_err_code_t
449 _gcry_ecc_update_curve_param (const char *name,
450                               enum gcry_mpi_ec_models *model,
451                               enum ecc_dialects *dialect,
452                               gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b,
453                               gcry_mpi_t *g, gcry_mpi_t *n)
454 {
455   int idx;
456
457   idx = find_domain_parms_idx (name);
458   if (idx < 0)
459     return GPG_ERR_UNKNOWN_CURVE;
460
461   if (g)
462     {
463       char *buf;
464       size_t len;
465
466       len = 4;
467       len += strlen (domain_parms[idx].g_x+2);
468       len += strlen (domain_parms[idx].g_y+2);
469       len++;
470       buf = gcry_malloc (len);
471       if (!buf)
472         return gpg_err_code_from_syserror ();
473       strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2),
474               domain_parms[idx].g_y+2);
475       *g = scanval (buf);
476       gcry_free (buf);
477     }
478   if (model)
479     *model = domain_parms[idx].model;
480   if (dialect)
481     *dialect = domain_parms[idx].dialect;
482   if (p)
483     *p = scanval (domain_parms[idx].p);
484   if (a)
485     *a = scanval (domain_parms[idx].a);
486   if (b)
487     *b = scanval (domain_parms[idx].b);
488   if (n)
489     *n = scanval (domain_parms[idx].n);
490   return 0;
491 }
492
493
494 /* Return the name matching the parameters in PKEY.  This works only
495    with curves described by the Weierstrass equation. */
496 const char *
497 _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits)
498 {
499   gpg_err_code_t rc;
500   const char *result = NULL;
501   elliptic_curve_t E;
502   gcry_mpi_t mpi_g = NULL;
503   gcry_mpi_t tmp = NULL;
504   int idx;
505
506   memset (&E, 0, sizeof E);
507
508   if (r_nbits)
509     *r_nbits = 0;
510
511   if (!keyparms)
512     {
513       idx = iterator;
514       if (idx >= 0 && idx < DIM (domain_parms))
515         {
516           result = domain_parms[idx].desc;
517           if (r_nbits)
518             *r_nbits = domain_parms[idx].nbits;
519         }
520       return result;
521     }
522
523
524   /*
525    * Extract the curve parameters..
526    */
527   rc = gpg_err_code (_gcry_sexp_extract_param (keyparms, NULL, "-pabgn",
528                                                &E.p, &E.a, &E.b, &mpi_g, &E.n,
529                                                NULL));
530   if (rc == GPG_ERR_NO_OBJ)
531     {
532       /* This might be the second use case of checking whether a
533          specific curve given by name is supported.  */
534       gcry_sexp_t l1;
535       char *name;
536
537       l1 = gcry_sexp_find_token (keyparms, "curve", 5);
538       if (!l1)
539         goto leave;  /* No curve name parameter.  */
540
541       name = _gcry_sexp_nth_string (l1, 1);
542       gcry_sexp_release (l1);
543       if (!name)
544         goto leave;  /* Name missing or out of core. */
545
546       idx = find_domain_parms_idx (name);
547       gcry_free (name);
548       if (idx >= 0)  /* Curve found.  */
549         {
550           result = domain_parms[idx].desc;
551           if (r_nbits)
552             *r_nbits = domain_parms[idx].nbits;
553         }
554       return result;
555     }
556
557   if (rc)
558     goto leave;
559
560   if (mpi_g)
561     {
562       _gcry_mpi_point_init (&E.G);
563       if (_gcry_ecc_os2ec (&E.G, mpi_g))
564         goto leave;
565     }
566
567   for (idx = 0; domain_parms[idx].desc; idx++)
568     {
569       tmp = scanval (domain_parms[idx].p);
570       if (!mpi_cmp (tmp, E.p))
571         {
572           mpi_free (tmp);
573           tmp = scanval (domain_parms[idx].a);
574           if (!mpi_cmp (tmp, E.a))
575             {
576               mpi_free (tmp);
577               tmp = scanval (domain_parms[idx].b);
578               if (!mpi_cmp (tmp, E.b))
579                 {
580                   mpi_free (tmp);
581                   tmp = scanval (domain_parms[idx].n);
582                   if (!mpi_cmp (tmp, E.n))
583                     {
584                       mpi_free (tmp);
585                       tmp = scanval (domain_parms[idx].g_x);
586                       if (!mpi_cmp (tmp, E.G.x))
587                         {
588                           mpi_free (tmp);
589                           tmp = scanval (domain_parms[idx].g_y);
590                           if (!mpi_cmp (tmp, E.G.y))
591                             {
592                               result = domain_parms[idx].desc;
593                               if (r_nbits)
594                                 *r_nbits = domain_parms[idx].nbits;
595                               goto leave;
596                             }
597                         }
598                     }
599                 }
600             }
601         }
602     }
603
604  leave:
605   gcry_mpi_release (tmp);
606   gcry_mpi_release (E.p);
607   gcry_mpi_release (E.a);
608   gcry_mpi_release (E.b);
609   gcry_mpi_release (mpi_g);
610   _gcry_mpi_point_free_parts (&E.G);
611   gcry_mpi_release (E.n);
612   return result;
613 }
614
615
616 /* Helper to extract an MPI from key parameters.  */
617 static gpg_err_code_t
618 mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name)
619 {
620   gcry_err_code_t ec = 0;
621   gcry_sexp_t l1;
622
623   l1 = gcry_sexp_find_token (keyparam, name, 0);
624   if (l1)
625     {
626       *r_a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
627       gcry_sexp_release (l1);
628       if (!*r_a)
629         ec = GPG_ERR_INV_OBJ;
630     }
631   return ec;
632 }
633
634 /* Helper to extract a point from key parameters.  If no parameter
635    with NAME is found, the functions tries to find a non-encoded point
636    by appending ".x", ".y" and ".z" to NAME.  ".z" is in this case
637    optional and defaults to 1.  EC is the context which at this point
638    may not be fully initialized. */
639 static gpg_err_code_t
640 point_from_keyparam (gcry_mpi_point_t *r_a,
641                      gcry_sexp_t keyparam, const char *name, mpi_ec_t ec)
642 {
643   gcry_err_code_t rc;
644   gcry_sexp_t l1;
645   gcry_mpi_point_t point;
646
647   l1 = gcry_sexp_find_token (keyparam, name, 0);
648   if (l1)
649     {
650       gcry_mpi_t a;
651
652       a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
653       gcry_sexp_release (l1);
654       if (!a)
655         return GPG_ERR_INV_OBJ;
656
657       point = gcry_mpi_point_new (0);
658       if (ec && ec->dialect == ECC_DIALECT_ED25519)
659         rc = _gcry_ecc_eddsa_decodepoint (a, ec, point, NULL, NULL);
660       else
661         rc = _gcry_ecc_os2ec (point, a);
662       mpi_free (a);
663       if (rc)
664         {
665           gcry_mpi_point_release (point);
666           return rc;
667         }
668     }
669   else
670     {
671       char *tmpname;
672       gcry_mpi_t x = NULL;
673       gcry_mpi_t y = NULL;
674       gcry_mpi_t z = NULL;
675
676       tmpname = gcry_malloc (strlen (name) + 2 + 1);
677       if (!tmpname)
678         return gpg_err_code_from_syserror ();
679       strcpy (stpcpy (tmpname, name), ".x");
680       rc = mpi_from_keyparam (&x, keyparam, tmpname);
681       if (rc)
682         {
683           gcry_free (tmpname);
684           return rc;
685         }
686       strcpy (stpcpy (tmpname, name), ".y");
687       rc = mpi_from_keyparam (&y, keyparam, tmpname);
688       if (rc)
689         {
690           mpi_free (x);
691           gcry_free (tmpname);
692           return rc;
693         }
694       strcpy (stpcpy (tmpname, name), ".z");
695       rc = mpi_from_keyparam (&z, keyparam, tmpname);
696       if (rc)
697         {
698           mpi_free (y);
699           mpi_free (x);
700           gcry_free (tmpname);
701           return rc;
702         }
703       if (!z)
704         z = mpi_set_ui (NULL, 1);
705       if (x && y)
706         point = gcry_mpi_point_snatch_set (NULL, x, y, z);
707       else
708         {
709           mpi_free (x);
710           mpi_free (y);
711           mpi_free (z);
712           point = NULL;
713         }
714       gcry_free (tmpname);
715     }
716
717   if (point)
718     *r_a = point;
719   return 0;
720 }
721
722
723 /* This function creates a new context for elliptic curve operations.
724    Either KEYPARAM or CURVENAME must be given.  If both are given and
725    KEYPARAM has no curve parameter, CURVENAME is used to add missing
726    parameters.  On success 0 is returned and the new context stored at
727    R_CTX.  On error NULL is stored at R_CTX and an error code is
728    returned.  The context needs to be released using
729    gcry_ctx_release.  */
730 gpg_err_code_t
731 _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
732                   gcry_sexp_t keyparam, const char *curvename)
733 {
734   gpg_err_code_t errc;
735   gcry_ctx_t ctx = NULL;
736   enum gcry_mpi_ec_models model = MPI_EC_WEIERSTRASS;
737   enum ecc_dialects dialect = ECC_DIALECT_STANDARD;
738   gcry_mpi_t p = NULL;
739   gcry_mpi_t a = NULL;
740   gcry_mpi_t b = NULL;
741   gcry_mpi_point_t G = NULL;
742   gcry_mpi_t n = NULL;
743   gcry_mpi_point_t Q = NULL;
744   gcry_mpi_t d = NULL;
745   int flags = 0;
746   gcry_sexp_t l1;
747
748   *r_ctx = NULL;
749
750   if (keyparam)
751     {
752       /* Parse an optional flags list.  */
753       l1 = gcry_sexp_find_token (keyparam, "flags", 0);
754       if (l1)
755         {
756           errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
757           gcry_sexp_release (l1);
758           l1 = NULL;
759           if (errc)
760             goto leave;
761         }
762
763       /* Check whether a curve name was given.  */
764       l1 = gcry_sexp_find_token (keyparam, "curve", 5);
765
766       /* If we don't have a curve name or if override parameters have
767          explicitly been requested, parse them.  */
768       if (!l1 || (flags & PUBKEY_FLAG_PARAM))
769         {
770           errc = mpi_from_keyparam (&p, keyparam, "p");
771           if (errc)
772             goto leave;
773           errc = mpi_from_keyparam (&a, keyparam, "a");
774           if (errc)
775             goto leave;
776           errc = mpi_from_keyparam (&b, keyparam, "b");
777           if (errc)
778             goto leave;
779           errc = point_from_keyparam (&G, keyparam, "g", NULL);
780           if (errc)
781             goto leave;
782           errc = mpi_from_keyparam (&n, keyparam, "n");
783           if (errc)
784             goto leave;
785         }
786     }
787   else
788     l1 = NULL; /* No curvename.  */
789
790   /* Check whether a curve parameter is available and use that to fill
791      in missing values.  If no curve parameter is available try an
792      optional provided curvename.  If only the curvename has been
793      given use that one. */
794   if (l1 || curvename)
795     {
796       char *name;
797       elliptic_curve_t *E;
798
799       if (l1)
800         {
801           name = _gcry_sexp_nth_string (l1, 1);
802           gcry_sexp_release (l1);
803           if (!name)
804             {
805               errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
806               goto leave;
807             }
808         }
809       else
810         name = NULL;
811
812       E = gcry_calloc (1, sizeof *E);
813       if (!E)
814         {
815           errc = gpg_err_code_from_syserror ();
816           gcry_free (name);
817           goto leave;
818         }
819
820       errc = _gcry_ecc_fill_in_curve (0, name? name : curvename, E, NULL);
821       gcry_free (name);
822       if (errc)
823         {
824           gcry_free (E);
825           goto leave;
826         }
827
828       model = E->model;
829       dialect = E->dialect;
830
831       if (!p)
832         {
833           p = E->p;
834           E->p = NULL;
835         }
836       if (!a)
837         {
838           a = E->a;
839           E->a = NULL;
840         }
841       if (!b)
842         {
843           b = E->b;
844           E->b = NULL;
845         }
846       if (!G)
847         {
848           G = gcry_mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z);
849           E->G.x = NULL;
850           E->G.y = NULL;
851           E->G.z = NULL;
852         }
853       if (!n)
854         {
855           n = E->n;
856           E->n = NULL;
857         }
858       _gcry_ecc_curve_free (E);
859       gcry_free (E);
860     }
861
862
863   errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b);
864   if (!errc)
865     {
866       mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
867
868       if (b)
869         {
870           mpi_free (ec->b);
871           ec->b = b;
872           b = NULL;
873         }
874       if (G)
875         {
876           ec->G = G;
877           G = NULL;
878         }
879       if (n)
880         {
881           ec->n = n;
882           n = NULL;
883         }
884
885       /* Now that we know the curve name we can look for the public key
886          Q.  point_from_keyparam needs to know the curve parameters so
887          that it is able to use the correct decompression.  Parsing
888          the private key D could have been done earlier but it is less
889          surprising if we do it here as well.  */
890       if (keyparam)
891         {
892           errc = point_from_keyparam (&Q, keyparam, "q", ec);
893           if (errc)
894             goto leave;
895           errc = mpi_from_keyparam (&d, keyparam, "d");
896           if (errc)
897             goto leave;
898         }
899
900       if (Q)
901         {
902           ec->Q = Q;
903           Q = NULL;
904         }
905       if (d)
906         {
907           ec->d = d;
908           d = NULL;
909         }
910
911       *r_ctx = ctx;
912       ctx = NULL;
913     }
914
915  leave:
916   gcry_ctx_release (ctx);
917   mpi_free (p);
918   mpi_free (a);
919   mpi_free (b);
920   gcry_mpi_point_release (G);
921   mpi_free (n);
922   gcry_mpi_point_release (Q);
923   mpi_free (d);
924   return errc;
925 }
926
927
928 /* Return the parameters of the curve NAME in an MPI array.  */
929 gcry_err_code_t
930 _gcry_ecc_get_param (const char *name, gcry_mpi_t *pkey)
931 {
932   gpg_err_code_t err;
933   unsigned int nbits;
934   elliptic_curve_t E;
935   mpi_ec_t ctx;
936   gcry_mpi_t g_x, g_y;
937
938   memset (&E, 0, sizeof E);
939   err = _gcry_ecc_fill_in_curve (0, name, &E, &nbits);
940   if (err)
941     return err;
942
943   g_x = mpi_new (0);
944   g_y = mpi_new (0);
945   ctx = _gcry_mpi_ec_p_internal_new (MPI_EC_WEIERSTRASS,
946                                      ECC_DIALECT_STANDARD,
947                                      0,
948                                      E.p, E.a, NULL);
949   if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
950     log_fatal ("ecc get param: Failed to get affine coordinates\n");
951   _gcry_mpi_ec_free (ctx);
952   _gcry_mpi_point_free_parts (&E.G);
953
954   pkey[0] = E.p;
955   pkey[1] = E.a;
956   pkey[2] = E.b;
957   pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p);
958   pkey[4] = E.n;
959   pkey[5] = NULL;
960
961   mpi_free (g_x);
962   mpi_free (g_y);
963
964   return 0;
965 }
966
967
968 /* Return the parameters of the curve NAME as an S-expression.  */
969 gcry_sexp_t
970 _gcry_ecc_get_param_sexp (const char *name)
971 {
972   gcry_mpi_t pkey[6];
973   gcry_sexp_t result;
974   int i;
975
976   if (_gcry_ecc_get_param (name, pkey))
977     return NULL;
978
979   if (gcry_sexp_build (&result, NULL,
980                        "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
981                        pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
982     result = NULL;
983
984   for (i=0; pkey[i]; i++)
985     gcry_mpi_release (pkey[i]);
986
987   return result;
988 }
989
990
991 /* Return an MPI (or opaque MPI) described by NAME and the context EC.
992    If COPY is true a copy is returned, if not a const MPI may be
993    returned.  In any case mpi_free must be used.  */
994 gcry_mpi_t
995 _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
996 {
997   if (!*name)
998     return NULL;
999
1000   if (!strcmp (name, "p") && ec->p)
1001     return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
1002   if (!strcmp (name, "a") && ec->a)
1003     return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
1004   if (!strcmp (name, "b") && ec->b)
1005     return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b);
1006   if (!strcmp (name, "n") && ec->n)
1007     return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n);
1008   if (!strcmp (name, "d") && ec->d)
1009     return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);
1010
1011   /* Return a requested point coordinate.  */
1012   if (!strcmp (name, "g.x") && ec->G && ec->G->x)
1013     return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
1014   if (!strcmp (name, "g.y") && ec->G && ec->G->y)
1015     return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
1016   if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
1017     return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
1018   if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
1019     return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);
1020
1021   /* If the base point has been requested, return it in standard
1022      encoding.  */
1023   if (!strcmp (name, "g") && ec->G)
1024     return _gcry_mpi_ec_ec2os (ec->G, ec);
1025
1026   /* If the public key has been requested, return it by default in
1027      standard uncompressed encoding or if requested in other
1028      encodings.  */
1029   if (*name == 'q' && (!name[1] || name[1] == '@'))
1030     {
1031       /* If only the private key is given, compute the public key.  */
1032       if (!ec->Q)
1033         ec->Q = _gcry_ecc_compute_public (NULL, ec);
1034
1035       if (!ec->Q)
1036         return NULL;
1037
1038       if (name[1] != '@')
1039         return _gcry_mpi_ec_ec2os (ec->Q, ec);
1040
1041       if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS)
1042         {
1043           unsigned char *encpk;
1044           unsigned int encpklen;
1045
1046           if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
1047                                             &encpk, &encpklen))
1048             return gcry_mpi_set_opaque (NULL, encpk, encpklen*8);
1049         }
1050     }
1051
1052   return NULL;
1053 }
1054
1055
1056 /* Return a point described by NAME and the context EC.  */
1057 gcry_mpi_point_t
1058 _gcry_ecc_get_point (const char *name, mpi_ec_t ec)
1059 {
1060   if (!strcmp (name, "g") && ec->G)
1061     return point_copy (ec->G);
1062   if (!strcmp (name, "q"))
1063     {
1064       /* If only the private key is given, compute the public key.  */
1065       if (!ec->Q)
1066         ec->Q = _gcry_ecc_compute_public (NULL, ec);
1067
1068       if (ec->Q)
1069         return point_copy (ec->Q);
1070     }
1071
1072   return NULL;
1073 }
1074
1075
1076 /* Store the MPI NEWVALUE into the context EC under NAME. */
1077 gpg_err_code_t
1078 _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec)
1079 {
1080   gpg_err_code_t rc = 0;
1081
1082   if (!*name)
1083     ;
1084   else if (!strcmp (name, "p"))
1085     {
1086       mpi_free (ec->p);
1087       ec->p = mpi_copy (newvalue);
1088       _gcry_mpi_ec_get_reset (ec);
1089     }
1090   else if (!strcmp (name, "a"))
1091     {
1092       mpi_free (ec->a);
1093       ec->a = mpi_copy (newvalue);
1094       _gcry_mpi_ec_get_reset (ec);
1095     }
1096   else if (!strcmp (name, "b"))
1097     {
1098       mpi_free (ec->b);
1099       ec->b = mpi_copy (newvalue);
1100     }
1101   else if (!strcmp (name, "n"))
1102     {
1103       mpi_free (ec->n);
1104       ec->n = mpi_copy (newvalue);
1105     }
1106   else if (*name == 'q' && (!name[1] || name[1] == '@'))
1107     {
1108       if (newvalue)
1109         {
1110           if (!ec->Q)
1111             ec->Q = gcry_mpi_point_new (0);
1112           if (ec->dialect == ECC_DIALECT_ED25519)
1113             rc = _gcry_ecc_eddsa_decodepoint (newvalue, ec, ec->Q, NULL, NULL);
1114           else
1115             rc = _gcry_ecc_os2ec (ec->Q, newvalue);
1116         }
1117       if (rc || !newvalue)
1118         {
1119           gcry_mpi_point_release (ec->Q);
1120           ec->Q = NULL;
1121         }
1122       /* Note: We assume that Q matches d and thus do not reset d.  */
1123     }
1124   else if (!strcmp (name, "d"))
1125     {
1126       mpi_free (ec->d);
1127       ec->d = mpi_copy (newvalue);
1128       if (ec->d)
1129         {
1130           /* We need to reset the public key because it may not
1131              anymore match.  */
1132           gcry_mpi_point_release (ec->Q);
1133           ec->Q = NULL;
1134         }
1135     }
1136   else
1137    rc = GPG_ERR_UNKNOWN_NAME;
1138
1139   return rc;
1140 }
1141
1142
1143 /* Store the point NEWVALUE into the context EC under NAME.  */
1144 gpg_err_code_t
1145 _gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec)
1146 {
1147   if (!strcmp (name, "g"))
1148     {
1149       gcry_mpi_point_release (ec->G);
1150       ec->G = point_copy (newvalue);
1151     }
1152   else if (!strcmp (name, "q"))
1153     {
1154       gcry_mpi_point_release (ec->Q);
1155       ec->Q = point_copy (newvalue);
1156     }
1157   else
1158     return GPG_ERR_UNKNOWN_NAME;
1159
1160   return 0;
1161 }