/* md.c  -  message digest dispatcher
 * Copyright (C) 1998, 1999, 2002, 2003, 2006,
 *               2008 Free Software Foundation, Inc.
 *
 * This file is part of Libgcrypt.
 *
 * Libgcrypt is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser general Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * Libgcrypt is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include "g10lib.h"
#include "cipher.h"
#include "ath.h"

#include "rmd.h"

/* A dummy extraspec so that we do not need to tests the extraspec
   field from the module specification against NULL and instead
   directly test the respective fields of extraspecs.  */
static md_extra_spec_t dummy_extra_spec;


/* This is the list of the digest implementations included in
   libgcrypt.  */
static struct digest_table_entry
{
  gcry_md_spec_t *digest;
  md_extra_spec_t *extraspec;
  unsigned int algorithm;
  int fips_allowed; 
} digest_table[] =
  {
#if USE_CRC    
    /* We allow the CRC algorithms even in FIPS mode because they are
       actually no cryptographic primitives.  */
    { &_gcry_digest_spec_crc32,   
      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
    { &_gcry_digest_spec_crc32_rfc1510,  
      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
    { &_gcry_digest_spec_crc24_rfc2440,
      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
#endif
#if USE_MD4
    { &_gcry_digest_spec_md4,
      &dummy_extra_spec,                 GCRY_MD_MD4 },
#endif
#if USE_MD5
    { &_gcry_digest_spec_md5,
      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
#endif
#if USE_RMD160
    { &_gcry_digest_spec_rmd160,
      &dummy_extra_spec,                 GCRY_MD_RMD160 },
#endif
#if USE_SHA1
    { &_gcry_digest_spec_sha1, 
      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
#endif
#if USE_SHA256
    { &_gcry_digest_spec_sha256,
      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
    { &_gcry_digest_spec_sha224,
      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
#endif
#if USE_SHA512
    { &_gcry_digest_spec_sha512,
      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
    { &_gcry_digest_spec_sha384,
      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
#endif
#if USE_TIGER
    { &_gcry_digest_spec_tiger,
      &dummy_extra_spec,                 GCRY_MD_TIGER },
    { &_gcry_digest_spec_tiger1,
      &dummy_extra_spec,                 GCRY_MD_TIGER1 },
    { &_gcry_digest_spec_tiger2,
      &dummy_extra_spec,                 GCRY_MD_TIGER2 },
#endif
#if USE_WHIRLPOOL
    { &_gcry_digest_spec_whirlpool,
      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
#endif
    { NULL },
  };

/* List of registered digests.  */
static gcry_module_t digests_registered;

/* This is the lock protecting DIGESTS_REGISTERED.  */
static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;

/* Flag to check wether the default ciphers have already been
   registered.  */
static int default_digests_registered;

typedef struct gcry_md_list
{
  gcry_md_spec_t *digest;
  gcry_module_t module;
  struct gcry_md_list *next;
  size_t actual_struct_size;     /* Allocated size of this structure. */
  PROPERLY_ALIGNED_TYPE context;
} GcryDigestEntry;

/* this structure is put right after the gcry_md_hd_t buffer, so that
 * only one memory block is needed. */
struct gcry_md_context
{
  int  magic;
  size_t actual_handle_size;     /* Allocated size of this handle. */
  int  secure;
  FILE  *debug;
  int finalized;
  GcryDigestEntry *list;
  byte *macpads;
  int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
};


#define CTX_MAGIC_NORMAL 0x11071961
#define CTX_MAGIC_SECURE 0x16917011

/* Convenient macro for registering the default digests.  */
#define REGISTER_DEFAULT_DIGESTS                   \
  do                                               \
    {                                              \
      ath_mutex_lock (&digests_registered_lock);   \
      if (! default_digests_registered)            \
        {                                          \
          md_register_default ();                  \
          default_digests_registered = 1;          \
        }                                          \
      ath_mutex_unlock (&digests_registered_lock); \
    }                                              \
  while (0)


static const char * digest_algo_to_string( int algo );
static gcry_err_code_t check_digest_algo (int algo);
static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
                                int secure, int hmac);
static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
static void md_close (gcry_md_hd_t a);
static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
static void md_final(gcry_md_hd_t a);
static byte *md_read( gcry_md_hd_t a, int algo );
static int md_get_algo( gcry_md_hd_t a );
static int md_digest_length( int algo );
static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
static void md_stop_debug ( gcry_md_hd_t a );




/* Internal function.  Register all the ciphers included in
   CIPHER_TABLE.  Returns zero on success or an error code.  */
static void
md_register_default (void)
{
  gcry_err_code_t err = 0;
  int i;
  
  for (i = 0; !err && digest_table[i].digest; i++)
    {
      if ( fips_mode ())
        {
          if (!digest_table[i].fips_allowed)
            continue;
          if (digest_table[i].algorithm == GCRY_MD_MD5
              && _gcry_enforced_fips_mode () )
            continue;  /* Do not register in enforced fips mode.  */
        }

      err = _gcry_module_add (&digests_registered,
                              digest_table[i].algorithm,
                              (void *) digest_table[i].digest,
                              (void *) digest_table[i].extraspec,
                              NULL);
    }

  if (err)
    BUG ();
}

/* Internal callback function.  */
static int
gcry_md_lookup_func_name (void *spec, void *data)
{
  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
  char *name = (char *) data;

  return (! stricmp (digest->name, name));
}

/* Internal callback function.  Used via _gcry_module_lookup.  */
static int
gcry_md_lookup_func_oid (void *spec, void *data)
{
  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
  char *oid = (char *) data;
  gcry_md_oid_spec_t *oid_specs = digest->oids;
  int ret = 0, i;

  if (oid_specs)
    {
      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
        if (! stricmp (oid, oid_specs[i].oidstring))
          ret = 1;
    }

  return ret;
}

/* Internal function.  Lookup a digest entry by it's name.  */
static gcry_module_t 
gcry_md_lookup_name (const char *name)
{
  gcry_module_t digest;

  digest = _gcry_module_lookup (digests_registered, (void *) name,
				gcry_md_lookup_func_name);

  return digest;
}

/* Internal function.  Lookup a cipher entry by it's oid.  */
static gcry_module_t
gcry_md_lookup_oid (const char *oid)
{
  gcry_module_t digest;

  digest = _gcry_module_lookup (digests_registered, (void *) oid,
				gcry_md_lookup_func_oid);

  return digest;
}

/* Register a new digest module whose specification can be found in
   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
   and a pointer representhing this module is stored in MODULE.  */
gcry_error_t
_gcry_md_register (gcry_md_spec_t *digest,
                   md_extra_spec_t *extraspec,
                   unsigned int *algorithm_id,
                   gcry_module_t *module)
{
  gcry_err_code_t err = 0;
  gcry_module_t mod;

  /* We do not support module loading in fips mode.  */
  if (fips_mode ())
    return gpg_error (GPG_ERR_NOT_SUPPORTED);

  ath_mutex_lock (&digests_registered_lock);
  err = _gcry_module_add (&digests_registered, 0,
			  (void *) digest, 
			  (void *)(extraspec? extraspec : &dummy_extra_spec), 
                          &mod);
  ath_mutex_unlock (&digests_registered_lock);
  
  if (! err)
    {
      *module = mod;
      *algorithm_id = mod->mod_id;
    }

  return gcry_error (err);
}

/* Unregister the digest identified by ID, which must have been
   registered with gcry_digest_register.  */
void
gcry_md_unregister (gcry_module_t module)
{
  ath_mutex_lock (&digests_registered_lock);
  _gcry_module_release (module);
  ath_mutex_unlock (&digests_registered_lock);
}


static int 
search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
{
  gcry_module_t module;
  int ret = 0;

  if (oid && ((! strncmp (oid, "oid.", 4))
	      || (! strncmp (oid, "OID.", 4))))
    oid += 4;

  module = gcry_md_lookup_oid (oid);
  if (module)
    {
      gcry_md_spec_t *digest = module->spec;
      int i;

      for (i = 0; digest->oids[i].oidstring && !ret; i++)
	if (! stricmp (oid, digest->oids[i].oidstring))
	  {
	    if (algorithm)
	      *algorithm = module->mod_id;
	    if (oid_spec)
	      *oid_spec = digest->oids[i];
	    ret = 1;
	  }
      _gcry_module_release (module);
    }

  return ret;
}

/****************
 * Map a string to the digest algo
 */
int
gcry_md_map_name (const char *string)
{
  gcry_module_t digest;
  int ret, algorithm = 0;

  if (! string)
    return 0;

  REGISTER_DEFAULT_DIGESTS;

  /* If the string starts with a digit (optionally prefixed with
     either "OID." or "oid."), we first look into our table of ASN.1
     object identifiers to figure out the algorithm */

  ath_mutex_lock (&digests_registered_lock);

  ret = search_oid (string, &algorithm, NULL);
  if (! ret)
    {
      /* Not found, search a matching digest name.  */
      digest = gcry_md_lookup_name (string);
      if (digest)
	{
	  algorithm = digest->mod_id;
	  _gcry_module_release (digest);
	}
    }
  ath_mutex_unlock (&digests_registered_lock);

  return algorithm;
}


/****************
 * Map a digest algo to a string
 */
static const char *
digest_algo_to_string (int algorithm)
{
  const char *name = NULL;
  gcry_module_t digest;

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
  if (digest)
    {
      name = ((gcry_md_spec_t *) digest->spec)->name;
      _gcry_module_release (digest);
    }
  ath_mutex_unlock (&digests_registered_lock);

  return name;
}

/****************
 * This function simply returns the name of the algorithm or some constant
 * string when there is no algo.  It will never return NULL.
 * Use	the macro gcry_md_test_algo() to check whether the algorithm
 * is valid.
 */
const char *
gcry_md_algo_name (int algorithm)
{
  const char *s = digest_algo_to_string (algorithm);
  return s ? s : "?";
}


static gcry_err_code_t
check_digest_algo (int algorithm)
{
  gcry_err_code_t rc = 0;
  gcry_module_t digest;

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
  if (digest)
    _gcry_module_release (digest);
  else
    rc = GPG_ERR_DIGEST_ALGO;
  ath_mutex_unlock (&digests_registered_lock);

  return rc;
}



/****************
 * Open a message digest handle for use with algorithm ALGO.
 * More algorithms may be added by md_enable(). The initial algorithm
 * may be 0.
 */
static gcry_err_code_t
md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
  int bufsize = secure ? 512 : 1024;
  struct gcry_md_context *ctx;
  gcry_md_hd_t hd;
  size_t n;

  /* Allocate a memory area to hold the caller visible buffer with it's
   * control information and the data required by this module. Set the
   * context pointer at the beginning to this area.
   * We have to use this strange scheme because we want to hide the
   * internal data but have a variable sized buffer.
   *
   *	+---+------+---........------+-------------+
   *	!ctx! bctl !  buffer	     ! private	   !
   *	+---+------+---........------+-------------+
   *	  !			      ^
   *	  !---------------------------!
   *
   * We have to make sure that private is well aligned.
   */
  n = sizeof (struct gcry_md_handle) + bufsize;
  n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
       / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);

  /* Allocate and set the Context pointer to the private data */
  if (secure)
    hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
  else
    hd = gcry_malloc (n + sizeof (struct gcry_md_context));

  if (! hd)
    err = gpg_err_code_from_errno (errno);

  if (! err)
    {
      hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
      /* Setup the globally visible data (bctl in the diagram).*/
      hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
      hd->bufpos = 0;

      /* Initialize the private data. */
      memset (hd->ctx, 0, sizeof *hd->ctx);
      ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
      ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
      ctx->secure = secure;

      if (hmac)
	{
	  switch (algo)
            {
              case GCRY_MD_SHA384:
              case GCRY_MD_SHA512:
                ctx->macpads_Bsize = 128;
                break;
              default:
                ctx->macpads_Bsize = 64;
                break;
            }
          ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
	  if (!ctx->macpads)
	    {
	      err = gpg_err_code_from_errno (errno);
	      md_close (hd);
	    }
	}
    }

  if (! err)
    {
      /* Hmmm, should we really do that? - yes [-wk] */
      _gcry_fast_random_poll ();

      if (algo)
	{
	  err = md_enable (hd, algo);
	  if (err)
	    md_close (hd);
	}
    }

  if (! err)
    *h = hd;

  return err;
}

/* Create a message digest object for algorithm ALGO.  FLAGS may be
   given as an bitwise OR of the gcry_md_flags values.  ALGO may be
   given as 0 if the algorithms to be used are later set using
   gcry_md_enable. H is guaranteed to be a valid handle or NULL on
   error.  */
gcry_error_t
gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
  gcry_md_hd_t hd;

  if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
    err = GPG_ERR_INV_ARG;
  else
    {
      err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
		     (flags & GCRY_MD_FLAG_HMAC));
    }

  *h = err? NULL : hd;
  return gcry_error (err);
}



static gcry_err_code_t
md_enable (gcry_md_hd_t hd, int algorithm)
{
  struct gcry_md_context *h = hd->ctx;
  gcry_md_spec_t *digest = NULL;
  GcryDigestEntry *entry;
  gcry_module_t module;
  gcry_err_code_t err = 0;

  for (entry = h->list; entry; entry = entry->next)
    if (entry->module->mod_id == algorithm)
      return err; /* already enabled */

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  module = _gcry_module_lookup_id (digests_registered, algorithm);
  ath_mutex_unlock (&digests_registered_lock);
  if (! module)
    {
      log_debug ("md_enable: algorithm %d not available\n", algorithm);
      err = GPG_ERR_DIGEST_ALGO;
    }
 else
    digest = (gcry_md_spec_t *) module->spec;

  
  if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
    {
      _gcry_inactivate_fips_mode ("MD5 used");
      if (_gcry_enforced_fips_mode () )
        {
          /* We should never get to here because we do not register
             MD5 in enforced fips mode. But better throw an error.  */
          err = GPG_ERR_DIGEST_ALGO;
        }
    }
  
  if (!err)
    {
      size_t size = (sizeof (*entry)
                     + digest->contextsize
                     - sizeof (entry->context));

      /* And allocate a new list entry. */
      if (h->secure)
	entry = gcry_malloc_secure (size);
      else
	entry = gcry_malloc (size);

      if (! entry)
	err = gpg_err_code_from_errno (errno);
      else
	{
	  entry->digest = digest;
	  entry->module = module;
	  entry->next = h->list;
          entry->actual_struct_size = size;
	  h->list = entry;

	  /* And init this instance. */
	  entry->digest->init (&entry->context.c);
	}
    }

  if (err)
    {
      if (module)
	{
	   ath_mutex_lock (&digests_registered_lock);
	   _gcry_module_release (module);
	   ath_mutex_unlock (&digests_registered_lock);
	}
    }

  return err;
}


gcry_error_t
gcry_md_enable (gcry_md_hd_t hd, int algorithm)
{
  return gcry_error (md_enable (hd, algorithm));
}

static gcry_err_code_t
md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;
  struct gcry_md_context *a = ahd->ctx;
  struct gcry_md_context *b;
  GcryDigestEntry *ar, *br;
  gcry_md_hd_t bhd;
  size_t n;
  
  if (ahd->bufpos)
    md_write (ahd, NULL, 0);

  n = (char *) ahd->ctx - (char *) ahd;
  if (a->secure)
    bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
  else
    bhd = gcry_malloc (n + sizeof (struct gcry_md_context));

  if (! bhd)
    err = gpg_err_code_from_errno (errno);

  if (! err)
    {
      bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
      /* No need to copy the buffer due to the write above. */
      gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
      bhd->bufsize = ahd->bufsize;
      bhd->bufpos = 0;
      gcry_assert (! ahd->bufpos);
      memcpy (b, a, sizeof *a);
      b->list = NULL;
      b->debug = NULL;
      if (a->macpads)
	{
	  b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
	  if (! b->macpads)
	    {
	      err = gpg_err_code_from_errno (errno);
	      md_close (bhd);
	    }
	  else
	    memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
	}
    }

  /* Copy the complete list of algorithms.  The copied list is
     reversed, but that doesn't matter. */
  if (!err)
    {
      for (ar = a->list; ar; ar = ar->next)
        {
          if (a->secure)
            br = gcry_malloc_secure (sizeof *br
                                     + ar->digest->contextsize
                                     - sizeof(ar->context));
          else
            br = gcry_malloc (sizeof *br
                              + ar->digest->contextsize
                              - sizeof (ar->context));
          if (!br)
            {
	      err = gpg_err_code_from_errno (errno);
              md_close (bhd);
              break;
            }

          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
                           - sizeof (ar->context)));
          br->next = b->list;
          b->list = br;
          
          /* Add a reference to the module.  */
          ath_mutex_lock (&digests_registered_lock);
          _gcry_module_use (br->module);
          ath_mutex_unlock (&digests_registered_lock);
        }
    }

  if (a->debug && !err)
    md_start_debug (bhd, "unknown");

  if (!err)
    *b_hd = bhd;

  return err;
}

gcry_error_t
gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
{
  gcry_err_code_t err;

  err = md_copy (hd, handle);
  if (err)
    *handle = NULL;
  return gcry_error (err);
}

/*
 * Reset all contexts and discard any buffered stuff.  This may be used
 * instead of a md_close(); md_open().
 */
void
gcry_md_reset (gcry_md_hd_t a)
{
  GcryDigestEntry *r;

  /* Note: We allow this even in fips non operational mode.  */

  a->bufpos = a->ctx->finalized = 0;

  for (r = a->ctx->list; r; r = r->next)
    {
      memset (r->context.c, 0, r->digest->contextsize);
      (*r->digest->init) (&r->context.c);
    }
  if (a->ctx->macpads)
    md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
}

static void
md_close (gcry_md_hd_t a)
{
  GcryDigestEntry *r, *r2;

  if (! a)
    return;
  if (a->ctx->debug)
    md_stop_debug (a);
  for (r = a->ctx->list; r; r = r2)
    {
      r2 = r->next;
      ath_mutex_lock (&digests_registered_lock);
      _gcry_module_release (r->module);
      ath_mutex_unlock (&digests_registered_lock);
      wipememory (r, r->actual_struct_size);
      gcry_free (r);
    }

  if (a->ctx->macpads)
    {
      wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
      gcry_free(a->ctx->macpads);
    }

  wipememory (a, a->ctx->actual_handle_size);
  gcry_free(a);
}

void
gcry_md_close (gcry_md_hd_t hd)
{
  /* Note: We allow this even in fips non operational mode.  */
  md_close (hd);
}

static void
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
{
  GcryDigestEntry *r;
  
  if (a->ctx->debug)
    {
      if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
	BUG();
      if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
	BUG();
    }

  for (r = a->ctx->list; r; r = r->next)
    {
      if (a->bufpos)
	(*r->digest->write) (&r->context.c, a->buf, a->bufpos);
      (*r->digest->write) (&r->context.c, inbuf, inlen);
    }
  a->bufpos = 0;
}

void
gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
{
  md_write (hd, inbuf, inlen);
}

static void
md_final (gcry_md_hd_t a)
{
  GcryDigestEntry *r;

  if (a->ctx->finalized)
    return;

  if (a->bufpos)
    md_write (a, NULL, 0);

  for (r = a->ctx->list; r; r = r->next)
    (*r->digest->final) (&r->context.c);

  a->ctx->finalized = 1;

  if (a->ctx->macpads)
    {
      /* Finish the hmac. */
      int algo = md_get_algo (a);
      byte *p = md_read (a, algo);
      size_t dlen = md_digest_length (algo);
      gcry_md_hd_t om;
      gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);

      if (err)
	_gcry_fatal_error (err, NULL);
      md_write (om, 
                (a->ctx->macpads)+(a->ctx->macpads_Bsize), 
                a->ctx->macpads_Bsize);
      md_write (om, p, dlen);
      md_final (om);
      /* Replace our digest with the mac (they have the same size). */
      memcpy (p, md_read (om, algo), dlen);
      md_close (om);
    }
}

static gcry_err_code_t
prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
{
  int i;
  int algo = md_get_algo (hd);
  unsigned char *helpkey = NULL;
  unsigned char *ipad, *opad;

  if (!algo)
    return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled.  */

  if ( keylen > hd->ctx->macpads_Bsize ) 
    {
      helpkey = gcry_malloc_secure (md_digest_length (algo));
      if (!helpkey)
        return gpg_err_code_from_errno (errno);
      gcry_md_hash_buffer (algo, helpkey, key, keylen);
      key = helpkey;
      keylen = md_digest_length (algo);
      gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
    }

  memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
  ipad = hd->ctx->macpads;
  opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
  memcpy ( ipad, key, keylen );
  memcpy ( opad, key, keylen );
  for (i=0; i < hd->ctx->macpads_Bsize; i++ ) 
    {
      ipad[i] ^= 0x36;
      opad[i] ^= 0x5c;
    }
  gcry_free (helpkey);

  return GPG_ERR_NO_ERROR;
}

gcry_error_t
gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
{
  gcry_err_code_t rc = 0;
  
  switch (cmd)
    {
    case GCRYCTL_FINALIZE:
      md_final (hd);
      break;
    case GCRYCTL_SET_KEY:
      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
      break;
    case GCRYCTL_START_DUMP:
      md_start_debug (hd, buffer);
      break;
    case GCRYCTL_STOP_DUMP:
      md_stop_debug ( hd );
      break;
    default:
      rc = GPG_ERR_INV_OP;
    }
  return gcry_error (rc);
}

gcry_error_t
gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
{
  gcry_err_code_t rc = GPG_ERR_NO_ERROR;

  if (!hd->ctx->macpads)
    rc = GPG_ERR_CONFLICT;
  else
    {
      rc = prepare_macpads (hd, key, keylen);
      if (! rc)
	gcry_md_reset (hd);
    }

  return gcry_error (rc);
}

/* The new debug interface.  If SUFFIX is a string it creates an debug
   file for the context HD.  IF suffix is NULL, the file is closed and
   debugging is stopped.  */
void
gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
{
  if (suffix)
    md_start_debug (hd, suffix);
  else
    md_stop_debug (hd);
}



/****************
 * if ALGO is null get the digest for the used algo (which should be only one)
 */
static byte *
md_read( gcry_md_hd_t a, int algo )
{
  GcryDigestEntry *r = a->ctx->list;

  if (! algo)
    {
      /* Return the first algorithm.  */
      if (r)
        {
          if (r->next)
            log_debug ("more than one algorithm in md_read(0)\n");
          return r->digest->read( &r->context.c );
        }
    }
  else
    {
      for (r = a->ctx->list; r; r = r->next)
	if (r->module->mod_id == algo)
	  return r->digest->read (&r->context.c);
    }
  BUG();
  return NULL;
}

/*
 * Read out the complete digest, this function implictly finalizes
 * the hash.
 */
byte *
gcry_md_read (gcry_md_hd_t hd, int algo)
{
  /* This function is expected to always return a digest, thus we
     can't return an error which we actually should do in
     non-operational state.  */
  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
  return md_read (hd, algo);
}


/*
 * Read out an intermediate digest.  Not yet functional.
 */
gcry_err_code_t
gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
{
  (void)hd;
  (void)algo;
  (void)buffer;
  (void)buflen;

  /*md_digest ... */
  fips_signal_error ("unimplemented function called");
  return GPG_ERR_INTERNAL;
}


/*
 * Shortcut function to hash a buffer with a given algo. The only
 * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
 * supplied digest buffer must be large enough to store the resulting
 * hash.  No error is returned, the function will abort on an invalid
 * algo.  DISABLED_ALGOS are ignored here.  */
void
gcry_md_hash_buffer (int algo, void *digest,
                     const void *buffer, size_t length)
{
  if (algo == GCRY_MD_SHA1)
    _gcry_sha1_hash_buffer (digest, buffer, length);
  else if (algo == GCRY_MD_RMD160 && !fips_mode () )
    _gcry_rmd160_hash_buffer (digest, buffer, length);
  else
    {
      /* For the others we do not have a fast function, so we use the
	 normal functions. */
      gcry_md_hd_t h;
      gpg_err_code_t err;

      if (algo == GCRY_MD_MD5 && fips_mode ())
        {
          _gcry_inactivate_fips_mode ("MD5 used");
          if (_gcry_enforced_fips_mode () )
            {
              /* We should never get to here because we do not register
                 MD5 in enforced fips mode.  */
              _gcry_fips_noreturn ();
            }
        }

      err = md_open (&h, algo, 0, 0);
      if (err)
	log_bug ("gcry_md_open failed for algo %d: %s",
                 algo, gpg_strerror (gcry_error(err)));
      md_write (h, (byte *) buffer, length);
      md_final (h);
      memcpy (digest, md_read (h, algo), md_digest_length (algo));
      md_close (h);
    }
}

static int
md_get_algo (gcry_md_hd_t a)
{
  GcryDigestEntry *r = a->ctx->list;

  if (r && r->next)
    {
      fips_signal_error ("possible usage error");
      log_error ("WARNING: more than one algorithm in md_get_algo()\n");
    }
  return r ? r->module->mod_id : 0;
}

int
gcry_md_get_algo (gcry_md_hd_t hd)
{
  return md_get_algo (hd);
}


/****************
 * Return the length of the digest
 */
static int
md_digest_length (int algorithm)
{
  gcry_module_t digest;
  int mdlen = 0;

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
  if (digest)
    {
      mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
      _gcry_module_release (digest);
    }
  ath_mutex_unlock (&digests_registered_lock);

  return mdlen;
}

/****************
 * Return the length of the digest in bytes.
 * This function will return 0 in case of errors.
 */
unsigned int
gcry_md_get_algo_dlen (int algorithm)
{
  return md_digest_length (algorithm);
}


/* Hmmm: add a mode to enumerate the OIDs
 *	to make g10/sig-check.c more portable */
static const byte *
md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
{
  const byte *asnoid = NULL;
  gcry_module_t digest;

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  digest = _gcry_module_lookup_id (digests_registered, algorithm);
  if (digest)
    {
      if (asnlen)
	*asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
      if (mdlen)
	*mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
      _gcry_module_release (digest);
    }
  else
    log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
  ath_mutex_unlock (&digests_registered_lock);

  return asnoid;
}



/****************
 * Return information about the given cipher algorithm
 * WHAT select the kind of information returned:
 *  GCRYCTL_TEST_ALGO:
 *	Returns 0 when the specified algorithm is available for use.
 *	buffer and nbytes must be zero.
 *  GCRYCTL_GET_ASNOID:
 *	Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
 *	the required length is returned.
 *
 * Note:  Because this function is in most cases used to return an
 * integer value, we can make it easier for the caller to just look at
 * the return value.  The caller will in all cases consult the value
 * and thereby detecting whether a error occured or not (i.e. while checking
 * the block size)
 */
gcry_error_t
gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;

  switch (what)
    {
    case GCRYCTL_TEST_ALGO:
      if (buffer || nbytes)
	err = GPG_ERR_INV_ARG;
      else
	err = check_digest_algo (algo);
      break;

    case GCRYCTL_GET_ASNOID:
      /* We need to check that the algo is available because
         md_asn_oid would otherwise raise an assertion. */
      err = check_digest_algo (algo);
      if (!err)
        {
          const char unsigned *asn;
          size_t asnlen;
          
          asn = md_asn_oid (algo, &asnlen, NULL);
          if (buffer && (*nbytes >= asnlen))
	  {
	    memcpy (buffer, asn, asnlen);
	    *nbytes = asnlen;
	  }
          else if (!buffer && nbytes)
            *nbytes = asnlen;
          else
            {
              if (buffer)
                err = GPG_ERR_TOO_SHORT;
              else
                err = GPG_ERR_INV_ARG;
            }
        }
      break;

  default:
    err = GPG_ERR_INV_OP;
  }

  return gcry_error (err);
}


static void
md_start_debug ( gcry_md_hd_t md, const char *suffix )
{
  static int idx=0;
  char buf[50];

  if (fips_mode ())
    return;
  
  if ( md->ctx->debug )
    {
      log_debug("Oops: md debug already started\n");
      return;
    }
  idx++;
  snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
  md->ctx->debug = fopen(buf, "w");
  if ( !md->ctx->debug )
    log_debug("md debug: can't open %s\n", buf );
}

static void
md_stop_debug( gcry_md_hd_t md )
{
  if ( md->ctx->debug )
    {
      if ( md->bufpos )
        md_write ( md, NULL, 0 );
      fclose (md->ctx->debug);
      md->ctx->debug = NULL;
    }

#ifdef HAVE_U64_TYPEDEF
  {  /* a kludge to pull in the __muldi3 for Solaris */
    volatile u32 a = (u32)(ulong)md;
    volatile u64 b = 42;
    volatile u64 c;
    c = a * b;
  }
#endif
}



/*
 * Return information about the digest handle.
 *  GCRYCTL_IS_SECURE:
 *	Returns 1 when the handle works on secured memory
 *	otherwise 0 is returned.  There is no error return.
 *  GCRYCTL_IS_ALGO_ENABLED:
 *     Returns 1 if the algo is enabled for that handle.
 *     The algo must be passed as the address of an int.
 */
gcry_error_t
gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;

  switch (cmd)
    {
    case GCRYCTL_IS_SECURE:
      *nbytes = h->ctx->secure;
      break;

    case GCRYCTL_IS_ALGO_ENABLED:
      {
	GcryDigestEntry *r;
	int algo;

	if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
	  err = GPG_ERR_INV_ARG;
	else
	  {
	    algo = *(int*)buffer;
	    
	    *nbytes = 0;
	    for(r=h->ctx->list; r; r = r->next ) {
	      if (r->module->mod_id == algo)
		{
		  *nbytes = 1;
		  break;
		}
	    }
	  }
	break;
      }

  default:
    err = GPG_ERR_INV_OP;
  }

  return gcry_error (err);
}


/* Explicitly initialize this module.  */
gcry_err_code_t
_gcry_md_init (void)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;

  REGISTER_DEFAULT_DIGESTS;

  return err;
}


int
gcry_md_is_secure (gcry_md_hd_t a) 
{
  size_t value;

  if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
    value = 1; /* It seems to be better to assume secure memory on
                  error. */
  return value;
}


int
gcry_md_is_enabled (gcry_md_hd_t a, int algo) 
{
  size_t value;

  value = sizeof algo;
  if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
    value = 0;
  return value;
}

/* Get a list consisting of the IDs of the loaded message digest
   modules.  If LIST is zero, write the number of loaded message
   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
   of according size.  In case there are less message digest modules
   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
   number.  */
gcry_error_t
gcry_md_list (int *list, int *list_length)
{
  gcry_err_code_t err = GPG_ERR_NO_ERROR;

  ath_mutex_lock (&digests_registered_lock);
  err = _gcry_module_list (digests_registered, list, list_length);
  ath_mutex_unlock (&digests_registered_lock);

  return err;
}


/* Run the selftests for digest algorithm ALGO with optional reporting
   function REPORT.  */
gpg_error_t
_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
{
  gcry_module_t module = NULL;
  cipher_extra_spec_t *extraspec = NULL;
  gcry_err_code_t ec = 0;

  REGISTER_DEFAULT_DIGESTS;

  ath_mutex_lock (&digests_registered_lock);
  module = _gcry_module_lookup_id (digests_registered, algo);
  if (module && !(module->flags & FLAG_MODULE_DISABLED))
    extraspec = module->extraspec;
  ath_mutex_unlock (&digests_registered_lock);
  if (extraspec && extraspec->selftest)
    ec = extraspec->selftest (algo, extended, report);
  else
    {
      ec = GPG_ERR_DIGEST_ALGO;
      if (report)
        report ("digest", algo, "module", 
                module && !(module->flags & FLAG_MODULE_DISABLED)?
                "no selftest available" :
                module? "algorithm disabled" : "algorithm not found");
    }

  if (module)
    {
      ath_mutex_lock (&digests_registered_lock);
      _gcry_module_release (module);
      ath_mutex_unlock (&digests_registered_lock);
    }
  return gpg_error (ec);
}
