Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/cipher/pubkey.c
Line
Count
Source (jump to first uncovered line)
1
/* pubkey.c  -  pubkey dispatcher
2
 * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
3
 *               2007, 2008, 2011 Free Software Foundation, Inc.
4
 * Copyright (C) 2013 g10 Code GmbH
5
 *
6
 * This file is part of Libgcrypt.
7
 *
8
 * Libgcrypt is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as
10
 * published by the Free Software Foundation; either version 2.1 of
11
 * the License, or (at your option) any later version.
12
 *
13
 * Libgcrypt is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include <config.h>
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <errno.h>
27
28
#include "g10lib.h"
29
#include "mpi.h"
30
#include "cipher.h"
31
#include "context.h"
32
#include "pubkey-internal.h"
33
34
35
/* This is the list of the public-key algorithms included in
36
   Libgcrypt.  */
37
static gcry_pk_spec_t * const pubkey_list[] =
38
  {
39
#if USE_ECC
40
    &_gcry_pubkey_spec_ecc,
41
#endif
42
#if USE_RSA
43
    &_gcry_pubkey_spec_rsa,
44
#endif
45
#if USE_DSA
46
    &_gcry_pubkey_spec_dsa,
47
#endif
48
#if USE_ELGAMAL
49
    &_gcry_pubkey_spec_elg,
50
#endif
51
    &_gcry_pubkey_spec_kem,
52
    NULL
53
  };
54
55
56
static int
57
map_algo (int algo)
58
0
{
59
0
 switch (algo)
60
0
   {
61
0
   case GCRY_PK_RSA_E: return GCRY_PK_RSA;
62
0
   case GCRY_PK_RSA_S: return GCRY_PK_RSA;
63
0
   case GCRY_PK_ELG_E: return GCRY_PK_ELG;
64
0
   case GCRY_PK_ECDSA: return GCRY_PK_ECC;
65
0
   case GCRY_PK_EDDSA: return GCRY_PK_ECC;
66
0
   case GCRY_PK_ECDH:  return GCRY_PK_ECC;
67
0
   default:            return algo;
68
0
   }
69
0
}
70
71
72
/* Return the spec structure for the public key algorithm ALGO.  For
73
   an unknown algorithm NULL is returned.  */
74
static gcry_pk_spec_t *
75
spec_from_algo (int algo)
76
0
{
77
0
  int idx;
78
0
  gcry_pk_spec_t *spec;
79
80
0
  algo = map_algo (algo);
81
82
0
  for (idx = 0; (spec = pubkey_list[idx]); idx++)
83
0
    if (algo == spec->algo)
84
0
      return spec;
85
0
  return NULL;
86
0
}
87
88
89
/* Return the spec structure for the public key algorithm with NAME.
90
   For an unknown name NULL is returned.  */
91
static gcry_pk_spec_t *
92
spec_from_name (const char *name)
93
446
{
94
446
  gcry_pk_spec_t *spec;
95
446
  int idx;
96
446
  const char **aliases;
97
98
446
  for (idx=0; (spec = pubkey_list[idx]); idx++)
99
446
    {
100
446
      if (!stricmp (name, spec->name))
101
0
        return spec;
102
892
      for (aliases = spec->aliases; *aliases; aliases++)
103
892
        if (!stricmp (name, *aliases))
104
446
          return spec;
105
446
    }
106
107
0
  return NULL;
108
446
}
109
110
111
112
/* Given the s-expression SEXP with the first element be either
113
 * "private-key" or "public-key" return the spec structure for it.  We
114
 * look through the list to find a list beginning with "private-key"
115
 * or "public-key" - the first one found is used.  If WANT_PRIVATE is
116
 * set the function will only succeed if a private key has been given.
117
 * On success the spec is stored at R_SPEC.  On error NULL is stored
118
 * at R_SPEC and an error code returned.  If R_PARMS is not NULL and
119
 * the function returns success, the parameter list below
120
 * "private-key" or "public-key" is stored there and the caller must
121
 * call gcry_sexp_release on it.
122
 */
123
static gcry_err_code_t
124
spec_from_sexp (gcry_sexp_t sexp, int want_private,
125
                gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
126
446
{
127
446
  gcry_sexp_t list, l2;
128
446
  char *name;
129
446
  gcry_pk_spec_t *spec;
130
131
446
  *r_spec = NULL;
132
446
  if (r_parms)
133
446
    *r_parms = NULL;
134
135
  /* Check that the first element is valid.  If we are looking for a
136
     public key but a private key was supplied, we allow the use of
137
     the private key anyway.  The rationale for this is that the
138
     private key is a superset of the public key.  */
139
446
  list = sexp_find_token (sexp, want_private? "private-key":"public-key", 0);
140
446
  if (!list && !want_private)
141
0
    list = sexp_find_token (sexp, "private-key", 0);
142
446
  if (!list)
143
0
    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
144
145
446
  l2 = sexp_cadr (list);
146
446
  sexp_release (list);
147
446
  list = l2;
148
446
  name = sexp_nth_string (list, 0);
149
446
  if (!name)
150
0
    {
151
0
      sexp_release ( list );
152
0
      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
153
0
    }
154
446
  spec = spec_from_name (name);
155
446
  xfree (name);
156
446
  if (!spec)
157
0
    {
158
0
      sexp_release (list);
159
0
      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
160
0
    }
161
446
  *r_spec = spec;
162
446
  if (r_parms)
163
446
    *r_parms = list;
164
0
  else
165
0
    sexp_release (list);
166
446
  return 0;
167
446
}
168
169
170
171
/* Disable the use of the algorithm ALGO.  This is not thread safe and
172
   should thus be called early.  */
173
static void
174
disable_pubkey_algo (int algo)
175
0
{
176
0
  gcry_pk_spec_t *spec = spec_from_algo (algo);
177
178
0
  if (spec)
179
0
    spec->flags.disabled = 1;
180
0
}
181
182
183

184
/*
185
 * Map a string to the pubkey algo
186
 */
187
int
188
_gcry_pk_map_name (const char *string)
189
0
{
190
0
  gcry_pk_spec_t *spec;
191
192
0
  if (!string)
193
0
    return 0;
194
0
  spec = spec_from_name (string);
195
0
  if (!spec)
196
0
    return 0;
197
0
  if (spec->flags.disabled)
198
0
    return 0;
199
0
  if (!spec->flags.fips && fips_mode ())
200
0
    return 0;
201
0
  return spec->algo;
202
0
}
203
204
205
/* Map the public key algorithm whose ID is contained in ALGORITHM to
206
   a string representation of the algorithm name.  For unknown
207
   algorithm IDs this functions returns "?". */
208
const char *
209
_gcry_pk_algo_name (int algo)
210
0
{
211
0
  gcry_pk_spec_t *spec;
212
213
0
  spec = spec_from_algo (algo);
214
0
  if (spec)
215
0
    return spec->name;
216
0
  return "?";
217
0
}
218
219
220
/****************
221
 * A USE of 0 means: don't care.
222
 */
223
static gcry_err_code_t
224
check_pubkey_algo (int algo, unsigned use)
225
0
{
226
0
  gcry_err_code_t err = 0;
227
0
  gcry_pk_spec_t *spec;
228
229
0
  spec = spec_from_algo (algo);
230
0
  if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
231
0
    {
232
0
      if (((use & GCRY_PK_USAGE_SIGN)
233
0
     && (! (spec->use & GCRY_PK_USAGE_SIGN)))
234
0
    || ((use & GCRY_PK_USAGE_ENCR)
235
0
        && (! (spec->use & GCRY_PK_USAGE_ENCR))))
236
0
  err = GPG_ERR_WRONG_PUBKEY_ALGO;
237
0
    }
238
0
  else
239
0
    err = GPG_ERR_PUBKEY_ALGO;
240
241
0
  return err;
242
0
}
243
244
245
/****************
246
 * Return the number of public key material numbers
247
 */
248
static int
249
pubkey_get_npkey (int algo)
250
0
{
251
0
  gcry_pk_spec_t *spec = spec_from_algo (algo);
252
253
0
  return spec? strlen (spec->elements_pkey) : 0;
254
0
}
255
256
257
/****************
258
 * Return the number of secret key material numbers
259
 */
260
static int
261
pubkey_get_nskey (int algo)
262
0
{
263
0
  gcry_pk_spec_t *spec = spec_from_algo (algo);
264
265
0
  return spec? strlen (spec->elements_skey) : 0;
266
0
}
267
268
269
/****************
270
 * Return the number of signature material numbers
271
 */
272
static int
273
pubkey_get_nsig (int algo)
274
0
{
275
0
  gcry_pk_spec_t *spec = spec_from_algo (algo);
276
277
0
  return spec? strlen (spec->elements_sig) : 0;
278
0
}
279
280
/****************
281
 * Return the number of encryption material numbers
282
 */
283
static int
284
pubkey_get_nenc (int algo)
285
0
{
286
0
  gcry_pk_spec_t *spec = spec_from_algo (algo);
287
288
0
  return spec? strlen (spec->elements_enc) : 0;
289
0
}
290
291
292

293
/*
294
   Do a PK encrypt operation
295
296
   Caller has to provide a public key as the SEXP pkey and data as a
297
   SEXP with just one MPI in it. Alternatively S_DATA might be a
298
   complex S-Expression, similar to the one used for signature
299
   verification.  This provides a flag which allows to handle PKCS#1
300
   block type 2 padding.  The function returns a sexp which may be
301
   passed to to pk_decrypt.
302
303
   Returns: 0 or an errorcode.
304
305
   s_data = See comment for _gcry_pk_util_data_to_mpi
306
   s_pkey = <key-as-defined-in-sexp_to_key>
307
   r_ciph = (enc-val
308
               (<algo>
309
                 (<param_name1> <mpi>)
310
                 ...
311
                 (<param_namen> <mpi>)
312
               ))
313
314
*/
315
gcry_err_code_t
316
_gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
317
0
{
318
0
  gcry_err_code_t rc;
319
0
  gcry_pk_spec_t *spec;
320
0
  gcry_sexp_t keyparms;
321
322
0
  *r_ciph = NULL;
323
324
0
  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
325
0
  if (rc)
326
0
    goto leave;
327
328
0
  if (spec->flags.disabled)
329
0
    rc = GPG_ERR_PUBKEY_ALGO;
330
0
  else if (!spec->flags.fips && fips_mode ())
331
0
    rc = GPG_ERR_PUBKEY_ALGO;
332
0
  else if (spec->encrypt)
333
0
    rc = spec->encrypt (r_ciph, s_data, keyparms);
334
0
  else
335
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
336
337
0
 leave:
338
0
  sexp_release (keyparms);
339
0
  return rc;
340
0
}
341
342
343
/*
344
   Do a PK decrypt operation
345
346
   Caller has to provide a secret key as the SEXP skey and data in a
347
   format as created by gcry_pk_encrypt.  For historic reasons the
348
   function returns simply an MPI as an S-expression part; this is
349
   deprecated and the new method should be used which returns a real
350
   S-expressionl this is selected by adding at least an empty flags
351
   list to S_DATA.
352
353
   Returns: 0 or an errorcode.
354
355
   s_data = (enc-val
356
              [(flags [raw, pkcs1, oaep])]
357
              (<algo>
358
                (<param_name1> <mpi>)
359
                ...
360
                (<param_namen> <mpi>)
361
              ))
362
   s_skey = <key-as-defined-in-sexp_to_key>
363
   r_plain= Either an incomplete S-expression without the parentheses
364
            or if the flags list is used (even if empty) a real S-expression:
365
            (value PLAIN).  In raw mode (or no flags given) the returned value
366
            is to be interpreted as a signed MPI, thus it may have an extra
367
            leading zero octet even if not included in the original data.
368
            With pkcs1 or oaep decoding enabled the returned value is a
369
            verbatim octet string.
370
 */
371
gcry_err_code_t
372
_gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
373
0
{
374
0
  gcry_err_code_t rc;
375
0
  gcry_pk_spec_t *spec;
376
0
  gcry_sexp_t keyparms;
377
378
0
  *r_plain = NULL;
379
380
0
  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
381
0
  if (rc)
382
0
    goto leave;
383
384
0
  if (spec->flags.disabled)
385
0
    rc = GPG_ERR_PUBKEY_ALGO;
386
0
  else if (!spec->flags.fips && fips_mode ())
387
0
    rc = GPG_ERR_PUBKEY_ALGO;
388
0
  else if (spec->decrypt)
389
0
    rc = spec->decrypt (r_plain, s_data, keyparms);
390
0
  else
391
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
392
393
0
 leave:
394
0
  sexp_release (keyparms);
395
0
  return rc;
396
0
}
397
398
399
400
/*
401
   Create a signature.
402
403
   Caller has to provide a secret key as the SEXP skey and data
404
   expressed as a SEXP list hash with only one element which should
405
   instantly be available as a MPI. Alternatively the structure given
406
   below may be used for S_HASH, it provides the abiliy to pass flags
407
   to the operation; the flags defined by now are "pkcs1" which does
408
   PKCS#1 block type 1 style padding and "pss" for PSS encoding.
409
410
   Returns: 0 or an errorcode.
411
            In case of 0 the function returns a new SEXP with the
412
            signature value; the structure of this signature depends on the
413
            other arguments but is always suitable to be passed to
414
            gcry_pk_verify
415
416
   s_hash = See comment for _gcry-pk_util_data_to_mpi
417
418
   s_skey = <key-as-defined-in-sexp_to_key>
419
   r_sig  = (sig-val
420
              (<algo>
421
                (<param_name1> <mpi>)
422
                ...
423
                (<param_namen> <mpi>))
424
             [(hash algo)])
425
426
  Note that (hash algo) in R_SIG is not used.
427
*/
428
gcry_err_code_t
429
_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
430
320
{
431
320
  gcry_err_code_t rc;
432
320
  gcry_pk_spec_t *spec;
433
320
  gcry_sexp_t keyparms;
434
435
320
  *r_sig = NULL;
436
437
320
  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
438
320
  if (rc)
439
0
    goto leave;
440
441
320
  if (spec->flags.disabled)
442
0
    rc = GPG_ERR_PUBKEY_ALGO;
443
320
  else if (!spec->flags.fips && fips_mode ())
444
0
    rc = GPG_ERR_PUBKEY_ALGO;
445
320
  else if (spec->sign)
446
320
    rc = spec->sign (r_sig, s_hash, keyparms);
447
0
  else
448
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
449
450
320
 leave:
451
320
  sexp_release (keyparms);
452
320
  return rc;
453
320
}
454
455
456
0
#define MAX_CONTEXTS 2 /* Currently, input data and random_override */
457
458
static gcry_err_code_t
459
prepare_datasexp_to_be_signed (const char *tmpl, gcry_md_hd_t hd,
460
                               gcry_ctx_t ctx, gcry_sexp_t *s_data_p)
461
0
{
462
0
  const char *s;
463
0
  const char *digest_name = NULL;
464
0
  const unsigned char *digest;
465
0
  int digest_size;
466
0
  int algo;
467
0
  gcry_err_code_t rc;
468
469
0
  if (hd == NULL)
470
0
    {
471
0
      const unsigned char *data[MAX_CONTEXTS];
472
0
      int data_size[MAX_CONTEXTS];
473
0
      int i = 0;
474
0
      void *argv[MAX_CONTEXTS*2];
475
476
0
      while (1)
477
0
        {
478
0
          size_t len;
479
480
0
          rc = _gcry_pk_get_single_data (&ctx, &data[i/2], &len);
481
0
          if (rc)
482
0
            return rc;
483
484
0
          data_size[i/2] = (int)len;
485
486
0
          argv[i] = (void *)&data_size[i/2];
487
0
          argv[i+1] = (void *)&data[i/2];
488
489
0
          i += 2;
490
491
0
          if (!ctx)
492
0
            break;
493
494
0
          if (i >= MAX_CONTEXTS*2)
495
0
            return GPG_ERR_EINVAL;
496
0
        }
497
498
0
      rc = _gcry_sexp_build_array (s_data_p, NULL, tmpl, argv);
499
0
      return rc;
500
0
    }
501
502
  /* Check if it has fixed hash name or %s */
503
0
  s = strstr (tmpl, "(hash ");
504
0
  if (s == NULL)
505
0
    return GPG_ERR_DIGEST_ALGO;
506
507
0
  s += 6;
508
0
  if (!strncmp (s, "%s", 2))
509
0
    {
510
0
      algo = _gcry_md_get_algo (hd);
511
512
0
      if (fips_mode () && algo == GCRY_MD_SHA1)
513
0
        {
514
0
          _gcry_md_close (hd);
515
0
          return GPG_ERR_DIGEST_ALGO;
516
0
        }
517
518
0
      digest_name = _gcry_md_algo_name (algo);
519
0
      digest_size = (int)_gcry_md_get_algo_dlen (algo);
520
0
      digest = _gcry_md_read (hd, 0);
521
0
    }
522
0
  else
523
0
    {
524
0
      const char *p;
525
0
      char *digest_name_supplied;
526
527
0
      for (p = s; *p && *p != ' '; p++)
528
0
  ;
529
530
0
      digest_name_supplied = xtrymalloc (p - s + 1);
531
0
      if (!digest_name_supplied)
532
0
  return gpg_error_from_syserror ();
533
0
      memcpy (digest_name_supplied, s, p - s);
534
0
      digest_name_supplied[p - s] = 0;
535
536
0
      algo = _gcry_md_map_name (digest_name_supplied);
537
0
      xfree (digest_name_supplied);
538
0
      if (algo == 0
539
0
          || (fips_mode () && algo == GCRY_MD_SHA1))
540
0
  {
541
0
    _gcry_md_close (hd);
542
0
    return GPG_ERR_DIGEST_ALGO;
543
0
  }
544
545
0
      digest_size = (int)_gcry_md_get_algo_dlen (algo);
546
0
      digest = _gcry_md_read (hd, algo);
547
0
    }
548
549
0
  if (!digest)
550
0
    {
551
0
      _gcry_md_close (hd);
552
0
      return GPG_ERR_NOT_IMPLEMENTED;
553
0
    }
554
555
0
  if (!ctx)
556
0
    {
557
0
      if (!digest_name)
558
0
  rc = _gcry_sexp_build (s_data_p, NULL, tmpl,
559
0
             digest_size, digest);
560
0
      else
561
0
  rc = _gcry_sexp_build (s_data_p, NULL, tmpl, digest_name,
562
0
             digest_size, digest);
563
0
    }
564
0
  else
565
0
    {
566
0
      const unsigned char *p;
567
0
      size_t len;
568
569
0
      rc = _gcry_pk_get_single_data (&ctx, &p, &len);
570
0
      if (rc)
571
0
        return rc;
572
573
0
      if (!digest_name)
574
0
  rc = _gcry_sexp_build (s_data_p, NULL, tmpl,
575
0
                               digest_size, digest, (int) len, p);
576
0
      else
577
0
  rc = _gcry_sexp_build (s_data_p, NULL, tmpl, digest_name,
578
0
                               digest_size, digest, (int) len, p);
579
0
    }
580
581
0
  _gcry_md_close (hd);
582
0
  return rc;
583
0
}
584
585
586
gcry_err_code_t
587
_gcry_pk_sign_md (gcry_sexp_t *r_sig, const char *tmpl, gcry_md_hd_t hd_orig,
588
                  gcry_sexp_t s_skey, gcry_ctx_t ctx)
589
0
{
590
0
  gcry_err_code_t rc;
591
0
  gcry_pk_spec_t *spec;
592
0
  gcry_sexp_t keyparms = NULL;
593
0
  gcry_sexp_t s_data = NULL;
594
0
  gcry_error_t err;
595
0
  gcry_md_hd_t hd;
596
597
0
  *r_sig = NULL;
598
599
0
  if (!hd_orig)
600
0
    hd = NULL;
601
0
  else
602
0
    {
603
0
      err = _gcry_md_copy (&hd, hd_orig);
604
0
      if (err)
605
0
        return gpg_err_code (err);
606
0
    }
607
608
0
  rc = prepare_datasexp_to_be_signed (tmpl, hd, ctx, &s_data);
609
0
  if (rc)
610
0
    return rc;
611
612
0
  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
613
0
  if (rc)
614
0
    goto leave;
615
616
0
  if (spec->flags.disabled)
617
0
    rc = GPG_ERR_PUBKEY_ALGO;
618
0
  else if (!spec->flags.fips && fips_mode ())
619
0
    rc = GPG_ERR_PUBKEY_ALGO;
620
0
  else if (spec->sign)
621
0
    rc = spec->sign (r_sig, s_data, keyparms);
622
0
  else
623
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
624
625
0
 leave:
626
0
  sexp_release (s_data);
627
0
  sexp_release (keyparms);
628
0
  return rc;
629
0
}
630
631
632
/*
633
   Verify a signature.
634
635
   Caller has to supply the public key pkey, the signature sig and his
636
   hashvalue data.  Public key has to be a standard public key given
637
   as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
638
   must be an S-Exp like the one in sign too.  */
639
gcry_err_code_t
640
_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
641
126
{
642
126
  gcry_err_code_t rc;
643
126
  gcry_pk_spec_t *spec;
644
126
  gcry_sexp_t keyparms;
645
646
126
  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
647
126
  if (rc)
648
0
    goto leave;
649
650
126
  if (spec->flags.disabled)
651
0
    rc = GPG_ERR_PUBKEY_ALGO;
652
126
  else if (!spec->flags.fips && fips_mode ())
653
0
    rc = GPG_ERR_PUBKEY_ALGO;
654
126
  else if (spec->verify)
655
126
    rc = spec->verify (s_sig, s_hash, keyparms);
656
0
  else
657
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
658
659
126
 leave:
660
126
  sexp_release (keyparms);
661
126
  return rc;
662
126
}
663
664
665
gcry_err_code_t
666
_gcry_pk_verify_md (gcry_sexp_t s_sig, const char *tmpl, gcry_md_hd_t hd_orig,
667
                    gcry_sexp_t s_pkey, gcry_ctx_t ctx)
668
0
{
669
0
  gcry_err_code_t rc;
670
0
  gcry_pk_spec_t *spec;
671
0
  gcry_sexp_t keyparms = NULL;
672
0
  gcry_sexp_t s_data = NULL;
673
0
  gcry_error_t err;
674
0
  gcry_md_hd_t hd;
675
676
0
  if (!hd_orig)
677
0
    hd = NULL;
678
0
  else
679
0
    {
680
0
      err = _gcry_md_copy (&hd, hd_orig);
681
0
      if (err)
682
0
        return gpg_err_code (err);
683
0
    }
684
685
0
  rc = prepare_datasexp_to_be_signed (tmpl, hd, ctx, &s_data);
686
0
  if (rc)
687
0
    return rc;
688
689
0
  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
690
0
  if (rc)
691
0
    goto leave;
692
693
0
  if (spec->flags.disabled)
694
0
    rc = GPG_ERR_PUBKEY_ALGO;
695
0
  else if (!spec->flags.fips && fips_mode ())
696
0
    rc = GPG_ERR_PUBKEY_ALGO;
697
0
  else if (spec->verify)
698
0
    rc = spec->verify (s_sig, s_data, keyparms);
699
0
  else
700
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
701
702
0
 leave:
703
0
  sexp_release (s_data);
704
0
  sexp_release (keyparms);
705
0
  return rc;
706
0
}
707
708
709
/*
710
   Test a key.
711
712
   This may be used either for a public or a secret key to see whether
713
   the internal structure is okay.
714
715
   Returns: 0 or an errorcode.
716
717
   NOTE: We currently support only secret key checking. */
718
gcry_err_code_t
719
_gcry_pk_testkey (gcry_sexp_t s_key)
720
0
{
721
0
  gcry_err_code_t rc;
722
0
  gcry_pk_spec_t *spec;
723
0
  gcry_sexp_t keyparms;
724
725
0
  rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
726
0
  if (rc)
727
0
    goto leave;
728
729
0
  if (spec->flags.disabled)
730
0
    rc = GPG_ERR_PUBKEY_ALGO;
731
0
  else if (!spec->flags.fips && fips_mode ())
732
0
    rc = GPG_ERR_PUBKEY_ALGO;
733
0
  else if (spec->check_secret_key)
734
0
    rc = spec->check_secret_key (keyparms);
735
0
  else
736
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
737
738
0
 leave:
739
0
  sexp_release (keyparms);
740
0
  return rc;
741
0
}
742
743
744
745
/* Create a public key pair and return it as R_KEY.
746
 * How the key is created depends on s_parms:
747
 *
748
 *   (genkey
749
 *     (algo
750
 *       (parameter_name_1 ....)
751
 *       ....
752
 *       (parameter_name_n ....)))
753
 *
754
 * The key is returned in a format depending on the algorithm. Both,
755
 * private and secret keys are returned and optionally some additional
756
 * information.  For example for Elgamal this structure is returned:
757
 *
758
 *   (key-data
759
 *     (public-key
760
 *       (elg
761
 *         (p <mpi>)
762
 *         (g <mpi>)
763
 *         (y <mpi>)))
764
 *     (private-key
765
 *       (elg
766
 *         (p <mpi>)
767
 *         (g <mpi>)
768
 *         (y <mpi>)
769
 *         (x <mpi>)))
770
 *     (misc-key-info
771
 *        (pm1-factors n1 n2 ... nn)))
772
 */
773
gcry_err_code_t
774
_gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
775
0
{
776
0
  gcry_pk_spec_t *spec = NULL;
777
0
  gcry_sexp_t list = NULL;
778
0
  gcry_sexp_t l2 = NULL;
779
0
  char *name = NULL;
780
0
  gcry_err_code_t rc;
781
782
0
  *r_key = NULL;
783
784
0
  list = sexp_find_token (s_parms, "genkey", 0);
785
0
  if (!list)
786
0
    {
787
0
      rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
788
0
      goto leave;
789
0
    }
790
791
0
  l2 = sexp_cadr (list);
792
0
  sexp_release (list);
793
0
  list = l2;
794
0
  l2 = NULL;
795
0
  if (! list)
796
0
    {
797
0
      rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
798
0
      goto leave;
799
0
    }
800
801
0
  name = _gcry_sexp_nth_string (list, 0);
802
0
  if (!name)
803
0
    {
804
0
      rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
805
0
      goto leave;
806
0
    }
807
808
0
  spec = spec_from_name (name);
809
0
  xfree (name);
810
0
  name = NULL;
811
0
  if (!spec || spec->flags.disabled || (!spec->flags.fips && fips_mode ()))
812
0
    {
813
0
      rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
814
0
      goto leave;
815
0
    }
816
817
0
  if (spec->generate)
818
0
    rc = spec->generate (list, r_key);
819
0
  else
820
0
    rc = GPG_ERR_NOT_IMPLEMENTED;
821
822
0
 leave:
823
0
  sexp_release (list);
824
0
  xfree (name);
825
0
  sexp_release (l2);
826
827
0
  return rc;
828
0
}
829
830
831
/*
832
   Get the number of nbits from the public key.
833
834
   Hmmm: Should we have really this function or is it better to have a
835
   more general function to retrieve different properties of the key?  */
836
unsigned int
837
_gcry_pk_get_nbits (gcry_sexp_t key)
838
0
{
839
0
  gcry_pk_spec_t *spec;
840
0
  gcry_sexp_t parms;
841
0
  unsigned int nbits;
842
843
  /* Parsing KEY might be considered too much overhead.  For example
844
     for RSA we would only need to look at P and stop parsing right
845
     away.  However, with ECC things are more complicate in that only
846
     a curve name might be specified.  Thus we need to tear the sexp
847
     apart. */
848
849
0
  if (spec_from_sexp (key, 0, &spec, &parms))
850
0
    return 0; /* Error - 0 is a suitable indication for that.  */
851
0
  if (spec->flags.disabled)
852
0
    return 0;
853
0
  if (!spec->flags.fips && fips_mode ())
854
0
    return 0;
855
856
0
  nbits = spec->get_nbits (parms);
857
0
  sexp_release (parms);
858
0
  return nbits;
859
0
}
860
861
862
/* Return the so called KEYGRIP which is the SHA-1 hash of the public
863
   key parameters expressed in a way depending on the algorithm.
864
865
   ARRAY must either be 20 bytes long or NULL; in the latter case a
866
   newly allocated array of that size is returned, otherwise ARRAY or
867
   NULL is returned to indicate an error which is most likely an
868
   unknown algorithm.  The function accepts public or secret keys. */
869
unsigned char *
870
_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
871
0
{
872
0
  gcry_sexp_t list = NULL;
873
0
  gcry_sexp_t l2 = NULL;
874
0
  gcry_pk_spec_t *spec = NULL;
875
0
  const char *s;
876
0
  char *name = NULL;
877
0
  int idx;
878
0
  const char *elems;
879
0
  gcry_md_hd_t md = NULL;
880
0
  int okay = 0;
881
882
  /* Check that the first element is valid. */
883
0
  list = sexp_find_token (key, "public-key", 0);
884
0
  if (! list)
885
0
    list = sexp_find_token (key, "private-key", 0);
886
0
  if (! list)
887
0
    list = sexp_find_token (key, "protected-private-key", 0);
888
0
  if (! list)
889
0
    list = sexp_find_token (key, "shadowed-private-key", 0);
890
0
  if (! list)
891
0
    return NULL; /* No public- or private-key object. */
892
893
0
  l2 = sexp_cadr (list);
894
0
  sexp_release (list);
895
0
  list = l2;
896
0
  l2 = NULL;
897
898
0
  name = _gcry_sexp_nth_string (list, 0);
899
0
  if (!name)
900
0
    goto fail; /* Invalid structure of object. */
901
902
0
  spec = spec_from_name (name);
903
0
  if (!spec)
904
0
    goto fail; /* Unknown algorithm.  */
905
906
0
  elems = spec->elements_grip;
907
0
  if (!elems)
908
0
    goto fail; /* No grip parameter.  */
909
910
0
  if (_gcry_md_open (&md, GCRY_MD_SHA1, 0))
911
0
    goto fail;
912
913
0
  if (spec->comp_keygrip)
914
0
    {
915
      /* Module specific method to compute a keygrip.  */
916
0
      if (spec->comp_keygrip (md, list))
917
0
        goto fail;
918
0
    }
919
0
  else
920
0
    {
921
      /* Generic method to compute a keygrip.  */
922
0
      for (idx = 0, s = elems; *s; s++, idx++)
923
0
        {
924
0
          const char *data;
925
0
          size_t datalen;
926
0
          char buf[30];
927
928
0
          l2 = sexp_find_token (list, s, 1);
929
0
          if (! l2)
930
0
            goto fail;
931
0
          data = sexp_nth_data (l2, 1, &datalen);
932
0
          if (! data)
933
0
            goto fail;
934
935
0
          snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
936
0
          _gcry_md_write (md, buf, strlen (buf));
937
0
          _gcry_md_write (md, data, datalen);
938
0
          sexp_release (l2);
939
0
          l2 = NULL;
940
0
          _gcry_md_write (md, ")", 1);
941
0
        }
942
0
    }
943
944
0
  if (!array)
945
0
    {
946
0
      array = xtrymalloc (20);
947
0
      if (! array)
948
0
        goto fail;
949
0
    }
950
951
0
  memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20);
952
0
  okay = 1;
953
954
0
 fail:
955
0
  xfree (name);
956
0
  sexp_release (l2);
957
0
  _gcry_md_close (md);
958
0
  sexp_release (list);
959
0
  return okay? array : NULL;
960
0
}
961
962
963

964
const char *
965
_gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
966
0
{
967
0
  const char *result = NULL;
968
0
  gcry_pk_spec_t *spec;
969
0
  gcry_sexp_t keyparms = NULL;
970
971
0
  if (r_nbits)
972
0
    *r_nbits = 0;
973
974
0
  if (key)
975
0
    {
976
0
      iterator = 0;
977
978
0
      if (spec_from_sexp (key, 0, &spec, &keyparms))
979
0
        return NULL;
980
0
    }
981
0
  else
982
0
    {
983
0
      spec = spec_from_name ("ecc");
984
0
      if (!spec)
985
0
        return NULL;
986
0
    }
987
988
0
  if (spec->flags.disabled)
989
0
    return NULL;
990
0
  if (!spec->flags.fips && fips_mode ())
991
0
    return NULL;
992
0
  if (spec->get_curve)
993
0
    result = spec->get_curve (keyparms, iterator, r_nbits);
994
995
0
  sexp_release (keyparms);
996
0
  return result;
997
0
}
998
999
1000

1001
gcry_sexp_t
1002
_gcry_pk_get_param (int algo, const char *name)
1003
0
{
1004
0
  gcry_sexp_t result = NULL;
1005
0
  gcry_pk_spec_t *spec = NULL;
1006
1007
0
  algo = map_algo (algo);
1008
1009
0
  if (algo != GCRY_PK_ECC)
1010
0
    return NULL;
1011
1012
0
  spec = spec_from_name ("ecc");
1013
0
  if (spec)
1014
0
    {
1015
0
      if (spec && spec->get_curve_param)
1016
0
        result = spec->get_curve_param (name);
1017
0
    }
1018
0
  return result;
1019
0
}
1020
1021
1022

1023
gcry_err_code_t
1024
_gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
1025
0
{
1026
0
  gcry_err_code_t rc = 0;
1027
1028
0
  switch (cmd)
1029
0
    {
1030
0
    case GCRYCTL_DISABLE_ALGO:
1031
      /* This one expects a buffer pointing to an integer with the
1032
         algo number.  */
1033
0
      if ((! buffer) || (buflen != sizeof (int)))
1034
0
  rc = GPG_ERR_INV_ARG;
1035
0
      else
1036
0
  disable_pubkey_algo (*((int *) buffer));
1037
0
      break;
1038
1039
0
    default:
1040
0
      rc = GPG_ERR_INV_OP;
1041
0
    }
1042
1043
0
  return rc;
1044
0
}
1045
1046
1047
/* Return information about the given algorithm
1048
1049
   WHAT selects the kind of information returned:
1050
1051
    GCRYCTL_TEST_ALGO:
1052
        Returns 0 when the specified algorithm is available for use.
1053
        Buffer must be NULL, nbytes  may have the address of a variable
1054
        with the required usage of the algorithm. It may be 0 for don't
1055
        care or a combination of the GCRY_PK_USAGE_xxx flags;
1056
1057
    GCRYCTL_GET_ALGO_USAGE:
1058
        Return the usage flags for the given algo.  An invalid algo
1059
        returns 0.  Disabled algos are ignored here because we
1060
        only want to know whether the algo is at all capable of
1061
        the usage.
1062
1063
   Note: Because this function is in most cases used to return an
1064
   integer value, we can make it easier for the caller to just look at
1065
   the return value.  The caller will in all cases consult the value
1066
   and thereby detecting whether a error occurred or not (i.e. while
1067
   checking the block size) */
1068
gcry_err_code_t
1069
_gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
1070
0
{
1071
0
  gcry_err_code_t rc = 0;
1072
1073
0
  switch (what)
1074
0
    {
1075
0
    case GCRYCTL_TEST_ALGO:
1076
0
      {
1077
0
  int use = nbytes ? *nbytes : 0;
1078
0
  if (buffer)
1079
0
    rc = GPG_ERR_INV_ARG;
1080
0
  else if (check_pubkey_algo (algorithm, use))
1081
0
    rc = GPG_ERR_PUBKEY_ALGO;
1082
0
  break;
1083
0
      }
1084
1085
0
    case GCRYCTL_GET_ALGO_USAGE:
1086
0
      {
1087
0
  gcry_pk_spec_t *spec;
1088
1089
0
  spec = spec_from_algo (algorithm);
1090
0
        *nbytes = spec? spec->use : 0;
1091
0
  break;
1092
0
      }
1093
1094
0
    case GCRYCTL_GET_ALGO_NPKEY:
1095
0
      {
1096
  /* FIXME?  */
1097
0
  int npkey = pubkey_get_npkey (algorithm);
1098
0
  *nbytes = npkey;
1099
0
  break;
1100
0
      }
1101
0
    case GCRYCTL_GET_ALGO_NSKEY:
1102
0
      {
1103
  /* FIXME?  */
1104
0
  int nskey = pubkey_get_nskey (algorithm);
1105
0
  *nbytes = nskey;
1106
0
  break;
1107
0
      }
1108
0
    case GCRYCTL_GET_ALGO_NSIGN:
1109
0
      {
1110
  /* FIXME?  */
1111
0
  int nsign = pubkey_get_nsig (algorithm);
1112
0
  *nbytes = nsign;
1113
0
  break;
1114
0
      }
1115
0
    case GCRYCTL_GET_ALGO_NENCR:
1116
0
      {
1117
  /* FIXME?  */
1118
0
  int nencr = pubkey_get_nenc (algorithm);
1119
0
  *nbytes = nencr;
1120
0
  break;
1121
0
      }
1122
1123
0
    default:
1124
0
      rc = GPG_ERR_INV_OP;
1125
0
    }
1126
1127
0
  return rc;
1128
0
}
1129
1130
1131
/* Return an S-expression representing the context CTX.  Depending on
1132
   the state of that context, the S-expression may either be a public
1133
   key, a private key or any other object used with public key
1134
   operations.  On success a new S-expression is stored at R_SEXP and
1135
   0 is returned, on error NULL is store there and an error code is
1136
   returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
1137
1138
   As of now it only support certain ECC operations because a context
1139
   object is right now only defined for ECC.  Over time this function
1140
   will be extended to cover more algorithms.  Note also that the name
1141
   of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
1142
   is that we will eventually provide variants of the existing
1143
   gcry_pk_xxx functions which will take a context parameter.   */
1144
gcry_err_code_t
1145
_gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
1146
0
{
1147
0
  mpi_ec_t ec;
1148
1149
0
  if (!r_sexp)
1150
0
    return GPG_ERR_INV_VALUE;
1151
0
  *r_sexp = NULL;
1152
0
  switch (mode)
1153
0
    {
1154
0
    case 0:
1155
0
    case GCRY_PK_GET_PUBKEY:
1156
0
    case GCRY_PK_GET_SECKEY:
1157
0
      break;
1158
0
    default:
1159
0
      return GPG_ERR_INV_VALUE;
1160
0
    }
1161
0
  if (!ctx)
1162
0
    return GPG_ERR_NO_CRYPT_CTX;
1163
1164
0
  ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
1165
0
  if (ec)
1166
0
    return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
1167
1168
0
  return GPG_ERR_WRONG_CRYPT_CTX;
1169
0
}
1170
1171
1172

1173
/* Explicitly initialize this module.  */
1174
gcry_err_code_t
1175
_gcry_pk_init (void)
1176
10
{
1177
10
  return 0;
1178
10
}
1179
1180
1181
/* Run the selftests for pubkey algorithm ALGO with optional reporting
1182
   function REPORT.  */
1183
gpg_error_t
1184
_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
1185
0
{
1186
0
  gcry_err_code_t ec;
1187
0
  gcry_pk_spec_t *spec;
1188
1189
0
  algo = map_algo (algo);
1190
0
  spec = spec_from_algo (algo);
1191
0
  if (spec && !spec->flags.disabled
1192
0
      && (spec->flags.fips || !fips_mode ())
1193
0
      && spec->selftest)
1194
0
    ec = spec->selftest (algo, extended, report);
1195
0
  else
1196
0
    {
1197
0
      ec = GPG_ERR_PUBKEY_ALGO;
1198
      /* Fixme: We need to change the report function to allow passing
1199
         of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
1200
0
      if (report)
1201
0
        report ("pubkey", algo, "module",
1202
0
                spec && !spec->flags.disabled
1203
0
                && (spec->flags.fips || !fips_mode ())?
1204
0
                "no selftest available" :
1205
0
                spec? "algorithm disabled" :
1206
0
                "algorithm not found");
1207
0
    }
1208
1209
0
  return gpg_error (ec);
1210
0
}
1211
1212
1213
struct pk_single_data {
1214
  size_t len;
1215
  unsigned char area[1];  /* In future, we may use flexible array member.  */
1216
};
1217
1218
gpg_err_code_t
1219
_gcry_pk_single_data_push (gcry_ctx_t *r_ctx,
1220
                          const unsigned char *p, size_t len)
1221
0
{
1222
0
  gcry_ctx_t ctx;
1223
0
  struct pk_single_data *psd;
1224
0
  int data_type = CONTEXT_TYPE_SINGLE_DATA;
1225
1226
0
  if (!p)
1227
0
    return GPG_ERR_EINVAL;
1228
1229
0
  ctx = _gcry_ctx_alloc (data_type,
1230
0
       offsetof (struct pk_single_data, area) + len,
1231
0
                         NULL, *r_ctx);
1232
0
  if (!ctx)
1233
0
    return gpg_err_code_from_syserror ();
1234
0
  psd = _gcry_ctx_get_pointer (ctx, data_type);
1235
0
  psd->len = len;
1236
0
  memcpy (psd->area, p, len);
1237
1238
0
  *r_ctx = ctx;
1239
0
  return 0;
1240
0
}
1241
1242
gpg_err_code_t
1243
_gcry_pk_get_single_data (gcry_ctx_t *r_ctx,
1244
                          const unsigned char **r_p, size_t *r_len)
1245
0
{
1246
0
  struct pk_single_data *psd;
1247
0
  int data_type = CONTEXT_TYPE_SINGLE_DATA;
1248
0
  gcry_ctx_t ctx = *r_ctx;
1249
1250
0
  psd = _gcry_ctx_find_pointer (ctx, data_type);
1251
0
  if (!psd)
1252
0
    return GPG_ERR_EINVAL;
1253
1254
0
  *r_p = psd->area;
1255
0
  *r_len = psd->len;
1256
0
  *r_ctx = _gcry_ctx_get_pointer (ctx, 0);
1257
1258
0
  return 0;
1259
0
}