Coverage Report

Created: 2022-12-08 06:09

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