summaryrefslogtreecommitdiff
path: root/cipher/md.c
diff options
context:
space:
mode:
authorMoritz Schulte <mo@g10code.com>2003-04-16 16:21:34 +0000
committerMoritz Schulte <mo@g10code.com>2003-04-16 16:21:34 +0000
commit62ee765f9df47ab2f37cfe00c019ffe81ded664a (patch)
tree05b8ceb9a842331db561e07b009158bc0e1efe5a /cipher/md.c
parent05a4715e94bd7d6c7d63c1dc307caa5a330a3b7e (diff)
downloadlibgcrypt-62ee765f9df47ab2f37cfe00c019ffe81ded664a.tar.gz
2003-04-16 Moritz Schulte <moritz@g10code.com>
* rand-internal.h: Removed declarations for constructor functions. * md.c (md_copy): Call _gcry_module_use for incrementing the usage counter of the digest modules. * rsa.c: Do not include "rsa.h". * dsa.c: Do not include "dsa.h". * elgamal.c: Do not include "elgamal.h". * des.c: Do not include "des.h". * cast5.c: Do not include "cast5.h". * blowfish.c: Do not include "blowfish.h". * arcfour.c: Do not include "arcfour.h". * Makefile.am (libcipher_la_DEPENDENCIES): Removed. (libcipher_la_LIBADD): Removed. Use Automake conditionals for conditional compilation. 2003-04-13 Moritz Schulte <moritz@g10code.com> * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS. * md.c (gcry_md_list): New member: module. (md_enable): New variable: module, changed use of module and digest. (md_enable): Initialize member: module. (md_close): Call _gcry_module_release. * cipher.c (gcry_cipher_open): New variable: module, changed use of module and cipher. (struct gcry_cipher_handle): New member: module. (gcry_cipher_open): Initialize member: module. (gcry_cipher_close): Call _gcry_module_release. 2003-04-09 Moritz Schulte <moritz@g10code.com> * cipher.c: Include "ath.h". * md.c: Likewise. * pubkey.c: Likewise. * cipher.c (ciphers_registered_lock): New variable. * md.c (digests_registered_lock): New variable. * pubkey.c (pubkeys_registered_lock): New variable. * rndlinux.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_rndlinux_constructor): Removed function. * rndegd.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_rndegd_constructor): Removed function. * rndunix.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_rndunix_constructor): Removed function. * rndw32.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_rndw32_constructor): Removed function. * rndegd.c (rndegd_connect_socket): Simplify code for creating the egd socket address. (rndegd_connect_socket): Call log_fatal use instead of g10_log_fatal. (egd_gather_random): Renamed to ... (rndegd_gather_random): ... here. 2003-04-08 Moritz Schulte <moritz@g10code.com> * rndlinux.c: Do not include "dynload.h". * rndunix.c: Likewise. * rndw32.c: Likewise. * rndegd.c (rndegd_connect_socket): Factored out from ... (egd_gather_random): here; call it. (egd_socket): New variable. (egd_gather_random): Initialize fd with egd_socket, do not declare fd static. (do_read): Merged few changes from GnuPG. FIXME - not finished? Do not include "dynload.h". * rndw32.c (gather_random): Renamed to rndw32_gather_random, do not declare static. (gather_random_fast): Renamed to rndw32_gather_random_fast, do not declare static. * rndunix.c (gather_random): Renamed to rndunix_gather_random, do not declare static. * rndegd.c (gather_random): Renamed to rndegd_gather_random, do not declare static. * rndlinux.c (gather_random): Renamed to rndlinux_gather_random, do not declare static. 2003-04-07 Moritz Schulte <moritz@g10code.com> * Makefile.am (libcipher_la_SOURCES): Removed construct.c. (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c, md5.c, tiger.c and crc.c (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger and crc. Removed definitions: EXTRA_md4_SOURCES, EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES, EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES, BUILT_SOURCES, DISTCLEANFILES. * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h". * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h, dsa.h, des.h, cast5.h, arcfour.h and blowfish.h. * rsa.h: Removed file. * elgamal.h: Removed file. * dsa.h: Removed file. * des.h: Removed file. * cast5.h: Removed file. * arcfour.h: Removed file. * blowfish.h: Removed file. * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and dynload.h. * rsa.c (pubkey_spec_rsa): New variable. * dsa.c (pubkey_spec_rsa): New variable. * elgamal.c (pubkey_spec_elg): New variable. * rsa.c (_gcry_rsa_get_info): Removed function. * elgamal.c (_gcry_elg_get_info): Removed function. * dsa.c (_gcry_dsa_get_info): Removed function. * tiger.c (tiger_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_tiger_constructor): Removed function. * sha1.c (sha1_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_sha1_constructor): Removed function. * sha256.c (sha256_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_sha256_constructor): Removed function. * rmd160.c (rmd160_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_rmd160_constructor): Removed function. * md5.c (md5_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_md5_constructor): Removed function. * md4.c (md4_get_info): Removed function. (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func): Removed function. (_gcry_md4_constructor): Removed function. * crc.c (crc_get_info): Removed function. * arcfour.c (do_arcfour_setkey): Changed type of context argument to `void *', added local variable for cast, adjusted callers. (arcfour_setkey): Likewise. (encrypt_stream): Likewise. * cast5.c (cast_setkey): Likewise. (encrypt_block): Likewise. * rijndael.c (rijndael_setkey): Likewise. (rijndael_encrypt): Likewise. (rijndael_decrypt): Likewise. * twofish.c (twofish_setkey): Likewise. (twofish_encrypt): Likewise. (twofish_decrypt): Likewise. * des.c (do_des_setkey): Likewise. (do_des_encrypt): Likewise. (do_des_encrypt): Likewise. (do_tripledes_encrypt): Likewise. (do_tripledes_encrypt): Likewise. * blowfish.c (bf_setkey: Likewise. (encrypt_block): Likewise. (decrypt_block): Likewise. * arcfour.c (encrypt_stream): Likewise. * rijndael.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func) Removed function. * twofish.c (gnupgext_version, func_table): Removed definitions. (gnupgext_enum_func) Removed function. * cast5.c (CIPHER_ALGO_CAST5): Removed. * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros. (CIPHER_ALGO_BLOWFISH): Removed symbol. * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise. * des.c (selftest_failed): Removed. (initialized): New variable. (do_des_setkey): Run selftest, if not yet done. (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros. * arcfour.c (_gcry_arcfour_get_info): Removed function. * blowfish.c (_gcry_blowfish_get_info): Removed function. * cast5.c (_gcry_cast5_get_info): Removed function. * des.c (_gcry_des_get_info): Removed function. * rijndael.c (_gcry_rijndael_get_info): Removed function. * twofish.c (_gcry_twofish_get_info): Removed function. * arcfour.c (cipher_spec_arcfour): New variable. * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New variables. * rijndael.c (cipher_spec_aes, cipher_spec_aes192, cipher_spec256): New variables. * des.c (cipher_spec_des, cipher_spec_tripledes): New variables. * cast5.c (cipher_spec_cast5): New variable. * blowfish.c (cipher_spec_blowfish): Likewise. * twofish.c: Do not include "dynload.h". * rijndael.c: Likewise. * des.c: Likewise. * cast5.c: Likewise. * blowfish.c: Likewise. * cipher.c: Likewise. * crc.c: Likewise. * md4.c: Likewise. * md5.c: Likewise. * md.c: Likewise. * pubkey.c: Likewise. * rijndael.c: Likewise. * sha1.c: Likewise. * sha256.c: Likewise. * arcfour.c: Include "cipher.h". * twofish.c: Likewise. * rijndael.c: Likewise. * des.c: Likewise. * cast5.c: Likewise. * blowfish.c: Likewise. * twofish.c (twofish_setkey): Declared argument `key' const. (twofish_encrypt): Declared argument `inbuf' const. (twofish_decrypt): Likewise. * rijndael.c (rijndael_setkey): Declared argument `key' const. (rijndael_encrypt): Declared argument `inbuf' const. (rijndael_decrypt): Likewise. * des.c (do_des_setkey): Declared argument `key' const. (do_tripledes_setkey): Likewise. (do_des_encrypt): Declared argument `inbuf' const. (do_des_decrypt): Likewise. (do_tripledes_encrypt): Likewise. (do_tripledes_decrypt): Likewise. * cast5.c (encrypt_block): Declared argument `inbuf' const. (decrypt_block): Likewise. (cast_setkey): Declared argument `key' const. * blowfish.c (do_bf_setkey): Declared argument `key' const. (encrypt_block): Declared argument `inbuf' const. (encrypt_block): Likewise. * cipher.c: Remove CIPHER_ALGO_DUMMY related code. Removed struct cipher_table_s. Changed definition of cipher_table. Removed definition of disabled_algos. (ciphers_registered, default_ciphers_registered): New variables. (REGISTER_DEFAULT_CIPHERS): New macro. (dummy_setkey): Declared argument `key' const. (dummy_encrypt_block): Declared argument `inbuf' const. (dummy_encrypt_block): Likewise. (dummy_encrypt_stream): Likewise. (dummy_encrypt_stream): Likewise. (dummy_setkey): Use `unsigned char' instead of `byte'. (dummy_encrypt_block): Likewise. (dummy_decrypt_block): Likewise. (dummy_encrypt_stream): Likewise. (dummy_decrypt_stream): Likewise. (gcry_cipher_register_default): New function. (gcry_cipher_lookup_func_id): New function. (gcry_cipher_lookup_func_name): New function. (gcry_cipher_lookup_id): New function. (gcry_cipher_lookup_name): New function. (gcry_cipher_id_new): New function. (gcry_cipher_register): New function. (gcry_cipher_unregister): New function. (setup_cipher_table): Removed function. (load_cipher_modules): Removed function. (gcry_cipher_map_name): Adjusted to use new module management. (cipher_algo_to_string): Likewise. (disable_cipher_algo): Likewise. (check_cipher_algo): Likewise. (cipher_get_keylen): Likewise. (cipher_get_blocksize): Likewise. (gcry_cipher_open): Likewise. (struct gcry_cipher_handle): Replaced members algo, algo_index, blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one member: cipher. (gcry_cipher_open): Adjusted code for new handle structure. (cipher_setkey): Likewise. (cipher_setiv): Likewise. (cipher_reset): Likewise. (do_ecb_encrypt): Likewise. (do_ecb_decrypt): Likewise. (do_cbc_encrypt): Likewise. (do_cbc_decrypt): Likewise. (do_cfb_encrypt): Likewise. (do_cfb_decrypt): Likewise. (do_ctr_encrypt): Likewise. (cipher_encrypt): Likewise. (gcry_cipher_encrypt): Likewise. (cipher_decrypt): Likewise. (gcry_cipher_decrypt): Likewise. (cipher_sync): Likewise. (gcry_cipher_ctl): Likewise. * pubkey.c: Removed struct pubkey_table_s. Changed definition of pubkey_table. Removed definition of disabled_algos. (pubkeys_registered, default_pubkeys_registered): New variables. (REGISTER_DEFAULT_PUBKEYS): New macro. (setup_pubkey_table): Removed function. (load_pubkey_modules): Removed function. (gcry_pubkey_register_default): New function. (gcry_pubkey_lookup_func_id): New function. (gcry_pubkey_lookup_func_name): New function. (gcry_pubkey_lookup_id): New function. (gcry_pubkey_lookup_name): New function. (gcry_pubkey_id_new): New function. (gcry_pubkey_register): New function. (gcry_pubkey_unregister): New function. (gcry_pk_map_name): Adjusted to use new module management. (gcry_pk_algo_name): Likewise. (disable_pubkey_algo): Likewise. (check_pubkey_algo): Likewise. (pubkey_get_npkey): Likewise. (pubkey_get_nskey): Likewise. (pubkey_get_nsig): Likewise. (pubkey_get_nenc): Likewise. (pubkey_generate): Likewise. (pubkey_check_secret_key): Likewise. (pubkey_encrypt): Likewise. (pubkey_decrypt): Likewise. (pubkey_sign): Likewise. (pubkey_verify): Likewise. (gcry_pk_get_nbits): Likewise. (gcry_pk_algo_info): Likewise. * md.c: Removed struct md_digest_list_s. (digest_list): Changed definition. (digests_registered, default_digests_registered): New variables. (REGISTER_DEFAULT_DIGESTS): New macro. (new_list_item): Removed function. (setup_md_table): Removed function. (load_digest_module): Removed function. (gcry_digest_register_default): New function. (gcry_digest_lookup_func_id): New function. (gcry_digest_lookup_func_name): New function. (gcry_digest_lookup_id): New function. (gcry_digest_lookup_name): New function. (gcry_digest_id_new): New function. (gcry_digest_register): New function. (gcry_digest_unregister): New function. (GcryDigestEntry): New type. (struct gcry_md_context): Adjusted type of `list'. (gcry_md_map_name): Adjusted to use new module management. (digest_algo_to_string): Likewise. (check_digest_algo): Likewise. (md_enable): Likewise. (md_digest_length): Likewise. (md_asn_oid): Likewise. 2003-04-07 Moritz Schulte <moritz@g10code.com> * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA, PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with GCRY_PK_ELG. * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA. 2003-04-01 Moritz Schulte <moritz@g10code.com> * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
Diffstat (limited to 'cipher/md.c')
-rw-r--r--cipher/md.c1326
1 files changed, 723 insertions, 603 deletions
diff --git a/cipher/md.c b/cipher/md.c
index 0cb4f341..f12f1b62 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -27,9 +27,9 @@
#include "g10lib.h"
#include "cipher.h"
-#include "dynload.h"
-#include "rmd.h"
+#include "ath.h"
+#include "rmd.h"
static struct {
const char *oidstring;
@@ -60,21 +60,193 @@ static struct {
{NULL}
};
+static struct
+{
+ GcryDigestSpec *digest;
+ int flags;
+} digest_table[] =
+ {
+#if USE_CRC
+ { &digest_spec_crc32, 0 },
+ { &digest_spec_crc32_rfc1510, 0 },
+ { &digest_spec_crc24_rfc2440, 0 },
+#endif
+#if USE_MD4
+ { &digest_spec_md4, 0 },
+#endif
+#if USE_MD5
+ { &digest_spec_md5, 0 },
+#endif
+#if USE_RMD160
+ { &digest_spec_rmd160, 0 },
+#endif
+#if USE_SHA1
+ { &digest_spec_sha1, 0 },
+#endif
+#if USE_SHA256
+ { &digest_spec_sha256, 0 },
+#endif
+#if USE_TIGER
+ { &digest_spec_tiger, 0 },
+#endif
+ { NULL },
+ };
+
+/* List of registered digests. */
+static GcryModule *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;
+
+/* Convenient macro for registering the default digests. */
+#define REGISTER_DEFAULT_DIGESTS \
+ do \
+ { \
+ ath_mutex_lock (&digests_registered_lock); \
+ if (! default_digests_registered) \
+ { \
+ gcry_digest_register_default (); \
+ default_digests_registered = 1; \
+ } \
+ ath_mutex_unlock (&digests_registered_lock); \
+ } \
+ while (0)
+
+/* Internal function. Register all the ciphers included in
+ CIPHER_TABLE. Returns zero on success or an error code. */
+static void
+gcry_digest_register_default (void)
+{
+ int i, err = 0;
+
+ for (i = 0; (! err) && digest_table[i].digest; i++)
+ err = _gcry_module_add (&digests_registered,
+ (void *) digest_table[i].digest,
+ NULL);
+
+ if (err)
+ BUG ();
+}
+
+/* Internal callback function. */
+static int
+gcry_digest_lookup_func_id (void *spec, void *data)
+{
+ GcryDigestSpec *digest = (GcryDigestSpec *) spec;
+ int id = *((int *) data);
+ return (digest->id == id);
+}
+/* Internal callback function. */
+static int
+gcry_digest_lookup_func_name (void *spec, void *data)
+{
+ GcryDigestSpec *digest = (GcryDigestSpec *) spec;
+ char *name = (char *) data;
-struct md_digest_list_s;
+ return (! stricmp (digest->name, name));
+}
+
+/* Internal function. Lookup a digest entry by it's ID. */
+static GcryModule *
+gcry_digest_lookup_id (int id)
+{
+ GcryModule *digest;
+
+ digest = _gcry_module_lookup (digests_registered, (void *) &id,
+ gcry_digest_lookup_func_id);
+
+ return digest;
+}
+
+/* Internal function. Lookup a digest entry by it's name. */
+static GcryModule *
+gcry_digest_lookup_name (const char *name)
+{
+ GcryModule *digest;
+
+ digest = _gcry_module_lookup (digests_registered, (void *) name,
+ gcry_digest_lookup_func_name);
+
+ return digest;
+}
+
+/* Return a new, unused digest ID for a user-provided digest
+ implementation. */
+static int
+gcry_digest_id_new (void)
+{
+ int id, id_start = 500, id_end = 600; /* FIXME. */
+
+ for (id = id_start; id < id_end; id++)
+ if (! gcry_digest_lookup_id (id))
+ return id;
+
+ return 0;
+}
+
+/* Public function. Register a provided DIGEST. Returns zero on
+ success, in which case the chosen digest ID has been stored in
+ DIGEST, or an error code. */
+int
+gcry_digest_register (GcryDigestSpec *digest, GcryModule **module)
+{
+ int id, err = 0;
+ GcryModule *mod;
+
+ ath_mutex_lock (&digests_registered_lock);
+ id = gcry_digest_id_new ();
+ if (! id)
+ err = GCRYERR_INTERNAL; /* FIXME. */
+ else
+ {
+ digest->id = id;
+ err = _gcry_module_add (&digests_registered, (void *) digest,
+ &mod);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ if (! err)
+ *module = mod;
+
+ return err;
+}
+
+/* Public function. Unregister the digest identified by ID, which
+ must have been registered with gcry_digest_register. */
+void
+gcry_digest_unregister (GcryModule *module)
+{
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&digests_registered_lock);
+}
+
+typedef struct gcry_md_list
+{
+ GcryDigestSpec *digest;
+ GcryModule *module;
+ struct gcry_md_list *next;
+ PROPERLY_ALIGNED_TYPE context;
+} GcryDigestEntry;
/* this structure is put right after the GCRY_MD_HD buffer, so that
* only one memory block is needed. */
-struct gcry_md_context {
- int magic;
- int secure;
- FILE *debug;
- int finalized;
- struct md_digest_list_s *list;
- byte *macpads;
+struct gcry_md_context
+{
+ int magic;
+ int secure;
+ FILE *debug;
+ int finalized;
+ GcryDigestEntry *list;
+ byte *macpads;
};
+
#define CTX_MAGIC_NORMAL 0x11071961
#define CTX_MAGIC_SECURE 0x16917011
@@ -94,151 +266,47 @@ static void md_start_debug( GCRY_MD_HD a, const char *suffix );
static void md_stop_debug( GCRY_MD_HD a );
/****************
- * This structure is used for the list of available algorithms
- * and for the list of algorithms in GCRY_MD_HD.
+ * Map a string to the digest algo
*/
-struct md_digest_list_s {
- struct md_digest_list_s *next;
- const char *name;
- int algo;
- byte *asnoid;
- int asnlen;
- int mdlen;
- void (*init)( void *c );
- void (*write)( void *c, byte *buf, size_t nbytes );
- void (*final)( void *c );
- byte *(*read)( void *c );
- size_t contextsize; /* allocate this amount of context */
- PROPERLY_ALIGNED_TYPE context;
-};
-
-static struct md_digest_list_s *digest_list;
-
-
-
-static struct md_digest_list_s *
-new_list_item( int algo,
- const char *(*get_info)( int, size_t*,byte**, int*, int*,
- void (**)(void*),
- void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*)) )
+int
+gcry_md_map_name (const char *string)
{
- struct md_digest_list_s *r;
-
- r = gcry_xcalloc( 1, sizeof *r );
- r->algo = algo,
- r->name = (*get_info)( algo, &r->contextsize,
- &r->asnoid, &r->asnlen, &r->mdlen,
- &r->init, &r->write, &r->final, &r->read );
- if( !r->name ) {
- gcry_free(r);
- r = NULL;
- }
- return r;
-}
+ GcryModule *digest;
+ int id = 0;
+ if (!string)
+ return 0;
+ /* 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 */
+ if (digitp (string)
+ || !strncmp (string, "oid.", 4)
+ || !strncmp (string, "OID.", 4) )
+ {
+ int i;
+ const char *s = digitp(string)? string : (string+4);
-/****************
- * Try to load the modules with the requested algorithm
- * and return true if new modules are available
- * If req_alog is -1 try to load all digest algorithms.
- */
-static int
-load_digest_module( int req_algo )
-{
- static int initialized = 0;
- static u32 checked_algos[512/32];
- static int checked_all = 0;
- struct md_digest_list_s *r;
- void *context = NULL;
- int algo;
- int any = 0;
- const char *(*get_info)( int, size_t*,byte**, int*, int*,
- void (**)(void*),
- void (**)(void*,byte*,size_t),
- void (**)(void*),byte *(**)(void*));
-
- if( !initialized ) {
- _gcry_cipher_modules_constructor();
- initialized = 1;
- }
- algo = req_algo;
- if( algo > 511 || !algo )
- return 0; /* algorithm number too high (does not fit into out bitmap)*/
- if( checked_all )
- return 0; /* already called with -1 */
- if( algo < 0 )
- checked_all = 1;
- else if( (checked_algos[algo/32] & (1 << (algo%32))) )
- return 0; /* already checked and not found */
- else
- checked_algos[algo/32] |= (1 << (algo%32));
-
- while( _gcry_enum_gnupgext_digests( &context, &algo, &get_info ) ) {
- if( req_algo != -1 && algo != req_algo )
- continue;
- for(r=digest_list; r; r = r->next )
- if( r->algo == algo )
- break;
- if( r ) {
- log_info("skipping digest %d: already loaded\n", algo );
- continue;
- }
- r = new_list_item( algo, get_info );
- if( ! r ) {
- log_info("skipping digest %d: no name\n", algo );
- continue;
+ for (i=0; oid_table[i].oidstring; i++)
+ {
+ if (!strcmp (s, oid_table[i].oidstring))
+ return oid_table[i].algo;
}
- /* put it into the list */
- if( _gcry_log_verbosity( 2 ) )
- log_info("loaded digest %d\n", algo);
- r->next = digest_list;
- digest_list = r;
- any = 1;
- if( req_algo != -1 )
- break;
}
- _gcry_enum_gnupgext_digests( &context, NULL, NULL );
- return any;
-}
+ REGISTER_DEFAULT_DIGESTS;
-/****************
- * Map a string to the digest algo
- */
-int
-gcry_md_map_name( const char *string )
-{
- struct md_digest_list_s *r;
-
- if (!string)
- return 0;
-
- /* 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 */
- if (digitp (string)
- || !strncmp (string, "oid.", 4)
- || !strncmp (string, "OID.", 4) )
- {
- int i;
- const char *s = digitp(string)? string : (string+4);
-
- for (i=0; oid_table[i].oidstring; i++)
- {
- if (!strcmp (s, oid_table[i].oidstring))
- return oid_table[i].algo;
- }
- }
+ ath_mutex_lock (&digests_registered_lock);
+ digest = gcry_digest_lookup_name (string);
+ if (digest)
+ {
+ id = ((GcryDigestSpec *) digest->spec)->id;
+ _gcry_module_release (digest);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
- do {
- for(r = digest_list; r; r = r->next )
- if( !stricmp( r->name, string ) )
- return r->algo;
- } while( !r && load_digest_module(-1) );
- return 0;
+ return id;
}
@@ -246,16 +314,23 @@ gcry_md_map_name( const char *string )
* Map a digest algo to a string
*/
static const char *
-digest_algo_to_string( int algo )
+digest_algo_to_string (int id)
{
- struct md_digest_list_s *r;
+ const char *name = NULL;
+ GcryModule *digest;
- do {
- for(r = digest_list; r; r = r->next )
- if( r->algo == algo )
- return r->name;
- } while( !r && load_digest_module( algo ) );
- return NULL;
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = gcry_digest_lookup_id (id);
+ if (digest)
+ {
+ name = ((GcryDigestSpec *) digest->spec)->name;
+ _gcry_module_release (digest);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return name;
}
/****************
@@ -265,24 +340,30 @@ digest_algo_to_string( int algo )
* is valid.
*/
const char *
-gcry_md_algo_name( int algo )
+gcry_md_algo_name (int id)
{
- const char *s = digest_algo_to_string( algo );
- return s? s: "?";
+ const char *s = digest_algo_to_string (id);
+ return s ? s : "?";
}
static int
-check_digest_algo( int algo )
+check_digest_algo (int id)
{
- struct md_digest_list_s *r;
+ int rc = 0;
+ GcryModule *digest;
- do {
- for(r = digest_list; r; r = r->next )
- if( r->algo == algo )
- return 0;
- } while( !r && load_digest_module(algo) );
- return GCRYERR_INV_MD_ALGO;
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = gcry_digest_lookup_id (id);
+ if (digest)
+ _gcry_module_release (digest);
+ else
+ rc = GCRYERR_INV_MD_ALGO;
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return rc;
}
@@ -295,59 +376,59 @@ check_digest_algo( int algo )
static GCRY_MD_HD
md_open( int algo, int secure, int hmac )
{
- GCRY_MD_HD hd;
- struct gcry_md_context *ctx;
- int bufsize = secure? 512 : 1024;
- 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 sture 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 */
- hd = secure ? gcry_malloc_secure( n + sizeof( struct gcry_md_context ) )
- : gcry_malloc( n + sizeof( struct gcry_md_context ) );
- if( !hd ) {
- set_lasterr( GCRYERR_NO_MEM );
- return NULL;
- }
-
- 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->secure = secure;
- if( hmac ) {
- ctx->macpads = gcry_malloc_secure( 128 );
- if( !ctx->macpads ) {
- md_close( hd );
- set_lasterr( GCRYERR_NO_MEM );
- return NULL;
- }
- }
- fast_random_poll(); /* FIXME: should we really do that? */
- if( algo && md_enable( hd, algo ) ) {
- md_close( hd );
- return NULL;
+ GCRY_MD_HD hd;
+ struct gcry_md_context *ctx;
+ int bufsize = secure? 512 : 1024;
+ 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 sture 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 */
+ hd = secure ? gcry_malloc_secure( n + sizeof( struct gcry_md_context ) )
+ : gcry_malloc( n + sizeof( struct gcry_md_context ) );
+ if( !hd ) {
+ set_lasterr( GCRYERR_NO_MEM );
+ return NULL;
+ }
+
+ 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->secure = secure;
+ if( hmac ) {
+ ctx->macpads = gcry_malloc_secure( 128 );
+ if( !ctx->macpads ) {
+ md_close( hd );
+ set_lasterr( GCRYERR_NO_MEM );
+ return NULL;
}
- return hd;
+ }
+ fast_random_poll(); /* FIXME: should we really do that? */
+ if( algo && md_enable( hd, algo ) ) {
+ md_close( hd );
+ return NULL;
+ }
+ return hd;
}
@@ -373,101 +454,128 @@ gcry_md_open (int algo, unsigned int flags)
static int
-md_enable( GCRY_MD_HD hd, int algo )
-{
- struct gcry_md_context *h = hd->ctx;
- struct md_digest_list_s *r, *ac;
-
- for( ac=h->list; ac; ac = ac->next )
- if( ac->algo == algo )
- return 0; /* already enabled */
- /* find the algorithm */
- do {
- for(r = digest_list; r; r = r->next )
- if( r->algo == algo )
- break;
- } while( !r && load_digest_module( algo ) );
- if( !r ) {
- log_debug("md_enable: algorithm %d not available\n", algo );
- return set_lasterr( GCRYERR_INV_MD_ALGO );
+md_enable (GCRY_MD_HD hd, int id)
+{
+ struct gcry_md_context *h = hd->ctx;
+ GcryDigestSpec *digest;
+ GcryDigestEntry *entry;
+ GcryModule *module;
+
+ for (entry = h->list; entry; entry = entry->next)
+ if (entry->digest->id == id)
+ return 0; /* already enabled */
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ module = gcry_digest_lookup_id (id);
+ ath_mutex_unlock (&digests_registered_lock);
+ if (! module)
+ {
+ log_debug ("md_enable: algorithm %d not available\n", id);
+ return set_lasterr (GCRYERR_INV_MD_ALGO);
}
- /* and allocate a new list entry */
- ac = h->secure? gcry_malloc_secure( sizeof *ac + r->contextsize
- - sizeof(r->context) )
- : gcry_malloc( sizeof *ac + r->contextsize
- - sizeof(r->context) );
- if( !ac )
- return set_lasterr( GCRYERR_NO_MEM );
-
- *ac = *r;
- ac->next = h->list;
- h->list = ac;
- /* and init this instance */
- (*ac->init)( &ac->context.c );
- return 0;
+
+ digest = (GcryDigestSpec *) module->spec;
+
+ /* and allocate a new list entry */
+ entry = h->secure
+ ? gcry_malloc_secure (sizeof (*entry)
+ + digest->contextsize
+ - sizeof (entry->context))
+ : gcry_malloc (sizeof (*entry)
+ + digest->contextsize
+ - sizeof (entry->context));
+
+ if (! entry)
+ return set_lasterr (GCRYERR_NO_MEM);
+
+ entry->digest = digest;
+ entry->module = module;
+ entry->next = h->list;
+ h->list = entry;
+
+ /* and init this instance */
+ (*entry->digest->init) (&entry->context.c);
+ return 0;
}
int
-gcry_md_enable( GCRY_MD_HD hd, int algo )
+gcry_md_enable (GCRY_MD_HD hd, int id)
{
- return md_enable( hd, algo );
+ return md_enable ( hd, id);
}
static GCRY_MD_HD
-md_copy( GCRY_MD_HD ahd )
-{
- struct gcry_md_context *a = ahd->ctx;
- struct gcry_md_context *b;
- GCRY_MD_HD bhd;
- struct md_digest_list_s *ar, *br;
- size_t n;
-
- if( ahd->bufpos )
- md_write( ahd, NULL, 0 );
-
- n = (char*)ahd->ctx - (char*)ahd;
- bhd = a->secure ? gcry_malloc_secure( n + sizeof( struct gcry_md_context ) )
- : gcry_malloc( n + sizeof( struct gcry_md_context ) );
- if( !bhd ) {
- set_lasterr( GCRYERR_NO_MEM );
- return NULL;
+md_copy (GCRY_MD_HD ahd)
+{
+ struct gcry_md_context *a = ahd->ctx;
+ struct gcry_md_context *b;
+ GCRY_MD_HD bhd;
+ GcryDigestEntry *ar, *br;
+ size_t n;
+
+ if (ahd->bufpos)
+ md_write (ahd, NULL, 0);
+
+ n = (char *) ahd->ctx - (char *) ahd;
+ bhd = a->secure
+ ? gcry_malloc_secure (n + sizeof (struct gcry_md_context))
+ : gcry_malloc (n + sizeof (struct gcry_md_context));
+
+ if (! bhd)
+ {
+ set_lasterr (GCRYERR_NO_MEM);
+ return NULL;
}
- bhd->ctx = b = (struct gcry_md_context*)( (char*)bhd + n );
- /* no need to copy the buffer due to the write above */
- assert( ahd->bufsize == (n - sizeof( struct gcry_md_handle ) + 1) );
- bhd->bufsize = ahd->bufsize;
- bhd->bufpos = 0; assert( !ahd->bufpos );
- memcpy( b, a, sizeof *a );
- b->list = NULL;
- b->debug = NULL;
- if( a->macpads ) {
- b->macpads = gcry_malloc_secure( 128 );
- memcpy( b->macpads, a->macpads, 128 );
+ bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
+ /* no need to copy the buffer due to the write above */
+ assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
+ bhd->bufsize = ahd->bufsize;
+ bhd->bufpos = 0;
+ assert (! ahd->bufpos);
+ memcpy (b, a, sizeof *a);
+ b->list = NULL;
+ b->debug = NULL;
+ if (a->macpads)
+ {
+ b->macpads = gcry_malloc_secure (128);
+ memcpy (b->macpads, a->macpads, 128);
}
- /* and now copy the complete list of algorithms */
- /* I know that the copied list is reversed, but that doesn't matter */
- for( ar=a->list; ar; ar = ar->next ) {
- br = a->secure ? gcry_xmalloc_secure( sizeof *br + ar->contextsize
- - sizeof(ar->context) )
- : gcry_xmalloc( sizeof *br + ar->contextsize
- - sizeof(ar->context) );
- memcpy( br, ar, sizeof(*br) + ar->contextsize
- - sizeof(ar->context) );
- br->next = b->list;
- b->list = br;
+
+ /* and now copy the complete list of algorithms */
+ /* I know that the copied list is reversed, but that doesn't matter */
+ for (ar = a->list; ar; ar = ar->next)
+ {
+ br = a->secure
+ ? gcry_xmalloc_secure (sizeof *br
+ + ar->digest->contextsize
+ - sizeof(ar->context))
+ : gcry_xmalloc (sizeof *br
+ + ar->digest->contextsize
+ - sizeof (ar->context));
+ 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 )
- md_start_debug( bhd, "unknown" );
- return bhd;
+ if (a->debug)
+ md_start_debug( bhd, "unknown" );
+ return bhd;
}
GCRY_MD_HD
-gcry_md_copy( GCRY_MD_HD hd )
+gcry_md_copy (GCRY_MD_HD hd)
{
- return md_copy( hd );
+ return md_copy (hd);
}
/****************
@@ -475,178 +583,181 @@ gcry_md_copy( GCRY_MD_HD hd )
* instead of a md_close(); md_open().
*/
void
-gcry_md_reset( GCRY_MD_HD a )
+gcry_md_reset (GCRY_MD_HD a)
{
- struct md_digest_list_s *r;
+ GcryDigestEntry *r;
+
+ a->bufpos = a->ctx->finalized = 0;
- a->bufpos = a->ctx->finalized = 0;
- for( r=a->ctx->list; r; r = r->next ) {
- memset( r->context.c, 0, r->contextsize );
- (*r->init)( &r->context.c );
- }
- if( a->ctx->macpads ) {
- md_write( a, a->ctx->macpads, 64 ); /* inner pad */
+ 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, 64); /* inner pad */
}
-
static void
-md_close(GCRY_MD_HD a)
+md_close (GCRY_MD_HD a)
{
- struct md_digest_list_s *r, *r2;
+ 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;
- gcry_free(r);
+ 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);
+ gcry_free (r);
}
- gcry_free(a->ctx->macpads);
- gcry_free(a);
+ gcry_free(a->ctx->macpads);
+ gcry_free(a);
}
-
void
-gcry_md_close( GCRY_MD_HD hd )
+gcry_md_close (GCRY_MD_HD hd)
{
- md_close( hd );
+ md_close (hd);
}
-
static void
-md_write( GCRY_MD_HD a, byte *inbuf, size_t inlen)
+md_write (GCRY_MD_HD a, byte *inbuf, size_t inlen)
{
- struct md_digest_list_s *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();
+ 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->write)( &r->context.c, a->buf, a->bufpos );
- (*r->write)( &r->context.c, inbuf, 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);
}
- a->bufpos = 0;
+ a->bufpos = 0;
}
-
void
-gcry_md_write( GCRY_MD_HD hd, const void *inbuf, size_t inlen)
+gcry_md_write (GCRY_MD_HD hd, const void *inbuf, size_t inlen)
{
- md_write( hd, (unsigned char *)inbuf, inlen );
+ md_write (hd, (unsigned char *) inbuf, inlen);
}
-
-
static void
-md_final(GCRY_MD_HD a)
+md_final (GCRY_MD_HD a)
{
- struct md_digest_list_s *r;
+ GcryDigestEntry *r;
- if( a->ctx->finalized )
- return;
+ if (a->ctx->finalized)
+ return;
- if( a->bufpos )
- md_write( a, NULL, 0 );
+ if (a->bufpos)
+ md_write (a, NULL, 0);
- for(r=a->ctx->list; r; r = r->next ) {
- (*r->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 om = md_open( algo, a->ctx->secure, 0 );
- if( !om )
- _gcry_fatal_error( gcry_errno(), NULL );
- md_write( om, a->ctx->macpads+64, 64 );
- 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 );
- }
-}
+ 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 om = md_open (algo, a->ctx->secure, 0);
+ if (! om)
+ _gcry_fatal_error (gcry_errno (), NULL);
+ md_write (om, a->ctx->macpads+64, 64);
+ 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 int
prepare_macpads( GCRY_MD_HD hd, const byte *key, size_t keylen)
{
- int i;
- int algo = md_get_algo( hd );
- byte *helpkey = NULL;
- byte *ipad, *opad;
-
- if( !algo )
- return GCRYERR_INV_MD_ALGO; /* i.e. no algo enabled */
-
- if( keylen > 64 ) {
- helpkey = gcry_malloc_secure( md_digest_length( algo ) );
- if( !helpkey )
- return GCRYERR_NO_MEM;
- gcry_md_hash_buffer( algo, helpkey, key, keylen );
- key = helpkey;
- keylen = md_digest_length( algo );
- assert( keylen <= 64 );
- }
-
- memset( hd->ctx->macpads, 0, 128 );
- ipad = hd->ctx->macpads;
- opad = hd->ctx->macpads+64;
- memcpy( ipad, key, keylen );
- memcpy( opad, key, keylen );
- for(i=0; i < 64; i++ ) {
- ipad[i] ^= 0x36;
- opad[i] ^= 0x5c;
- }
- gcry_free( helpkey );
- return 0;
+ int i;
+ int algo = md_get_algo( hd );
+ byte *helpkey = NULL;
+ byte *ipad, *opad;
+
+ if( !algo )
+ return GCRYERR_INV_MD_ALGO; /* i.e. no algo enabled */
+
+ if( keylen > 64 ) {
+ helpkey = gcry_malloc_secure( md_digest_length( algo ) );
+ if( !helpkey )
+ return GCRYERR_NO_MEM;
+ gcry_md_hash_buffer( algo, helpkey, key, keylen );
+ key = helpkey;
+ keylen = md_digest_length( algo );
+ assert( keylen <= 64 );
+ }
+
+ memset( hd->ctx->macpads, 0, 128 );
+ ipad = hd->ctx->macpads;
+ opad = hd->ctx->macpads+64;
+ memcpy( ipad, key, keylen );
+ memcpy( opad, key, keylen );
+ for(i=0; i < 64; i++ ) {
+ ipad[i] ^= 0x36;
+ opad[i] ^= 0x5c;
+ }
+ gcry_free( helpkey );
+ return 0;
}
int
-gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
+gcry_md_ctl (GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
{
- int rc = 0;
-
- switch (cmd)
- {
- case GCRYCTL_FINALIZE:
- md_final (hd);
- break;
- case GCRYCTL_SET_KEY:
- rc = 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 = GCRYERR_INV_OP;
- }
- return set_lasterr( rc );
+ int rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_FINALIZE:
+ md_final (hd);
+ break;
+ case GCRYCTL_SET_KEY:
+ rc = 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 = GCRYERR_INV_OP;
+ }
+ return set_lasterr( rc );
}
int
gcry_md_setkey( GCRY_MD_HD hd, const void *key, size_t keylen )
-{
- int rc = 0;
+ {
+ int rc = 0;
- if( !(hd->ctx->macpads ) )
- rc = GCRYERR_CONFLICT;
- else if ( !(rc = prepare_macpads( hd, key, keylen )) )
- gcry_md_reset( hd );
+ if( !(hd->ctx->macpads ) )
+ rc = GCRYERR_CONFLICT;
+ else if ( !(rc = prepare_macpads( hd, key, keylen )) )
+ gcry_md_reset( hd );
- return rc;
+ return rc;
}
@@ -656,22 +767,23 @@ gcry_md_setkey( GCRY_MD_HD hd, const void *key, size_t keylen )
static byte *
md_read( GCRY_MD_HD a, int algo )
{
- struct md_digest_list_s *r;
+ GcryDigestEntry *r = a->ctx->list;
- if( !algo ) { /* return the first algorithm */
- if( (r=a->ctx->list) ) {
- if( r->next )
- log_debug("more than algorithm in md_read(0)\n");
- return (*r->read)( &r->context.c );
- }
+ if (! algo)
+ {
+ /* return the first algorithm */
+ if (r && r->next)
+ log_debug("more than 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->algo == algo )
- return (*r->read)( &r->context.c );
+ else
+ {
+ for (r = a->ctx->list; r; r = r->next)
+ if (r->digest->id == algo)
+ return (*r->digest->read) (&r->context.c);
}
- BUG();
- return NULL;
+ BUG();
+ return NULL;
}
/****************
@@ -679,13 +791,12 @@ md_read( GCRY_MD_HD a, int algo )
* the hash.
*/
byte *
-gcry_md_read( GCRY_MD_HD hd, int algo )
+gcry_md_read (GCRY_MD_HD hd, int algo)
{
- gcry_md_ctl( hd, GCRYCTL_FINALIZE, NULL, 0 );
- return md_read( hd, algo);
+ gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ return md_read (hd, algo);
}
-
/****************
* This function combines md_final and md_read but keeps the context
* intact. This function can be used to calculate intermediate
@@ -699,42 +810,42 @@ gcry_md_read( GCRY_MD_HD hd, int algo )
static int
md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
{
- struct md_digest_list_s *r = NULL;
- char *context;
- char *digest;
-
- if( a->bufpos )
- md_write( a, NULL, 0 );
-
- if( !algo ) { /* return digest for the first algorithm */
- if( (r=a->ctx->list) && r->next )
- log_debug("more than algorithm in md_digest(0)\n");
- }
- else {
- for(r=a->ctx->list; r; r = r->next )
- if( r->algo == algo )
- break;
- }
- if( !r )
- BUG();
+ struct md_digest_list_s *r = NULL;
+ char *context;
+ char *digest;
+
+ if( a->bufpos )
+ md_write( a, NULL, 0 );
+
+ if( !algo ) { /* return digest for the first algorithm */
+ if( (r=a->ctx->list) && r->next )
+ log_debug("more than algorithm in md_digest(0)\n");
+ }
+ else {
+ for(r=a->ctx->list; r; r = r->next )
+ if( r->algo == algo )
+ break;
+ }
+ if( !r )
+ BUG();
- if( !buffer )
- return r->mdlen;
+ if( !buffer )
+ return r->mdlen;
- /* I don't want to change the interface, so I simply work on a copy
- * of the context (extra overhead - should be fixed)*/
- context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize )
- : gcry_xmalloc( r->contextsize );
- memcpy( context, r->context.c, r->contextsize );
- (*r->final)( context );
- digest = (*r->read)( context );
+ /* I don't want to change the interface, so I simply work on a copy
+ * of the context (extra overhead - should be fixed)*/
+ context = a->ctx->secure ? gcry_xmalloc_secure( r->contextsize )
+ : gcry_xmalloc( r->contextsize );
+ memcpy( context, r->context.c, r->contextsize );
+ (*r->digest->final)( context );
+ digest = (*r->digest->read)( context );
- if( buflen > r->mdlen )
- buflen = r->mdlen;
- memcpy( buffer, digest, buflen );
+ if( buflen > r->mdlen )
+ buflen = r->mdlen;
+ memcpy( buffer, digest, buflen );
- gcry_free(context);
- return buflen;
+ gcry_free(context);
+ return buflen;
}
#endif
@@ -742,10 +853,10 @@ md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen )
* Read out an intermediate digest.
*/
int
-gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen )
+gcry_md_get (GCRY_MD_HD hd, int algo, byte *buffer, int buflen)
{
- /*md_digest ... */
- return GCRYERR_INTERNAL;
+ /*md_digest ... */
+ return GCRYERR_INTERNAL;
}
@@ -756,33 +867,33 @@ gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen )
* 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_RMD160 )
- _gcry_rmd160_hash_buffer( digest, buffer, length );
- else { /* for the others we do not have a fast function, so
- * we use the normal functions to do it */
- GCRY_MD_HD h = md_open( algo, 0, 0 );
- if( !h )
- BUG(); /* algo not available */
- md_write( h, (byte*)buffer, length );
- md_final( h );
- memcpy( digest, md_read( h, algo ), md_digest_length( algo ) );
- md_close (h);
+gcry_md_hash_buffer (int algo, void *digest, const void *buffer, size_t length)
+{
+ if (algo == GCRY_MD_RMD160)
+ _gcry_rmd160_hash_buffer (digest, buffer, length);
+ else
+ {
+ /* for the others we do not have a fast function, so we use the
+ normal functions to do it */
+
+ GCRY_MD_HD h = md_open (algo, 0, 0);
+ if( !h )
+ BUG(); /* algo not available */
+ 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 a )
+md_get_algo (GCRY_MD_HD a)
{
- struct md_digest_list_s *r;
+ GcryDigestEntry *r = a->ctx->list;
- if( (r=a->ctx->list) ) {
- if( r->next )
- log_error("WARNING: more than algorithm in md_get_algo()\n");
- return r->algo;
- }
- return 0;
+ if (r && r->next)
+ log_error("WARNING: more than algorithm in md_get_algo()\n");
+ return r->digest->id;
}
@@ -803,17 +914,23 @@ gcry_md_get_algo (GCRY_MD_HD hd)
* Return the length of the digest
*/
static int
-md_digest_length( int algo )
+md_digest_length (int id)
{
- struct md_digest_list_s *r;
+ GcryModule *digest;
+ int mdlen = 0;
- do {
- for(r = digest_list; r; r = r->next ) {
- if( r->algo == algo )
- return r->mdlen;
- }
- } while( !r && load_digest_module( algo ) );
- return 0;
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = gcry_digest_lookup_id (id);
+ if (digest)
+ {
+ mdlen = ((GcryDigestSpec *) digest->spec)->mdlen;
+ _gcry_module_release (digest);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return mdlen;
}
/****************
@@ -850,23 +967,29 @@ gcry_md_get_algo_dlen( int algo )
/* Hmmm: add a mode to enumerate the OIDs
* to make g10/sig-check.c more portable */
static const byte *
-md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
-{
- struct md_digest_list_s *r;
-
- do {
- for(r = digest_list; r; r = r->next ) {
- if( r->algo == algo ) {
- if( asnlen )
- *asnlen = r->asnlen;
- if( mdlen )
- *mdlen = r->mdlen;
- return r->asnoid;
- }
- }
- } while( !r && load_digest_module( algo ) );
- log_bug("no asn for md algo %d\n", algo);
- return NULL;
+md_asn_oid (int id, size_t *asnlen, size_t *mdlen)
+{
+ const byte *asnoid = NULL;
+ GcryModule *digest;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = gcry_digest_lookup_id (id);
+ if (digest)
+ {
+ if (asnlen)
+ *asnlen = ((GcryDigestSpec *) digest->spec)->asnlen;
+ if (mdlen)
+ *mdlen = ((GcryDigestSpec *) digest->spec)->mdlen;
+ asnoid = ((GcryDigestSpec *) digest->spec)->asnoid;
+ _gcry_module_release (digest);
+ }
+ else
+ log_bug ("no asn for md algo %d\n", id);
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return asnoid;
}
@@ -892,40 +1015,40 @@ md_asn_oid( int algo, size_t *asnlen, size_t *mdlen )
int
gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
{
- switch( what ) {
- case GCRYCTL_TEST_ALGO:
- if( buffer || nbytes ) {
- set_lasterr( GCRYERR_INV_ARG );
- return -1;
- }
- if( check_digest_algo( algo ) ) {
- set_lasterr( GCRYERR_INV_MD_ALGO );
- return -1;
- }
- break;
-
- case GCRYCTL_GET_ASNOID: {
- size_t asnlen;
- const char *asn = md_asn_oid( algo, &asnlen, NULL );
- if( buffer && *nbytes >= asnlen ) {
- memcpy( buffer, asn, asnlen );
- *nbytes = asnlen;
- return 0;
- }
- if( !buffer && nbytes ) {
- *nbytes = asnlen;
- return 0;
- }
- set_lasterr( buffer ? GCRYERR_TOO_SHORT : GCRYERR_INV_ARG );
- return -1;
- }
- break;
-
- default:
- set_lasterr( GCRYERR_INV_OP );
- return -1;
+ switch( what ) {
+ case GCRYCTL_TEST_ALGO:
+ if( buffer || nbytes ) {
+ set_lasterr( GCRYERR_INV_ARG );
+ return -1;
}
- return 0;
+ if( check_digest_algo( algo ) ) {
+ set_lasterr( GCRYERR_INV_MD_ALGO );
+ return -1;
+ }
+ break;
+
+ case GCRYCTL_GET_ASNOID: {
+ size_t asnlen;
+ const char *asn = md_asn_oid( algo, &asnlen, NULL );
+ if( buffer && *nbytes >= asnlen ) {
+ memcpy( buffer, asn, asnlen );
+ *nbytes = asnlen;
+ return 0;
+ }
+ if( !buffer && nbytes ) {
+ *nbytes = asnlen;
+ return 0;
+ }
+ set_lasterr( buffer ? GCRYERR_TOO_SHORT : GCRYERR_INV_ARG );
+ return -1;
+ }
+ break;
+
+ default:
+ set_lasterr( GCRYERR_INV_OP );
+ return -1;
+ }
+ return 0;
}
@@ -934,37 +1057,37 @@ gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes)
static void
md_start_debug( GCRY_MD_HD md, const char *suffix )
{
- static int idx=0;
- char buf[25];
-
- if( md->ctx->debug ) {
- log_debug("Oops: md debug already started\n");
- return;
- }
- idx++;
- sprintf(buf, "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 int idx=0;
+ char buf[25];
+
+ if( md->ctx->debug ) {
+ log_debug("Oops: md debug already started\n");
+ return;
+ }
+ idx++;
+ sprintf(buf, "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 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
+ 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
}
@@ -982,34 +1105,31 @@ int
gcry_md_info( GCRY_MD_HD h, int cmd, void *buffer, size_t *nbytes)
{
- switch( cmd ) {
- case GCRYCTL_IS_SECURE:
- return h->ctx->secure;
-
- case GCRYCTL_IS_ALGO_ENABLED:
- {
- int algo;
- struct md_digest_list_s *r;
-
- if (!buffer || (nbytes && *nbytes != sizeof (int))) {
- set_lasterr (GCRYERR_INV_ARG);
- return -1;
- }
- algo = *(int*)buffer;
- for(r=h->ctx->list; r; r = r->next ) {
- if( r->algo == algo )
- return 1;
- }
- }
- break;
-
- default:
- set_lasterr( GCRYERR_INV_OP );
- return -1;
- }
- return 0;
-}
+ switch( cmd ) {
+ case GCRYCTL_IS_SECURE:
+ return h->ctx->secure;
+ case GCRYCTL_IS_ALGO_ENABLED:
+ {
+ int algo;
+ GcryDigestEntry *r;
+ if (!buffer || (nbytes && *nbytes != sizeof (int))) {
+ set_lasterr (GCRYERR_INV_ARG);
+ return -1;
+ }
+ algo = *(int*)buffer;
+ for(r=h->ctx->list; r; r = r->next ) {
+ if( r->digest->id == algo )
+ return 1;
+ }
+ }
+ break;
+ default:
+ set_lasterr( GCRYERR_INV_OP );
+ return -1;
+ }
+ return 0;
+}