diff options
author | Moritz Schulte <mo@g10code.com> | 2003-04-16 16:21:34 +0000 |
---|---|---|
committer | Moritz Schulte <mo@g10code.com> | 2003-04-16 16:21:34 +0000 |
commit | 62ee765f9df47ab2f37cfe00c019ffe81ded664a (patch) | |
tree | 05b8ceb9a842331db561e07b009158bc0e1efe5a /cipher/md.c | |
parent | 05a4715e94bd7d6c7d63c1dc307caa5a330a3b7e (diff) | |
download | libgcrypt-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.c | 1326 |
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; +} |