~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to lib/libgcrypt/cipher/md.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* md.c  -  message digest dispatcher
2
 
 * Copyright (C) 1998, 1999, 2002, 2003, 2006,
3
 
 *               2008 Free Software Foundation, Inc.
4
 
 *
5
 
 * This file is part of Libgcrypt.
6
 
 *
7
 
 * Libgcrypt is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU Lesser general Public License as
9
 
 * published by the Free Software Foundation; either version 2.1 of
10
 
 * the License, or (at your option) any later version.
11
 
 *
12
 
 * Libgcrypt is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU Lesser General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19
 
 */
20
 
 
21
 
#include <config.h>
22
 
#include <stdio.h>
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
#include <errno.h>
26
 
 
27
 
#include "g10lib.h"
28
 
#include "cipher.h"
29
 
#include "ath.h"
30
 
 
31
 
#include "rmd.h"
32
 
 
33
 
/* A dummy extraspec so that we do not need to tests the extraspec
34
 
   field from the module specification against NULL and instead
35
 
   directly test the respective fields of extraspecs.  */
36
 
static md_extra_spec_t dummy_extra_spec;
37
 
 
38
 
 
39
 
/* This is the list of the digest implementations included in
40
 
   libgcrypt.  */
41
 
static struct digest_table_entry
42
 
{
43
 
  gcry_md_spec_t *digest;
44
 
  md_extra_spec_t *extraspec;
45
 
  unsigned int algorithm;
46
 
  int fips_allowed; 
47
 
} digest_table[] =
48
 
  {
49
 
#if USE_CRC    
50
 
    /* We allow the CRC algorithms even in FIPS mode because they are
51
 
       actually no cryptographic primitives.  */
52
 
    { &_gcry_digest_spec_crc32,   
53
 
      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
54
 
    { &_gcry_digest_spec_crc32_rfc1510,  
55
 
      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
56
 
    { &_gcry_digest_spec_crc24_rfc2440,
57
 
      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
58
 
#endif
59
 
#if USE_MD4
60
 
    { &_gcry_digest_spec_md4,
61
 
      &dummy_extra_spec,                 GCRY_MD_MD4 },
62
 
#endif
63
 
#if USE_MD5
64
 
    { &_gcry_digest_spec_md5,
65
 
      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
66
 
#endif
67
 
#if USE_RMD160
68
 
    { &_gcry_digest_spec_rmd160,
69
 
      &dummy_extra_spec,                 GCRY_MD_RMD160 },
70
 
#endif
71
 
#if USE_SHA1
72
 
    { &_gcry_digest_spec_sha1, 
73
 
      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
74
 
#endif
75
 
#if USE_SHA256
76
 
    { &_gcry_digest_spec_sha256,
77
 
      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
78
 
    { &_gcry_digest_spec_sha224,
79
 
      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
80
 
#endif
81
 
#if USE_SHA512
82
 
    { &_gcry_digest_spec_sha512,
83
 
      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
84
 
    { &_gcry_digest_spec_sha384,
85
 
      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
86
 
#endif
87
 
#if USE_TIGER
88
 
    { &_gcry_digest_spec_tiger,
89
 
      &dummy_extra_spec,                 GCRY_MD_TIGER },
90
 
#endif
91
 
#if USE_WHIRLPOOL
92
 
    { &_gcry_digest_spec_whirlpool,
93
 
      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
94
 
#endif
95
 
    { NULL },
96
 
  };
97
 
 
98
 
/* List of registered digests.  */
99
 
static gcry_module_t digests_registered;
100
 
 
101
 
/* This is the lock protecting DIGESTS_REGISTERED.  */
102
 
static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
103
 
 
104
 
/* Flag to check wether the default ciphers have already been
105
 
   registered.  */
106
 
static int default_digests_registered;
107
 
 
108
 
typedef struct gcry_md_list
109
 
{
110
 
  gcry_md_spec_t *digest;
111
 
  gcry_module_t module;
112
 
  struct gcry_md_list *next;
113
 
  size_t actual_struct_size;     /* Allocated size of this structure. */
114
 
  PROPERLY_ALIGNED_TYPE context;
115
 
} GcryDigestEntry;
116
 
 
117
 
/* this structure is put right after the gcry_md_hd_t buffer, so that
118
 
 * only one memory block is needed. */
119
 
struct gcry_md_context
120
 
{
121
 
  int  magic;
122
 
  size_t actual_handle_size;     /* Allocated size of this handle. */
123
 
  int  secure;
124
 
  FILE  *debug;
125
 
  int finalized;
126
 
  GcryDigestEntry *list;
127
 
  byte *macpads;
128
 
  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
129
 
};
130
 
 
131
 
 
132
 
#define CTX_MAGIC_NORMAL 0x11071961
133
 
#define CTX_MAGIC_SECURE 0x16917011
134
 
 
135
 
/* Convenient macro for registering the default digests.  */
136
 
#define REGISTER_DEFAULT_DIGESTS                   \
137
 
  do                                               \
138
 
    {                                              \
139
 
      ath_mutex_lock (&digests_registered_lock);   \
140
 
      if (! default_digests_registered)            \
141
 
        {                                          \
142
 
          md_register_default ();                  \
143
 
          default_digests_registered = 1;          \
144
 
        }                                          \
145
 
      ath_mutex_unlock (&digests_registered_lock); \
146
 
    }                                              \
147
 
  while (0)
148
 
 
149
 
 
150
 
static const char * digest_algo_to_string( int algo );
151
 
static gcry_err_code_t check_digest_algo (int algo);
152
 
static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
153
 
                                int secure, int hmac);
154
 
static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
155
 
static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
156
 
static void md_close (gcry_md_hd_t a);
157
 
static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
158
 
static void md_final(gcry_md_hd_t a);
159
 
static byte *md_read( gcry_md_hd_t a, int algo );
160
 
static int md_get_algo( gcry_md_hd_t a );
161
 
static int md_digest_length( int algo );
162
 
static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
163
 
static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
164
 
static void md_stop_debug ( gcry_md_hd_t a );
165
 
 
166
 
 
167
 
 
168
 
 
169
 
/* Internal function.  Register all the ciphers included in
170
 
   CIPHER_TABLE.  Returns zero on success or an error code.  */
171
 
static void
172
 
md_register_default (void)
173
 
{
174
 
  gcry_err_code_t err = 0;
175
 
  int i;
176
 
  
177
 
  for (i = 0; !err && digest_table[i].digest; i++)
178
 
    {
179
 
      if ( fips_mode ())
180
 
        {
181
 
          if (!digest_table[i].fips_allowed)
182
 
            continue;
183
 
          if (digest_table[i].algorithm == GCRY_MD_MD5
184
 
              && _gcry_enforced_fips_mode () )
185
 
            continue;  /* Do not register in enforced fips mode.  */
186
 
        }
187
 
 
188
 
      err = _gcry_module_add (&digests_registered,
189
 
                              digest_table[i].algorithm,
190
 
                              (void *) digest_table[i].digest,
191
 
                              (void *) digest_table[i].extraspec,
192
 
                              NULL);
193
 
    }
194
 
 
195
 
  if (err)
196
 
    BUG ();
197
 
}
198
 
 
199
 
/* Internal callback function.  */
200
 
static int
201
 
gcry_md_lookup_func_name (void *spec, void *data)
202
 
{
203
 
  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
204
 
  char *name = (char *) data;
205
 
 
206
 
  return (! stricmp (digest->name, name));
207
 
}
208
 
 
209
 
/* Internal callback function.  Used via _gcry_module_lookup.  */
210
 
static int
211
 
gcry_md_lookup_func_oid (void *spec, void *data)
212
 
{
213
 
  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
214
 
  char *oid = (char *) data;
215
 
  gcry_md_oid_spec_t *oid_specs = digest->oids;
216
 
  int ret = 0, i;
217
 
 
218
 
  if (oid_specs)
219
 
    {
220
 
      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
221
 
        if (! stricmp (oid, oid_specs[i].oidstring))
222
 
          ret = 1;
223
 
    }
224
 
 
225
 
  return ret;
226
 
}
227
 
 
228
 
/* Internal function.  Lookup a digest entry by it's name.  */
229
 
static gcry_module_t 
230
 
gcry_md_lookup_name (const char *name)
231
 
{
232
 
  gcry_module_t digest;
233
 
 
234
 
  digest = _gcry_module_lookup (digests_registered, (void *) name,
235
 
                                gcry_md_lookup_func_name);
236
 
 
237
 
  return digest;
238
 
}
239
 
 
240
 
/* Internal function.  Lookup a cipher entry by it's oid.  */
241
 
static gcry_module_t
242
 
gcry_md_lookup_oid (const char *oid)
243
 
{
244
 
  gcry_module_t digest;
245
 
 
246
 
  digest = _gcry_module_lookup (digests_registered, (void *) oid,
247
 
                                gcry_md_lookup_func_oid);
248
 
 
249
 
  return digest;
250
 
}
251
 
 
252
 
/* Register a new digest module whose specification can be found in
253
 
   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
254
 
   and a pointer representhing this module is stored in MODULE.  */
255
 
gcry_error_t
256
 
_gcry_md_register (gcry_md_spec_t *digest,
257
 
                   md_extra_spec_t *extraspec,
258
 
                   unsigned int *algorithm_id,
259
 
                   gcry_module_t *module)
260
 
{
261
 
  gcry_err_code_t err = 0;
262
 
  gcry_module_t mod;
263
 
 
264
 
  /* We do not support module loading in fips mode.  */
265
 
  if (fips_mode ())
266
 
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
267
 
 
268
 
  ath_mutex_lock (&digests_registered_lock);
269
 
  err = _gcry_module_add (&digests_registered, 0,
270
 
                          (void *) digest, 
271
 
                          (void *)(extraspec? extraspec : &dummy_extra_spec), 
272
 
                          &mod);
273
 
  ath_mutex_unlock (&digests_registered_lock);
274
 
  
275
 
  if (! err)
276
 
    {
277
 
      *module = mod;
278
 
      *algorithm_id = mod->mod_id;
279
 
    }
280
 
 
281
 
  return gcry_error (err);
282
 
}
283
 
 
284
 
/* Unregister the digest identified by ID, which must have been
285
 
   registered with gcry_digest_register.  */
286
 
void
287
 
gcry_md_unregister (gcry_module_t module)
288
 
{
289
 
  ath_mutex_lock (&digests_registered_lock);
290
 
  _gcry_module_release (module);
291
 
  ath_mutex_unlock (&digests_registered_lock);
292
 
}
293
 
 
294
 
 
295
 
static int 
296
 
search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
297
 
{
298
 
  gcry_module_t module;
299
 
  int ret = 0;
300
 
 
301
 
  if (oid && ((! strncmp (oid, "oid.", 4))
302
 
              || (! strncmp (oid, "OID.", 4))))
303
 
    oid += 4;
304
 
 
305
 
  module = gcry_md_lookup_oid (oid);
306
 
  if (module)
307
 
    {
308
 
      gcry_md_spec_t *digest = module->spec;
309
 
      int i;
310
 
 
311
 
      for (i = 0; digest->oids[i].oidstring && !ret; i++)
312
 
        if (! stricmp (oid, digest->oids[i].oidstring))
313
 
          {
314
 
            if (algorithm)
315
 
              *algorithm = module->mod_id;
316
 
            if (oid_spec)
317
 
              *oid_spec = digest->oids[i];
318
 
            ret = 1;
319
 
          }
320
 
      _gcry_module_release (module);
321
 
    }
322
 
 
323
 
  return ret;
324
 
}
325
 
 
326
 
/****************
327
 
 * Map a string to the digest algo
328
 
 */
329
 
int
330
 
gcry_md_map_name (const char *string)
331
 
{
332
 
  gcry_module_t digest;
333
 
  int ret, algorithm = 0;
334
 
 
335
 
  if (! string)
336
 
    return 0;
337
 
 
338
 
  REGISTER_DEFAULT_DIGESTS;
339
 
 
340
 
  /* If the string starts with a digit (optionally prefixed with
341
 
     either "OID." or "oid."), we first look into our table of ASN.1
342
 
     object identifiers to figure out the algorithm */
343
 
 
344
 
  ath_mutex_lock (&digests_registered_lock);
345
 
 
346
 
  ret = search_oid (string, &algorithm, NULL);
347
 
  if (! ret)
348
 
    {
349
 
      /* Not found, search a matching digest name.  */
350
 
      digest = gcry_md_lookup_name (string);
351
 
      if (digest)
352
 
        {
353
 
          algorithm = digest->mod_id;
354
 
          _gcry_module_release (digest);
355
 
        }
356
 
    }
357
 
  ath_mutex_unlock (&digests_registered_lock);
358
 
 
359
 
  return algorithm;
360
 
}
361
 
 
362
 
 
363
 
/****************
364
 
 * Map a digest algo to a string
365
 
 */
366
 
static const char *
367
 
digest_algo_to_string (int algorithm)
368
 
{
369
 
  const char *name = NULL;
370
 
  gcry_module_t digest;
371
 
 
372
 
  REGISTER_DEFAULT_DIGESTS;
373
 
 
374
 
  ath_mutex_lock (&digests_registered_lock);
375
 
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
376
 
  if (digest)
377
 
    {
378
 
      name = ((gcry_md_spec_t *) digest->spec)->name;
379
 
      _gcry_module_release (digest);
380
 
    }
381
 
  ath_mutex_unlock (&digests_registered_lock);
382
 
 
383
 
  return name;
384
 
}
385
 
 
386
 
/****************
387
 
 * This function simply returns the name of the algorithm or some constant
388
 
 * string when there is no algo.  It will never return NULL.
389
 
 * Use  the macro gcry_md_test_algo() to check whether the algorithm
390
 
 * is valid.
391
 
 */
392
 
const char *
393
 
gcry_md_algo_name (int algorithm)
394
 
{
395
 
  const char *s = digest_algo_to_string (algorithm);
396
 
  return s ? s : "?";
397
 
}
398
 
 
399
 
 
400
 
static gcry_err_code_t
401
 
check_digest_algo (int algorithm)
402
 
{
403
 
  gcry_err_code_t rc = 0;
404
 
  gcry_module_t digest;
405
 
 
406
 
  REGISTER_DEFAULT_DIGESTS;
407
 
 
408
 
  ath_mutex_lock (&digests_registered_lock);
409
 
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
410
 
  if (digest)
411
 
    _gcry_module_release (digest);
412
 
  else
413
 
    rc = GPG_ERR_DIGEST_ALGO;
414
 
  ath_mutex_unlock (&digests_registered_lock);
415
 
 
416
 
  return rc;
417
 
}
418
 
 
419
 
 
420
 
 
421
 
/****************
422
 
 * Open a message digest handle for use with algorithm ALGO.
423
 
 * More algorithms may be added by md_enable(). The initial algorithm
424
 
 * may be 0.
425
 
 */
426
 
static gcry_err_code_t
427
 
md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
428
 
{
429
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
430
 
  int bufsize = secure ? 512 : 1024;
431
 
  struct gcry_md_context *ctx;
432
 
  gcry_md_hd_t hd;
433
 
  size_t n;
434
 
 
435
 
  /* Allocate a memory area to hold the caller visible buffer with it's
436
 
   * control information and the data required by this module. Set the
437
 
   * context pointer at the beginning to this area.
438
 
   * We have to use this strange scheme because we want to hide the
439
 
   * internal data but have a variable sized buffer.
440
 
   *
441
 
   *    +---+------+---........------+-------------+
442
 
   *    !ctx! bctl !  buffer         ! private     !
443
 
   *    +---+------+---........------+-------------+
444
 
   *      !                           ^
445
 
   *      !---------------------------!
446
 
   *
447
 
   * We have to make sure that private is well aligned.
448
 
   */
449
 
  n = sizeof (struct gcry_md_handle) + bufsize;
450
 
  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
451
 
       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
452
 
 
453
 
  /* Allocate and set the Context pointer to the private data */
454
 
  if (secure)
455
 
    hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
456
 
  else
457
 
    hd = gcry_malloc (n + sizeof (struct gcry_md_context));
458
 
 
459
 
  if (! hd)
460
 
    err = gpg_err_code_from_errno (errno);
461
 
 
462
 
  if (! err)
463
 
    {
464
 
      hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
465
 
      /* Setup the globally visible data (bctl in the diagram).*/
466
 
      hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
467
 
      hd->bufpos = 0;
468
 
 
469
 
      /* Initialize the private data. */
470
 
      memset (hd->ctx, 0, sizeof *hd->ctx);
471
 
      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
472
 
      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
473
 
      ctx->secure = secure;
474
 
 
475
 
      if (hmac)
476
 
        {
477
 
          switch (algo)
478
 
            {
479
 
              case GCRY_MD_SHA384:
480
 
              case GCRY_MD_SHA512:
481
 
                ctx->macpads_Bsize = 128;
482
 
                break;
483
 
              default:
484
 
                ctx->macpads_Bsize = 64;
485
 
                break;
486
 
            }
487
 
          ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
488
 
          if (!ctx->macpads)
489
 
            {
490
 
              err = gpg_err_code_from_errno (errno);
491
 
              md_close (hd);
492
 
            }
493
 
        }
494
 
    }
495
 
 
496
 
  if (! err)
497
 
    {
498
 
      /* Hmmm, should we really do that? - yes [-wk] */
499
 
      _gcry_fast_random_poll ();
500
 
 
501
 
      if (algo)
502
 
        {
503
 
          err = md_enable (hd, algo);
504
 
          if (err)
505
 
            md_close (hd);
506
 
        }
507
 
    }
508
 
 
509
 
  if (! err)
510
 
    *h = hd;
511
 
 
512
 
  return err;
513
 
}
514
 
 
515
 
/* Create a message digest object for algorithm ALGO.  FLAGS may be
516
 
   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
517
 
   given as 0 if the algorithms to be used are later set using
518
 
   gcry_md_enable. H is guaranteed to be a valid handle or NULL on
519
 
   error.  */
520
 
gcry_error_t
521
 
gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
522
 
{
523
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
524
 
  gcry_md_hd_t hd;
525
 
 
526
 
  if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
527
 
    err = GPG_ERR_INV_ARG;
528
 
  else
529
 
    {
530
 
      err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
531
 
                     (flags & GCRY_MD_FLAG_HMAC));
532
 
    }
533
 
 
534
 
  *h = err? NULL : hd;
535
 
  return gcry_error (err);
536
 
}
537
 
 
538
 
 
539
 
 
540
 
static gcry_err_code_t
541
 
md_enable (gcry_md_hd_t hd, int algorithm)
542
 
{
543
 
  struct gcry_md_context *h = hd->ctx;
544
 
  gcry_md_spec_t *digest = NULL;
545
 
  GcryDigestEntry *entry;
546
 
  gcry_module_t module;
547
 
  gcry_err_code_t err = 0;
548
 
 
549
 
  for (entry = h->list; entry; entry = entry->next)
550
 
    if (entry->module->mod_id == algorithm)
551
 
      return err; /* already enabled */
552
 
 
553
 
  REGISTER_DEFAULT_DIGESTS;
554
 
 
555
 
  ath_mutex_lock (&digests_registered_lock);
556
 
  module = _gcry_module_lookup_id (digests_registered, algorithm);
557
 
  ath_mutex_unlock (&digests_registered_lock);
558
 
  if (! module)
559
 
    {
560
 
      log_debug ("md_enable: algorithm %d not available\n", algorithm);
561
 
      err = GPG_ERR_DIGEST_ALGO;
562
 
    }
563
 
 else
564
 
    digest = (gcry_md_spec_t *) module->spec;
565
 
 
566
 
  
567
 
  if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
568
 
    {
569
 
      _gcry_inactivate_fips_mode ("MD5 used");
570
 
      if (_gcry_enforced_fips_mode () )
571
 
        {
572
 
          /* We should never get to here because we do not register
573
 
             MD5 in enforced fips mode. But better throw an error.  */
574
 
          err = GPG_ERR_DIGEST_ALGO;
575
 
        }
576
 
    }
577
 
  
578
 
  if (!err)
579
 
    {
580
 
      size_t size = (sizeof (*entry)
581
 
                     + digest->contextsize
582
 
                     - sizeof (entry->context));
583
 
 
584
 
      /* And allocate a new list entry. */
585
 
      if (h->secure)
586
 
        entry = gcry_malloc_secure (size);
587
 
      else
588
 
        entry = gcry_malloc (size);
589
 
 
590
 
      if (! entry)
591
 
        err = gpg_err_code_from_errno (errno);
592
 
      else
593
 
        {
594
 
          entry->digest = digest;
595
 
          entry->module = module;
596
 
          entry->next = h->list;
597
 
          entry->actual_struct_size = size;
598
 
          h->list = entry;
599
 
 
600
 
          /* And init this instance. */
601
 
          entry->digest->init (&entry->context.c);
602
 
        }
603
 
    }
604
 
 
605
 
  if (err)
606
 
    {
607
 
      if (module)
608
 
        {
609
 
           ath_mutex_lock (&digests_registered_lock);
610
 
           _gcry_module_release (module);
611
 
           ath_mutex_unlock (&digests_registered_lock);
612
 
        }
613
 
    }
614
 
 
615
 
  return err;
616
 
}
617
 
 
618
 
 
619
 
gcry_error_t
620
 
gcry_md_enable (gcry_md_hd_t hd, int algorithm)
621
 
{
622
 
  return gcry_error (md_enable (hd, algorithm));
623
 
}
624
 
 
625
 
static gcry_err_code_t
626
 
md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
627
 
{
628
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
629
 
  struct gcry_md_context *a = ahd->ctx;
630
 
  struct gcry_md_context *b;
631
 
  GcryDigestEntry *ar, *br;
632
 
  gcry_md_hd_t bhd;
633
 
  size_t n;
634
 
  
635
 
  if (ahd->bufpos)
636
 
    md_write (ahd, NULL, 0);
637
 
 
638
 
  n = (char *) ahd->ctx - (char *) ahd;
639
 
  if (a->secure)
640
 
    bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
641
 
  else
642
 
    bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
643
 
 
644
 
  if (! bhd)
645
 
    err = gpg_err_code_from_errno (errno);
646
 
 
647
 
  if (! err)
648
 
    {
649
 
      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
650
 
      /* No need to copy the buffer due to the write above. */
651
 
      gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
652
 
      bhd->bufsize = ahd->bufsize;
653
 
      bhd->bufpos = 0;
654
 
      gcry_assert (! ahd->bufpos);
655
 
      memcpy (b, a, sizeof *a);
656
 
      b->list = NULL;
657
 
      b->debug = NULL;
658
 
      if (a->macpads)
659
 
        {
660
 
          b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
661
 
          if (! b->macpads)
662
 
            {
663
 
              err = gpg_err_code_from_errno (errno);
664
 
              md_close (bhd);
665
 
            }
666
 
          else
667
 
            memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
668
 
        }
669
 
    }
670
 
 
671
 
  /* Copy the complete list of algorithms.  The copied list is
672
 
     reversed, but that doesn't matter. */
673
 
  if (!err)
674
 
    {
675
 
      for (ar = a->list; ar; ar = ar->next)
676
 
        {
677
 
          if (a->secure)
678
 
            br = gcry_malloc_secure (sizeof *br
679
 
                                     + ar->digest->contextsize
680
 
                                     - sizeof(ar->context));
681
 
          else
682
 
            br = gcry_malloc (sizeof *br
683
 
                              + ar->digest->contextsize
684
 
                              - sizeof (ar->context));
685
 
          if (!br)
686
 
            {
687
 
              err = gpg_err_code_from_errno (errno);
688
 
              md_close (bhd);
689
 
              break;
690
 
            }
691
 
 
692
 
          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
693
 
                           - sizeof (ar->context)));
694
 
          br->next = b->list;
695
 
          b->list = br;
696
 
          
697
 
          /* Add a reference to the module.  */
698
 
          ath_mutex_lock (&digests_registered_lock);
699
 
          _gcry_module_use (br->module);
700
 
          ath_mutex_unlock (&digests_registered_lock);
701
 
        }
702
 
    }
703
 
 
704
 
  if (a->debug && !err)
705
 
    md_start_debug (bhd, "unknown");
706
 
 
707
 
  if (!err)
708
 
    *b_hd = bhd;
709
 
 
710
 
  return err;
711
 
}
712
 
 
713
 
gcry_error_t
714
 
gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
715
 
{
716
 
  gcry_err_code_t err;
717
 
 
718
 
  err = md_copy (hd, handle);
719
 
  if (err)
720
 
    *handle = NULL;
721
 
  return gcry_error (err);
722
 
}
723
 
 
724
 
/*
725
 
 * Reset all contexts and discard any buffered stuff.  This may be used
726
 
 * instead of a md_close(); md_open().
727
 
 */
728
 
void
729
 
gcry_md_reset (gcry_md_hd_t a)
730
 
{
731
 
  GcryDigestEntry *r;
732
 
 
733
 
  /* Note: We allow this even in fips non operational mode.  */
734
 
 
735
 
  a->bufpos = a->ctx->finalized = 0;
736
 
 
737
 
  for (r = a->ctx->list; r; r = r->next)
738
 
    {
739
 
      memset (r->context.c, 0, r->digest->contextsize);
740
 
      (*r->digest->init) (&r->context.c);
741
 
    }
742
 
  if (a->ctx->macpads)
743
 
    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
744
 
}
745
 
 
746
 
static void
747
 
md_close (gcry_md_hd_t a)
748
 
{
749
 
  GcryDigestEntry *r, *r2;
750
 
 
751
 
  if (! a)
752
 
    return;
753
 
  if (a->ctx->debug)
754
 
    md_stop_debug (a);
755
 
  for (r = a->ctx->list; r; r = r2)
756
 
    {
757
 
      r2 = r->next;
758
 
      ath_mutex_lock (&digests_registered_lock);
759
 
      _gcry_module_release (r->module);
760
 
      ath_mutex_unlock (&digests_registered_lock);
761
 
      wipememory (r, r->actual_struct_size);
762
 
      gcry_free (r);
763
 
    }
764
 
 
765
 
  if (a->ctx->macpads)
766
 
    {
767
 
      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
768
 
      gcry_free(a->ctx->macpads);
769
 
    }
770
 
 
771
 
  wipememory (a, a->ctx->actual_handle_size);
772
 
  gcry_free(a);
773
 
}
774
 
 
775
 
void
776
 
gcry_md_close (gcry_md_hd_t hd)
777
 
{
778
 
  /* Note: We allow this even in fips non operational mode.  */
779
 
  md_close (hd);
780
 
}
781
 
 
782
 
static void
783
 
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
784
 
{
785
 
  GcryDigestEntry *r;
786
 
  
787
 
  if (a->ctx->debug)
788
 
    {
789
 
      if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
790
 
        BUG();
791
 
      if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
792
 
        BUG();
793
 
    }
794
 
 
795
 
  for (r = a->ctx->list; r; r = r->next)
796
 
    {
797
 
      if (a->bufpos)
798
 
        (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
799
 
      (*r->digest->write) (&r->context.c, inbuf, inlen);
800
 
    }
801
 
  a->bufpos = 0;
802
 
}
803
 
 
804
 
void
805
 
gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
806
 
{
807
 
  md_write (hd, inbuf, inlen);
808
 
}
809
 
 
810
 
static void
811
 
md_final (gcry_md_hd_t a)
812
 
{
813
 
  GcryDigestEntry *r;
814
 
 
815
 
  if (a->ctx->finalized)
816
 
    return;
817
 
 
818
 
  if (a->bufpos)
819
 
    md_write (a, NULL, 0);
820
 
 
821
 
  for (r = a->ctx->list; r; r = r->next)
822
 
    (*r->digest->final) (&r->context.c);
823
 
 
824
 
  a->ctx->finalized = 1;
825
 
 
826
 
  if (a->ctx->macpads)
827
 
    {
828
 
      /* Finish the hmac. */
829
 
      int algo = md_get_algo (a);
830
 
      byte *p = md_read (a, algo);
831
 
      size_t dlen = md_digest_length (algo);
832
 
      gcry_md_hd_t om;
833
 
      gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
834
 
 
835
 
      if (err)
836
 
        _gcry_fatal_error (err, NULL);
837
 
      md_write (om, 
838
 
                (a->ctx->macpads)+(a->ctx->macpads_Bsize), 
839
 
                a->ctx->macpads_Bsize);
840
 
      md_write (om, p, dlen);
841
 
      md_final (om);
842
 
      /* Replace our digest with the mac (they have the same size). */
843
 
      memcpy (p, md_read (om, algo), dlen);
844
 
      md_close (om);
845
 
    }
846
 
}
847
 
 
848
 
static gcry_err_code_t
849
 
prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
850
 
{
851
 
  int i;
852
 
  int algo = md_get_algo (hd);
853
 
  unsigned char *helpkey = NULL;
854
 
  unsigned char *ipad, *opad;
855
 
 
856
 
  if (!algo)
857
 
    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */
858
 
 
859
 
  if ( keylen > hd->ctx->macpads_Bsize ) 
860
 
    {
861
 
      helpkey = gcry_malloc_secure (md_digest_length (algo));
862
 
      if (!helpkey)
863
 
        return gpg_err_code_from_errno (errno);
864
 
      gcry_md_hash_buffer (algo, helpkey, key, keylen);
865
 
      key = helpkey;
866
 
      keylen = md_digest_length (algo);
867
 
      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
868
 
    }
869
 
 
870
 
  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
871
 
  ipad = hd->ctx->macpads;
872
 
  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
873
 
  memcpy ( ipad, key, keylen );
874
 
  memcpy ( opad, key, keylen );
875
 
  for (i=0; i < hd->ctx->macpads_Bsize; i++ ) 
876
 
    {
877
 
      ipad[i] ^= 0x36;
878
 
      opad[i] ^= 0x5c;
879
 
    }
880
 
  gcry_free (helpkey);
881
 
 
882
 
  return GPG_ERR_NO_ERROR;
883
 
}
884
 
 
885
 
gcry_error_t
886
 
gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
887
 
{
888
 
  gcry_err_code_t rc = 0;
889
 
  
890
 
  switch (cmd)
891
 
    {
892
 
    case GCRYCTL_FINALIZE:
893
 
      md_final (hd);
894
 
      break;
895
 
    case GCRYCTL_SET_KEY:
896
 
      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
897
 
      break;
898
 
    case GCRYCTL_START_DUMP:
899
 
      md_start_debug (hd, buffer);
900
 
      break;
901
 
    case GCRYCTL_STOP_DUMP:
902
 
      md_stop_debug ( hd );
903
 
      break;
904
 
    default:
905
 
      rc = GPG_ERR_INV_OP;
906
 
    }
907
 
  return gcry_error (rc);
908
 
}
909
 
 
910
 
gcry_error_t
911
 
gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
912
 
{
913
 
  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
914
 
 
915
 
  if (!hd->ctx->macpads)
916
 
    rc = GPG_ERR_CONFLICT;
917
 
  else
918
 
    {
919
 
      rc = prepare_macpads (hd, key, keylen);
920
 
      if (! rc)
921
 
        gcry_md_reset (hd);
922
 
    }
923
 
 
924
 
  return gcry_error (rc);
925
 
}
926
 
 
927
 
/* The new debug interface.  If SUFFIX is a string it creates an debug
928
 
   file for the context HD.  IF suffix is NULL, the file is closed and
929
 
   debugging is stopped.  */
930
 
void
931
 
gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
932
 
{
933
 
  if (suffix)
934
 
    md_start_debug (hd, suffix);
935
 
  else
936
 
    md_stop_debug (hd);
937
 
}
938
 
 
939
 
 
940
 
 
941
 
/****************
942
 
 * if ALGO is null get the digest for the used algo (which should be only one)
943
 
 */
944
 
static byte *
945
 
md_read( gcry_md_hd_t a, int algo )
946
 
{
947
 
  GcryDigestEntry *r = a->ctx->list;
948
 
 
949
 
  if (! algo)
950
 
    {
951
 
      /* return the first algorithm */
952
 
      if (r && r->next)
953
 
        log_debug ("more than one algorithm in md_read(0)\n");
954
 
      return r->digest->read( &r->context.c );
955
 
    }
956
 
  else
957
 
    {
958
 
      for (r = a->ctx->list; r; r = r->next)
959
 
        if (r->module->mod_id == algo)
960
 
          return r->digest->read (&r->context.c);
961
 
    }
962
 
  BUG();
963
 
  return NULL;
964
 
}
965
 
 
966
 
/*
967
 
 * Read out the complete digest, this function implictly finalizes
968
 
 * the hash.
969
 
 */
970
 
byte *
971
 
gcry_md_read (gcry_md_hd_t hd, int algo)
972
 
{
973
 
  /* This function is expected to always return a digest, thus we
974
 
     can't return an error which we actually should do in
975
 
     non-operational state.  */
976
 
  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
977
 
  return md_read (hd, algo);
978
 
}
979
 
 
980
 
 
981
 
/*
982
 
 * Read out an intermediate digest.  Not yet functional.
983
 
 */
984
 
gcry_err_code_t
985
 
gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
986
 
{
987
 
  (void)hd;
988
 
  (void)algo;
989
 
  (void)buffer;
990
 
  (void)buflen;
991
 
 
992
 
  /*md_digest ... */
993
 
  fips_signal_error ("unimplemented function called");
994
 
  return GPG_ERR_INTERNAL;
995
 
}
996
 
 
997
 
 
998
 
/*
999
 
 * Shortcut function to hash a buffer with a given algo. The only
1000
 
 * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
1001
 
 * supplied digest buffer must be large enough to store the resulting
1002
 
 * hash.  No error is returned, the function will abort on an invalid
1003
 
 * algo.  DISABLED_ALGOS are ignored here.  */
1004
 
void
1005
 
gcry_md_hash_buffer (int algo, void *digest,
1006
 
                     const void *buffer, size_t length)
1007
 
{
1008
 
  if (algo == GCRY_MD_SHA1)
1009
 
    _gcry_sha1_hash_buffer (digest, buffer, length);
1010
 
  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
1011
 
    _gcry_rmd160_hash_buffer (digest, buffer, length);
1012
 
  else
1013
 
    {
1014
 
      /* For the others we do not have a fast function, so we use the
1015
 
         normal functions. */
1016
 
      gcry_md_hd_t h;
1017
 
      gpg_err_code_t err;
1018
 
 
1019
 
      if (algo == GCRY_MD_MD5 && fips_mode ())
1020
 
        {
1021
 
          _gcry_inactivate_fips_mode ("MD5 used");
1022
 
          if (_gcry_enforced_fips_mode () )
1023
 
            {
1024
 
              /* We should never get to here because we do not register
1025
 
                 MD5 in enforced fips mode.  */
1026
 
              _gcry_fips_noreturn ();
1027
 
            }
1028
 
        }
1029
 
 
1030
 
      err = md_open (&h, algo, 0, 0);
1031
 
      if (err)
1032
 
        log_bug ("gcry_md_open failed for algo %d: %s",
1033
 
                 algo, gpg_strerror (gcry_error(err)));
1034
 
      md_write (h, (byte *) buffer, length);
1035
 
      md_final (h);
1036
 
      memcpy (digest, md_read (h, algo), md_digest_length (algo));
1037
 
      md_close (h);
1038
 
    }
1039
 
}
1040
 
 
1041
 
static int
1042
 
md_get_algo (gcry_md_hd_t a)
1043
 
{
1044
 
  GcryDigestEntry *r = a->ctx->list;
1045
 
 
1046
 
  if (r && r->next)
1047
 
    {
1048
 
      fips_signal_error ("possible usage error");
1049
 
      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
1050
 
    }
1051
 
  return r ? r->module->mod_id : 0;
1052
 
}
1053
 
 
1054
 
int
1055
 
gcry_md_get_algo (gcry_md_hd_t hd)
1056
 
{
1057
 
  return md_get_algo (hd);
1058
 
}
1059
 
 
1060
 
 
1061
 
/****************
1062
 
 * Return the length of the digest
1063
 
 */
1064
 
static int
1065
 
md_digest_length (int algorithm)
1066
 
{
1067
 
  gcry_module_t digest;
1068
 
  int mdlen = 0;
1069
 
 
1070
 
  REGISTER_DEFAULT_DIGESTS;
1071
 
 
1072
 
  ath_mutex_lock (&digests_registered_lock);
1073
 
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
1074
 
  if (digest)
1075
 
    {
1076
 
      mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
1077
 
      _gcry_module_release (digest);
1078
 
    }
1079
 
  ath_mutex_unlock (&digests_registered_lock);
1080
 
 
1081
 
  return mdlen;
1082
 
}
1083
 
 
1084
 
/****************
1085
 
 * Return the length of the digest in bytes.
1086
 
 * This function will return 0 in case of errors.
1087
 
 */
1088
 
unsigned int
1089
 
gcry_md_get_algo_dlen (int algorithm)
1090
 
{
1091
 
  return md_digest_length (algorithm);
1092
 
}
1093
 
 
1094
 
 
1095
 
/* Hmmm: add a mode to enumerate the OIDs
1096
 
 *      to make g10/sig-check.c more portable */
1097
 
static const byte *
1098
 
md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
1099
 
{
1100
 
  const byte *asnoid = NULL;
1101
 
  gcry_module_t digest;
1102
 
 
1103
 
  REGISTER_DEFAULT_DIGESTS;
1104
 
 
1105
 
  ath_mutex_lock (&digests_registered_lock);
1106
 
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
1107
 
  if (digest)
1108
 
    {
1109
 
      if (asnlen)
1110
 
        *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
1111
 
      if (mdlen)
1112
 
        *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
1113
 
      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
1114
 
      _gcry_module_release (digest);
1115
 
    }
1116
 
  else
1117
 
    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
1118
 
  ath_mutex_unlock (&digests_registered_lock);
1119
 
 
1120
 
  return asnoid;
1121
 
}
1122
 
 
1123
 
 
1124
 
 
1125
 
/****************
1126
 
 * Return information about the given cipher algorithm
1127
 
 * WHAT select the kind of information returned:
1128
 
 *  GCRYCTL_TEST_ALGO:
1129
 
 *      Returns 0 when the specified algorithm is available for use.
1130
 
 *      buffer and nbytes must be zero.
1131
 
 *  GCRYCTL_GET_ASNOID:
1132
 
 *      Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
1133
 
 *      the required length is returned.
1134
 
 *
1135
 
 * Note:  Because this function is in most cases used to return an
1136
 
 * integer value, we can make it easier for the caller to just look at
1137
 
 * the return value.  The caller will in all cases consult the value
1138
 
 * and thereby detecting whether a error occured or not (i.e. while checking
1139
 
 * the block size)
1140
 
 */
1141
 
gcry_error_t
1142
 
gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
1143
 
{
1144
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
1145
 
 
1146
 
  switch (what)
1147
 
    {
1148
 
    case GCRYCTL_TEST_ALGO:
1149
 
      if (buffer || nbytes)
1150
 
        err = GPG_ERR_INV_ARG;
1151
 
      else
1152
 
        err = check_digest_algo (algo);
1153
 
      break;
1154
 
 
1155
 
    case GCRYCTL_GET_ASNOID:
1156
 
      /* We need to check that the algo is available because
1157
 
         md_asn_oid would otherwise raise an assertion. */
1158
 
      err = check_digest_algo (algo);
1159
 
      if (!err)
1160
 
        {
1161
 
          const char unsigned *asn;
1162
 
          size_t asnlen;
1163
 
          
1164
 
          asn = md_asn_oid (algo, &asnlen, NULL);
1165
 
          if (buffer && (*nbytes >= asnlen))
1166
 
          {
1167
 
            memcpy (buffer, asn, asnlen);
1168
 
            *nbytes = asnlen;
1169
 
          }
1170
 
          else if (!buffer && nbytes)
1171
 
            *nbytes = asnlen;
1172
 
          else
1173
 
            {
1174
 
              if (buffer)
1175
 
                err = GPG_ERR_TOO_SHORT;
1176
 
              else
1177
 
                err = GPG_ERR_INV_ARG;
1178
 
            }
1179
 
        }
1180
 
      break;
1181
 
 
1182
 
  default:
1183
 
    err = GPG_ERR_INV_OP;
1184
 
  }
1185
 
 
1186
 
  return gcry_error (err);
1187
 
}
1188
 
 
1189
 
 
1190
 
static void
1191
 
md_start_debug ( gcry_md_hd_t md, const char *suffix )
1192
 
{
1193
 
  static int idx=0;
1194
 
  char buf[50];
1195
 
 
1196
 
  if (fips_mode ())
1197
 
    return;
1198
 
  
1199
 
  if ( md->ctx->debug )
1200
 
    {
1201
 
      log_debug("Oops: md debug already started\n");
1202
 
      return;
1203
 
    }
1204
 
  idx++;
1205
 
  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
1206
 
  md->ctx->debug = fopen(buf, "w");
1207
 
  if ( !md->ctx->debug )
1208
 
    log_debug("md debug: can't open %s\n", buf );
1209
 
}
1210
 
 
1211
 
static void
1212
 
md_stop_debug( gcry_md_hd_t md )
1213
 
{
1214
 
  if ( md->ctx->debug )
1215
 
    {
1216
 
      if ( md->bufpos )
1217
 
        md_write ( md, NULL, 0 );
1218
 
      fclose (md->ctx->debug);
1219
 
      md->ctx->debug = NULL;
1220
 
    }
1221
 
 
1222
 
#ifdef HAVE_U64_TYPEDEF
1223
 
  {  /* a kludge to pull in the __muldi3 for Solaris */
1224
 
    volatile u32 a = (u32)(ulong)md;
1225
 
    volatile u64 b = 42;
1226
 
    volatile u64 c;
1227
 
    c = a * b;
1228
 
  }
1229
 
#endif
1230
 
}
1231
 
 
1232
 
 
1233
 
 
1234
 
/*
1235
 
 * Return information about the digest handle.
1236
 
 *  GCRYCTL_IS_SECURE:
1237
 
 *      Returns 1 when the handle works on secured memory
1238
 
 *      otherwise 0 is returned.  There is no error return.
1239
 
 *  GCRYCTL_IS_ALGO_ENABLED:
1240
 
 *     Returns 1 if the algo is enabled for that handle.
1241
 
 *     The algo must be passed as the address of an int.
1242
 
 */
1243
 
gcry_error_t
1244
 
gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
1245
 
{
1246
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
1247
 
 
1248
 
  switch (cmd)
1249
 
    {
1250
 
    case GCRYCTL_IS_SECURE:
1251
 
      *nbytes = h->ctx->secure;
1252
 
      break;
1253
 
 
1254
 
    case GCRYCTL_IS_ALGO_ENABLED:
1255
 
      {
1256
 
        GcryDigestEntry *r;
1257
 
        int algo;
1258
 
 
1259
 
        if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
1260
 
          err = GPG_ERR_INV_ARG;
1261
 
        else
1262
 
          {
1263
 
            algo = *(int*)buffer;
1264
 
            
1265
 
            *nbytes = 0;
1266
 
            for(r=h->ctx->list; r; r = r->next ) {
1267
 
              if (r->module->mod_id == algo)
1268
 
                {
1269
 
                  *nbytes = 1;
1270
 
                  break;
1271
 
                }
1272
 
            }
1273
 
          }
1274
 
        break;
1275
 
      }
1276
 
 
1277
 
  default:
1278
 
    err = GPG_ERR_INV_OP;
1279
 
  }
1280
 
 
1281
 
  return gcry_error (err);
1282
 
}
1283
 
 
1284
 
 
1285
 
/* Explicitly initialize this module.  */
1286
 
gcry_err_code_t
1287
 
_gcry_md_init (void)
1288
 
{
1289
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
1290
 
 
1291
 
  REGISTER_DEFAULT_DIGESTS;
1292
 
 
1293
 
  return err;
1294
 
}
1295
 
 
1296
 
 
1297
 
int
1298
 
gcry_md_is_secure (gcry_md_hd_t a) 
1299
 
{
1300
 
  size_t value;
1301
 
 
1302
 
  if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
1303
 
    value = 1; /* It seems to be better to assume secure memory on
1304
 
                  error. */
1305
 
  return value;
1306
 
}
1307
 
 
1308
 
 
1309
 
int
1310
 
gcry_md_is_enabled (gcry_md_hd_t a, int algo) 
1311
 
{
1312
 
  size_t value;
1313
 
 
1314
 
  value = sizeof algo;
1315
 
  if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
1316
 
    value = 0;
1317
 
  return value;
1318
 
}
1319
 
 
1320
 
/* Get a list consisting of the IDs of the loaded message digest
1321
 
   modules.  If LIST is zero, write the number of loaded message
1322
 
   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
1323
 
   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
1324
 
   of according size.  In case there are less message digest modules
1325
 
   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
1326
 
   number.  */
1327
 
gcry_error_t
1328
 
gcry_md_list (int *list, int *list_length)
1329
 
{
1330
 
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
1331
 
 
1332
 
  ath_mutex_lock (&digests_registered_lock);
1333
 
  err = _gcry_module_list (digests_registered, list, list_length);
1334
 
  ath_mutex_unlock (&digests_registered_lock);
1335
 
 
1336
 
  return err;
1337
 
}
1338
 
 
1339
 
 
1340
 
/* Run the selftests for digest algorithm ALGO with optional reporting
1341
 
   function REPORT.  */
1342
 
gpg_error_t
1343
 
_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
1344
 
{
1345
 
  gcry_module_t module = NULL;
1346
 
  cipher_extra_spec_t *extraspec = NULL;
1347
 
  gcry_err_code_t ec = 0;
1348
 
 
1349
 
  REGISTER_DEFAULT_DIGESTS;
1350
 
 
1351
 
  ath_mutex_lock (&digests_registered_lock);
1352
 
  module = _gcry_module_lookup_id (digests_registered, algo);
1353
 
  if (module && !(module->flags & FLAG_MODULE_DISABLED))
1354
 
    extraspec = module->extraspec;
1355
 
  ath_mutex_unlock (&digests_registered_lock);
1356
 
  if (extraspec && extraspec->selftest)
1357
 
    ec = extraspec->selftest (algo, extended, report);
1358
 
  else
1359
 
    {
1360
 
      ec = GPG_ERR_DIGEST_ALGO;
1361
 
      if (report)
1362
 
        report ("digest", algo, "module", 
1363
 
                module && !(module->flags & FLAG_MODULE_DISABLED)?
1364
 
                "no selftest available" :
1365
 
                module? "algorithm disabled" : "algorithm not found");
1366
 
    }
1367
 
 
1368
 
  if (module)
1369
 
    {
1370
 
      ath_mutex_lock (&digests_registered_lock);
1371
 
      _gcry_module_release (module);
1372
 
      ath_mutex_unlock (&digests_registered_lock);
1373
 
    }
1374
 
  return gpg_error (ec);
1375
 
}