Add ARMv8/CE acceleration for AES-XTS
[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, 2015 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 originally 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   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
45     special case in mpi_powm or check whether mpi_mulm is faster.
46
47 */
48
49
50 #include <config.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <errno.h>
55
56 #include "g10lib.h"
57 #include "mpi.h"
58 #include "cipher.h"
59 #include "context.h"
60 #include "ec-context.h"
61 #include "pubkey-internal.h"
62 #include "ecc-common.h"
63
64
65 static const char *ecc_names[] =
66   {
67     "ecc",
68     "ecdsa",
69     "ecdh",
70     "eddsa",
71     "gost",
72     NULL,
73   };
74
75
76 /* Sample NIST P-256 key from RFC 6979 A.2.5 */
77 static const char sample_public_key_secp256[] =
78   "(public-key"
79   " (ecc"
80   "  (curve secp256r1)"
81   "  (q #04"
82   /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
83   /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
84
85 static const char sample_secret_key_secp256[] =
86   "(private-key"
87   " (ecc"
88   "  (curve secp256r1)"
89   "  (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
90   "  (q #04"
91   /**/  "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
92   /**/  "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)))";
93
94
95 /* Registered progress function and its callback value. */
96 static void (*progress_cb) (void *, const char*, int, int, int);
97 static void *progress_cb_data;
98
99
100 \f
101 /* Local prototypes. */
102 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
103 static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits, int flags);
104 static unsigned int ecc_get_nbits (gcry_sexp_t parms);
105
106
107
108 \f
109 void
110 _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
111                                             int, int, int),
112                                 void *cb_data)
113 {
114   progress_cb = cb;
115   progress_cb_data = cb_data;
116 }
117
118 /* static void */
119 /* progress (int c) */
120 /* { */
121 /*   if (progress_cb) */
122 /*     progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
123 /* } */
124
125
126 \f
127 /**
128  * nist_generate_key - Standard version of the ECC key generation.
129  * @sk:  A struct to receive the secret key.
130  * @E:   Parameters of the curve.
131  * @ctx: Elliptic curve computation context.
132  * @flags: Flags controlling aspects of the creation.
133  * @nbits: Only for testing
134  * @r_x: On success this receives an allocated MPI with the affine
135  *       x-coordinate of the poblic key.  On error NULL is stored.
136  * @r_y: Ditto for the y-coordinate.
137  *
138  * Return: An error code.
139  *
140  * The @flags bits used by this function are %PUBKEY_FLAG_TRANSIENT to
141  * use a faster RNG, and %PUBKEY_FLAG_NO_KEYTEST to skip the assertion
142  * that the key works as expected.
143  *
144  * FIXME: Check whether N is needed.
145  */
146 static gpg_err_code_t
147 nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
148                    int flags, unsigned int nbits,
149                    gcry_mpi_t *r_x, gcry_mpi_t *r_y)
150 {
151   mpi_point_struct Q;
152   gcry_random_level_t random_level;
153   gcry_mpi_t x, y;
154   const unsigned int pbits = mpi_get_nbits (E->p);
155
156   point_init (&Q);
157
158   if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
159     random_level = GCRY_STRONG_RANDOM;
160   else
161     random_level = GCRY_VERY_STRONG_RANDOM;
162
163   /* Generate a secret.  */
164   if (ctx->dialect == ECC_DIALECT_ED25519 || (flags & PUBKEY_FLAG_DJB_TWEAK))
165     {
166       char *rndbuf;
167
168       sk->d = mpi_snew (256);
169       rndbuf = _gcry_random_bytes_secure (32, random_level);
170       rndbuf[0] &= 0x7f;  /* Clear bit 255. */
171       rndbuf[0] |= 0x40;  /* Set bit 254.   */
172       rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
173       _gcry_mpi_set_buffer (sk->d, rndbuf, 32, 0);
174       xfree (rndbuf);
175     }
176   else
177     sk->d = _gcry_dsa_gen_k (E->n, random_level);
178
179
180   /* Compute Q.  */
181   _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
182
183   /* Copy the stuff to the key structures. */
184   sk->E.model = E->model;
185   sk->E.dialect = E->dialect;
186   sk->E.p = mpi_copy (E->p);
187   sk->E.a = mpi_copy (E->a);
188   sk->E.b = mpi_copy (E->b);
189   point_init (&sk->E.G);
190   point_set (&sk->E.G, &E->G);
191   sk->E.n = mpi_copy (E->n);
192   sk->E.h = mpi_copy (E->h);
193   point_init (&sk->Q);
194
195   x = mpi_new (pbits);
196   if (r_y == NULL)
197     y = NULL;
198   else
199     y = mpi_new (pbits);
200   if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
201     log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
202
203   /* We want the Q=(x,y) be a "compliant key" in terms of the
204    * http://tools.ietf.org/html/draft-jivsov-ecc-compact, which simply
205    * means that we choose either Q=(x,y) or -Q=(x,p-y) such that we
206    * end up with the min(y,p-y) as the y coordinate.  Such a public
207    * key allows the most efficient compression: y can simply be
208    * dropped because we know that it's a minimum of the two
209    * possibilities without any loss of security.  Note that we don't
210    * do that for Ed25519 so that we do not violate the special
211    * construction of the secret key.  */
212   if (r_y == NULL || E->dialect == ECC_DIALECT_ED25519)
213     point_set (&sk->Q, &Q);
214   else
215     {
216       gcry_mpi_t negative;
217
218       negative = mpi_new (pbits);
219
220       if (E->model == MPI_EC_WEIERSTRASS)
221         mpi_sub (negative, E->p, y);      /* negative = p - y */
222       else
223         mpi_sub (negative, E->p, x);      /* negative = p - x */
224
225       if (mpi_cmp (negative, y) < 0)   /* p - y < p */
226         {
227           /* We need to end up with -Q; this assures that new Q's y is
228              the smallest one */
229           if (E->model == MPI_EC_WEIERSTRASS)
230             {
231               mpi_free (y);
232               y = negative;
233             }
234           else
235             {
236               mpi_free (x);
237               x = negative;
238             }
239           mpi_sub (sk->d, E->n, sk->d);   /* d = order - d */
240           mpi_point_set (&sk->Q, x, y, mpi_const (MPI_C_ONE));
241
242           if (DBG_CIPHER)
243             log_debug ("ecgen converted Q to a compliant point\n");
244         }
245       else /* p - y >= p */
246         {
247           /* No change is needed exactly 50% of the time: just copy. */
248           mpi_free (negative);
249           point_set (&sk->Q, &Q);
250           if (DBG_CIPHER)
251             log_debug ("ecgen didn't need to convert Q to a compliant point\n");
252         }
253     }
254
255   *r_x = x;
256   if (r_y)
257     *r_y = y;
258
259   point_free (&Q);
260   /* Now we can test our keys (this should never fail!).  */
261   if ((flags & PUBKEY_FLAG_NO_KEYTEST))
262     ; /* User requested to skip the test.  */
263   else if (sk->E.model != MPI_EC_MONTGOMERY)
264     test_keys (sk, nbits - 64);
265   else
266     test_ecdh_only_keys (sk, nbits - 64, flags);
267
268   return 0;
269 }
270
271
272 /*
273  * To verify correct skey it use a random information.
274  * First, encrypt and decrypt this dummy value,
275  * test if the information is recuperated.
276  * Second, test with the sign and verify functions.
277  */
278 static void
279 test_keys (ECC_secret_key *sk, unsigned int nbits)
280 {
281   ECC_public_key pk;
282   gcry_mpi_t test = mpi_new (nbits);
283   mpi_point_struct R_;
284   gcry_mpi_t c = mpi_new (nbits);
285   gcry_mpi_t out = mpi_new (nbits);
286   gcry_mpi_t r = mpi_new (nbits);
287   gcry_mpi_t s = mpi_new (nbits);
288
289   if (DBG_CIPHER)
290     log_debug ("Testing key.\n");
291
292   point_init (&R_);
293
294   pk.E = _gcry_ecc_curve_copy (sk->E);
295   point_init (&pk.Q);
296   point_set (&pk.Q, &sk->Q);
297
298   _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
299
300   if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) )
301     log_fatal ("ECDSA operation: sign failed\n");
302
303   if (_gcry_ecc_ecdsa_verify (test, &pk, r, s))
304     {
305       log_fatal ("ECDSA operation: sign, verify failed\n");
306     }
307
308   if (DBG_CIPHER)
309     log_debug ("ECDSA operation: sign, verify ok.\n");
310
311   point_free (&pk.Q);
312   _gcry_ecc_curve_free (&pk.E);
313
314   point_free (&R_);
315   mpi_free (s);
316   mpi_free (r);
317   mpi_free (out);
318   mpi_free (c);
319   mpi_free (test);
320 }
321
322
323 static void
324 test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits, int flags)
325 {
326   ECC_public_key pk;
327   gcry_mpi_t test;
328   mpi_point_struct R_;
329   gcry_mpi_t x0, x1;
330   mpi_ec_t ec;
331
332   if (DBG_CIPHER)
333     log_debug ("Testing ECDH only key.\n");
334
335   point_init (&R_);
336
337   pk.E = _gcry_ecc_curve_copy (sk->E);
338   point_init (&pk.Q);
339   point_set (&pk.Q, &sk->Q);
340
341   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
342     {
343       char *rndbuf;
344
345       test = mpi_new (256);
346       rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM);
347       rndbuf[0] &= 0x7f;  /* Clear bit 255. */
348       rndbuf[0] |= 0x40;  /* Set bit 254.   */
349       rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0  */
350       _gcry_mpi_set_buffer (test, rndbuf, 32, 0);
351       xfree (rndbuf);
352     }
353   else
354     {
355       test = mpi_new (nbits);
356       _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
357     }
358
359   ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, flags,
360                                     pk.E.p, pk.E.a, pk.E.b);
361   x0 = mpi_new (0);
362   x1 = mpi_new (0);
363
364   /* R_ = hkQ  <=>  R_ = hkdG  */
365   _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec);
366   if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
367     _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
368   if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec))
369     log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n");
370
371   _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec);
372   _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec);
373   /* R_ = hdkG */
374   if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
375     _gcry_mpi_ec_mul_point (&R_, ec->h, &R_, ec);
376
377   if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec))
378     log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n");
379
380   if (mpi_cmp (x0, x1))
381     {
382       log_fatal ("ECDH test failed.\n");
383     }
384
385   mpi_free (x0);
386   mpi_free (x1);
387   _gcry_mpi_ec_free (ec);
388
389   point_free (&pk.Q);
390   _gcry_ecc_curve_free (&pk.E);
391
392   point_free (&R_);
393   mpi_free (test);
394 }
395
396
397 /*
398  * To check the validity of the value, recalculate the correspondence
399  * between the public value and the secret one.
400  */
401 static int
402 check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
403 {
404   int rc = 1;
405   mpi_point_struct Q;
406   gcry_mpi_t x1, y1;
407   gcry_mpi_t x2 = NULL;
408   gcry_mpi_t y2 = NULL;
409
410   point_init (&Q);
411   x1 = mpi_new (0);
412   if (ec->model == MPI_EC_MONTGOMERY)
413     y1 = NULL;
414   else
415     y1 = mpi_new (0);
416
417   /* G in E(F_p) */
418   if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec))
419     {
420       if (DBG_CIPHER)
421         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
422       goto leave;
423     }
424
425   /* G != PaI */
426   if (!mpi_cmp_ui (sk->E.G.z, 0))
427     {
428       if (DBG_CIPHER)
429         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
430       goto leave;
431     }
432
433   /* Check order of curve.  */
434   if (sk->E.dialect != ECC_DIALECT_ED25519 && !(flags & PUBKEY_FLAG_DJB_TWEAK))
435     {
436       _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec);
437       if (mpi_cmp_ui (Q.z, 0))
438         {
439           if (DBG_CIPHER)
440             log_debug ("check_secret_key: E is not a curve of order n\n");
441           goto leave;
442         }
443     }
444
445   /* Pubkey cannot be PaI */
446   if (!mpi_cmp_ui (sk->Q.z, 0))
447     {
448       if (DBG_CIPHER)
449         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
450       goto leave;
451     }
452
453   /* pubkey = [d]G over E */
454   if (!_gcry_ecc_compute_public (&Q, ec, &sk->E.G, sk->d))
455     {
456       if (DBG_CIPHER)
457         log_debug ("Bad check: computation of dG failed\n");
458       goto leave;
459     }
460   if (_gcry_mpi_ec_get_affine (x1, y1, &Q, ec))
461     {
462       if (DBG_CIPHER)
463         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
464       goto leave;
465     }
466
467   if ((flags & PUBKEY_FLAG_EDDSA))
468     ; /* Fixme: EdDSA is special.  */
469   else if (!mpi_cmp_ui (sk->Q.z, 1))
470     {
471       /* Fast path if Q is already in affine coordinates.  */
472       if (mpi_cmp (x1, sk->Q.x) || (y1 && mpi_cmp (y1, sk->Q.y)))
473         {
474           if (DBG_CIPHER)
475             log_debug
476               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
477           goto leave;
478         }
479     }
480   else
481     {
482       x2 = mpi_new (0);
483       y2 = mpi_new (0);
484       if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ec))
485         {
486           if (DBG_CIPHER)
487             log_debug ("Bad check: Q can not be a Point at Infinity!\n");
488           goto leave;
489         }
490
491       if (mpi_cmp (x1, x2) || mpi_cmp (y1, y2))
492         {
493           if (DBG_CIPHER)
494             log_debug
495               ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
496           goto leave;
497         }
498     }
499   rc = 0; /* Okay.  */
500
501  leave:
502   mpi_free (x2);
503   mpi_free (x1);
504   mpi_free (y1);
505   mpi_free (y2);
506   point_free (&Q);
507   return rc;
508 }
509
510
511 \f
512 /*********************************************
513  **************  interface  ******************
514  *********************************************/
515
516 static gcry_err_code_t
517 ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
518 {
519   gpg_err_code_t rc;
520   unsigned int nbits;
521   elliptic_curve_t E;
522   ECC_secret_key sk;
523   gcry_mpi_t Gx = NULL;
524   gcry_mpi_t Gy = NULL;
525   gcry_mpi_t Qx = NULL;
526   gcry_mpi_t Qy = NULL;
527   char *curve_name = NULL;
528   gcry_sexp_t l1;
529   mpi_ec_t ctx = NULL;
530   gcry_sexp_t curve_info = NULL;
531   gcry_sexp_t curve_flags = NULL;
532   gcry_mpi_t base = NULL;
533   gcry_mpi_t public = NULL;
534   gcry_mpi_t secret = NULL;
535   int flags = 0;
536
537   memset (&E, 0, sizeof E);
538   memset (&sk, 0, sizeof sk);
539
540   rc = _gcry_pk_util_get_nbits (genparms, &nbits);
541   if (rc)
542     return rc;
543
544   /* Parse the optional "curve" parameter. */
545   l1 = sexp_find_token (genparms, "curve", 0);
546   if (l1)
547     {
548       curve_name = _gcry_sexp_nth_string (l1, 1);
549       sexp_release (l1);
550       if (!curve_name)
551         return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
552     }
553
554   /* Parse the optional flags list.  */
555   l1 = sexp_find_token (genparms, "flags", 0);
556   if (l1)
557     {
558       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
559       sexp_release (l1);
560       if (rc)
561         goto leave;
562     }
563
564   /* Parse the deprecated optional transient-key flag.  */
565   l1 = sexp_find_token (genparms, "transient-key", 0);
566   if (l1)
567     {
568       flags |= PUBKEY_FLAG_TRANSIENT_KEY;
569       sexp_release (l1);
570     }
571
572   /* NBITS is required if no curve name has been given.  */
573   if (!nbits && !curve_name)
574     return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
575
576   rc = _gcry_ecc_fill_in_curve (nbits, curve_name, &E, &nbits);
577   if (rc)
578     goto leave;
579
580   if (DBG_CIPHER)
581     {
582       log_debug ("ecgen curve info: %s/%s\n",
583                  _gcry_ecc_model2str (E.model),
584                  _gcry_ecc_dialect2str (E.dialect));
585       if (E.name)
586         log_debug ("ecgen curve used: %s\n", E.name);
587       log_printmpi ("ecgen curve   p", E.p);
588       log_printmpi ("ecgen curve   a", E.a);
589       log_printmpi ("ecgen curve   b", E.b);
590       log_printmpi ("ecgen curve   n", E.n);
591       log_printmpi ("ecgen curve   h", E.h);
592       log_printpnt ("ecgen curve G", &E.G, NULL);
593     }
594
595   ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, flags, E.p, E.a, E.b);
596
597   if (E.model == MPI_EC_MONTGOMERY)
598     rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, NULL);
599   else if ((flags & PUBKEY_FLAG_EDDSA))
600     rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, flags);
601   else
602     rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, &Qy);
603   if (rc)
604     goto leave;
605
606   /* Copy data to the result.  */
607   Gx = mpi_new (0);
608   Gy = mpi_new (0);
609   if (E.model != MPI_EC_MONTGOMERY)
610     {
611       if (_gcry_mpi_ec_get_affine (Gx, Gy, &sk.E.G, ctx))
612         log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "G");
613       base = _gcry_ecc_ec2os (Gx, Gy, sk.E.p);
614     }
615   if ((sk.E.dialect == ECC_DIALECT_ED25519 || E.model == MPI_EC_MONTGOMERY)
616       && !(flags & PUBKEY_FLAG_NOCOMP))
617     {
618       unsigned char *encpk;
619       unsigned int encpklen;
620
621       if (E.model != MPI_EC_MONTGOMERY)
622         /* (Gx and Gy are used as scratch variables)  */
623         rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, Gx, Gy,
624                                           !!(flags & PUBKEY_FLAG_COMP),
625                                           &encpk, &encpklen);
626       else
627         {
628           encpk = _gcry_mpi_get_buffer_extra (Qx, nbits/8,
629                                               -1, &encpklen, NULL);
630           if (encpk == NULL)
631             rc = gpg_err_code_from_syserror ();
632           else
633             {
634               encpk[0] = 0x40;
635               encpklen++;
636             }
637         }
638       if (rc)
639         goto leave;
640       public = mpi_new (0);
641       mpi_set_opaque (public, encpk, encpklen*8);
642     }
643   else
644     {
645       if (!Qx)
646         {
647           /* This is the case for a key from _gcry_ecc_eddsa_generate
648              with no compression.  */
649           Qx = mpi_new (0);
650           Qy = mpi_new (0);
651           if (_gcry_mpi_ec_get_affine (Qx, Qy, &sk.Q, ctx))
652             log_fatal ("ecgen: Failed to get affine coordinates for %s\n", "Q");
653         }
654       public = _gcry_ecc_ec2os (Qx, Qy, sk.E.p);
655     }
656   secret = sk.d; sk.d = NULL;
657   if (E.name)
658     {
659       rc = sexp_build (&curve_info, NULL, "(curve %s)", E.name);
660       if (rc)
661         goto leave;
662     }
663
664   if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA)
665       || (flags & PUBKEY_FLAG_DJB_TWEAK))
666     {
667       rc = sexp_build
668         (&curve_flags, NULL,
669          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
670          "(flags param eddsa)" :
671          ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
672          "(flags param djb-tweak)" :
673          ((flags & PUBKEY_FLAG_PARAM))?
674          "(flags param)" : ((flags & PUBKEY_FLAG_EDDSA))?
675          "(flags eddsa)" : "(flags djb-tweak)" );
676       if (rc)
677         goto leave;
678     }
679
680   if ((flags & PUBKEY_FLAG_PARAM) && E.name)
681     rc = sexp_build (r_skey, NULL,
682                      "(key-data"
683                      " (public-key"
684                      "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))"
685                      " (private-key"
686                      "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))"
687                      " )",
688                      curve_info, curve_flags,
689                      sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public,
690                      curve_info, curve_flags,
691                      sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public,
692                                                                    secret);
693   else
694     rc = sexp_build (r_skey, NULL,
695                      "(key-data"
696                      " (public-key"
697                      "  (ecc%S%S(q%m)))"
698                      " (private-key"
699                      "  (ecc%S%S(q%m)(d%m)))"
700                      " )",
701                      curve_info, curve_flags,
702                      public,
703                      curve_info, curve_flags,
704                      public, secret);
705   if (rc)
706     goto leave;
707
708   if (DBG_CIPHER)
709     {
710       log_printmpi ("ecgen result  p", sk.E.p);
711       log_printmpi ("ecgen result  a", sk.E.a);
712       log_printmpi ("ecgen result  b", sk.E.b);
713       log_printmpi ("ecgen result  G", base);
714       log_printmpi ("ecgen result  n", sk.E.n);
715       log_printmpi ("ecgen result  h", sk.E.h);
716       log_printmpi ("ecgen result  Q", public);
717       log_printmpi ("ecgen result  d", secret);
718       if ((flags & PUBKEY_FLAG_EDDSA))
719         log_debug ("ecgen result  using Ed25519+EdDSA\n");
720     }
721
722  leave:
723   mpi_free (secret);
724   mpi_free (public);
725   mpi_free (base);
726   {
727     _gcry_ecc_curve_free (&sk.E);
728     point_free (&sk.Q);
729     mpi_free (sk.d);
730   }
731   _gcry_ecc_curve_free (&E);
732   mpi_free (Gx);
733   mpi_free (Gy);
734   mpi_free (Qx);
735   mpi_free (Qy);
736   _gcry_mpi_ec_free (ctx);
737   xfree (curve_name);
738   sexp_release (curve_flags);
739   sexp_release (curve_info);
740   return rc;
741 }
742
743
744 static gcry_err_code_t
745 ecc_check_secret_key (gcry_sexp_t keyparms)
746 {
747   gcry_err_code_t rc;
748   gcry_sexp_t l1 = NULL;
749   int flags = 0;
750   char *curvename = NULL;
751   gcry_mpi_t mpi_g = NULL;
752   gcry_mpi_t mpi_q = NULL;
753   ECC_secret_key sk;
754   mpi_ec_t ec = NULL;
755
756   memset (&sk, 0, sizeof sk);
757
758   /* Look for flags. */
759   l1 = sexp_find_token (keyparms, "flags", 0);
760   if (l1)
761     {
762       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
763       if (rc)
764         goto leave;
765     }
766
767   /* Extract the parameters.  */
768   if ((flags & PUBKEY_FLAG_PARAM))
769     rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d",
770                              &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
771                              &sk.E.h, &mpi_q, &sk.d, NULL);
772   else
773     rc = sexp_extract_param (keyparms, NULL, "/q?+d",
774                              &mpi_q, &sk.d, NULL);
775   if (rc)
776     goto leave;
777
778   /* Add missing parameters using the optional curve parameter.  */
779   sexp_release (l1);
780   l1 = sexp_find_token (keyparms, "curve", 5);
781   if (l1)
782     {
783       curvename = sexp_nth_string (l1, 1);
784       if (curvename)
785         {
786           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
787           if (rc)
788             goto leave;
789         }
790     }
791   if (mpi_g)
792     {
793       if (!sk.E.G.x)
794         point_init (&sk.E.G);
795       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
796       if (rc)
797         goto leave;
798     }
799
800   /* Guess required fields if a curve parameter has not been given.
801      FIXME: This is a crude hacks.  We need to fix that.  */
802   if (!curvename)
803     {
804       sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
805                ? MPI_EC_EDWARDS
806                : MPI_EC_WEIERSTRASS);
807       sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA)
808                       ? ECC_DIALECT_ED25519
809                       : ECC_DIALECT_STANDARD);
810       if (!sk.E.h)
811         sk.E.h = mpi_const (MPI_C_ONE);
812     }
813   if (DBG_CIPHER)
814     {
815       log_debug ("ecc_testkey inf: %s/%s\n",
816                  _gcry_ecc_model2str (sk.E.model),
817                  _gcry_ecc_dialect2str (sk.E.dialect));
818       if (sk.E.name)
819         log_debug  ("ecc_testkey nam: %s\n", sk.E.name);
820       log_printmpi ("ecc_testkey   p", sk.E.p);
821       log_printmpi ("ecc_testkey   a", sk.E.a);
822       log_printmpi ("ecc_testkey   b", sk.E.b);
823       log_printpnt ("ecc_testkey g",   &sk.E.G, NULL);
824       log_printmpi ("ecc_testkey   n", sk.E.n);
825       log_printmpi ("ecc_testkey   h", sk.E.h);
826       log_printmpi ("ecc_testkey   q", mpi_q);
827       if (!fips_mode ())
828         log_printmpi ("ecc_testkey   d", sk.d);
829     }
830   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
831     {
832       rc = GPG_ERR_NO_OBJ;
833       goto leave;
834     }
835
836   ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
837                                     sk.E.p, sk.E.a, sk.E.b);
838
839   if (mpi_q)
840     {
841       point_init (&sk.Q);
842       if (ec->dialect == ECC_DIALECT_ED25519)
843         rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &sk.Q, NULL, NULL);
844       else if (ec->model == MPI_EC_MONTGOMERY)
845         rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &sk.Q);
846       else
847         rc = _gcry_ecc_os2ec (&sk.Q, mpi_q);
848       if (rc)
849         goto leave;
850     }
851   else
852     {
853       /* The secret key test requires Q.  */
854       rc = GPG_ERR_NO_OBJ;
855       goto leave;
856     }
857
858   if (check_secret_key (&sk, ec, flags))
859     rc = GPG_ERR_BAD_SECKEY;
860
861  leave:
862   _gcry_mpi_ec_free (ec);
863   _gcry_mpi_release (sk.E.p);
864   _gcry_mpi_release (sk.E.a);
865   _gcry_mpi_release (sk.E.b);
866   _gcry_mpi_release (mpi_g);
867   point_free (&sk.E.G);
868   _gcry_mpi_release (sk.E.n);
869   _gcry_mpi_release (sk.E.h);
870   _gcry_mpi_release (mpi_q);
871   point_free (&sk.Q);
872   _gcry_mpi_release (sk.d);
873   xfree (curvename);
874   sexp_release (l1);
875   if (DBG_CIPHER)
876     log_debug ("ecc_testkey   => %s\n", gpg_strerror (rc));
877   return rc;
878 }
879
880
881 static gcry_err_code_t
882 ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
883 {
884   gcry_err_code_t rc;
885   struct pk_encoding_ctx ctx;
886   gcry_mpi_t data = NULL;
887   gcry_sexp_t l1 = NULL;
888   char *curvename = NULL;
889   gcry_mpi_t mpi_g = NULL;
890   gcry_mpi_t mpi_q = NULL;
891   ECC_secret_key sk;
892   gcry_mpi_t sig_r = NULL;
893   gcry_mpi_t sig_s = NULL;
894
895   memset (&sk, 0, sizeof sk);
896
897   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, 0);
898
899   /* Extract the data.  */
900   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
901   if (rc)
902     goto leave;
903   if (DBG_CIPHER)
904     log_mpidump ("ecc_sign   data", data);
905
906   /*
907    * Extract the key.
908    */
909   if ((ctx.flags & PUBKEY_FLAG_PARAM))
910     rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d",
911                              &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
912                              &sk.E.h, &mpi_q, &sk.d, NULL);
913   else
914     rc = sexp_extract_param (keyparms, NULL, "/q?+d",
915                              &mpi_q, &sk.d, NULL);
916   if (rc)
917     goto leave;
918   if (mpi_g)
919     {
920       point_init (&sk.E.G);
921       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
922       if (rc)
923         goto leave;
924     }
925   /* Add missing parameters using the optional curve parameter.  */
926   l1 = sexp_find_token (keyparms, "curve", 5);
927   if (l1)
928     {
929       curvename = sexp_nth_string (l1, 1);
930       if (curvename)
931         {
932           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
933           if (rc)
934             goto leave;
935         }
936     }
937   /* Guess required fields if a curve parameter has not been given.
938      FIXME: This is a crude hacks.  We need to fix that.  */
939   if (!curvename)
940     {
941       sk.E.model = ((ctx.flags & PUBKEY_FLAG_EDDSA)
942                     ? MPI_EC_EDWARDS
943                     : MPI_EC_WEIERSTRASS);
944       sk.E.dialect = ((ctx.flags & PUBKEY_FLAG_EDDSA)
945                       ? ECC_DIALECT_ED25519
946                       : ECC_DIALECT_STANDARD);
947       if (!sk.E.h)
948         sk.E.h = mpi_const (MPI_C_ONE);
949     }
950   if (DBG_CIPHER)
951     {
952       log_debug ("ecc_sign   info: %s/%s%s\n",
953                  _gcry_ecc_model2str (sk.E.model),
954                  _gcry_ecc_dialect2str (sk.E.dialect),
955                  (ctx.flags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
956       if (sk.E.name)
957         log_debug  ("ecc_sign   name: %s\n", sk.E.name);
958       log_printmpi ("ecc_sign      p", sk.E.p);
959       log_printmpi ("ecc_sign      a", sk.E.a);
960       log_printmpi ("ecc_sign      b", sk.E.b);
961       log_printpnt ("ecc_sign    g",   &sk.E.G, NULL);
962       log_printmpi ("ecc_sign      n", sk.E.n);
963       log_printmpi ("ecc_sign      h", sk.E.h);
964       log_printmpi ("ecc_sign      q", mpi_q);
965       if (!fips_mode ())
966         log_printmpi ("ecc_sign      d", sk.d);
967     }
968   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
969     {
970       rc = GPG_ERR_NO_OBJ;
971       goto leave;
972     }
973
974
975   sig_r = mpi_new (0);
976   sig_s = mpi_new (0);
977   if ((ctx.flags & PUBKEY_FLAG_EDDSA))
978     {
979       /* EdDSA requires the public key.  */
980       rc = _gcry_ecc_eddsa_sign (data, &sk, sig_r, sig_s, ctx.hash_algo, mpi_q);
981       if (!rc)
982         rc = sexp_build (r_sig, NULL,
983                          "(sig-val(eddsa(r%M)(s%M)))", sig_r, sig_s);
984     }
985   else if ((ctx.flags & PUBKEY_FLAG_GOST))
986     {
987       rc = _gcry_ecc_gost_sign (data, &sk, sig_r, sig_s);
988       if (!rc)
989         rc = sexp_build (r_sig, NULL,
990                          "(sig-val(gost(r%M)(s%M)))", sig_r, sig_s);
991     }
992   else
993     {
994       rc = _gcry_ecc_ecdsa_sign (data, &sk, sig_r, sig_s,
995                                  ctx.flags, ctx.hash_algo);
996       if (!rc)
997         rc = sexp_build (r_sig, NULL,
998                          "(sig-val(ecdsa(r%M)(s%M)))", sig_r, sig_s);
999     }
1000
1001
1002  leave:
1003   _gcry_mpi_release (sk.E.p);
1004   _gcry_mpi_release (sk.E.a);
1005   _gcry_mpi_release (sk.E.b);
1006   _gcry_mpi_release (mpi_g);
1007   point_free (&sk.E.G);
1008   _gcry_mpi_release (sk.E.n);
1009   _gcry_mpi_release (sk.E.h);
1010   _gcry_mpi_release (mpi_q);
1011   point_free (&sk.Q);
1012   _gcry_mpi_release (sk.d);
1013   _gcry_mpi_release (sig_r);
1014   _gcry_mpi_release (sig_s);
1015   xfree (curvename);
1016   _gcry_mpi_release (data);
1017   sexp_release (l1);
1018   _gcry_pk_util_free_encoding_ctx (&ctx);
1019   if (DBG_CIPHER)
1020     log_debug ("ecc_sign      => %s\n", gpg_strerror (rc));
1021   return rc;
1022 }
1023
1024
1025 static gcry_err_code_t
1026 ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
1027 {
1028   gcry_err_code_t rc;
1029   struct pk_encoding_ctx ctx;
1030   gcry_sexp_t l1 = NULL;
1031   char *curvename = NULL;
1032   gcry_mpi_t mpi_g = NULL;
1033   gcry_mpi_t mpi_q = NULL;
1034   gcry_mpi_t sig_r = NULL;
1035   gcry_mpi_t sig_s = NULL;
1036   gcry_mpi_t data = NULL;
1037   ECC_public_key pk;
1038   int sigflags;
1039
1040   memset (&pk, 0, sizeof pk);
1041   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
1042                                    ecc_get_nbits (s_keyparms));
1043
1044   /* Extract the data.  */
1045   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
1046   if (rc)
1047     goto leave;
1048   if (DBG_CIPHER)
1049     log_mpidump ("ecc_verify data", data);
1050
1051   /*
1052    * Extract the signature value.
1053    */
1054   rc = _gcry_pk_util_preparse_sigval (s_sig, ecc_names, &l1, &sigflags);
1055   if (rc)
1056     goto leave;
1057   rc = sexp_extract_param (l1, NULL, (sigflags & PUBKEY_FLAG_EDDSA)? "/rs":"rs",
1058                            &sig_r, &sig_s, NULL);
1059   if (rc)
1060     goto leave;
1061   if (DBG_CIPHER)
1062     {
1063       log_mpidump ("ecc_verify  s_r", sig_r);
1064       log_mpidump ("ecc_verify  s_s", sig_s);
1065     }
1066   if ((ctx.flags & PUBKEY_FLAG_EDDSA) ^ (sigflags & PUBKEY_FLAG_EDDSA))
1067     {
1068       rc = GPG_ERR_CONFLICT; /* Inconsistent use of flag/algoname.  */
1069       goto leave;
1070     }
1071
1072
1073   /*
1074    * Extract the key.
1075    */
1076   if ((ctx.flags & PUBKEY_FLAG_PARAM))
1077     rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?h?/q",
1078                              &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
1079                              &pk.E.h, &mpi_q, NULL);
1080   else
1081     rc = sexp_extract_param (s_keyparms, NULL, "/q",
1082                              &mpi_q, NULL);
1083   if (rc)
1084     goto leave;
1085   if (mpi_g)
1086     {
1087       point_init (&pk.E.G);
1088       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
1089       if (rc)
1090         goto leave;
1091     }
1092   /* Add missing parameters using the optional curve parameter.  */
1093   sexp_release (l1);
1094   l1 = sexp_find_token (s_keyparms, "curve", 5);
1095   if (l1)
1096     {
1097       curvename = sexp_nth_string (l1, 1);
1098       if (curvename)
1099         {
1100           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
1101           if (rc)
1102             goto leave;
1103         }
1104     }
1105   /* Guess required fields if a curve parameter has not been given.
1106      FIXME: This is a crude hacks.  We need to fix that.  */
1107   if (!curvename)
1108     {
1109       pk.E.model = ((sigflags & PUBKEY_FLAG_EDDSA)
1110                     ? MPI_EC_EDWARDS
1111                     : MPI_EC_WEIERSTRASS);
1112       pk.E.dialect = ((sigflags & PUBKEY_FLAG_EDDSA)
1113                       ? ECC_DIALECT_ED25519
1114                       : ECC_DIALECT_STANDARD);
1115       if (!pk.E.h)
1116         pk.E.h = mpi_const (MPI_C_ONE);
1117     }
1118
1119   if (DBG_CIPHER)
1120     {
1121       log_debug ("ecc_verify info: %s/%s%s\n",
1122                  _gcry_ecc_model2str (pk.E.model),
1123                  _gcry_ecc_dialect2str (pk.E.dialect),
1124                  (sigflags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
1125       if (pk.E.name)
1126         log_debug  ("ecc_verify name: %s\n", pk.E.name);
1127       log_printmpi ("ecc_verify    p", pk.E.p);
1128       log_printmpi ("ecc_verify    a", pk.E.a);
1129       log_printmpi ("ecc_verify    b", pk.E.b);
1130       log_printpnt ("ecc_verify  g",   &pk.E.G, NULL);
1131       log_printmpi ("ecc_verify    n", pk.E.n);
1132       log_printmpi ("ecc_verify    h", pk.E.h);
1133       log_printmpi ("ecc_verify    q", mpi_q);
1134     }
1135   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q)
1136     {
1137       rc = GPG_ERR_NO_OBJ;
1138       goto leave;
1139     }
1140
1141
1142   /*
1143    * Verify the signature.
1144    */
1145   if ((sigflags & PUBKEY_FLAG_EDDSA))
1146     {
1147       rc = _gcry_ecc_eddsa_verify (data, &pk, sig_r, sig_s,
1148                                    ctx.hash_algo, mpi_q);
1149     }
1150   else if ((sigflags & PUBKEY_FLAG_GOST))
1151     {
1152       point_init (&pk.Q);
1153       rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
1154       if (rc)
1155         goto leave;
1156
1157       rc = _gcry_ecc_gost_verify (data, &pk, sig_r, sig_s);
1158     }
1159   else
1160     {
1161       point_init (&pk.Q);
1162       if (pk.E.dialect == ECC_DIALECT_ED25519)
1163         {
1164           mpi_ec_t ec;
1165
1166           /* Fixme: Factor the curve context setup out of eddsa_verify
1167              and ecdsa_verify. So that we don't do it twice.  */
1168           ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
1169                                             pk.E.p, pk.E.a, pk.E.b);
1170
1171           rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &pk.Q, NULL, NULL);
1172           _gcry_mpi_ec_free (ec);
1173         }
1174       else
1175         {
1176           rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
1177         }
1178       if (rc)
1179         goto leave;
1180
1181       if (mpi_is_opaque (data))
1182         {
1183           const void *abuf;
1184           unsigned int abits, qbits;
1185           gcry_mpi_t a;
1186
1187           qbits = mpi_get_nbits (pk.E.n);
1188
1189           abuf = mpi_get_opaque (data, &abits);
1190           rc = _gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
1191           if (!rc)
1192             {
1193               if (abits > qbits)
1194                 mpi_rshift (a, a, abits - qbits);
1195
1196               rc = _gcry_ecc_ecdsa_verify (a, &pk, sig_r, sig_s);
1197               _gcry_mpi_release (a);
1198             }
1199         }
1200       else
1201         rc = _gcry_ecc_ecdsa_verify (data, &pk, sig_r, sig_s);
1202     }
1203
1204  leave:
1205   _gcry_mpi_release (pk.E.p);
1206   _gcry_mpi_release (pk.E.a);
1207   _gcry_mpi_release (pk.E.b);
1208   _gcry_mpi_release (mpi_g);
1209   point_free (&pk.E.G);
1210   _gcry_mpi_release (pk.E.n);
1211   _gcry_mpi_release (pk.E.h);
1212   _gcry_mpi_release (mpi_q);
1213   point_free (&pk.Q);
1214   _gcry_mpi_release (data);
1215   _gcry_mpi_release (sig_r);
1216   _gcry_mpi_release (sig_s);
1217   xfree (curvename);
1218   sexp_release (l1);
1219   _gcry_pk_util_free_encoding_ctx (&ctx);
1220   if (DBG_CIPHER)
1221     log_debug ("ecc_verify    => %s\n", rc?gpg_strerror (rc):"Good");
1222   return rc;
1223 }
1224
1225
1226 /* ecdh raw is classic 2-round DH protocol published in 1976.
1227  *
1228  * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
1229  *
1230  * As with any PK operation, encrypt version uses a public key and
1231  * decrypt -- private.
1232  *
1233  * Symbols used below:
1234  *     G - field generator point
1235  *     d - private long-term scalar
1236  *    dG - public long-term key
1237  *     k - ephemeral scalar
1238  *    kG - ephemeral public key
1239  *   dkG - shared secret
1240  *
1241  * ecc_encrypt_raw description:
1242  *   input:
1243  *     data[0] : private scalar (k)
1244  *   output: A new S-expression with the parameters:
1245  *     s : shared point (kdG)
1246  *     e : generated ephemeral public key (kG)
1247  *
1248  * ecc_decrypt_raw description:
1249  *   input:
1250  *     data[0] : a point kG (ephemeral public key)
1251  *   output:
1252  *     result[0] : shared point (kdG)
1253  */
1254 static gcry_err_code_t
1255 ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
1256 {
1257   unsigned int nbits;
1258   gcry_err_code_t rc;
1259   struct pk_encoding_ctx ctx;
1260   gcry_sexp_t l1 = NULL;
1261   char *curvename = NULL;
1262   gcry_mpi_t mpi_g = NULL;
1263   gcry_mpi_t mpi_q = NULL;
1264   gcry_mpi_t mpi_s = NULL;
1265   gcry_mpi_t mpi_e = NULL;
1266   gcry_mpi_t data = NULL;
1267   ECC_public_key pk;
1268   mpi_ec_t ec = NULL;
1269   int flags = 0;
1270
1271   memset (&pk, 0, sizeof pk);
1272   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
1273                                    (nbits = ecc_get_nbits (keyparms)));
1274
1275   /* Look for flags. */
1276   l1 = sexp_find_token (keyparms, "flags", 0);
1277   if (l1)
1278     {
1279       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
1280       if (rc)
1281         goto leave;
1282     }
1283   sexp_release (l1);
1284   l1 = NULL;
1285
1286   /*
1287    * Extract the data.
1288    */
1289   rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
1290   if (rc)
1291     goto leave;
1292   if (mpi_is_opaque (data))
1293     {
1294       rc = GPG_ERR_INV_DATA;
1295       goto leave;
1296     }
1297
1298   /*
1299    * Extract the key.
1300    */
1301   rc = sexp_extract_param (keyparms, NULL,
1302                            (flags & PUBKEY_FLAG_DJB_TWEAK)?
1303                            "-p?a?b?g?n?h?/q" : "-p?a?b?g?n?h?+q",
1304                            &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, &pk.E.h,
1305                            &mpi_q, NULL);
1306   if (rc)
1307     goto leave;
1308   if (mpi_g)
1309     {
1310       point_init (&pk.E.G);
1311       rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
1312       if (rc)
1313         goto leave;
1314     }
1315   /* Add missing parameters using the optional curve parameter.  */
1316   l1 = sexp_find_token (keyparms, "curve", 5);
1317   if (l1)
1318     {
1319       curvename = sexp_nth_string (l1, 1);
1320       if (curvename)
1321         {
1322           rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
1323           if (rc)
1324             goto leave;
1325         }
1326     }
1327   /* Guess required fields if a curve parameter has not been given.  */
1328   if (!curvename)
1329     {
1330       pk.E.model = MPI_EC_WEIERSTRASS;
1331       pk.E.dialect = ECC_DIALECT_STANDARD;
1332       if (!pk.E.h)
1333         pk.E.h = mpi_const (MPI_C_ONE);
1334     }
1335
1336   /*
1337    * Tweak the scalar bits by cofactor and number of bits of the field.
1338    * It assumes the cofactor is a power of 2.
1339    */
1340   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
1341     {
1342       int i;
1343
1344       for (i = 0; i < mpi_get_nbits (pk.E.h) - 1; i++)
1345         mpi_clear_bit (data, i);
1346       mpi_set_highbit (data, mpi_get_nbits (pk.E.p) - 1);
1347     }
1348   if (DBG_CIPHER)
1349     log_mpidump ("ecc_encrypt data", data);
1350
1351   if (DBG_CIPHER)
1352     {
1353       log_debug ("ecc_encrypt info: %s/%s\n",
1354                  _gcry_ecc_model2str (pk.E.model),
1355                  _gcry_ecc_dialect2str (pk.E.dialect));
1356       if (pk.E.name)
1357         log_debug  ("ecc_encrypt name: %s\n", pk.E.name);
1358       log_printmpi ("ecc_encrypt    p", pk.E.p);
1359       log_printmpi ("ecc_encrypt    a", pk.E.a);
1360       log_printmpi ("ecc_encrypt    b", pk.E.b);
1361       log_printpnt ("ecc_encrypt  g",   &pk.E.G, NULL);
1362       log_printmpi ("ecc_encrypt    n", pk.E.n);
1363       log_printmpi ("ecc_encrypt    h", pk.E.h);
1364       log_printmpi ("ecc_encrypt    q", mpi_q);
1365     }
1366   if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q)
1367     {
1368       rc = GPG_ERR_NO_OBJ;
1369       goto leave;
1370     }
1371
1372   /* Compute the encrypted value.  */
1373   ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, flags,
1374                                     pk.E.p, pk.E.a, pk.E.b);
1375
1376   /* Convert the public key.  */
1377   if (mpi_q)
1378     {
1379       point_init (&pk.Q);
1380       if (ec->model == MPI_EC_MONTGOMERY)
1381         rc = _gcry_ecc_mont_decodepoint (mpi_q, ec, &pk.Q);
1382       else
1383         rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
1384       if (rc)
1385         goto leave;
1386     }
1387
1388   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
1389   {
1390     mpi_point_struct R;  /* Result that we return.  */
1391     gcry_mpi_t x, y;
1392     unsigned char *rawmpi;
1393     unsigned int rawmpilen;
1394
1395     x = mpi_new (0);
1396     if (ec->model == MPI_EC_MONTGOMERY)
1397       y = NULL;
1398     else
1399       y = mpi_new (0);
1400
1401     point_init (&R);
1402
1403     /* R = kQ  <=>  R = kdG  */
1404     _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
1405
1406     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1407       {
1408         /*
1409          * Here, X is 0.  In the X25519 computation on Curve25519, X0
1410          * function maps infinity to zero.  So, when PUBKEY_FLAG_DJB_TWEAK
1411          * is enabled, return the result of 0 not raising an error.
1412          *
1413          * This is a corner case.  It never occurs with properly
1414          * generated public keys, but it might happen with blindly
1415          * imported public key which might not follow the key
1416          * generation procedure.
1417          */
1418         if (!(flags & PUBKEY_FLAG_DJB_TWEAK))
1419           { /* It's not for X25519, then, the input data was simply wrong.  */
1420             rc = GPG_ERR_INV_DATA;
1421             goto leave;
1422           }
1423       }
1424     if (y)
1425       mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
1426     else
1427       {
1428         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
1429         if (!rawmpi)
1430           rc = gpg_err_code_from_syserror ();
1431         else
1432           {
1433             rawmpi[0] = 0x40;
1434             rawmpilen++;
1435             mpi_s = mpi_new (0);
1436             mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8);
1437           }
1438       }
1439
1440     /* R = kG */
1441     _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
1442
1443     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1444       {
1445         rc = GPG_ERR_INV_DATA;
1446         goto leave;
1447       }
1448     if (y)
1449       mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
1450     else
1451       {
1452         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1, &rawmpilen, NULL);
1453         if (!rawmpi)
1454           rc = gpg_err_code_from_syserror ();
1455         else
1456           {
1457             rawmpi[0] = 0x40;
1458             rawmpilen++;
1459             mpi_e = mpi_new (0);
1460             mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8);
1461           }
1462       }
1463
1464
1465     mpi_free (x);
1466     mpi_free (y);
1467
1468     point_free (&R);
1469   }
1470
1471   if (!rc)
1472     rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
1473
1474  leave:
1475   _gcry_mpi_release (pk.E.p);
1476   _gcry_mpi_release (pk.E.a);
1477   _gcry_mpi_release (pk.E.b);
1478   _gcry_mpi_release (mpi_g);
1479   point_free (&pk.E.G);
1480   _gcry_mpi_release (pk.E.n);
1481   _gcry_mpi_release (pk.E.h);
1482   _gcry_mpi_release (mpi_q);
1483   point_free (&pk.Q);
1484   _gcry_mpi_release (data);
1485   _gcry_mpi_release (mpi_s);
1486   _gcry_mpi_release (mpi_e);
1487   xfree (curvename);
1488   sexp_release (l1);
1489   _gcry_mpi_ec_free (ec);
1490   _gcry_pk_util_free_encoding_ctx (&ctx);
1491   if (DBG_CIPHER)
1492     log_debug ("ecc_encrypt    => %s\n", gpg_strerror (rc));
1493   return rc;
1494 }
1495
1496
1497 /*  input:
1498  *     data[0] : a point kG (ephemeral public key)
1499  *   output:
1500  *     resaddr[0] : shared point kdG
1501  *
1502  *  see ecc_encrypt_raw for details.
1503  */
1504 static gcry_err_code_t
1505 ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
1506 {
1507   unsigned int nbits;
1508   gpg_err_code_t rc;
1509   struct pk_encoding_ctx ctx;
1510   gcry_sexp_t l1 = NULL;
1511   gcry_mpi_t data_e = NULL;
1512   ECC_secret_key sk;
1513   gcry_mpi_t mpi_g = NULL;
1514   char *curvename = NULL;
1515   mpi_ec_t ec = NULL;
1516   mpi_point_struct kG;
1517   mpi_point_struct R;
1518   gcry_mpi_t r = NULL;
1519   int flags = 0;
1520
1521   memset (&sk, 0, sizeof sk);
1522   point_init (&kG);
1523   point_init (&R);
1524
1525   _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
1526                                    (nbits = ecc_get_nbits (keyparms)));
1527
1528   /* Look for flags. */
1529   l1 = sexp_find_token (keyparms, "flags", 0);
1530   if (l1)
1531     {
1532       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
1533       if (rc)
1534         goto leave;
1535     }
1536   sexp_release (l1);
1537   l1 = NULL;
1538
1539   /*
1540    * Extract the data.
1541    */
1542   rc = _gcry_pk_util_preparse_encval (s_data, ecc_names, &l1, &ctx);
1543   if (rc)
1544     goto leave;
1545   rc = sexp_extract_param (l1, NULL, "e", &data_e, NULL);
1546   if (rc)
1547     goto leave;
1548   if (DBG_CIPHER)
1549     log_printmpi ("ecc_decrypt  d_e", data_e);
1550   if (mpi_is_opaque (data_e))
1551     {
1552       rc = GPG_ERR_INV_DATA;
1553       goto leave;
1554     }
1555
1556   /*
1557    * Extract the key.
1558    */
1559   rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+d",
1560                            &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
1561                            &sk.E.h, &sk.d, NULL);
1562   if (rc)
1563     goto leave;
1564   if (mpi_g)
1565     {
1566       point_init (&sk.E.G);
1567       rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
1568       if (rc)
1569         goto leave;
1570     }
1571   /* Add missing parameters using the optional curve parameter.  */
1572   sexp_release (l1);
1573   l1 = sexp_find_token (keyparms, "curve", 5);
1574   if (l1)
1575     {
1576       curvename = sexp_nth_string (l1, 1);
1577       if (curvename)
1578         {
1579           rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
1580           if (rc)
1581             goto leave;
1582         }
1583     }
1584   /* Guess required fields if a curve parameter has not been given.  */
1585   if (!curvename)
1586     {
1587       sk.E.model = MPI_EC_WEIERSTRASS;
1588       sk.E.dialect = ECC_DIALECT_STANDARD;
1589       if (!sk.E.h)
1590         sk.E.h = mpi_const (MPI_C_ONE);
1591     }
1592   if (DBG_CIPHER)
1593     {
1594       log_debug ("ecc_decrypt info: %s/%s\n",
1595                  _gcry_ecc_model2str (sk.E.model),
1596                  _gcry_ecc_dialect2str (sk.E.dialect));
1597       if (sk.E.name)
1598         log_debug  ("ecc_decrypt name: %s\n", sk.E.name);
1599       log_printmpi ("ecc_decrypt    p", sk.E.p);
1600       log_printmpi ("ecc_decrypt    a", sk.E.a);
1601       log_printmpi ("ecc_decrypt    b", sk.E.b);
1602       log_printpnt ("ecc_decrypt  g",   &sk.E.G, NULL);
1603       log_printmpi ("ecc_decrypt    n", sk.E.n);
1604       log_printmpi ("ecc_decrypt    h", sk.E.h);
1605       if (!fips_mode ())
1606         log_printmpi ("ecc_decrypt    d", sk.d);
1607     }
1608   if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d)
1609     {
1610       rc = GPG_ERR_NO_OBJ;
1611       goto leave;
1612     }
1613
1614
1615   ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, flags,
1616                                     sk.E.p, sk.E.a, sk.E.b);
1617
1618   /*
1619    * Compute the plaintext.
1620    */
1621   if (ec->model == MPI_EC_MONTGOMERY)
1622     rc = _gcry_ecc_mont_decodepoint (data_e, ec, &kG);
1623   else
1624     rc = _gcry_ecc_os2ec (&kG, data_e);
1625   if (rc)
1626     goto leave;
1627
1628   if (DBG_CIPHER)
1629     log_printpnt ("ecc_decrypt    kG", &kG, NULL);
1630
1631   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
1632     {
1633       /* For X25519, by its definition, validation should not be done.  */
1634       /* (Instead, we do output check.)
1635        *
1636        * However, to mitigate secret key leak from our implementation,
1637        * we also do input validation here.  For constant-time
1638        * implementation, we can remove this input validation.
1639        */
1640       if (_gcry_mpi_ec_bad_point (&kG, ec))
1641         {
1642           rc = GPG_ERR_INV_DATA;
1643           goto leave;
1644         }
1645     }
1646   else if (!_gcry_mpi_ec_curve_point (&kG, ec))
1647     {
1648       rc = GPG_ERR_INV_DATA;
1649       goto leave;
1650     }
1651
1652   /* R = dkG */
1653   _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
1654
1655   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
1656   {
1657     gcry_mpi_t x, y;
1658
1659     x = mpi_new (0);
1660     if (ec->model == MPI_EC_MONTGOMERY)
1661       y = NULL;
1662     else
1663       y = mpi_new (0);
1664
1665     if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
1666       {
1667         rc = GPG_ERR_INV_DATA;
1668         goto leave;
1669         /*
1670          * Note for X25519.
1671          *
1672          * By the definition of X25519, this is the case where X25519
1673          * returns 0, mapping infinity to zero.  However, we
1674          * deliberately let it return an error.
1675          *
1676          * For X25519 ECDH, comming here means that it might be
1677          * decrypted by anyone with the shared secret of 0 (the result
1678          * of this function could be always 0 by other scalar values,
1679          * other than the private key of SK.D).
1680          *
1681          * So, it looks like an encrypted message but it can be
1682          * decrypted by anyone, or at least something wrong
1683          * happens.  Recipient should not proceed as if it were
1684          * properly encrypted message.
1685          *
1686          * This handling is needed for our major usage of GnuPG,
1687          * where it does the One-Pass Diffie-Hellman method,
1688          * C(1, 1, ECC CDH), with an ephemeral key.
1689          */
1690       }
1691
1692     if (y)
1693       r = _gcry_ecc_ec2os (x, y, sk.E.p);
1694     else
1695       {
1696         unsigned char *rawmpi;
1697         unsigned int rawmpilen;
1698
1699         rawmpi = _gcry_mpi_get_buffer_extra (x, nbits/8, -1,
1700                                              &rawmpilen, NULL);
1701         if (!rawmpi)
1702           {
1703             rc = gpg_err_code_from_syserror ();
1704             goto leave;
1705           }
1706         else
1707           {
1708             rawmpi[0] = 0x40;
1709             rawmpilen++;
1710             r = mpi_new (0);
1711             mpi_set_opaque (r, rawmpi, rawmpilen*8);
1712           }
1713       }
1714     if (!r)
1715       rc = gpg_err_code_from_syserror ();
1716     else
1717       rc = 0;
1718     mpi_free (x);
1719     mpi_free (y);
1720   }
1721   if (DBG_CIPHER)
1722     log_printmpi ("ecc_decrypt  res", r);
1723
1724   if (!rc)
1725     rc = sexp_build (r_plain, NULL, "(value %m)", r);
1726
1727  leave:
1728   point_free (&R);
1729   point_free (&kG);
1730   _gcry_mpi_release (r);
1731   _gcry_mpi_release (sk.E.p);
1732   _gcry_mpi_release (sk.E.a);
1733   _gcry_mpi_release (sk.E.b);
1734   _gcry_mpi_release (mpi_g);
1735   point_free (&sk.E.G);
1736   _gcry_mpi_release (sk.E.n);
1737   _gcry_mpi_release (sk.E.h);
1738   _gcry_mpi_release (sk.d);
1739   _gcry_mpi_release (data_e);
1740   xfree (curvename);
1741   sexp_release (l1);
1742   _gcry_mpi_ec_free (ec);
1743   _gcry_pk_util_free_encoding_ctx (&ctx);
1744   if (DBG_CIPHER)
1745     log_debug ("ecc_decrypt    => %s\n", gpg_strerror (rc));
1746   return rc;
1747 }
1748
1749
1750 /* Return the number of bits for the key described by PARMS.  On error
1751  * 0 is returned.  The format of PARMS starts with the algorithm name;
1752  * for example:
1753  *
1754  *   (ecc
1755  *     (curve <name>)
1756  *     (p <mpi>)
1757  *     (a <mpi>)
1758  *     (b <mpi>)
1759  *     (g <mpi>)
1760  *     (n <mpi>)
1761  *     (q <mpi>))
1762  *
1763  * More parameters may be given. Either P or CURVE is needed.
1764  */
1765 static unsigned int
1766 ecc_get_nbits (gcry_sexp_t parms)
1767 {
1768   gcry_sexp_t l1;
1769   gcry_mpi_t p;
1770   unsigned int nbits = 0;
1771   char *curve;
1772
1773   l1 = sexp_find_token (parms, "p", 1);
1774   if (!l1)
1775     { /* Parameter P not found - check whether we have "curve".  */
1776       l1 = sexp_find_token (parms, "curve", 5);
1777       if (!l1)
1778         return 0; /* Neither P nor CURVE found.  */
1779
1780       curve = sexp_nth_string (l1, 1);
1781       sexp_release (l1);
1782       if (!curve)
1783         return 0;  /* No curve name given (or out of core). */
1784
1785       if (_gcry_ecc_fill_in_curve (0, curve, NULL, &nbits))
1786         nbits = 0;
1787       xfree (curve);
1788     }
1789   else
1790     {
1791       p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
1792       sexp_release (l1);
1793       if (p)
1794         {
1795           nbits = mpi_get_nbits (p);
1796           _gcry_mpi_release (p);
1797         }
1798     }
1799   return nbits;
1800 }
1801
1802
1803 /* See rsa.c for a description of this function.  */
1804 static gpg_err_code_t
1805 compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
1806 {
1807 #define N_COMPONENTS 7
1808   static const char names[N_COMPONENTS] = "pabgnhq";
1809   gpg_err_code_t rc;
1810   gcry_sexp_t l1;
1811   gcry_mpi_t values[N_COMPONENTS];
1812   int idx;
1813   char *curvename = NULL;
1814   int flags = 0;
1815   enum gcry_mpi_ec_models model = 0;
1816   enum ecc_dialects dialect = 0;
1817
1818   /* Clear the values first.  */
1819   for (idx=0; idx < N_COMPONENTS; idx++)
1820     values[idx] = NULL;
1821
1822
1823   /* Look for flags. */
1824   l1 = sexp_find_token (keyparms, "flags", 0);
1825   if (l1)
1826     {
1827       rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
1828       if (rc)
1829         goto leave;
1830     }
1831
1832   /* Extract the parameters.  */
1833   if ((flags & PUBKEY_FLAG_PARAM))
1834     {
1835       if ((flags & PUBKEY_FLAG_DJB_TWEAK))
1836         rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?/q",
1837                                  &values[0], &values[1], &values[2],
1838                                  &values[3], &values[4], &values[5],
1839                                  &values[6], NULL);
1840       else
1841         rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?q",
1842                                  &values[0], &values[1], &values[2],
1843                                  &values[3], &values[4], &values[5],
1844                                  &values[6], NULL);
1845     }
1846   else
1847     {
1848       if ((flags & PUBKEY_FLAG_DJB_TWEAK))
1849         rc = sexp_extract_param (keyparms, NULL, "/q",
1850                                  &values[6], NULL);
1851       else
1852         rc = sexp_extract_param (keyparms, NULL, "q",
1853                                  &values[6], NULL);
1854     }
1855   if (rc)
1856     goto leave;
1857
1858   /* Check whether a curve parameter is available and use that to fill
1859      in missing values.  */
1860   sexp_release (l1);
1861   l1 = sexp_find_token (keyparms, "curve", 5);
1862   if (l1)
1863     {
1864       curvename = sexp_nth_string (l1, 1);
1865       if (curvename)
1866         {
1867           rc = _gcry_ecc_update_curve_param (curvename,
1868                                              &model, &dialect,
1869                                              &values[0], &values[1], &values[2],
1870                                              &values[3], &values[4], &values[5]);
1871           if (rc)
1872             goto leave;
1873         }
1874     }
1875
1876   /* Guess required fields if a curve parameter has not been given.
1877      FIXME: This is a crude hacks.  We need to fix that.  */
1878   if (!curvename)
1879     {
1880       model = ((flags & PUBKEY_FLAG_EDDSA)
1881                ? MPI_EC_EDWARDS
1882                : MPI_EC_WEIERSTRASS);
1883       dialect = ((flags & PUBKEY_FLAG_EDDSA)
1884                  ? ECC_DIALECT_ED25519
1885                  : ECC_DIALECT_STANDARD);
1886       if (!values[5])
1887         values[5] = mpi_const (MPI_C_ONE);
1888     }
1889
1890   /* Check that all parameters are known and normalize all MPIs (that
1891      should not be required but we use an internal function later and
1892      thus we better make 100% sure that they are normalized). */
1893   for (idx = 0; idx < N_COMPONENTS; idx++)
1894     if (!values[idx])
1895       {
1896         rc = GPG_ERR_NO_OBJ;
1897         goto leave;
1898       }
1899     else
1900       _gcry_mpi_normalize (values[idx]);
1901
1902   /* Uncompress the public key with the exception of EdDSA where
1903      compression is the default and we thus compute the keygrip using
1904      the compressed version.  Because we don't support any non-eddsa
1905      compression, the only thing we need to do is to compress
1906      EdDSA.  */
1907   if ((flags & PUBKEY_FLAG_DJB_TWEAK))
1908     {
1909       rc = _gcry_ecc_eddsa_ensure_compact (values[6], 256);
1910       if (rc)
1911         goto leave;
1912     }
1913
1914   /* Hash them all.  */
1915   for (idx = 0; idx < N_COMPONENTS; idx++)
1916     {
1917       char buf[30];
1918
1919       if (idx == 5)
1920         continue;               /* Skip cofactor. */
1921
1922       if (mpi_is_opaque (values[idx]))
1923         {
1924           const unsigned char *raw;
1925           unsigned int n;
1926
1927           raw = mpi_get_opaque (values[idx], &n);
1928           n = (n + 7)/8;
1929           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], n);
1930           _gcry_md_write (md, buf, strlen (buf));
1931           _gcry_md_write (md, raw, n);
1932           _gcry_md_write (md, ")", 1);
1933         }
1934       else
1935         {
1936           unsigned char *rawmpi;
1937           unsigned int rawmpilen;
1938
1939           rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
1940           if (!rawmpi)
1941             {
1942               rc = gpg_err_code_from_syserror ();
1943               goto leave;
1944             }
1945           snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
1946           _gcry_md_write (md, buf, strlen (buf));
1947           _gcry_md_write (md, rawmpi, rawmpilen);
1948           _gcry_md_write (md, ")", 1);
1949           xfree (rawmpi);
1950         }
1951     }
1952
1953  leave:
1954   xfree (curvename);
1955   sexp_release (l1);
1956   for (idx = 0; idx < N_COMPONENTS; idx++)
1957     _gcry_mpi_release (values[idx]);
1958
1959   return rc;
1960 #undef N_COMPONENTS
1961 }
1962
1963
1964 \f
1965 /*
1966    Low-level API helper functions.
1967  */
1968
1969 /* This is the worker function for gcry_pubkey_get_sexp for ECC
1970    algorithms.  Note that the caller has already stored NULL at
1971    R_SEXP.  */
1972 gpg_err_code_t
1973 _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
1974 {
1975   gpg_err_code_t rc;
1976   gcry_mpi_t mpi_G = NULL;
1977   gcry_mpi_t mpi_Q = NULL;
1978
1979   if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->h)
1980     return GPG_ERR_BAD_CRYPT_CTX;
1981
1982   if (mode == GCRY_PK_GET_SECKEY && !ec->d)
1983     return GPG_ERR_NO_SECKEY;
1984
1985   /* Compute the public point if it is missing.  */
1986   if (!ec->Q && ec->d)
1987     ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);
1988
1989   /* Encode G and Q.  */
1990   mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
1991   if (!mpi_G)
1992     {
1993       rc = GPG_ERR_BROKEN_PUBKEY;
1994       goto leave;
1995     }
1996   if (!ec->Q)
1997     {
1998       rc = GPG_ERR_BAD_CRYPT_CTX;
1999       goto leave;
2000     }
2001
2002   if (ec->dialect == ECC_DIALECT_ED25519)
2003     {
2004       unsigned char *encpk;
2005       unsigned int encpklen;
2006
2007       rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0,
2008                                         &encpk, &encpklen);
2009       if (rc)
2010         goto leave;
2011       mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
2012       encpk = NULL;
2013     }
2014   else
2015     {
2016       mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
2017     }
2018   if (!mpi_Q)
2019     {
2020       rc = GPG_ERR_BROKEN_PUBKEY;
2021       goto leave;
2022     }
2023
2024   /* Fixme: We should return a curve name instead of the parameters if
2025      if know that they match a curve.  */
2026
2027   if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
2028     {
2029       /* Let's return a private key. */
2030       rc = sexp_build (r_sexp, NULL,
2031                        "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))",
2032                        ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q, ec->d);
2033     }
2034   else if (ec->Q)
2035     {
2036       /* Let's return a public key.  */
2037       rc = sexp_build (r_sexp, NULL,
2038                        "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))",
2039                        ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q);
2040     }
2041   else
2042     rc = GPG_ERR_BAD_CRYPT_CTX;
2043
2044  leave:
2045   mpi_free (mpi_Q);
2046   mpi_free (mpi_G);
2047   return rc;
2048 }
2049
2050
2051 \f
2052 /*
2053      Self-test section.
2054  */
2055
2056 static const char *
2057 selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
2058 {
2059   /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
2060   static const char sample_data[] =
2061     "(data (flags rfc6979)"
2062     " (hash sha256 #af2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
2063     /**/           "62113d8a62add1bf#))";
2064   static const char sample_data_bad[] =
2065     "(data (flags rfc6979)"
2066     " (hash sha256 #bf2bdbe1aa9b6ec1e2ade1d694f41fc71a831d0268e98915"
2067     /**/           "62113d8a62add1bf#))";
2068   static const char signature_r[] =
2069     "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
2070   static const char signature_s[] =
2071     "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
2072
2073   const char *errtxt = NULL;
2074   gcry_error_t err;
2075   gcry_sexp_t data = NULL;
2076   gcry_sexp_t data_bad = NULL;
2077   gcry_sexp_t sig = NULL;
2078   gcry_sexp_t l1 = NULL;
2079   gcry_sexp_t l2 = NULL;
2080   gcry_mpi_t r = NULL;
2081   gcry_mpi_t s = NULL;
2082   gcry_mpi_t calculated_r = NULL;
2083   gcry_mpi_t calculated_s = NULL;
2084   int cmp;
2085
2086   err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
2087   if (!err)
2088     err = sexp_sscan (&data_bad, NULL,
2089                       sample_data_bad, strlen (sample_data_bad));
2090   if (!err)
2091     err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
2092   if (!err)
2093     err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
2094
2095   if (err)
2096     {
2097       errtxt = "converting data failed";
2098       goto leave;
2099     }
2100
2101   err = _gcry_pk_sign (&sig, data, skey);
2102   if (err)
2103     {
2104       errtxt = "signing failed";
2105       goto leave;
2106     }
2107
2108   /* check against known signature */
2109   errtxt = "signature validity failed";
2110   l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
2111   if (!l1)
2112     goto leave;
2113   l2 = _gcry_sexp_find_token (l1, "ecdsa", 0);
2114   if (!l2)
2115     goto leave;
2116
2117   sexp_release (l1);
2118   l1 = l2;
2119
2120   l2 = _gcry_sexp_find_token (l1, "r", 0);
2121   if (!l2)
2122     goto leave;
2123   calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
2124   if (!calculated_r)
2125     goto leave;
2126
2127   sexp_release (l2);
2128   l2 = _gcry_sexp_find_token (l1, "s", 0);
2129   if (!l2)
2130     goto leave;
2131   calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
2132   if (!calculated_s)
2133     goto leave;
2134
2135   errtxt = "known sig check failed";
2136
2137   cmp = _gcry_mpi_cmp (r, calculated_r);
2138   if (cmp)
2139     goto leave;
2140   cmp = _gcry_mpi_cmp (s, calculated_s);
2141   if (cmp)
2142     goto leave;
2143
2144   errtxt = NULL;
2145
2146   /* verify generated signature */
2147   err = _gcry_pk_verify (sig, data, pkey);
2148   if (err)
2149     {
2150       errtxt = "verify failed";
2151       goto leave;
2152     }
2153   err = _gcry_pk_verify (sig, data_bad, pkey);
2154   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
2155     {
2156       errtxt = "bad signature not detected";
2157       goto leave;
2158     }
2159
2160
2161  leave:
2162   sexp_release (sig);
2163   sexp_release (data_bad);
2164   sexp_release (data);
2165   sexp_release (l1);
2166   sexp_release (l2);
2167   mpi_release (r);
2168   mpi_release (s);
2169   mpi_release (calculated_r);
2170   mpi_release (calculated_s);
2171   return errtxt;
2172 }
2173
2174
2175 static gpg_err_code_t
2176 selftests_ecdsa (selftest_report_func_t report)
2177 {
2178   const char *what;
2179   const char *errtxt;
2180   gcry_error_t err;
2181   gcry_sexp_t skey = NULL;
2182   gcry_sexp_t pkey = NULL;
2183
2184   what = "convert";
2185   err = sexp_sscan (&skey, NULL, sample_secret_key_secp256,
2186                     strlen (sample_secret_key_secp256));
2187   if (!err)
2188     err = sexp_sscan (&pkey, NULL, sample_public_key_secp256,
2189                       strlen (sample_public_key_secp256));
2190   if (err)
2191     {
2192       errtxt = _gcry_strerror (err);
2193       goto failed;
2194     }
2195
2196   what = "key consistency";
2197   err = ecc_check_secret_key(skey);
2198   if (err)
2199     {
2200       errtxt = _gcry_strerror (err);
2201       goto failed;
2202     }
2203
2204   what = "sign";
2205   errtxt = selftest_sign (pkey, skey);
2206   if (errtxt)
2207     goto failed;
2208
2209   sexp_release(pkey);
2210   sexp_release(skey);
2211   return 0; /* Succeeded. */
2212
2213  failed:
2214   sexp_release(pkey);
2215   sexp_release(skey);
2216   if (report)
2217     report ("pubkey", GCRY_PK_ECC, what, errtxt);
2218   return GPG_ERR_SELFTEST_FAILED;
2219 }
2220
2221
2222 /* Run a full self-test for ALGO and return 0 on success.  */
2223 static gpg_err_code_t
2224 run_selftests (int algo, int extended, selftest_report_func_t report)
2225 {
2226   (void)extended;
2227
2228   if (algo != GCRY_PK_ECC)
2229     return GPG_ERR_PUBKEY_ALGO;
2230
2231   return selftests_ecdsa (report);
2232 }
2233
2234
2235
2236 \f
2237 gcry_pk_spec_t _gcry_pubkey_spec_ecc =
2238   {
2239     GCRY_PK_ECC, { 0, 1 },
2240     (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
2241     "ECC", ecc_names,
2242     "pabgnhq", "pabgnhqd", "sw", "rs", "pabgnhq",
2243     ecc_generate,
2244     ecc_check_secret_key,
2245     ecc_encrypt_raw,
2246     ecc_decrypt_raw,
2247     ecc_sign,
2248     ecc_verify,
2249     ecc_get_nbits,
2250     run_selftests,
2251     compute_keygrip,
2252     _gcry_ecc_get_curve,
2253     _gcry_ecc_get_param_sexp
2254   };