Coverage Report

Created: 2022-12-08 06:10

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