Coverage Report

Created: 2022-12-08 06:09

/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
516k
#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
210k
{
293
210k
  return algo;
294
210k
}
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
210k
{
302
210k
  const gcry_md_spec_t *spec = NULL;
303
304
210k
  algo = map_algo (algo);
305
306
210k
  if (algo >= 0 && algo < DIM(digest_list_algo0))
307
195k
    spec = digest_list_algo0[algo];
308
15.2k
  else if (algo >= 301 && algo < 301 + DIM(digest_list_algo301))
309
6.66k
    spec = digest_list_algo301[algo - 301];
310
311
210k
  if (spec)
312
140k
    gcry_assert (spec->algo == algo);
313
314
0
  return spec;
315
210k
}
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
48.1k
{
432
48.1k
  const gcry_md_spec_t *spec;
433
434
48.1k
  spec = spec_from_algo (algorithm);
435
48.1k
  if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
436
48.1k
    return 0;
437
438
0
  return GPG_ERR_DIGEST_ALGO;
439
440
48.1k
}
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
258k
{
451
258k
  gcry_err_code_t err = 0;
452
258k
  int secure = !!(flags & GCRY_MD_FLAG_SECURE);
453
258k
  int hmac =   !!(flags & GCRY_MD_FLAG_HMAC);
454
258k
  int bufsize = secure ? 512 : 1024;
455
258k
  gcry_md_hd_t hd;
456
258k
  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
258k
  n = offsetof (struct gcry_md_handle, buf) + bufsize;
473
258k
  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
474
258k
       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
475
476
  /* Allocate and set the Context pointer to the private data */
477
258k
  if (secure)
478
0
    hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
479
258k
  else
480
258k
    hd = xtrymalloc (n + sizeof (struct gcry_md_context));
481
482
258k
  if (! hd)
483
0
    err = gpg_err_code_from_errno (errno);
484
485
258k
  if (! err)
486
258k
    {
487
258k
      struct gcry_md_context *ctx;
488
489
258k
      ctx = (void *) (hd->buf - offsetof (struct gcry_md_handle, buf) + n);
490
      /* Setup the globally visible data (bctl in the diagram).*/
491
258k
      hd->ctx = ctx;
492
258k
      hd->bufsize = n - offsetof (struct gcry_md_handle, buf);
493
258k
      hd->bufpos = 0;
494
495
      /* Initialize the private data. */
496
258k
      wipememory2 (ctx, 0, sizeof *ctx);
497
258k
      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
498
258k
      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
499
258k
      ctx->flags.secure = secure;
500
258k
      ctx->flags.hmac = hmac;
501
258k
      ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
502
258k
    }
503
504
258k
  if (! err)
505
258k
    {
506
      /* Hmmm, should we really do that? - yes [-wk] */
507
258k
      _gcry_fast_random_poll ();
508
509
258k
      if (algo)
510
14.1k
  {
511
14.1k
    err = md_enable (hd, algo);
512
14.1k
    if (err)
513
1.03k
      md_close (hd);
514
14.1k
  }
515
258k
    }
516
517
258k
  if (! err)
518
257k
    *h = hd;
519
520
258k
  return err;
521
258k
}
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
258k
{
531
258k
  gcry_err_code_t rc;
532
258k
  gcry_md_hd_t hd;
533
534
258k
  if ((flags & ~(GCRY_MD_FLAG_SECURE
535
258k
                 | GCRY_MD_FLAG_HMAC
536
258k
                 | GCRY_MD_FLAG_BUGEMU1)))
537
0
    rc = GPG_ERR_INV_ARG;
538
258k
  else
539
258k
    rc = md_open (&hd, algo, flags);
540
541
258k
  *h = rc? NULL : hd;
542
258k
  return rc;
543
258k
}
544
545
546
547
static gcry_err_code_t
548
md_enable (gcry_md_hd_t hd, int algorithm)
549
175k
{
550
175k
  struct gcry_md_context *h = hd->ctx;
551
175k
  const gcry_md_spec_t *spec;
552
175k
  GcryDigestEntry *entry;
553
175k
  gcry_err_code_t err = 0;
554
555
213k
  for (entry = h->list; entry; entry = entry->next)
556
51.0k
    if (entry->spec->algo == algorithm)
557
13.0k
      return 0; /* Already enabled */
558
559
162k
  spec = spec_from_algo (algorithm);
560
162k
  if (!spec)
561
70.7k
    {
562
70.7k
      log_debug ("md_enable: algorithm %d not available\n", algorithm);
563
70.7k
      err = GPG_ERR_DIGEST_ALGO;
564
70.7k
    }
565
566
162k
  if (!err && spec->flags.disabled)
567
0
    err = GPG_ERR_DIGEST_ALGO;
568
569
  /* Any non-FIPS algorithm should go this way */
570
162k
  if (!err && !spec->flags.fips && fips_mode ())
571
0
    err = GPG_ERR_DIGEST_ALGO;
572
573
162k
  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
162k
  if (!err)
580
91.9k
    {
581
91.9k
      size_t size = (sizeof (*entry)
582
91.9k
                     + spec->contextsize * (h->flags.hmac? 3 : 1)
583
91.9k
                     - sizeof (entry->context));
584
585
      /* And allocate a new list entry. */
586
91.9k
      if (h->flags.secure)
587
0
  entry = xtrymalloc_secure (size);
588
91.9k
      else
589
91.9k
  entry = xtrymalloc (size);
590
591
91.9k
      if (! entry)
592
0
  err = gpg_err_code_from_errno (errno);
593
91.9k
      else
594
91.9k
  {
595
91.9k
    entry->spec = spec;
596
91.9k
    entry->next = h->list;
597
91.9k
          entry->actual_struct_size = size;
598
91.9k
    h->list = entry;
599
600
    /* And init this instance. */
601
91.9k
    entry->spec->init (entry->context,
602
91.9k
                             h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
603
91.9k
  }
604
91.9k
    }
605
606
162k
  return err;
607
175k
}
608
609
610
gcry_err_code_t
611
_gcry_md_enable (gcry_md_hd_t hd, int algorithm)
612
161k
{
613
161k
  return md_enable (hd, algorithm);
614
161k
}
615
616
617
static gcry_err_code_t
618
md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
619
16.2k
{
620
16.2k
  gcry_err_code_t err = 0;
621
16.2k
  struct gcry_md_context *a = ahd->ctx;
622
16.2k
  struct gcry_md_context *b;
623
16.2k
  GcryDigestEntry *ar, *br;
624
16.2k
  gcry_md_hd_t bhd;
625
16.2k
  size_t n;
626
627
16.2k
  if (ahd->bufpos)
628
41
    md_write (ahd, NULL, 0);
629
630
16.2k
  n = (char *) ahd->ctx - (char *) ahd;
631
16.2k
  if (a->flags.secure)
632
0
    bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
633
16.2k
  else
634
16.2k
    bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
635
636
16.2k
  if (!bhd)
637
0
    {
638
0
      err = gpg_err_code_from_syserror ();
639
0
      goto leave;
640
0
    }
641
642
16.2k
  bhd->ctx = b = (void *) ((char *) bhd + n);
643
  /* No need to copy the buffer due to the write above. */
644
16.2k
  gcry_assert (ahd->bufsize == (n - offsetof (struct gcry_md_handle, buf)));
645
0
  bhd->bufsize = ahd->bufsize;
646
16.2k
  bhd->bufpos = 0;
647
16.2k
  gcry_assert (! ahd->bufpos);
648
0
  memcpy (b, a, sizeof *a);
649
16.2k
  b->list = NULL;
650
16.2k
  b->debug = NULL;
651
652
  /* Copy the complete list of algorithms.  The copied list is
653
     reversed, but that doesn't matter. */
654
32.0k
  for (ar = a->list; ar; ar = ar->next)
655
15.8k
    {
656
15.8k
      if (a->flags.secure)
657
0
        br = xtrymalloc_secure (ar->actual_struct_size);
658
15.8k
      else
659
15.8k
        br = xtrymalloc (ar->actual_struct_size);
660
15.8k
      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
15.8k
      memcpy (br, ar, ar->actual_struct_size);
668
15.8k
      br->next = b->list;
669
15.8k
      b->list = br;
670
15.8k
    }
671
672
16.2k
  if (a->debug)
673
0
    md_start_debug (bhd, "unknown");
674
675
16.2k
  *b_hd = bhd;
676
677
16.2k
 leave:
678
16.2k
  return err;
679
16.2k
}
680
681
682
gcry_err_code_t
683
_gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
684
16.2k
{
685
16.2k
  gcry_err_code_t rc;
686
687
16.2k
  rc = md_copy (hd, handle);
688
16.2k
  if (rc)
689
0
    *handle = NULL;
690
16.2k
  return rc;
691
16.2k
}
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
44.7k
{
701
44.7k
  GcryDigestEntry *r;
702
703
  /* Note: We allow this even in fips non operational mode.  */
704
705
44.7k
  a->bufpos = a->ctx->flags.finalized = 0;
706
707
44.7k
  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
44.7k
  else
714
89.5k
    for (r = a->ctx->list; r; r = r->next)
715
44.7k
      {
716
44.7k
        memset (r->context, 0, r->spec->contextsize);
717
44.7k
        (*r->spec->init) (r->context,
718
44.7k
                          a->ctx->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
719
44.7k
      }
720
44.7k
}
721
722
723
static void
724
md_close (gcry_md_hd_t a)
725
1.11M
{
726
1.11M
  GcryDigestEntry *r, *r2;
727
728
1.11M
  if (! a)
729
843k
    return;
730
274k
  if (a->ctx->debug)
731
0
    md_stop_debug (a);
732
382k
  for (r = a->ctx->list; r; r = r2)
733
107k
    {
734
107k
      r2 = r->next;
735
107k
      wipememory (r, r->actual_struct_size);
736
107k
      xfree (r);
737
107k
    }
738
739
274k
  wipememory (a, a->ctx->actual_handle_size);
740
274k
  xfree(a);
741
274k
}
742
743
744
void
745
_gcry_md_close (gcry_md_hd_t hd)
746
1.11M
{
747
  /* Note: We allow this even in fips non operational mode.  */
748
1.11M
  md_close (hd);
749
1.11M
}
750
751
752
static void
753
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
754
35.9k
{
755
35.9k
  GcryDigestEntry *r;
756
757
35.9k
  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
82.4k
  for (r = a->ctx->list; r; r = r->next)
766
46.4k
    {
767
46.4k
      if (a->bufpos)
768
9.90k
  (*r->spec->write) (r->context, a->buf, a->bufpos);
769
46.4k
      (*r->spec->write) (r->context, inbuf, inlen);
770
46.4k
    }
771
35.9k
  a->bufpos = 0;
772
35.9k
}
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
35.9k
{
781
35.9k
  md_write (hd, inbuf, inlen);
782
35.9k
}
783
784
785
static void
786
md_final (gcry_md_hd_t a)
787
43.2k
{
788
43.2k
  GcryDigestEntry *r;
789
790
43.2k
  if (a->ctx->flags.finalized)
791
1.50k
    return;
792
793
41.7k
  if (a->bufpos)
794
0
    md_write (a, NULL, 0);
795
796
83.5k
  for (r = a->ctx->list; r; r = r->next)
797
41.7k
    (*r->spec->final) (r->context);
798
799
41.7k
  a->ctx->flags.finalized = 1;
800
801
41.7k
  if (!a->ctx->flags.hmac)
802
41.7k
    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
43.2k
{
1002
43.2k
  gcry_err_code_t rc = 0;
1003
1004
43.2k
  (void)buflen; /* Currently not used.  */
1005
1006
43.2k
  switch (cmd)
1007
43.2k
    {
1008
43.2k
    case GCRYCTL_FINALIZE:
1009
43.2k
      md_final (hd);
1010
43.2k
      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
43.2k
    }
1020
43.2k
  return rc;
1021
43.2k
}
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.50k
{
1064
1.50k
  GcryDigestEntry *r = a->ctx->list;
1065
1066
1.50k
  if (! algo)
1067
0
    {
1068
      /* Return the first algorithm */
1069
0
      if (r)
1070
0
        {
1071
0
          if (r->next)
1072
0
            log_debug ("more than one algorithm in md_read(0)\n");
1073
0
          if (r->spec->read)
1074
0
            return r->spec->read (r->context);
1075
0
        }
1076
0
    }
1077
1.50k
  else
1078
1.50k
    {
1079
1.50k
      for (r = a->ctx->list; r; r = r->next)
1080
1.50k
  if (r->spec->algo == algo)
1081
1.50k
    {
1082
1.50k
      if (r->spec->read)
1083
1.50k
              return r->spec->read (r->context);
1084
0
            break;
1085
1.50k
    }
1086
1.50k
    }
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.50k
{
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.50k
  _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
1108
1.50k
  return md_read (hd, algo);
1109
1.50k
}
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
0
{
1185
0
  const gcry_md_spec_t *spec;
1186
1187
0
  spec = spec_from_algo (algo);
1188
0
  if (!spec)
1189
0
    {
1190
0
      log_debug ("md_hash_buffer: algorithm %d not available\n", algo);
1191
0
      return;
1192
0
    }
1193
1194
0
  if (spec->hash_buffers != NULL)
1195
0
    {
1196
0
      gcry_buffer_t iov;
1197
1198
0
      iov.size = 0;
1199
0
      iov.data = (void *)buffer;
1200
0
      iov.off = 0;
1201
0
      iov.len = length;
1202
1203
0
      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
0
      spec->hash_buffers (digest, spec->mdlen, &iov, 1);
1208
0
    }
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
0
}
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
0
{
1343
0
  GcryDigestEntry *r = a->ctx->list;
1344
1345
0
  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
0
  return r ? r->spec->algo : 0;
1351
0
}
1352
1353
1354
int
1355
_gcry_md_get_algo (gcry_md_hd_t hd)
1356
0
{
1357
0
  return md_get_algo (hd);
1358
0
}
1359
1360
1361
/****************
1362
 * Return the length of the digest
1363
 */
1364
static int
1365
md_digest_length (int algorithm)
1366
0
{
1367
0
  const gcry_md_spec_t *spec;
1368
1369
0
  spec = spec_from_algo (algorithm);
1370
0
  return spec? spec->mdlen : 0;
1371
0
}
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
0
{
1381
0
  return md_digest_length (algorithm);
1382
0
}
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
0
{
1390
0
  const gcry_md_spec_t *spec;
1391
0
  const byte *asnoid = NULL;
1392
1393
0
  spec = spec_from_algo (algorithm);
1394
0
  if (spec)
1395
0
    {
1396
0
      if (asnlen)
1397
0
  *asnlen = spec->asnlen;
1398
0
      if (mdlen)
1399
0
  *mdlen = spec->mdlen;
1400
0
      asnoid = spec->asnoid;
1401
0
    }
1402
0
  else
1403
0
    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
1404
1405
0
  return asnoid;
1406
0
}
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
48.1k
{
1430
48.1k
  gcry_err_code_t rc;
1431
1432
48.1k
  switch (what)
1433
48.1k
    {
1434
48.1k
    case GCRYCTL_TEST_ALGO:
1435
48.1k
      if (buffer || nbytes)
1436
0
  rc = GPG_ERR_INV_ARG;
1437
48.1k
      else
1438
48.1k
  rc = check_digest_algo (algo);
1439
48.1k
      break;
1440
1441
0
    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
0
      rc = check_digest_algo (algo);
1445
0
      if (!rc)
1446
0
        {
1447
0
          const char unsigned *asn;
1448
0
          size_t asnlen;
1449
1450
0
          asn = md_asn_oid (algo, &asnlen, NULL);
1451
0
          if (buffer && (*nbytes >= asnlen))
1452
0
            {
1453
0
              memcpy (buffer, asn, asnlen);
1454
0
              *nbytes = asnlen;
1455
0
            }
1456
0
          else if (!buffer && nbytes)
1457
0
            *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
0
        }
1466
0
      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
48.1k
  }
1478
1479
48.1k
  return rc;
1480
48.1k
}
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
14.5k
{
1539
14.5k
  gcry_err_code_t rc = 0;
1540
1541
14.5k
  switch (cmd)
1542
14.5k
    {
1543
0
    case GCRYCTL_IS_SECURE:
1544
0
      *nbytes = h->ctx->flags.secure;
1545
0
      break;
1546
1547
14.5k
    case GCRYCTL_IS_ALGO_ENABLED:
1548
14.5k
      {
1549
14.5k
  GcryDigestEntry *r;
1550
14.5k
  int algo;
1551
1552
14.5k
  if ( !buffer || !nbytes || *nbytes != sizeof (int))
1553
0
    rc = GPG_ERR_INV_ARG;
1554
14.5k
  else
1555
14.5k
    {
1556
14.5k
      algo = *(int*)buffer;
1557
1558
14.5k
      *nbytes = 0;
1559
15.9k
      for(r=h->ctx->list; r; r = r->next ) {
1560
14.0k
        if (r->spec->algo == algo)
1561
12.5k
    {
1562
12.5k
      *nbytes = 1;
1563
12.5k
      break;
1564
12.5k
    }
1565
14.0k
      }
1566
14.5k
    }
1567
14.5k
  break;
1568
0
      }
1569
1570
0
  default:
1571
0
    rc = GPG_ERR_INV_OP;
1572
14.5k
  }
1573
1574
14.5k
  return rc;
1575
14.5k
}
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
0
{
1589
0
  size_t value;
1590
1591
0
  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
0
  return value;
1595
0
}
1596
1597
1598
int
1599
_gcry_md_is_enabled (gcry_md_hd_t a, int algo)
1600
14.5k
{
1601
14.5k
  size_t value;
1602
1603
14.5k
  value = sizeof algo;
1604
14.5k
  if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
1605
0
    value = 0;
1606
14.5k
  return value;
1607
14.5k
}
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
}