Coverage Report

Created: 2024-11-21 07:03

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