summaryrefslogtreecommitdiff
path: root/cipher/md.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-10-02 13:39:47 +0200
committerWerner Koch <wk@gnupg.org>2013-10-02 13:39:47 +0200
commit0d39997932617ba20656f8bcc230ba744b76c87e (patch)
treeb5c52e2190f11703285b41f48ecc21a91dd4c579 /cipher/md.c
parent3ca180b25e8df252fc16f802cfdc27496e307830 (diff)
downloadlibgcrypt-0d39997932617ba20656f8bcc230ba744b76c87e.tar.gz
md: Simplify the message digest dispatcher md.c.
* 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>
Diffstat (limited to 'cipher/md.c')
-rw-r--r--cipher/md.c550
1 files changed, 172 insertions, 378 deletions
diff --git a/cipher/md.c b/cipher/md.c
index c65eb70b..e3cc6c66 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -31,105 +31,64 @@
#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 );
+
+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);
}