Coverage Report

Created: 2022-12-08 06:10

/src/libgcrypt/cipher/md.c
Line
Count
Source (jump to first uncovered line)
1
/* md.c  -  message digest dispatcher
2
 * Copyright (C) 1998, 1999, 2002, 2003, 2006,
3
 *               2008 Free Software Foundation, Inc.
4
 * Copyright (C) 2013, 2014 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 "cipher.h"
30
31
32
/* This is the list of the digest implementations included in
33
   libgcrypt.  */
34
static const gcry_md_spec_t * const digest_list[] =
35
  {
36
#if USE_CRC
37
     &_gcry_digest_spec_crc32,
38
     &_gcry_digest_spec_crc32_rfc1510,
39
     &_gcry_digest_spec_crc24_rfc2440,
40
#endif
41
#if USE_SHA1
42
     &_gcry_digest_spec_sha1,
43
#endif
44
#if USE_SHA256
45
     &_gcry_digest_spec_sha256,
46
     &_gcry_digest_spec_sha224,
47
#endif
48
#if USE_SHA512
49
     &_gcry_digest_spec_sha512,
50
     &_gcry_digest_spec_sha384,
51
     &_gcry_digest_spec_sha512_256,
52
     &_gcry_digest_spec_sha512_224,
53
#endif
54
#if USE_SHA3
55
     &_gcry_digest_spec_sha3_224,
56
     &_gcry_digest_spec_sha3_256,
57
     &_gcry_digest_spec_sha3_384,
58
     &_gcry_digest_spec_sha3_512,
59
     &_gcry_digest_spec_shake128,
60
     &_gcry_digest_spec_shake256,
61
#endif
62
#if USE_GOST_R_3411_94
63
     &_gcry_digest_spec_gost3411_94,
64
     &_gcry_digest_spec_gost3411_cp,
65
#endif
66
#if USE_GOST_R_3411_12
67
     &_gcry_digest_spec_stribog_256,
68
     &_gcry_digest_spec_stribog_512,
69
#endif
70
#if USE_WHIRLPOOL
71
     &_gcry_digest_spec_whirlpool,
72
#endif
73
#if USE_RMD160
74
     &_gcry_digest_spec_rmd160,
75
#endif
76
#if USE_TIGER
77
     &_gcry_digest_spec_tiger,
78
     &_gcry_digest_spec_tiger1,
79
     &_gcry_digest_spec_tiger2,
80
#endif
81
#if USE_MD5
82
     &_gcry_digest_spec_md5,
83
#endif
84
#if USE_MD4
85
     &_gcry_digest_spec_md4,
86
#endif
87
#if USE_MD2
88
     &_gcry_digest_spec_md2,
89
#endif
90
#if USE_BLAKE2
91
     &_gcry_digest_spec_blake2b_512,
92
     &_gcry_digest_spec_blake2b_384,
93
     &_gcry_digest_spec_blake2b_256,
94
     &_gcry_digest_spec_blake2b_160,
95
     &_gcry_digest_spec_blake2s_256,
96
     &_gcry_digest_spec_blake2s_224,
97
     &_gcry_digest_spec_blake2s_160,
98
     &_gcry_digest_spec_blake2s_128,
99
#endif
100
#if USE_SM3
101
     &_gcry_digest_spec_sm3,
102
#endif
103
     NULL
104
  };
105
106
/* Digest implementations starting with index 0 (enum gcry_md_algos) */
107
static const gcry_md_spec_t * const digest_list_algo0[] =
108
  {
109
    NULL, /* GCRY_MD_NONE */
110
#if USE_MD5
111
    &_gcry_digest_spec_md5,
112
#else
113
    NULL,
114
#endif
115
#if USE_SHA1
116
    &_gcry_digest_spec_sha1,
117
#else
118
    NULL,
119
#endif
120
#if USE_RMD160
121
    &_gcry_digest_spec_rmd160,
122
#else
123
    NULL,
124
#endif
125
    NULL, /* Unused index 4 */
126
#if USE_MD2
127
    &_gcry_digest_spec_md2,
128
#else
129
    NULL,
130
#endif
131
#if USE_TIGER
132
    &_gcry_digest_spec_tiger,
133
#else
134
    NULL,
135
#endif
136
    NULL, /* GCRY_MD_HAVAL */
137
#if USE_SHA256
138
    &_gcry_digest_spec_sha256,
139
#else
140
    NULL,
141
#endif
142
#if USE_SHA512
143
    &_gcry_digest_spec_sha384,
144
    &_gcry_digest_spec_sha512,
145
#else
146
    NULL,
147
    NULL,
148
#endif
149
#if USE_SHA256
150
    &_gcry_digest_spec_sha224
151
#else
152
    NULL
153
#endif
154
  };
155
156
/* Digest implementations starting with index 301 (enum gcry_md_algos) */
157
static const gcry_md_spec_t * const digest_list_algo301[] =
158
  {
159
#if USE_MD4
160
    &_gcry_digest_spec_md4,
161
#else
162
    NULL,
163
#endif
164
#if USE_CRC
165
    &_gcry_digest_spec_crc32,
166
    &_gcry_digest_spec_crc32_rfc1510,
167
    &_gcry_digest_spec_crc24_rfc2440,
168
#else
169
    NULL,
170
    NULL,
171
    NULL,
172
#endif
173
#if USE_WHIRLPOOL
174
    &_gcry_digest_spec_whirlpool,
175
#else
176
    NULL,
177
#endif
178
#if USE_TIGER
179
    &_gcry_digest_spec_tiger1,
180
    &_gcry_digest_spec_tiger2,
181
#else
182
    NULL,
183
    NULL,
184
#endif
185
#if USE_GOST_R_3411_94
186
    &_gcry_digest_spec_gost3411_94,
187
#else
188
    NULL,
189
#endif
190
#if USE_GOST_R_3411_12
191
    &_gcry_digest_spec_stribog_256,
192
    &_gcry_digest_spec_stribog_512,
193
#else
194
    NULL,
195
    NULL,
196
#endif
197
#if USE_GOST_R_3411_94
198
    &_gcry_digest_spec_gost3411_cp,
199
#else
200
    NULL,
201
#endif
202
#if USE_SHA3
203
    &_gcry_digest_spec_sha3_224,
204
    &_gcry_digest_spec_sha3_256,
205
    &_gcry_digest_spec_sha3_384,
206
    &_gcry_digest_spec_sha3_512,
207
    &_gcry_digest_spec_shake128,
208
    &_gcry_digest_spec_shake256,
209
#else
210
    NULL,
211
    NULL,
212
    NULL,
213
    NULL,
214
    NULL,
215
    NULL,
216
#endif
217
#if USE_BLAKE2
218
    &_gcry_digest_spec_blake2b_512,
219
    &_gcry_digest_spec_blake2b_384,
220
    &_gcry_digest_spec_blake2b_256,
221
    &_gcry_digest_spec_blake2b_160,
222
    &_gcry_digest_spec_blake2s_256,
223
    &_gcry_digest_spec_blake2s_224,
224
    &_gcry_digest_spec_blake2s_160,
225
    &_gcry_digest_spec_blake2s_128,
226
#else
227
    NULL,
228
    NULL,
229
    NULL,
230
    NULL,
231
    NULL,
232
    NULL,
233
    NULL,
234
    NULL,
235
#endif
236
#if USE_SM3
237
    &_gcry_digest_spec_sm3,
238
#else
239
    NULL,
240
#endif
241
#if USE_SHA512
242
    &_gcry_digest_spec_sha512_256,
243
    &_gcry_digest_spec_sha512_224,
244
#else
245
    NULL,
246
    NULL,
247
#endif
248
  };
249
250
251
typedef struct gcry_md_list
252
{
253
  const gcry_md_spec_t *spec;
254
  struct gcry_md_list *next;
255
  size_t actual_struct_size;     /* Allocated size of this structure. */
256
  PROPERLY_ALIGNED_TYPE context[1];
257
} GcryDigestEntry;
258
259
/* This structure is put right after the gcry_md_hd_t buffer, so that
260
 * only one memory block is needed. */
261
struct gcry_md_context
262
{
263
  int  magic;
264
  struct {
265
    unsigned int secure:1;
266
    unsigned int finalized:1;
267
    unsigned int bugemu1:1;
268
    unsigned int hmac:1;
269
  } flags;
270
  size_t actual_handle_size;     /* Allocated size of this handle. */
271
  FILE  *debug;
272
  GcryDigestEntry *list;
273
};
274
275
276
2.47k
#define CTX_MAGIC_NORMAL 0x11071961
277
0
#define CTX_MAGIC_SECURE 0x16917011
278
279
static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
280
static void md_close (gcry_md_hd_t a);
281
static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
282
static byte *md_read( gcry_md_hd_t a, int algo );
283
static int md_get_algo( gcry_md_hd_t a );
284
static int md_digest_length( int algo );
285
static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
286
static void md_stop_debug ( gcry_md_hd_t a );
287
288
289

290
static int
291
map_algo (int algo)
292
129k
{
293
129k
  return algo;
294
129k
}
295
296
297
/* Return the spec structure for the hash algorithm ALGO.  For an
298
   unknown algorithm NULL is returned.  */
299
static const gcry_md_spec_t *
300
spec_from_algo (int algo)
301
129k
{
302
129k
  const gcry_md_spec_t *spec = NULL;
303
304
129k
  algo = map_algo (algo);
305
306
129k
  if (algo >= 0 && algo < DIM(digest_list_algo0))
307
129k
    spec = digest_list_algo0[algo];
308
53
  else if (algo >= 301 && algo < 301 + DIM(digest_list_algo301))
309
53
    spec = digest_list_algo301[algo - 301];
310
311
129k
  if (spec)
312
129k
    gcry_assert (spec->algo == algo);
313
314
0
  return spec;
315
129k
}
316
317
318
/* Lookup a hash's spec by its name.  */
319
static const gcry_md_spec_t *
320
spec_from_name (const char *name)
321
0
{
322
0
  const gcry_md_spec_t *spec;
323
0
  int idx;
324
325
0
  for (idx=0; (spec = digest_list[idx]); idx++)
326
0
    {
327
0
      if (!stricmp (name, spec->name))
328
0
        return spec;
329
0
    }
330
331
0
  return NULL;
332
0
}
333
334
335
/* Lookup a hash's spec by its OID.  */
336
static const gcry_md_spec_t *
337
spec_from_oid (const char *oid)
338
0
{
339
0
  const gcry_md_spec_t *spec;
340
0
  const gcry_md_oid_spec_t *oid_specs;
341
0
  int idx, j;
342
343
0
  for (idx=0; (spec = digest_list[idx]); idx++)
344
0
    {
345
0
      oid_specs = spec->oids;
346
0
      if (oid_specs)
347
0
        {
348
0
          for (j = 0; oid_specs[j].oidstring; j++)
349
0
            if (!stricmp (oid, oid_specs[j].oidstring))
350
0
              return spec;
351
0
        }
352
0
    }
353
354
0
  return NULL;
355
0
}
356
357
358
static const gcry_md_spec_t *
359
search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
360
0
{
361
0
  const gcry_md_spec_t *spec;
362
0
  int i;
363
364
0
  if (!oid)
365
0
    return NULL;
366
367
0
  if (!strncmp (oid, "oid.", 4) || !strncmp (oid, "OID.", 4))
368
0
    oid += 4;
369
370
0
  spec = spec_from_oid (oid);
371
0
  if (spec && spec->oids)
372
0
    {
373
0
      for (i = 0; spec->oids[i].oidstring; i++)
374
0
  if (!stricmp (oid, spec->oids[i].oidstring))
375
0
    {
376
0
      if (oid_spec)
377
0
        *oid_spec = spec->oids[i];
378
0
      return spec;
379
0
    }
380
0
    }
381
382
0
  return NULL;
383
0
}
384
385
386
/****************
387
 * Map a string to the digest algo
388
 */
389
int
390
_gcry_md_map_name (const char *string)
391
0
{
392
0
  const gcry_md_spec_t *spec;
393
394
0
  if (!string)
395
0
    return 0;
396
397
  /* If the string starts with a digit (optionally prefixed with
398
     either "OID." or "oid."), we first look into our table of ASN.1
399
     object identifiers to figure out the algorithm */
400
0
  spec = search_oid (string, NULL);
401
0
  if (spec)
402
0
    return spec->algo;
403
404
  /* Not found, search a matching digest name.  */
405
0
  spec = spec_from_name (string);
406
0
  if (spec)
407
0
    return spec->algo;
408
409
0
  return 0;
410
0
}
411
412
413
/****************
414
 * This function simply returns the name of the algorithm or some constant
415
 * string when there is no algo.  It will never return NULL.
416
 * Use  the macro gcry_md_test_algo() to check whether the algorithm
417
 * is valid.
418
 */
419
const char *
420
_gcry_md_algo_name (int algorithm)
421
0
{
422
0
  const gcry_md_spec_t *spec;
423
424
0
  spec = spec_from_algo (algorithm);
425
0
  return spec ? spec->name : "?";
426
0
}
427
428
429
static gcry_err_code_t
430
check_digest_algo (int algorithm)
431
126k
{
432
126k
  const gcry_md_spec_t *spec;
433
434
126k
  spec = spec_from_algo (algorithm);
435
126k
  if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
436
126k
    return 0;
437
438
0
  return GPG_ERR_DIGEST_ALGO;
439
440
126k
}
441
442
443
/****************
444
 * Open a message digest handle for use with algorithm ALGO.
445
 * More algorithms may be added by md_enable(). The initial algorithm
446
 * may be 0.
447
 */
448
static gcry_err_code_t
449
md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
450
1.23k
{
451
1.23k
  gcry_err_code_t err = 0;
452
1.23k
  int secure = !!(flags & GCRY_MD_FLAG_SECURE);
453
1.23k
  int hmac =   !!(flags & GCRY_MD_FLAG_HMAC);
454
1.23k
  int bufsize = secure ? 512 : 1024;
455
1.23k
  gcry_md_hd_t hd;
456
1.23k
  size_t n;
457
458
  /* Allocate a memory area to hold the caller visible buffer with it's
459
   * control information and the data required by this module. Set the
460
   * context pointer at the beginning to this area.
461
   * We have to use this strange scheme because we want to hide the
462
   * internal data but have a variable sized buffer.
463
   *
464
   *  +---+------+---........------+-------------+
465
   *  !ctx! bctl !  buffer       ! private     !
466
   *  +---+------+---........------+-------------+
467
   *    !           ^
468
   *    !---------------------------!
469
   *
470
   * We have to make sure that private is well aligned.
471
   */
472
1.23k
  n = offsetof (struct gcry_md_handle, buf) + bufsize;
473
1.23k
  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
474
1.23k
       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
475
476
  /* Allocate and set the Context pointer to the private data */
477
1.23k
  if (secure)
478
0
    hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
479
1.23k
  else
480
1.23k
    hd = xtrymalloc (n + sizeof (struct gcry_md_context));
481
482
1.23k
  if (! hd)
483
0
    err = gpg_err_code_from_errno (errno);
484
485
1.23k
  if (! err)
486
1.23k
    {
487
1.23k
      struct gcry_md_context *ctx;
488
489
1.23k
      ctx = (void *) (hd->buf - offsetof (struct gcry_md_handle, buf) + n);
490
      /* Setup the globally visible data (bctl in the diagram).*/
491
1.23k
      hd->ctx = ctx;
492
1.23k
      hd->bufsize = n - offsetof (struct gcry_md_handle, buf);
493
1.23k
      hd->bufpos = 0;
494
495
      /* Initialize the private data. */
496
1.23k
      wipememory2 (ctx, 0, sizeof *ctx);
497
1.23k
      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
498
1.23k
      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
499
1.23k
      ctx->flags.secure = secure;
500
1.23k
      ctx->flags.hmac = hmac;
501
1.23k
      ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
502
1.23k
    }
503
504
1.23k
  if (! err)
505
1.23k
    {
506
      /* Hmmm, should we really do that? - yes [-wk] */
507
1.23k
      _gcry_fast_random_poll ();
508
509
1.23k
      if (algo)
510
1.23k
  {
511
1.23k
    err = md_enable (hd, algo);
512
1.23k
    if (err)
513
0
      md_close (hd);
514
1.23k
  }
515
1.23k
    }
516
517
1.23k
  if (! err)
518
1.23k
    *h = hd;
519
520
1.23k
  return err;
521
1.23k
}
522
523
/* Create a message digest object for algorithm ALGO.  FLAGS may be
524
   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
525
   given as 0 if the algorithms to be used are later set using
526
   gcry_md_enable. H is guaranteed to be a valid handle or NULL on
527
   error.  */
528
gcry_err_code_t
529
_gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
530
1.23k
{
531
1.23k
  gcry_err_code_t rc;
532
1.23k
  gcry_md_hd_t hd;
533
534
1.23k
  if ((flags & ~(GCRY_MD_FLAG_SECURE
535
1.23k
                 | GCRY_MD_FLAG_HMAC
536
1.23k
                 | GCRY_MD_FLAG_BUGEMU1)))
537
0
    rc = GPG_ERR_INV_ARG;
538
1.23k
  else
539
1.23k
    rc = md_open (&hd, algo, flags);
540
541
1.23k
  *h = rc? NULL : hd;
542
1.23k
  return rc;
543
1.23k
}
544
545
546
547
static gcry_err_code_t
548
md_enable (gcry_md_hd_t hd, int algorithm)
549
1.39k
{
550
1.39k
  struct gcry_md_context *h = hd->ctx;
551
1.39k
  const gcry_md_spec_t *spec;
552
1.39k
  GcryDigestEntry *entry;
553
1.39k
  gcry_err_code_t err = 0;
554
555
1.39k
  for (entry = h->list; entry; entry = entry->next)
556
158
    if (entry->spec->algo == algorithm)
557
158
      return 0; /* Already enabled */
558
559
1.23k
  spec = spec_from_algo (algorithm);
560
1.23k
  if (!spec)
561
0
    {
562
0
      log_debug ("md_enable: algorithm %d not available\n", algorithm);
563
0
      err = GPG_ERR_DIGEST_ALGO;
564
0
    }
565
566
1.23k
  if (!err && spec->flags.disabled)
567
0
    err = GPG_ERR_DIGEST_ALGO;
568
569
  /* Any non-FIPS algorithm should go this way */
570
1.23k
  if (!err && !spec->flags.fips && fips_mode ())
571
0
    err = GPG_ERR_DIGEST_ALGO;
572
573
1.23k
  if (!err && h->flags.hmac && spec->read == NULL)
574
0
    {
575
      /* Expandable output function cannot act as part of HMAC. */
576
0
      err = GPG_ERR_DIGEST_ALGO;
577
0
    }
578
579
1.23k
  if (!err)
580
1.23k
    {
581
1.23k
      size_t size = (sizeof (*entry)
582
1.23k
                     + spec->contextsize * (h->flags.hmac? 3 : 1)
583
1.23k
                     - sizeof (entry->context));
584
585
      /* And allocate a new list entry. */
586
1.23k
      if (h->flags.secure)
587
0
  entry = xtrymalloc_secure (size);
588
1.23k
      else
589
1.23k
  entry = xtrymalloc (size);
590
591
1.23k
      if (! entry)
592
0
  err = gpg_err_code_from_errno (errno);
593
1.23k
      else
594
1.23k
  {
595
1.23k
    entry->spec = spec;
596
1.23k
    entry->next = h->list;
597
1.23k
          entry->actual_struct_size = size;
598
1.23k
    h->list = entry;
599
600
    /* And init this instance. */
601
1.23k
    entry->spec->init (entry->context,
602
1.23k
                             h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
603
1.23k
  }
604
1.23k
    }
605
606
1.23k
  return err;
607
1.39k
}
608
609
610
gcry_err_code_t
611
_gcry_md_enable (gcry_md_hd_t hd, int algorithm)
612
158
{
613
158
  return md_enable (hd, algorithm);
614
158
}
615
616
617
static gcry_err_code_t
618
md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
619
0
{
620
0
  gcry_err_code_t err = 0;
621
0
  struct gcry_md_context *a = ahd->ctx;
622
0
  struct gcry_md_context *b;
623
0
  GcryDigestEntry *ar, *br;
624
0
  gcry_md_hd_t bhd;
625
0
  size_t n;
626
627
0
  if (ahd->bufpos)
628
0
    md_write (ahd, NULL, 0);
629
630
0
  n = (char *) ahd->ctx - (char *) ahd;
631
0
  if (a->flags.secure)
632
0
    bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
633
0
  else
634
0
    bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
635
636
0
  if (!bhd)
637
0
    {
638
0
      err = gpg_err_code_from_syserror ();
639
0
      goto leave;
640
0
    }
641
642
0
  bhd->ctx = b = (void *) ((char *) bhd + n);
643
  /* No need to copy the buffer due to the write above. */
644
0
  gcry_assert (ahd->bufsize == (n - offsetof (struct gcry_md_handle, buf)));
645
0
  bhd->bufsize = ahd->bufsize;
646
0
  bhd->bufpos = 0;
647
0
  gcry_assert (! ahd->bufpos);
648
0
  memcpy (b, a, sizeof *a);
649
0
  b->list = NULL;
650
0
  b->debug = NULL;
651
652
  /* Copy the complete list of algorithms.  The copied list is
653
     reversed, but that doesn't matter. */
654
0
  for (ar = a->list; ar; ar = ar->next)
655
0
    {
656
0
      if (a->flags.secure)
657
0
        br = xtrymalloc_secure (ar->actual_struct_size);
658
0
      else
659
0
        br = xtrymalloc (ar->actual_struct_size);
660
0
      if (!br)
661
0
        {
662
0
          err = gpg_err_code_from_syserror ();
663
0
          md_close (bhd);
664
0
          goto leave;
665
0
        }
666
667
0
      memcpy (br, ar, ar->actual_struct_size);
668
0
      br->next = b->list;
669
0
      b->list = br;
670
0
    }
671
672
0
  if (a->debug)
673
0
    md_start_debug (bhd, "unknown");
674
675
0
  *b_hd = bhd;
676
677
0
 leave:
678
0
  return err;
679
0
}
680
681
682
gcry_err_code_t
683
_gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
684
0
{
685
0
  gcry_err_code_t rc;
686
687
0
  rc = md_copy (hd, handle);
688
0
  if (rc)
689
0
    *handle = NULL;
690
0
  return rc;
691
0
}
692
693
694
/*
695
 * Reset all contexts and discard any buffered stuff.  This may be used
696
 * instead of a md_close(); md_open().
697
 */
698
void
699
_gcry_md_reset (gcry_md_hd_t a)
700
1.50k
{
701
1.50k
  GcryDigestEntry *r;
702
703
  /* Note: We allow this even in fips non operational mode.  */
704
705
1.50k
  a->bufpos = a->ctx->flags.finalized = 0;
706
707
1.50k
  if (a->ctx->flags.hmac)
708
0
    for (r = a->ctx->list; r; r = r->next)
709
0
      {
710
0
        memcpy (r->context, (char *)r->context + r->spec->contextsize,
711
0
                r->spec->contextsize);
712
0
      }
713
1.50k
  else
714
3.01k
    for (r = a->ctx->list; r; r = r->next)
715
1.50k
      {
716
1.50k
        memset (r->context, 0, r->spec->contextsize);
717
1.50k
        (*r->spec->init) (r->context,
718
1.50k
                          a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
719
1.50k
      }
720
1.50k
}
721
722
723
static void
724
md_close (gcry_md_hd_t a)
725
1.23k
{
726
1.23k
  GcryDigestEntry *r, *r2;
727
728
1.23k
  if (! a)
729
0
    return;
730
1.23k
  if (a->ctx->debug)
731
0
    md_stop_debug (a);
732
2.47k
  for (r = a->ctx->list; r; r = r2)
733
1.23k
    {
734
1.23k
      r2 = r->next;
735
1.23k
      wipememory (r, r->actual_struct_size);
736
1.23k
      xfree (r);
737
1.23k
    }
738
739
1.23k
  wipememory (a, a->ctx->actual_handle_size);
740
1.23k
  xfree(a);
741
1.23k
}
742
743
744
void
745
_gcry_md_close (gcry_md_hd_t hd)
746
1.23k
{
747
  /* Note: We allow this even in fips non operational mode.  */
748
1.23k
  md_close (hd);
749
1.23k
}
750
751
752
static void
753
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
754
2.82k
{
755
2.82k
  GcryDigestEntry *r;
756
757
2.82k
  if (a->ctx->debug)
758
0
    {
759
0
      if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
760
0
  BUG();
761
0
      if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
762
0
  BUG();
763
0
    }
764
765
5.65k
  for (r = a->ctx->list; r; r = r->next)
766
2.82k
    {
767
2.82k
      if (a->bufpos)
768
1.33k
  (*r->spec->write) (r->context, a->buf, a->bufpos);
769
2.82k
      (*r->spec->write) (r->context, inbuf, inlen);
770
2.82k
    }
771
2.82k
  a->bufpos = 0;
772
2.82k
}
773
774
775
/* Note that this function may be used after finalize and read to keep
776
   on writing to the transform function so to mitigate timing
777
   attacks.  */
778
void
779
_gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
780
2.57k
{
781
2.57k
  md_write (hd, inbuf, inlen);
782
2.57k
}
783
784
785
static void
786
md_final (gcry_md_hd_t a)
787
3.75k
{
788
3.75k
  GcryDigestEntry *r;
789
790
3.75k
  if (a->ctx->flags.finalized)
791
1.08k
    return;
792
793
2.67k
  if (a->bufpos)
794
253
    md_write (a, NULL, 0);
795
796
5.34k
  for (r = a->ctx->list; r; r = r->next)
797
2.67k
    (*r->spec->final) (r->context);
798
799
2.67k
  a->ctx->flags.finalized = 1;
800
801
2.67k
  if (!a->ctx->flags.hmac)
802
2.67k
    return;
803
804
0
  for (r = a->ctx->list; r; r = r->next)
805
0
    {
806
0
      byte *p;
807
0
      size_t dlen = r->spec->mdlen;
808
0
      byte *hash;
809
0
      gcry_err_code_t err;
810
811
0
      if (r->spec->read == NULL)
812
0
        continue;
813
814
0
      p = r->spec->read (r->context);
815
816
0
      if (a->ctx->flags.secure)
817
0
        hash = xtrymalloc_secure (dlen);
818
0
      else
819
0
        hash = xtrymalloc (dlen);
820
0
      if (!hash)
821
0
        {
822
0
          err = gpg_err_code_from_errno (errno);
823
0
          _gcry_fatal_error (err, NULL);
824
0
        }
825
826
0
      memcpy (hash, p, dlen);
827
0
      memcpy (r->context, (char *)r->context + r->spec->contextsize * 2,
828
0
              r->spec->contextsize);
829
0
      (*r->spec->write) (r->context, hash, dlen);
830
0
      (*r->spec->final) (r->context);
831
0
      xfree (hash);
832
0
    }
833
0
}
834
835
836
static gcry_err_code_t
837
md_setkey (gcry_md_hd_t h, const unsigned char *key, size_t keylen)
838
0
{
839
0
  gcry_err_code_t rc = 0;
840
0
  GcryDigestEntry *r;
841
0
  int algo_had_setkey = 0;
842
843
0
  if (!h->ctx->list)
844
0
    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
845
846
0
  if (h->ctx->flags.hmac)
847
0
    return GPG_ERR_DIGEST_ALGO; /* Tried md_setkey for HMAC md. */
848
849
0
  for (r = h->ctx->list; r; r = r->next)
850
0
    {
851
0
      switch (r->spec->algo)
852
0
  {
853
0
#if USE_BLAKE2
854
  /* TODO? add spec->init_with_key? */
855
0
  case GCRY_MD_BLAKE2B_512:
856
0
  case GCRY_MD_BLAKE2B_384:
857
0
  case GCRY_MD_BLAKE2B_256:
858
0
  case GCRY_MD_BLAKE2B_160:
859
0
  case GCRY_MD_BLAKE2S_256:
860
0
  case GCRY_MD_BLAKE2S_224:
861
0
  case GCRY_MD_BLAKE2S_160:
862
0
  case GCRY_MD_BLAKE2S_128:
863
0
    algo_had_setkey = 1;
864
0
    memset (r->context, 0, r->spec->contextsize);
865
0
    rc = _gcry_blake2_init_with_key (r->context,
866
0
             h->ctx->flags.bugemu1
867
0
               ? GCRY_MD_FLAG_BUGEMU1:0,
868
0
             key, keylen, r->spec->algo);
869
0
    break;
870
0
#endif
871
0
  default:
872
0
    rc = GPG_ERR_DIGEST_ALGO;
873
0
    break;
874
0
  }
875
876
0
      if (rc)
877
0
  break;
878
0
    }
879
880
0
  if (rc && !algo_had_setkey)
881
0
    {
882
      /* None of algorithms had setkey implementation, so contexts were not
883
       * modified. Just return error. */
884
0
      return rc;
885
0
    }
886
0
  else if (rc && algo_had_setkey)
887
0
    {
888
      /* Some of the contexts have been modified, but got error. Reset
889
       * all contexts. */
890
0
      _gcry_md_reset (h);
891
0
      return rc;
892
0
    }
893
894
  /* Successful md_setkey implies reset. */
895
0
  h->bufpos = h->ctx->flags.finalized = 0;
896
897
0
  return 0;
898
0
}
899
900
901
static gcry_err_code_t
902
prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
903
0
{
904
0
  GcryDigestEntry *r;
905
906
0
  if (!a->ctx->list)
907
0
    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
908
909
0
  if (!a->ctx->flags.hmac)
910
0
    return GPG_ERR_DIGEST_ALGO; /* Tried prepare_macpads for non-HMAC md. */
911
912
0
  for (r = a->ctx->list; r; r = r->next)
913
0
    {
914
0
      const unsigned char *k;
915
0
      size_t k_len;
916
0
      unsigned char *key_allocated = NULL;
917
0
      int macpad_Bsize;
918
0
      int i;
919
920
0
      switch (r->spec->algo)
921
0
        {
922
  /* TODO: add spec->blocksize */
923
0
        case GCRY_MD_SHA3_224:
924
0
          macpad_Bsize = 1152 / 8;
925
0
          break;
926
0
        case GCRY_MD_SHA3_256:
927
0
          macpad_Bsize = 1088 / 8;
928
0
          break;
929
0
        case GCRY_MD_SHA3_384:
930
0
          macpad_Bsize = 832 / 8;
931
0
          break;
932
0
        case GCRY_MD_SHA3_512:
933
0
          macpad_Bsize = 576 / 8;
934
0
          break;
935
0
        case GCRY_MD_SHA384:
936
0
        case GCRY_MD_SHA512:
937
0
        case GCRY_MD_SHA512_256:
938
0
        case GCRY_MD_SHA512_224:
939
0
        case GCRY_MD_BLAKE2B_512:
940
0
        case GCRY_MD_BLAKE2B_384:
941
0
        case GCRY_MD_BLAKE2B_256:
942
0
        case GCRY_MD_BLAKE2B_160:
943
0
          macpad_Bsize = 128;
944
0
          break;
945
0
        case GCRY_MD_GOSTR3411_94:
946
0
        case GCRY_MD_GOSTR3411_CP:
947
0
          macpad_Bsize = 32;
948
0
          break;
949
0
        default:
950
0
          macpad_Bsize = 64;
951
0
          break;
952
0
        }
953
954
0
      if ( keylen > macpad_Bsize )
955
0
        {
956
0
          k = key_allocated = xtrymalloc_secure (r->spec->mdlen);
957
0
          if (!k)
958
0
            return gpg_err_code_from_errno (errno);
959
0
          _gcry_md_hash_buffer (r->spec->algo, key_allocated, key, keylen);
960
0
          k_len = r->spec->mdlen;
961
0
          gcry_assert ( k_len <= macpad_Bsize );
962
0
        }
963
0
      else
964
0
        {
965
0
          k = key;
966
0
          k_len = keylen;
967
0
        }
968
969
0
      (*r->spec->init) (r->context,
970
0
                        a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
971
0
      a->bufpos = 0;
972
0
      for (i=0; i < k_len; i++ )
973
0
        _gcry_md_putc (a, k[i] ^ 0x36);
974
0
      for (; i < macpad_Bsize; i++ )
975
0
        _gcry_md_putc (a, 0x36);
976
0
      (*r->spec->write) (r->context, a->buf, a->bufpos);
977
0
      memcpy ((char *)r->context + r->spec->contextsize, r->context,
978
0
              r->spec->contextsize);
979
980
0
      (*r->spec->init) (r->context,
981
0
                        a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
982
0
      a->bufpos = 0;
983
0
      for (i=0; i < k_len; i++ )
984
0
        _gcry_md_putc (a, k[i] ^ 0x5c);
985
0
      for (; i < macpad_Bsize; i++ )
986
0
        _gcry_md_putc (a, 0x5c);
987
0
      (*r->spec->write) (r->context, a->buf, a->bufpos);
988
0
      memcpy ((char *)r->context + r->spec->contextsize*2, r->context,
989
0
              r->spec->contextsize);
990
991
0
      xfree (key_allocated);
992
0
    }
993
994
0
  a->bufpos = 0;
995
0
  return 0;
996
0
}
997
998
999
gcry_err_code_t
1000
_gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
1001
3.75k
{
1002
3.75k
  gcry_err_code_t rc = 0;
1003
1004
3.75k
  (void)buflen; /* Currently not used.  */
1005
1006
3.75k
  switch (cmd)
1007
3.75k
    {
1008
3.75k
    case GCRYCTL_FINALIZE:
1009
3.75k
      md_final (hd);
1010
3.75k
      break;
1011
0
    case GCRYCTL_START_DUMP:
1012
0
      md_start_debug (hd, buffer);
1013
0
      break;
1014
0
    case GCRYCTL_STOP_DUMP:
1015
0
      md_stop_debug ( hd );
1016
0
      break;
1017
0
    default:
1018
0
      rc = GPG_ERR_INV_OP;
1019
3.75k
    }
1020
3.75k
  return rc;
1021
3.75k
}
1022
1023
1024
gcry_err_code_t
1025
_gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
1026
0
{
1027
0
  gcry_err_code_t rc;
1028
1029
0
  if (hd->ctx->flags.hmac)
1030
0
    {
1031
0
      rc = prepare_macpads (hd, key, keylen);
1032
0
      if (!rc)
1033
0
  _gcry_md_reset (hd);
1034
0
    }
1035
0
  else
1036
0
    {
1037
0
      rc = md_setkey (hd, key, keylen);
1038
0
    }
1039
1040
0
  return rc;
1041
0
}
1042
1043
1044
/* The new debug interface.  If SUFFIX is a string it creates an debug
1045
   file for the context HD.  IF suffix is NULL, the file is closed and
1046
   debugging is stopped.  */
1047
void
1048
_gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
1049
0
{
1050
0
  if (suffix)
1051
0
    md_start_debug (hd, suffix);
1052
0
  else
1053
0
    md_stop_debug (hd);
1054
0
}
1055
1056
1057
/****************
1058
 * If ALGO is null get the digest for the used algo (which should be
1059
 * only one)
1060
 */
1061
static byte *
1062
md_read( gcry_md_hd_t a, int algo )
1063
1.10k
{
1064
1.10k
  GcryDigestEntry *r = a->ctx->list;
1065
1066
1.10k
  if (! algo)
1067
1.01k
    {
1068
      /* Return the first algorithm */
1069
1.01k
      if (r)
1070
1.01k
        {
1071
1.01k
          if (r->next)
1072
0
            log_debug ("more than one algorithm in md_read(0)\n");
1073
1.01k
          if (r->spec->read)
1074
1.01k
            return r->spec->read (r->context);
1075
1.01k
        }
1076
1.01k
    }
1077
89
  else
1078
89
    {
1079
89
      for (r = a->ctx->list; r; r = r->next)
1080
89
  if (r->spec->algo == algo)
1081
89
    {
1082
89
      if (r->spec->read)
1083
89
              return r->spec->read (r->context);
1084
0
            break;
1085
89
    }
1086
89
    }
1087
1088
0
  if (r && !r->spec->read)
1089
0
    _gcry_fatal_error (GPG_ERR_DIGEST_ALGO,
1090
0
                       "requested algo has no fixed digest length");
1091
0
  else
1092
0
    _gcry_fatal_error (GPG_ERR_DIGEST_ALGO, "requested algo not in md context");
1093
0
  return NULL;
1094
0
}
1095
1096
1097
/*
1098
 * Read out the complete digest, this function implictly finalizes
1099
 * the hash.
1100
 */
1101
byte *
1102
_gcry_md_read (gcry_md_hd_t hd, int algo)
1103
1.10k
{
1104
  /* This function is expected to always return a digest, thus we
1105
     can't return an error which we actually should do in
1106
     non-operational state.  */
1107
1.10k
  _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
1108
1.10k
  return md_read (hd, algo);
1109
1.10k
}
1110
1111
1112
/****************
1113
 * If ALGO is null get the digest for the used algo (which should be
1114
 * only one)
1115
 */
1116
static gcry_err_code_t
1117
md_extract(gcry_md_hd_t a, int algo, void *out, size_t outlen)
1118
0
{
1119
0
  GcryDigestEntry *r = a->ctx->list;
1120
1121
0
  if (!algo)
1122
0
    {
1123
      /* Return the first algorithm */
1124
0
      if (r && r->spec->extract)
1125
0
  {
1126
0
    if (r->next)
1127
0
      log_debug ("more than one algorithm in md_extract(0)\n");
1128
0
    r->spec->extract (r->context, out, outlen);
1129
0
    return 0;
1130
0
  }
1131
0
    }
1132
0
  else
1133
0
    {
1134
0
      for (r = a->ctx->list; r; r = r->next)
1135
0
  if (r->spec->algo == algo && r->spec->extract)
1136
0
    {
1137
0
      r->spec->extract (r->context, out, outlen);
1138
0
      return 0;
1139
0
    }
1140
0
    }
1141
1142
0
  return GPG_ERR_DIGEST_ALGO;
1143
0
}
1144
1145
1146
/*
1147
 * Expand the output from XOF class digest, this function implictly finalizes
1148
 * the hash.
1149
 */
1150
gcry_err_code_t
1151
_gcry_md_extract (gcry_md_hd_t hd, int algo, void *out, size_t outlen)
1152
0
{
1153
0
  _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
1154
0
  return md_extract (hd, algo, out, outlen);
1155
0
}
1156
1157
1158
/*
1159
 * Read out an intermediate digest.  Not yet functional.
1160
 */
1161
gcry_err_code_t
1162
_gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
1163
0
{
1164
0
  (void)hd;
1165
0
  (void)algo;
1166
0
  (void)buffer;
1167
0
  (void)buflen;
1168
1169
  /*md_digest ... */
1170
0
  fips_signal_error ("unimplemented function called");
1171
0
  return GPG_ERR_INTERNAL;
1172
0
}
1173
1174
1175
/*
1176
 * Shortcut function to hash a buffer with a given algo. The only
1177
 * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
1178
 * supplied digest buffer must be large enough to store the resulting
1179
 * hash.  No error is returned, the function will abort on an invalid
1180
 * algo.  DISABLED_ALGOS are ignored here.  */
1181
void
1182
_gcry_md_hash_buffer (int algo, void *digest,
1183
                      const void *buffer, size_t length)
1184
25
{
1185
25
  const gcry_md_spec_t *spec;
1186
1187
25
  spec = spec_from_algo (algo);
1188
25
  if (!spec)
1189
0
    {
1190
0
      log_debug ("md_hash_buffer: algorithm %d not available\n", algo);
1191
0
      return;
1192
0
    }
1193
1194
25
  if (spec->hash_buffers != NULL)
1195
25
    {
1196
25
      gcry_buffer_t iov;
1197
1198
25
      iov.size = 0;
1199
25
      iov.data = (void *)buffer;
1200
25
      iov.off = 0;
1201
25
      iov.len = length;
1202
1203
25
      if (spec->flags.disabled || (!spec->flags.fips && fips_mode ()))
1204
0
        log_bug ("gcry_md_hash_buffer failed for algo %d: %s",
1205
0
                algo, gpg_strerror (gcry_error (GPG_ERR_DIGEST_ALGO)));
1206
1207
25
      spec->hash_buffers (digest, spec->mdlen, &iov, 1);
1208
25
    }
1209
0
  else
1210
0
    {
1211
      /* For the others we do not have a fast function, so we use the
1212
         normal functions. */
1213
0
      gcry_md_hd_t h;
1214
0
      gpg_err_code_t err;
1215
1216
0
      err = md_open (&h, algo, 0);
1217
0
      if (err)
1218
0
        log_bug ("gcry_md_open failed for algo %d: %s",
1219
0
                algo, gpg_strerror (gcry_error(err)));
1220
0
      md_write (h, (byte *) buffer, length);
1221
0
      md_final (h);
1222
0
      memcpy (digest, md_read (h, algo), md_digest_length (algo));
1223
0
      md_close (h);
1224
0
    }
1225
25
}
1226
1227
1228
/* Shortcut function to hash multiple buffers with a given algo.  In
1229
   contrast to gcry_md_hash_buffer, this function returns an error on
1230
   invalid arguments or on other problems; disabled algorithms are
1231
   _not_ ignored but flagged as an error.
1232
1233
   The data to sign is taken from the array IOV which has IOVCNT items.
1234
1235
   The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns
1236
   this function into a HMAC function; the first item in IOV is then
1237
   used as the key.
1238
1239
   On success 0 is returned and resulting hash or HMAC is stored at
1240
   DIGEST. DIGESTLEN may be given as -1, in which case DIGEST must
1241
   have been provided by the caller with an appropriate length.
1242
   DIGESTLEN may also be the appropriate length or, in case of XOF
1243
   algorithms, DIGESTLEN indicates number bytes to extract from XOF
1244
   to DIGEST.  */
1245
gpg_err_code_t
1246
_gcry_md_hash_buffers_extract (int algo, unsigned int flags, void *digest,
1247
             int digestlen, const gcry_buffer_t *iov,
1248
             int iovcnt)
1249
0
{
1250
0
  const gcry_md_spec_t *spec;
1251
0
  int hmac;
1252
1253
0
  if (!iov || iovcnt < 0)
1254
0
    return GPG_ERR_INV_ARG;
1255
0
  if (flags & ~(GCRY_MD_FLAG_HMAC))
1256
0
    return GPG_ERR_INV_ARG;
1257
1258
0
  hmac = !!(flags & GCRY_MD_FLAG_HMAC);
1259
0
  if (hmac && iovcnt < 1)
1260
0
    return GPG_ERR_INV_ARG;
1261
1262
0
  spec = spec_from_algo (algo);
1263
0
  if (!spec)
1264
0
    {
1265
0
      log_debug ("md_hash_buffers: algorithm %d not available\n", algo);
1266
0
      return GPG_ERR_DIGEST_ALGO;
1267
0
    }
1268
1269
0
  if (spec->mdlen > 0 && digestlen != -1 && digestlen != spec->mdlen)
1270
0
    return GPG_ERR_DIGEST_ALGO;
1271
0
  if (spec->mdlen == 0 && digestlen == -1)
1272
0
    return GPG_ERR_DIGEST_ALGO;
1273
1274
0
  if (!hmac && spec->hash_buffers)
1275
0
    {
1276
0
      if (spec->flags.disabled || (!spec->flags.fips && fips_mode ()))
1277
0
        return GPG_ERR_DIGEST_ALGO;
1278
1279
0
      spec->hash_buffers (digest, digestlen, iov, iovcnt);
1280
0
    }
1281
0
  else
1282
0
    {
1283
      /* For the others we do not have a fast function, so we use the
1284
         normal functions.  */
1285
0
      gcry_md_hd_t h;
1286
0
      gpg_err_code_t rc;
1287
1288
0
      rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
1289
0
      if (rc)
1290
0
        return rc;
1291
1292
0
      if (hmac)
1293
0
        {
1294
0
          rc = _gcry_md_setkey (h,
1295
0
                                (const char*)iov[0].data + iov[0].off,
1296
0
                                iov[0].len);
1297
0
          if (rc)
1298
0
            {
1299
0
              md_close (h);
1300
0
              return rc;
1301
0
            }
1302
0
          iov++; iovcnt--;
1303
0
        }
1304
0
      for (;iovcnt; iov++, iovcnt--)
1305
0
        md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len);
1306
0
      md_final (h);
1307
0
      if (spec->mdlen > 0)
1308
0
  memcpy (digest, md_read (h, algo), spec->mdlen);
1309
0
      else if (digestlen > 0)
1310
0
  md_extract (h, algo, digest, digestlen);
1311
0
      md_close (h);
1312
0
    }
1313
1314
0
  return 0;
1315
0
}
1316
1317
1318
/* Shortcut function to hash multiple buffers with a given algo.  In
1319
   contrast to gcry_md_hash_buffer, this function returns an error on
1320
   invalid arguments or on other problems; disabled algorithms are
1321
   _not_ ignored but flagged as an error.
1322
1323
   The data to sign is taken from the array IOV which has IOVCNT items.
1324
1325
   The only supported flag in FLAGS is GCRY_MD_FLAG_HMAC which turns
1326
   this function into a HMAC function; the first item in IOV is then
1327
   used as the key.
1328
1329
   On success 0 is returned and resulting hash or HMAC is stored at
1330
   DIGEST which must have been provided by the caller with an
1331
   appropriate length.  */
1332
gpg_err_code_t
1333
_gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
1334
           const gcry_buffer_t *iov, int iovcnt)
1335
0
{
1336
0
  return _gcry_md_hash_buffers_extract(algo, flags, digest, -1, iov, iovcnt);
1337
0
}
1338
1339
1340
static int
1341
md_get_algo (gcry_md_hd_t a)
1342
1.01k
{
1343
1.01k
  GcryDigestEntry *r = a->ctx->list;
1344
1345
1.01k
  if (r && r->next)
1346
0
    {
1347
0
      fips_signal_error ("possible usage error");
1348
0
      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
1349
0
    }
1350
1.01k
  return r ? r->spec->algo : 0;
1351
1.01k
}
1352
1353
1354
int
1355
_gcry_md_get_algo (gcry_md_hd_t hd)
1356
1.01k
{
1357
1.01k
  return md_get_algo (hd);
1358
1.01k
}
1359
1360
1361
/****************
1362
 * Return the length of the digest
1363
 */
1364
static int
1365
md_digest_length (int algorithm)
1366
1.17k
{
1367
1.17k
  const gcry_md_spec_t *spec;
1368
1369
1.17k
  spec = spec_from_algo (algorithm);
1370
1.17k
  return spec? spec->mdlen : 0;
1371
1.17k
}
1372
1373
1374
/****************
1375
 * Return the length of the digest in bytes.
1376
 * This function will return 0 in case of errors.
1377
 */
1378
unsigned int
1379
_gcry_md_get_algo_dlen (int algorithm)
1380
1.17k
{
1381
1.17k
  return md_digest_length (algorithm);
1382
1.17k
}
1383
1384
1385
/* Hmmm: add a mode to enumerate the OIDs
1386
 *  to make g10/sig-check.c more portable */
1387
static const byte *
1388
md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
1389
284
{
1390
284
  const gcry_md_spec_t *spec;
1391
284
  const byte *asnoid = NULL;
1392
1393
284
  spec = spec_from_algo (algorithm);
1394
284
  if (spec)
1395
284
    {
1396
284
      if (asnlen)
1397
284
  *asnlen = spec->asnlen;
1398
284
      if (mdlen)
1399
0
  *mdlen = spec->mdlen;
1400
284
      asnoid = spec->asnoid;
1401
284
    }
1402
0
  else
1403
0
    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
1404
1405
284
  return asnoid;
1406
284
}
1407
1408
1409
/****************
1410
 * Return information about the given cipher algorithm
1411
 * WHAT select the kind of information returned:
1412
 *  GCRYCTL_TEST_ALGO:
1413
 *  Returns 0 when the specified algorithm is available for use.
1414
 *  buffer and nbytes must be zero.
1415
 *  GCRYCTL_GET_ASNOID:
1416
 *  Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
1417
 *  the required length is returned.
1418
 *  GCRYCTL_SELFTEST
1419
 *      Helper for the regression tests - shall not be used by applications.
1420
 *
1421
 * Note:  Because this function is in most cases used to return an
1422
 * integer value, we can make it easier for the caller to just look at
1423
 * the return value.  The caller will in all cases consult the value
1424
 * and thereby detecting whether a error occurred or not (i.e. while checking
1425
 * the block size)
1426
 */
1427
gcry_err_code_t
1428
_gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
1429
126k
{
1430
126k
  gcry_err_code_t rc;
1431
1432
126k
  switch (what)
1433
126k
    {
1434
126k
    case GCRYCTL_TEST_ALGO:
1435
126k
      if (buffer || nbytes)
1436
0
  rc = GPG_ERR_INV_ARG;
1437
126k
      else
1438
126k
  rc = check_digest_algo (algo);
1439
126k
      break;
1440
1441
284
    case GCRYCTL_GET_ASNOID:
1442
      /* We need to check that the algo is available because
1443
         md_asn_oid would otherwise raise an assertion. */
1444
284
      rc = check_digest_algo (algo);
1445
284
      if (!rc)
1446
284
        {
1447
284
          const char unsigned *asn;
1448
284
          size_t asnlen;
1449
1450
284
          asn = md_asn_oid (algo, &asnlen, NULL);
1451
284
          if (buffer && (*nbytes >= asnlen))
1452
142
            {
1453
142
              memcpy (buffer, asn, asnlen);
1454
142
              *nbytes = asnlen;
1455
142
            }
1456
142
          else if (!buffer && nbytes)
1457
142
            *nbytes = asnlen;
1458
0
          else
1459
0
            {
1460
0
              if (buffer)
1461
0
                rc = GPG_ERR_TOO_SHORT;
1462
0
              else
1463
0
                rc = GPG_ERR_INV_ARG;
1464
0
            }
1465
284
        }
1466
284
      break;
1467
1468
0
    case GCRYCTL_SELFTEST:
1469
      /* Helper function for the regression tests.  */
1470
0
      rc = gpg_err_code (_gcry_md_selftest (algo, nbytes? (int)*nbytes : 0,
1471
0
                                             NULL));
1472
0
      break;
1473
1474
0
    default:
1475
0
      rc = GPG_ERR_INV_OP;
1476
0
      break;
1477
126k
  }
1478
1479
126k
  return rc;
1480
126k
}
1481
1482
1483
static void
1484
md_start_debug ( gcry_md_hd_t md, const char *suffix )
1485
0
{
1486
0
  static int idx=0;
1487
0
  char buf[50];
1488
1489
0
  if (fips_mode ())
1490
0
    return;
1491
1492
0
  if ( md->ctx->debug )
1493
0
    {
1494
0
      log_debug("Oops: md debug already started\n");
1495
0
      return;
1496
0
    }
1497
0
  idx++;
1498
0
  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
1499
0
  md->ctx->debug = fopen(buf, "w");
1500
0
  if ( !md->ctx->debug )
1501
0
    log_debug("md debug: can't open %s\n", buf );
1502
0
}
1503
1504
1505
static void
1506
md_stop_debug( gcry_md_hd_t md )
1507
0
{
1508
0
  if ( md->ctx->debug )
1509
0
    {
1510
0
      if ( md->bufpos )
1511
0
        md_write ( md, NULL, 0 );
1512
0
      fclose (md->ctx->debug);
1513
0
      md->ctx->debug = NULL;
1514
0
    }
1515
1516
0
  {  /* a kludge to pull in the __muldi3 for Solaris */
1517
0
    volatile u32 a = (u32)(uintptr_t)md;
1518
0
    volatile u64 b = 42;
1519
0
    volatile u64 c;
1520
0
    c = a * b;
1521
0
    (void)c;
1522
0
  }
1523
0
}
1524
1525
1526
1527
/*
1528
 * Return information about the digest handle.
1529
 *  GCRYCTL_IS_SECURE:
1530
 *  Returns 1 when the handle works on secured memory
1531
 *  otherwise 0 is returned.  There is no error return.
1532
 *  GCRYCTL_IS_ALGO_ENABLED:
1533
 *     Returns 1 if the algo is enabled for that handle.
1534
 *     The algo must be passed as the address of an int.
1535
 */
1536
gcry_err_code_t
1537
_gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
1538
15
{
1539
15
  gcry_err_code_t rc = 0;
1540
1541
15
  switch (cmd)
1542
15
    {
1543
15
    case GCRYCTL_IS_SECURE:
1544
15
      *nbytes = h->ctx->flags.secure;
1545
15
      break;
1546
1547
0
    case GCRYCTL_IS_ALGO_ENABLED:
1548
0
      {
1549
0
  GcryDigestEntry *r;
1550
0
  int algo;
1551
1552
0
  if ( !buffer || !nbytes || *nbytes != sizeof (int))
1553
0
    rc = GPG_ERR_INV_ARG;
1554
0
  else
1555
0
    {
1556
0
      algo = *(int*)buffer;
1557
1558
0
      *nbytes = 0;
1559
0
      for(r=h->ctx->list; r; r = r->next ) {
1560
0
        if (r->spec->algo == algo)
1561
0
    {
1562
0
      *nbytes = 1;
1563
0
      break;
1564
0
    }
1565
0
      }
1566
0
    }
1567
0
  break;
1568
0
      }
1569
1570
0
  default:
1571
0
    rc = GPG_ERR_INV_OP;
1572
15
  }
1573
1574
15
  return rc;
1575
15
}
1576
1577
1578
/* Explicitly initialize this module.  */
1579
gcry_err_code_t
1580
_gcry_md_init (void)
1581
1
{
1582
1
  return 0;
1583
1
}
1584
1585
1586
int
1587
_gcry_md_is_secure (gcry_md_hd_t a)
1588
15
{
1589
15
  size_t value;
1590
1591
15
  if (_gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
1592
0
    value = 1; /* It seems to be better to assume secure memory on
1593
                  error. */
1594
15
  return value;
1595
15
}
1596
1597
1598
int
1599
_gcry_md_is_enabled (gcry_md_hd_t a, int algo)
1600
0
{
1601
0
  size_t value;
1602
1603
0
  value = sizeof algo;
1604
0
  if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
1605
0
    value = 0;
1606
0
  return value;
1607
0
}
1608
1609
1610
/* Run the selftests for digest algorithm ALGO with optional reporting
1611
   function REPORT.  */
1612
gpg_error_t
1613
_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
1614
0
{
1615
0
  gcry_err_code_t ec = 0;
1616
0
  const gcry_md_spec_t *spec;
1617
1618
0
  spec = spec_from_algo (algo);
1619
0
  if (spec && !spec->flags.disabled
1620
0
      && (spec->flags.fips || !fips_mode ())
1621
0
      && spec->selftest)
1622
0
    ec = spec->selftest (algo, extended, report);
1623
0
  else
1624
0
    {
1625
0
      ec = (spec && spec->selftest) ? GPG_ERR_DIGEST_ALGO
1626
0
        /* */                       : GPG_ERR_NOT_IMPLEMENTED;
1627
0
      if (report)
1628
0
        report ("digest", algo, "module",
1629
0
                spec && !spec->flags.disabled
1630
0
                && (spec->flags.fips || !fips_mode ())?
1631
0
                "no selftest available" :
1632
0
                spec? "algorithm disabled" : "algorithm not found");
1633
0
    }
1634
1635
0
  return gpg_error (ec);
1636
0
}