md: Simplify the message digest dispatcher md.c.
authorWerner Koch <wk@gnupg.org>
Wed, 2 Oct 2013 11:39:47 +0000 (13:39 +0200)
committerWerner Koch <wk@gnupg.org>
Wed, 2 Oct 2013 11:39:47 +0000 (13:39 +0200)
* src/gcrypt-module.h (gcry_md_spec_t):  Move to ...
* src/cipher-proto.h: here.  Merge with md_extra_spec_t.  Add fields
ALGO and FLAGS.  Set these fields in all digest modules.
* cipher/md.c: Change most code to replace the former module
system by a simpler system to gain information about the algorithms.

Signed-off-by: Werner Koch <wk@gnupg.org>
15 files changed:
cipher/crc.c
cipher/gostr3411-94.c
cipher/md.c
cipher/md4.c
cipher/md5.c
cipher/rmd160.c
cipher/sha1.c
cipher/sha256.c
cipher/sha512.c
cipher/stribog.c
cipher/tiger.c
cipher/whirlpool.c
src/cipher-proto.h
src/cipher.h
src/gcrypt-module.h

index 9e406f1..4f72ffb 100644 (file)
@@ -272,8 +272,12 @@ crc24rfc2440_final (void *context)
   ctx->buf[2] = (ctx->CRC      ) & 0xFF;
 }
 
+/* We allow the CRC algorithms even in FIPS mode because they are
+   actually no cryptographic primitives.  */
+
 gcry_md_spec_t _gcry_digest_spec_crc32 =
   {
+    GCRY_MD_CRC32, {0, 1},
     "CRC32", NULL, 0, NULL, 4,
     crc32_init, crc32_write, crc32_final, crc32_read,
     sizeof (CRC_CONTEXT)
@@ -281,6 +285,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32 =
 
 gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
   {
+    GCRY_MD_CRC32_RFC1510, {0, 1},
     "CRC32RFC1510", NULL, 0, NULL, 4,
     crc32rfc1510_init, crc32_write,
     crc32rfc1510_final, crc32_read,
@@ -289,6 +294,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
 
 gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
   {
+    GCRY_MD_CRC24_RFC2440, {0, 1},
     "CRC24RFC2440", NULL, 0, NULL, 3,
     crc24rfc2440_init, crc24rfc2440_write,
     crc24rfc2440_final, crc32_read,
index 368fc01..1267216 100644 (file)
@@ -277,6 +277,7 @@ gost3411_read (void *context)
 }
 gcry_md_spec_t _gcry_digest_spec_gost3411_94 =
   {
+    GCRY_MD_GOSTR3411_94, {0, 0},
     "GOSTR3411_94", NULL, 0, NULL, 32,
     gost3411_init, _gcry_md_block_write, gost3411_final, gost3411_read,
     sizeof (GOSTR3411_CONTEXT)
index c65eb70..e3cc6c6 100644 (file)
 
 #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[] =
+static gcry_md_spec_t *digest_list[] =
   {
 #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 },
+     &_gcry_digest_spec_crc32,
+     &_gcry_digest_spec_crc32_rfc1510,
+     &_gcry_digest_spec_crc24_rfc2440,
 #endif
-#ifdef USE_GOST_R_3411_94
-    { &_gcry_digest_spec_gost3411_94,
-      &dummy_extra_spec,                 GCRY_MD_GOSTR3411_94 },
-#endif
-#ifdef USE_GOST_R_3411_12
-    { &_gcry_digest_spec_stribog_256,
-      &dummy_extra_spec,                 GCRY_MD_STRIBOG256 },
-    { &_gcry_digest_spec_stribog_512,
-      &dummy_extra_spec,                 GCRY_MD_STRIBOG512 },
+#if USE_SHA1
+     &_gcry_digest_spec_sha1,
 #endif
-#if USE_MD4
-    { &_gcry_digest_spec_md4,
-      &dummy_extra_spec,                 GCRY_MD_MD4 },
+#if USE_SHA256
+     &_gcry_digest_spec_sha256,
+     &_gcry_digest_spec_sha224,
 #endif
-#if USE_MD5
-    { &_gcry_digest_spec_md5,
-      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
+#if USE_SHA512
+     &_gcry_digest_spec_sha512,
+     &_gcry_digest_spec_sha384,
 #endif
-#if USE_RMD160
-    { &_gcry_digest_spec_rmd160,
-      &dummy_extra_spec,                 GCRY_MD_RMD160 },
+#ifdef USE_GOST_R_3411_94
+     &_gcry_digest_spec_gost3411_94,
 #endif
-#if USE_SHA1
-    { &_gcry_digest_spec_sha1,
-      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
+#ifdef USE_GOST_R_3411_12
+     &_gcry_digest_spec_stribog_256,
+     &_gcry_digest_spec_stribog_512,
 #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 },
+#if USE_WHIRLPOOL
+     &_gcry_digest_spec_whirlpool,
 #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 },
+#if USE_RMD160
+     &_gcry_digest_spec_rmd160,
 #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 },
+     &_gcry_digest_spec_tiger,
+     &_gcry_digest_spec_tiger1,
+     &_gcry_digest_spec_tiger2,
 #endif
-#if USE_WHIRLPOOL
-    { &_gcry_digest_spec_whirlpool,
-      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
+#if USE_MD5
+     &_gcry_digest_spec_md5,
+#endif
+#if USE_MD4
+     &_gcry_digest_spec_md4,
 #endif
-    { NULL },
+    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;
-
-/* Flag to check whether 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;
+  gcry_md_spec_t *spec;
   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
+/* This structure is put right after the gcry_md_hd_t buffer, so that
  * only one memory block is needed. */
 struct gcry_md_context
 {
@@ -147,248 +106,135 @@ struct gcry_md_context
 #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 );
 
 
+\f
+static int
+map_algo (int algo)
+{
+  return algo;
+}
 
 
-/* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  Returns zero on success or an error code.  */
-static void
-md_register_default (void)
+/* Return the spec structure for the hash algorithm ALGO.  For an
+   unknown algorithm NULL is returned.  */
+static gcry_md_spec_t *
+spec_from_algo (int algo)
 {
-  gcry_err_code_t err = 0;
-  int i;
+  int idx;
+  gcry_md_spec_t *spec;
 
-  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.  */
-        }
+  algo = map_algo (algo);
 
-      err = _gcry_module_add (&digests_registered,
-                              digest_table[i].algorithm,
-                              (void *) digest_table[i].digest,
-                              (void *) digest_table[i].extraspec,
-                              NULL);
-    }
-
-  if (err)
-    BUG ();
+  for (idx = 0; (spec = digest_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
 }
 
-/* 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)
+/* Lookup a hash's spec by its name.  */
+static gcry_md_spec_t *
+spec_from_name (const char *name)
 {
-  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;
+  gcry_md_spec_t *spec;
+  int idx;
 
-  if (oid_specs)
+  for (idx=0; (spec = digest_list[idx]); idx++)
     {
-      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
-        if (! stricmp (oid, oid_specs[i].oidstring))
-          ret = 1;
+      if (!stricmp (name, spec->name))
+        return spec;
     }
 
-  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;
+  return NULL;
 }
 
-/* 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)
+/* Lookup a hash's spec by its OID.  */
+static gcry_md_spec_t *
+spec_from_oid (const char *oid)
 {
-  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);
+  gcry_md_spec_t *spec;
+  gcry_md_oid_spec_t *oid_specs;
+  int idx, j;
 
-  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)
+  for (idx=0; (spec = digest_list[idx]); idx++)
     {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
+      oid_specs = spec->oids;
+      if (oid_specs)
+        {
+          for (j = 0; oid_specs[j].oidstring; j++)
+            if (!stricmp (oid, oid_specs[j].oidstring))
+              return spec;
+        }
     }
 
-  return gcry_error (err);
+  return NULL;
 }
 
 
-static int
-search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
+static gcry_md_spec_t *
+search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
 {
-  gcry_module_t module;
-  int ret = 0;
+  gcry_md_spec_t *spec;
+  int i;
 
   if (oid && ((! strncmp (oid, "oid.", 4))
              || (! strncmp (oid, "OID.", 4))))
     oid += 4;
 
-  module = gcry_md_lookup_oid (oid);
-  if (module)
+  spec = spec_from_oid (oid);
+  if (spec && spec->oids)
     {
-      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))
+      for (i = 0; spec->oids[i].oidstring; i++)
+       if (stricmp (oid, spec->oids[i].oidstring))
          {
-           if (algorithm)
-             *algorithm = module->mod_id;
            if (oid_spec)
-             *oid_spec = digest->oids[i];
-           ret = 1;
+             *oid_spec = spec->oids[i];
+           return spec;
          }
-      _gcry_module_release (module);
     }
 
-  return ret;
+  return NULL;
 }
 
+
 /****************
  * Map a string to the digest algo
  */
 int
 gcry_md_map_name (const char *string)
 {
-  gcry_module_t digest;
-  int ret, algorithm = 0;
+  gcry_md_spec_t *spec;
 
-  if (! string)
+  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 */
+  spec = search_oid (string, NULL);
+  if (spec)
+    return spec->algo;
 
-  ath_mutex_lock (&digests_registered_lock);
+  /* Not found, search a matching digest name.  */
+  spec = spec_from_name (string);
+  if (spec)
+    return spec->algo;
 
-  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;
+  return 0;
 }
 
 
 /****************
- * 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
@@ -397,32 +243,27 @@ digest_algo_to_string (int algorithm)
 const char *
 gcry_md_algo_name (int algorithm)
 {
-  const char *s = digest_algo_to_string (algorithm);
-  return s ? s : "?";
+  gcry_md_spec_t *spec;
+
+  spec = spec_from_algo (algorithm);
+  return spec ? spec->name : "?";
 }
 
 
 static gcry_err_code_t
 check_digest_algo (int algorithm)
 {
-  gcry_err_code_t rc = 0;
-  gcry_module_t digest;
+  gcry_md_spec_t *spec;
 
-  REGISTER_DEFAULT_DIGESTS;
+  spec = spec_from_algo (algorithm);
+  if (spec && !spec->flags.disabled)
+    return 0;
 
-  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 GPG_ERR_DIGEST_ALGO;
 
-  return rc;
 }
 
 
-
 /****************
  * Open a message digest handle for use with algorithm ALGO.
  * More algorithms may be added by md_enable(). The initial algorithm
@@ -525,7 +366,7 @@ md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
 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_err_code_t err;
   gcry_md_hd_t hd;
 
   if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
@@ -546,27 +387,20 @@ 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;
+  gcry_md_spec_t *spec;
   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 */
+    if (entry->spec->algo == algorithm)
+      return 0; /* 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)
+  spec = spec_from_algo (algorithm);
+  if (!spec)
     {
       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 ())
@@ -583,7 +417,7 @@ md_enable (gcry_md_hd_t hd, int algorithm)
   if (!err)
     {
       size_t size = (sizeof (*entry)
-                     + digest->contextsize
+                     + spec->contextsize
                      - sizeof (entry->context));
 
       /* And allocate a new list entry. */
@@ -596,24 +430,13 @@ md_enable (gcry_md_hd_t hd, int algorithm)
        err = gpg_err_code_from_errno (errno);
       else
        {
-         entry->digest = digest;
-         entry->module = module;
+         entry->spec = spec;
          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);
+         entry->spec->init (&entry->context.c);
        }
     }
 
@@ -627,10 +450,11 @@ 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;
+  gcry_err_code_t err = 0;
   struct gcry_md_context *a = ahd->ctx;
   struct gcry_md_context *b;
   GcryDigestEntry *ar, *br;
@@ -681,11 +505,11 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
         {
           if (a->secure)
             br = gcry_malloc_secure (sizeof *br
-                                     + ar->digest->contextsize
+                                     + ar->spec->contextsize
                                      - sizeof(ar->context));
           else
             br = gcry_malloc (sizeof *br
-                              + ar->digest->contextsize
+                              + ar->spec->contextsize
                               - sizeof (ar->context));
           if (!br)
             {
@@ -694,15 +518,10 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
               break;
             }
 
-          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
+          memcpy (br, ar, (sizeof (*br) + ar->spec->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);
         }
     }
 
@@ -715,6 +534,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
   return err;
 }
 
+
 gcry_error_t
 gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
 {
@@ -726,6 +546,7 @@ gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
   return gcry_error (err);
 }
 
+
 /*
  * Reset all contexts and discard any buffered stuff.  This may be used
  * instead of a md_close(); md_open().
@@ -741,13 +562,14 @@ gcry_md_reset (gcry_md_hd_t a)
 
   for (r = a->ctx->list; r; r = r->next)
     {
-      memset (r->context.c, 0, r->digest->contextsize);
-      (*r->digest->init) (&r->context.c);
+      memset (r->context.c, 0, r->spec->contextsize);
+      (*r->spec->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)
 {
@@ -760,9 +582,6 @@ md_close (gcry_md_hd_t 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);
     }
@@ -777,6 +596,7 @@ md_close (gcry_md_hd_t a)
   gcry_free(a);
 }
 
+
 void
 gcry_md_close (gcry_md_hd_t hd)
 {
@@ -784,6 +604,7 @@ gcry_md_close (gcry_md_hd_t hd)
   md_close (hd);
 }
 
+
 static void
 md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
 {
@@ -800,18 +621,20 @@ md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
   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);
+       (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
+      (*r->spec->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)
 {
@@ -824,7 +647,7 @@ md_final (gcry_md_hd_t a)
     md_write (a, NULL, 0);
 
   for (r = a->ctx->list; r; r = r->next)
-    (*r->digest->final) (&r->context.c);
+    (*r->spec->final) (&r->context.c);
 
   a->ctx->finalized = 1;
 
@@ -850,6 +673,7 @@ md_final (gcry_md_hd_t a)
     }
 }
 
+
 static gcry_err_code_t
 prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
 {
@@ -884,9 +708,10 @@ prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
     }
   gcry_free (helpkey);
 
-  return GPG_ERR_NO_ERROR;
+  return 0;
 }
 
+
 gcry_error_t
 gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
 {
@@ -912,10 +737,11 @@ gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
   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;
+  gcry_err_code_t rc;
 
   if (!hd->ctx->macpads)
     rc = GPG_ERR_CONFLICT;
@@ -929,6 +755,7 @@ gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
   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.  */
@@ -942,9 +769,9 @@ gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
 }
 
 
-
 /****************
- * if ALGO is null get the digest for the used algo (which should be only one)
+ * 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 )
@@ -958,19 +785,20 @@ md_read( gcry_md_hd_t a, int algo )
         {
           if (r->next)
             log_debug ("more than one algorithm in md_read(0)\n");
-          return r->digest->read (&r->context.c);
+          return r->spec->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);
+       if (r->spec->algo == algo)
+         return r->spec->read (&r->context.c);
     }
   BUG();
   return NULL;
 }
 
+
 /*
  * Read out the complete digest, this function implictly finalizes
  * the hash.
@@ -1133,9 +961,10 @@ md_get_algo (gcry_md_hd_t a)
       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;
+  return r ? r->spec->algo : 0;
 }
 
+
 int
 gcry_md_get_algo (gcry_md_hd_t hd)
 {
@@ -1149,23 +978,13 @@ gcry_md_get_algo (gcry_md_hd_t hd)
 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);
+  gcry_md_spec_t *spec;
 
-  return mdlen;
+  spec = spec_from_algo (algorithm);
+  return spec? spec->mdlen : 0;
 }
 
+
 /****************
  * Return the length of the digest in bytes.
  * This function will return 0 in case of errors.
@@ -1182,31 +1001,25 @@ gcry_md_get_algo_dlen (int algorithm)
 static const byte *
 md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
 {
+  gcry_md_spec_t *spec;
   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)
+  spec = spec_from_algo (algorithm);
+  if (spec)
     {
       if (asnlen)
-       *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
+       *asnlen = spec->asnlen;
       if (mdlen)
-       *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
-      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
-      _gcry_module_release (digest);
+       *mdlen = spec->mdlen;
+      asnoid = spec->asnoid;
     }
   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:
@@ -1226,7 +1039,7 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
 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;
+  gcry_err_code_t err;
 
   switch (what)
     {
@@ -1248,10 +1061,10 @@ gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
 
           asn = md_asn_oid (algo, &asnlen, NULL);
           if (buffer && (*nbytes >= asnlen))
-         {
-           memcpy (buffer, asn, asnlen);
-           *nbytes = asnlen;
-         }
+            {
+              memcpy (buffer, asn, asnlen);
+              *nbytes = asnlen;
+            }
           else if (!buffer && nbytes)
             *nbytes = asnlen;
           else
@@ -1264,8 +1077,9 @@ gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
         }
       break;
 
-  default:
-    err = GPG_ERR_INV_OP;
+    default:
+      err = GPG_ERR_INV_OP;
+      break;
   }
 
   return gcry_error (err);
@@ -1293,6 +1107,7 @@ md_start_debug ( gcry_md_hd_t md, const char *suffix )
     log_debug("md debug: can't open %s\n", buf );
 }
 
+
 static void
 md_stop_debug( gcry_md_hd_t md )
 {
@@ -1329,7 +1144,7 @@ md_stop_debug( gcry_md_hd_t md )
 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;
+  gcry_err_code_t err = 0;
 
   switch (cmd)
     {
@@ -1350,7 +1165,7 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 
            *nbytes = 0;
            for(r=h->ctx->list; r; r = r->next ) {
-             if (r->module->mod_id == algo)
+             if (r->spec->algo == algo)
                {
                  *nbytes = 1;
                  break;
@@ -1372,15 +1187,7 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_md_init (void)
 {
-  gcry_err_code_t err;
-
-  err = ath_mutex_init (&digests_registered_lock);
-  if (err)
-    return gpg_err_code_from_errno (err);
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  return err;
+  return 0;
 }
 
 
@@ -1413,34 +1220,21 @@ gcry_md_is_enabled (gcry_md_hd_t a, int algo)
 gpg_error_t
 _gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
 {
-  gcry_module_t module = NULL;
-  md_extra_spec_t *extraspec = NULL;
   gcry_err_code_t ec = 0;
+  gcry_md_spec_t *spec;
 
-  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);
+  spec = spec_from_algo (algo);
+  if (spec && !spec->flags.disabled && spec->selftest)
+    ec = spec->selftest (algo, extended, report);
   else
     {
       ec = GPG_ERR_DIGEST_ALGO;
       if (report)
         report ("digest", algo, "module",
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                (spec && !spec->flags.disabled)?
                 "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
+                spec? "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);
 }
index e2d096c..ab32b14 100644 (file)
@@ -261,6 +261,7 @@ static gcry_md_oid_spec_t oid_spec_md4[] =
 
 gcry_md_spec_t _gcry_digest_spec_md4 =
   {
+    GCRY_MD_MD4, {0, 0},
     "MD4", asn, DIM (asn), oid_spec_md4,16,
     md4_init, _gcry_md_block_write, md4_final, md4_read,
     sizeof (MD4_CONTEXT)
index db0f315..1b6ad48 100644 (file)
@@ -287,6 +287,7 @@ static gcry_md_oid_spec_t oid_spec_md5[] =
 
 gcry_md_spec_t _gcry_digest_spec_md5 =
   {
+    GCRY_MD_MD5, {0, 1},
     "MD5", asn, DIM (asn), oid_spec_md5, 16,
     md5_init, _gcry_md_block_write, md5_final, md5_read,
     sizeof (MD5_CONTEXT)
index d156e61..f7430ea 100644 (file)
@@ -504,6 +504,7 @@ static gcry_md_oid_spec_t oid_spec_rmd160[] =
 
 gcry_md_spec_t _gcry_digest_spec_rmd160 =
   {
+    GCRY_MD_RMD160, {0, 0},
     "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
     _gcry_rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read,
     sizeof (RMD160_CONTEXT)
index aef9f05..95591eb 100644 (file)
@@ -411,11 +411,9 @@ static gcry_md_oid_spec_t oid_spec_sha1[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha1 =
   {
+    GCRY_MD_SHA1, {0, 1},
     "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
     sha1_init, _gcry_md_block_write, sha1_final, sha1_read,
-    sizeof (SHA1_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha1 =
-  {
+    sizeof (SHA1_CONTEXT),
     run_selftests
   };
index ad08cc7..d3917e4 100644 (file)
@@ -475,22 +475,18 @@ static gcry_md_oid_spec_t oid_spec_sha256[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha224 =
   {
+    GCRY_MD_SHA224, {0, 1},
     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
     sha224_init, _gcry_md_block_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha224 =
-  {
+    sizeof (SHA256_CONTEXT),
     run_selftests
   };
 
 gcry_md_spec_t _gcry_digest_spec_sha256 =
   {
+    GCRY_MD_SHA256, {0, 1},
     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
     sha256_init, _gcry_md_block_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha256 =
-  {
+    sizeof (SHA256_CONTEXT),
     run_selftests
   };
index 505a1e4..af30775 100644 (file)
@@ -731,12 +731,10 @@ static gcry_md_oid_spec_t oid_spec_sha512[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha512 =
   {
+    GCRY_MD_SHA512, {0, 1},
     "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
     sha512_init, _gcry_md_block_write, sha512_final, sha512_read,
     sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha512 =
-  {
     run_selftests
   };
 
@@ -759,11 +757,9 @@ static gcry_md_oid_spec_t oid_spec_sha384[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha384 =
   {
+    GCRY_MD_SHA384, {0, 1},
     "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
     sha384_init, _gcry_md_block_write, sha512_final, sha512_read,
     sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha384 =
-  {
     run_selftests
   };
index 61aa222..7dcdfd6 100644 (file)
@@ -1387,6 +1387,7 @@ stribog_read_256 (void *context)
 
 gcry_md_spec_t _gcry_digest_spec_stribog_256 =
   {
+    GCRY_MD_STRIBOG256, {0, 0},
     "STRIBOG256", NULL, 0, NULL, 32,
     stribog_init_256, _gcry_md_block_write, stribog_final, stribog_read_256,
     sizeof (STRIBOG_CONTEXT)
@@ -1394,6 +1395,7 @@ gcry_md_spec_t _gcry_digest_spec_stribog_256 =
 
 gcry_md_spec_t _gcry_digest_spec_stribog_512 =
   {
+    GCRY_MD_STRIBOG512, {0, 0},
     "STRIBOG512", NULL, 0, NULL, 64,
     stribog_init_512, _gcry_md_block_write, stribog_final, stribog_read_512,
     sizeof (STRIBOG_CONTEXT)
index df16098..a70a3f2 100644 (file)
@@ -810,6 +810,7 @@ tiger_read( void *context )
    an OID anymore because that would not be correct.  */
 gcry_md_spec_t _gcry_digest_spec_tiger =
   {
+    GCRY_MD_TIGER, {0, 0},
     "TIGER192", NULL, 0, NULL, 24,
     tiger_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
@@ -832,6 +833,7 @@ static gcry_md_oid_spec_t oid_spec_tiger1[] =
 
 gcry_md_spec_t _gcry_digest_spec_tiger1 =
   {
+    GCRY_MD_TIGER1, {0, 0},
     "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
     tiger1_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
@@ -842,6 +844,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 =
 /* This is TIGER2 which usues a changed padding algorithm.  */
 gcry_md_spec_t _gcry_digest_spec_tiger2 =
   {
+    GCRY_MD_TIGER2, {0, 0},
     "TIGER2", NULL, 0, NULL, 24,
     tiger2_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
index fa632f9..168c38f 100644 (file)
@@ -1351,6 +1351,7 @@ whirlpool_read (void *ctx)
 
 gcry_md_spec_t _gcry_digest_spec_whirlpool =
   {
+    GCRY_MD_WHIRLPOOL, {0, 0},
     "WHIRLPOOL", NULL, 0, NULL, 64,
     whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read,
     sizeof (whirlpool_context_t)
index 62bc8b9..f4b9959 100644 (file)
@@ -230,20 +230,46 @@ typedef struct gcry_cipher_spec
  *
  */
 
-typedef struct md_extra_spec
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
 {
-  selftest_func_t selftest;
-} md_extra_spec_t;
+  const char *oidstring;
+} gcry_md_oid_spec_t;
 
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  unsigned char *asnoid;
+  int asnlen;
+  gcry_md_oid_spec_t *oids;
+  int mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  size_t contextsize; /* allocate this amount of context */
+  selftest_func_t selftest;
+} gcry_md_spec_t;
 
 
 \f
-/* The private register functions. */
-gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
-                                md_extra_spec_t *extraspec,
-                                unsigned int *algorithm_id,
-                                gcry_module_t *module);
-
 /* The selftest functions.  */
 gcry_error_t _gcry_cipher_selftest (int algo, int extended,
                                     selftest_report_func_t report);
index d080e72..3b7744a 100644 (file)
@@ -224,12 +224,6 @@ extern gcry_md_spec_t _gcry_digest_spec_tiger1;
 extern gcry_md_spec_t _gcry_digest_spec_tiger2;
 extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
 
-extern md_extra_spec_t _gcry_digest_extraspec_sha1;
-extern md_extra_spec_t _gcry_digest_extraspec_sha224;
-extern md_extra_spec_t _gcry_digest_extraspec_sha256;
-extern md_extra_spec_t _gcry_digest_extraspec_sha384;
-extern md_extra_spec_t _gcry_digest_extraspec_sha512;
-
 /* Declarations for the pubkey cipher specifications.  */
 extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
index 621a3a4..35a928c 100644 (file)
@@ -47,37 +47,6 @@ typedef struct gcry_module *gcry_module_t;
 
 /* ********************** */
 
-/* Type for the md_init function.  */
-typedef void (*gcry_md_init_t) (void *c);
-
-/* Type for the md_write function.  */
-typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
-
-/* Type for the md_final function.  */
-typedef void (*gcry_md_final_t) (void *c);
-
-/* Type for the md_read function.  */
-typedef unsigned char *(*gcry_md_read_t) (void *c);
-
-typedef struct gcry_md_oid_spec
-{
-  const char *oidstring;
-} gcry_md_oid_spec_t;
-
-/* Module specification structure for message digests.  */
-typedef struct gcry_md_spec
-{
-  const char *name;
-  unsigned char *asnoid;
-  int asnlen;
-  gcry_md_oid_spec_t *oids;
-  int mdlen;
-  gcry_md_init_t init;
-  gcry_md_write_t write;
-  gcry_md_final_t final;
-  gcry_md_read_t read;
-  size_t contextsize; /* allocate this amount of context */
-} gcry_md_spec_t;
 
 #if 0 /* keep Emacsens's auto-indent happy */
 {