~darkmuggle-deactivatedaccount/ubuntu/quantal/grub2/fix-872244

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt/cipher/md.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

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
}