~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, 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
 
}