2003-04-16 Moritz Schulte <moritz@g10code.com>
authorMoritz Schulte <mo@g10code.com>
Wed, 16 Apr 2003 16:21:34 +0000 (16:21 +0000)
committerMoritz Schulte <mo@g10code.com>
Wed, 16 Apr 2003 16:21:34 +0000 (16:21 +0000)
* 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.

28 files changed:
cipher/ChangeLog
cipher/Makefile.am
cipher/arcfour.c
cipher/blowfish.c
cipher/cast5.c
cipher/cipher.c
cipher/crc.c
cipher/des.c
cipher/dsa.c
cipher/elgamal.c
cipher/md.c
cipher/md4.c
cipher/md5.c
cipher/pubkey.c
cipher/rand-internal.h
cipher/random.c
cipher/rijndael.c
cipher/rmd.h
cipher/rmd160.c
cipher/rndegd.c
cipher/rndlinux.c
cipher/rndunix.c
cipher/rndw32.c
cipher/rsa.c
cipher/sha1.c
cipher/sha256.c
cipher/tiger.c
cipher/twofish.c

index bdc5137..d51974c 100644 (file)
@@ -1,5 +1,402 @@
+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.
+
 2003-03-31  Moritz Schulte  <moritz@g10code.com>
 
+       * tiger.c (tiger_get_info): Do not declare static.
+       * sha256.c (sha256_get_info): Likewise.
+       * sha1.c (sha1_get_info): Likewise.
+       * rmd160.c (rmd160_get_info): Likewise.
+       * md5.c (md5_get_info): Likewise.
+       * md4.c (md4_get_info): Likewise.
+       * crc.c (crc_get_info): Likewise.
+
+       * md.c (load_digest_module): Call setup_md_table during
+       initialization.
+       (new_list_item): Link new element into digest_list.
+
        * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
        for do_ctr_encrypt, since these functions are identical.
 
index 9c78703..9dc0c7b 100644 (file)
@@ -1,5 +1,5 @@
 # Makefile for cipher modules
-# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 #
 # This file is part of Libgcrypt.
 #
@@ -26,57 +26,108 @@ noinst_LTLIBRARIES = libcipher.la
 
 #OMIT_DEPENDENCIES = types.h gcrypt.h
 
-
-# The configure script greps the module names from the EXTRA_PROGRAMS line
-EXTRA_PROGRAMS = rndlinux rndunix rndegd rndw32 sha1 sha256 rmd160 md4 md5 tiger crc
-
-EXTRA_rndlinux_SOURCES = rndlinux.c
-EXTRA_rndunix_SOURCES = rndunix.c
-EXTRA_rndegd_SOURCES = rndegd.c
-EXTRA_rndw32_SOURCES = rndw32.c
-EXTRA_md4_SOURCES = md4.c
-EXTRA_md5_SOURCES = md5.c
-EXTRA_rmd160_SOURCES = rmd160.c
-EXTRA_sha1_SOURCES = sha1.c
-EXTRA_sha256_SOURCES = sha256.c
-EXTRA_tiger_SOURCES = tiger.c
-EXTRA_crc_SOURCES = crc.c
-
+if USE_ARCFOUR
+  tmp_arcfour = arcfour.c
+endif
+if USE_BLOWFISH
+  tmp_blowfish = blowfish.c
+endif
+if USE_CAST5
+  tmp_cast5 = cast5.c
+endif
+if USE_DES
+  tmp_des = des.c
+endif
+if USE_AES
+  tmp_aes = rijndael.c
+endif
+if USE_TWOFISH
+  tmp_twofish = twofish.c
+endif
+
+ciphers = \
+$(tmp_arcfour) \
+$(tmp_blowfish) \
+$(tmp_cast5) \
+$(tmp_des) \
+$(tmp_aes) \
+$(tmp_twofish)
+
+if USE_DSA
+  tmp_dsa = dsa.c
+endif
+if USE_RSA
+  tmp_rsa = rsa.c
+endif
+if USE_ELGAMAL
+  tmp_elgamal = elgamal.c
+endif
+
+pubkey_ciphers = \
+$(tmp_dsa) \
+$(tmp_rsa) \
+$(tmp_elgamal)
+
+if USE_CRC
+  tmp_crc = crc.c
+endif
+if USE_MD4
+  tmp_md4 = md4.c
+endif
+if USE_MD5
+  tmp_md5 = md5.c
+endif
+if USE_SHA1
+  tmp_sha1 = sha1.c
+endif
+if USE_SHA256
+  tmp_sha256 = sha256.c
+endif
+if USE_TIGER
+  tmp_tiger = tiger.c
+endif
+if USE_RMD160
+  tmp_rmd160 = rmd160.c
+endif
+
+digests = \
+$(tmp_crc) \
+$(tmp_md4) \
+$(tmp_md5) \
+$(tmp_sha1) \
+$(tmp_sha256) \
+$(tmp_tiger) \
+$(tmp_rmd160)
+
+if USE_RNDLINUX
+  tmp_rndlinux = rndlinux.c
+endif
+if USE_RNDUNIX
+  tmp_rndunix = rndunix.c
+endif
+if USE_RNDEGD
+  tmp_rndegd = rndegd.c
+endif
+if USE_RNDW32
+  tmp_rndw32 = rndw32.c
+endif
+
+random = \
+$(tmp_rndlinux) \
+$(tmp_rndunix) \
+$(tmp_rndegd) \
+$(tmp_rndw32)
 
 libcipher_la_LDFLAGS =
-libcipher_la_SOURCES = cipher.c  \
-                pubkey.c       \
-                md.c           \
-                dynload.c      \
-                dynload.h      \
-                bithelp.h      \
-                des.c          \
-                des.h          \
-                rijndael.c     \
-                twofish.c      \
-                blowfish.c     \
-                blowfish.h     \
-                cast5.c        \
-                cast5.h        \
-                arcfour.c arcfour.h \
-                elgamal.c      \
-                elgamal.h      \
-                primegen.c     \
-                random.h       \
-                random.c       \
-                rand-internal.h \
-                rmd.h          \
-                dsa.h          \
-                dsa.c          \
-                rsa.c rsa.h    \
-                construct.c
-
-# configure creates the constructor file
-BUILT_SOURCES = construct.c
-DISTCLEANFILES = construct.c
-
-libcipher_la_DEPENDENCIES = @STATIC_CIPHER_OBJS@
-libcipher_la_LIBADD =      @STATIC_CIPHER_OBJS@
+libcipher_la_SOURCES = \
+cipher.c $(ciphers) \
+pubkey.c $(pubkey_ciphers) \
+md.c  $(digests) \
+bithelp.h   \
+primegen.c  \
+random.c random.h $(random) \
+rand-internal.h \
+rmd.h
 
 # We need to lower the optimization for this module.
 tiger.o: $(srcdir)/tiger.c
@@ -84,7 +135,3 @@ tiger.o: $(srcdir)/tiger.c
 
 tiger.lo: $(srcdir)/tiger.c
        `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | sed -e 's/-O[2-9s]*/-O1/g' `
-
-
-
-
index 702d0a7..8e2ba4f 100644 (file)
 #include <string.h>
 #include "types.h"
 #include "g10lib.h"
-#include "arcfour.h"
+#include "cipher.h"
 
 static const char *selftest(void);
 
-
 typedef struct {
     int idx_i, idx_j;
     byte sbox[256];
 } ARCFOUR_context;
 
-
 static void
 do_encrypt_stream( ARCFOUR_context *ctx,
-                byte *outbuf, const byte *inbuf, unsigned int length )
+                  byte *outbuf, const byte *inbuf, unsigned int length )
 {
   register int i = ctx->idx_i;
   register int j = ctx->idx_j;
@@ -64,22 +62,23 @@ do_encrypt_stream( ARCFOUR_context *ctx,
 }
 
 static void
-encrypt_stream( ARCFOUR_context *ctx,
-                byte *outbuf, const byte *inbuf, unsigned int length )
+encrypt_stream (void *context,
+                byte *outbuf, const byte *inbuf, unsigned int length)
 {
-
-    do_encrypt_stream (ctx, outbuf, inbuf, length );
-    _gcry_burn_stack (64);
+  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+  do_encrypt_stream (ctx, outbuf, inbuf, length );
+  _gcry_burn_stack (64);
 }
 
 
 static int
-do_arcfour_setkey( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
+do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
 {
     static int initialized;
     static const char* selftest_failed;
     int i, j;
     byte karr[256];
+    ARCFOUR_context *ctx = (ARCFOUR_context *) context;
 
     if( !initialized ) {
        initialized = 1;
@@ -111,11 +110,12 @@ do_arcfour_setkey( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
 }
 
 static int
-arcfour_setkey ( ARCFOUR_context *ctx, const byte *key, unsigned int keylen )
+arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
 {
-    int rc = do_arcfour_setkey (ctx, key, keylen );
-    _gcry_burn_stack (300);
-    return rc;
+  ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+  int rc = do_arcfour_setkey (ctx, key, keylen );
+  _gcry_burn_stack (300);
+  return rc;
 }
 
 
@@ -127,9 +127,9 @@ selftest(void)
     
     /* Test vector from Cryptlib labeled there:
      * "from the State/Commerce Department" */
-    static const byte key_1[] =
+    static byte key_1[] =
         { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
-    static const byte plaintext_1[] =
+    static byte plaintext_1[] =
         { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
     static const byte ciphertext_1[] =
         { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
@@ -145,38 +145,10 @@ selftest(void)
     return NULL;
 }
 
+\f
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- * NOTE: This is a special get_info function which is different from all
- * others because arcfour is a stream cipher.  We use this hack until
- * we have redesign the interface.
- */
-const char *
-_gcry_arcfour_get_info( int algo, size_t *keylen, size_t *blocksize,
-                  size_t *contextsize,
-                  int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
-                  void (**r_stencrypt)( void *c, byte *outbuf,
-                                       byte *inbuf, unsigned int nbytes ),
-                  void (**r_stdecrypt)( void *c, byte *outbuf,
-                                       byte *inbuf, unsigned int nbytes )
-                )
-{
-    *keylen = 128; /* arbitrary value */
-    *blocksize = 1;
-    *contextsize = sizeof(ARCFOUR_context);
-    *(int  (**)(ARCFOUR_context*, const byte*, unsigned))r_setkey
-                                                       = arcfour_setkey;
-    *(void (**)(ARCFOUR_context*, byte*, const byte*, unsigned))r_stencrypt
-                                                       = encrypt_stream;
-    *(void (**)(ARCFOUR_context*, byte*, const byte*, unsigned))r_stdecrypt
-                                                       = encrypt_stream;
-
-
-    if( algo == GCRY_CIPHER_ARCFOUR )
-       return "ARCFOUR";
-    return NULL;
-}
+GcryCipherSpec cipher_spec_arcfour =
+  {
+    "ARCFOUR", GCRY_CIPHER_ARCFOUR, 1, 128, sizeof (ARCFOUR_context),
+    arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
+  };
index a911c5b..707c956 100644 (file)
 #include <assert.h>
 #include "types.h"
 #include "g10lib.h"
-#include "blowfish.h"
-#include "dynload.h"
-
-
-
-#define CIPHER_ALGO_BLOWFISH    4  /* blowfish 128 bit key */
-
-#define FNCCAST_SETKEY(f)  (int(*)(void*, byte*, unsigned))(f)
-#define FNCCAST_CRYPT(f)   (void(*)(void*, byte*, byte*))(f)
+#include "cipher.h"
 
 #define BLOWFISH_BLOCKSIZE 8
 #define BLOWFISH_ROUNDS 16
@@ -57,9 +49,9 @@ typedef struct {
     u32 p[BLOWFISH_ROUNDS+2];
 } BLOWFISH_context;
 
-static int  bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen );
-static void encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf );
-static void decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf );
+static int  bf_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
 
 
 /* precomputed S boxes */
@@ -415,7 +407,7 @@ decrypt(  BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
 #undef R
 
 static void
-do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 {
     u32 d1, d2;
 
@@ -433,15 +425,16 @@ do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
 }
 
 static void
-encrypt_block ( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+encrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
-    do_encrypt_block (bc, outbuf, inbuf);
-    _gcry_burn_stack (64);
+  BLOWFISH_context *bc = (BLOWFISH_context *) context;
+  do_encrypt_block (bc, outbuf, inbuf);
+  _gcry_burn_stack (64);
 }
 
 
 static void
-do_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
 {
     u32 d1, d2;
 
@@ -459,10 +452,11 @@ do_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
 }
 
 static void
-decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf )
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
-    do_decrypt_block (bc, outbuf, inbuf);
-    _gcry_burn_stack (64);
+  BLOWFISH_context *bc = (BLOWFISH_context *) context;
+  do_decrypt_block (bc, outbuf, inbuf);
+  _gcry_burn_stack (64);
 }
 
 
@@ -476,19 +470,19 @@ selftest(void)
     byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
     byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
 
-    bf_setkey( &c, "abcdefghijklmnopqrstuvwxyz", 26 );
-    encrypt_block( &c, buffer, plain );
+    bf_setkey( (void *) &c, "abcdefghijklmnopqrstuvwxyz", 26 );
+    encrypt_block( (void *) &c, buffer, plain );
     if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
        return "Blowfish selftest failed (1).";
-    decrypt_block( &c, buffer, buffer );
+    decrypt_block( (void *) &c, buffer, buffer );
     if( memcmp( buffer, plain, 8 ) )
        return "Blowfish selftest failed (2).";
 
-    bf_setkey( &c, key3, 8 );
-    encrypt_block( &c, buffer, plain3 );
+    bf_setkey( (void *) &c, key3, 8 );
+    encrypt_block( (void *) &c, buffer, plain3 );
     if( memcmp( buffer, cipher3, 8 ) )
        return "Blowfish selftest failed (3).";
-    decrypt_block( &c, buffer, buffer );
+    decrypt_block( (void *) &c, buffer, buffer );
     if( memcmp( buffer, plain3, 8 ) )
        return "Blowfish selftest failed (4).";
     return NULL;
@@ -497,7 +491,7 @@ selftest(void)
 
 
 static int
-do_bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
+do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
 {
     int i, j;
     u32 data, datal, datar;
@@ -581,40 +575,19 @@ do_bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
 
 
 static int
-bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen )
+bf_setkey (void *context, const byte *key, unsigned keylen)
 {
-    int rc = do_bf_setkey (c, key, keylen);
-    _gcry_burn_stack (64);
-    return rc;
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  int rc = do_bf_setkey (c, key, keylen);
+  _gcry_burn_stack (64);
+  return rc;
 }
 
+\f
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-const char *
-_gcry_blowfish_get_info( int algo, size_t *keylen,
-                  size_t *blocksize, size_t *contextsize,
-                  int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
-                  void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
-                  void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
-                )
-{
-    *keylen = 128;
-    *blocksize = BLOWFISH_BLOCKSIZE;
-    *contextsize = sizeof(BLOWFISH_context);
-    *(int  (**)(BLOWFISH_context*, byte*, unsigned))r_setkey
-                                                       = bf_setkey;
-    *(void (**)(BLOWFISH_context*, byte*, byte*))r_encrypt
-                                                       = encrypt_block;
-    *(void (**)(BLOWFISH_context*, byte*, byte*))r_decrypt
-                                                       = decrypt_block;
-
-    if( algo == CIPHER_ALGO_BLOWFISH )
-       return "BLOWFISH";
-    return NULL;
-}
-
+GcryCipherSpec cipher_spec_blowfish =
+  {
+    "BLOWFISH", GCRY_CIPHER_BLOWFISH, BLOWFISH_BLOCKSIZE, 128,
+    sizeof (BLOWFISH_context),
+    bf_setkey, encrypt_block, decrypt_block,
+  };
index e378854..89ff6cf 100644 (file)
 #include <string.h>
 #include "g10lib.h"
 #include "types.h"
-#include "cast5.h"
-
-
-#define CIPHER_ALGO_CAST5       3
-
-#define FNCCAST_SETKEY(f)  (int(*)(void*, byte*, unsigned))(f)
-#define FNCCAST_CRYPT(f)   (void(*)(void*, byte*, byte*))(f)
+#include "cipher.h"
 
 #define CAST5_BLOCKSIZE 8
 
@@ -56,9 +50,9 @@ typedef struct {
     byte Kr[16];
 } CAST5_context;
 
-static int  cast_setkey( CAST5_context *c, byte *key, unsigned keylen );
-static void encrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
-static void decrypt_block( CAST5_context *bc, byte *outbuf, byte *inbuf );
+static int  cast_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
 
 
 
@@ -358,7 +352,7 @@ rol(int n, u32 x)
     (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
 
 static void
-do_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
 {
     u32 l, r, t;
     u32 I;   /* used by the Fx macros */
@@ -412,16 +406,17 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
 }
 
 static void
-encrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
 {
-    do_encrypt_block (c, outbuf, inbuf);
-    _gcry_burn_stack (20+4*sizeof(void*));
+  CAST5_context *c = (CAST5_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  _gcry_burn_stack (20+4*sizeof(void*));
 }
 
 \f
 
 static void
-do_decrypt_block (CAST5_context *c, byte *outbuf, byte *inbuf )
+do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
 {
     u32 l, r, t;
     u32 I;
@@ -462,10 +457,11 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, byte *inbuf )
 }
 
 static void
-decrypt_block( CAST5_context *c, byte *outbuf, byte *inbuf )
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
-    do_decrypt_block (c, outbuf, inbuf);
-    _gcry_burn_stack (20+4*sizeof(void*));
+  CAST5_context *c = (CAST5_context *) context;
+  do_decrypt_block (c, outbuf, inbuf);
+  _gcry_burn_stack (20+4*sizeof(void*));
 }
 \f
 
@@ -566,7 +562,7 @@ key_schedule( u32 *x, u32 *z, u32 *k )
 
 
 static int
-do_cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
+do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
 {
   static int initialized;
   static const char* selftest_failed;
@@ -609,14 +605,16 @@ do_cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
 }
 
 static int
-cast_setkey( CAST5_context *c, byte *key, unsigned keylen )
+cast_setkey (void *context, const byte *key, unsigned keylen )
 {
-    int rc = do_cast_setkey (c, key, keylen);
-    _gcry_burn_stack (96+7*sizeof(void*));
-    return rc;
+  CAST5_context *c = (CAST5_context *) context;
+  int rc = do_cast_setkey (c, key, keylen);
+  _gcry_burn_stack (96+7*sizeof(void*));
+  return rc;
 }
 \f
 
+#if 0
 /****************
  * Return some information about the algorithm.  We need algo here to
  * distinguish different flavors of the algorithm.
@@ -642,8 +640,15 @@ _gcry_cast5_get_info( int algo, size_t *keylen,
                                                        = decrypt_block;
 
 
-    if( algo == CIPHER_ALGO_CAST5 )
+    if( algo == GCRY_CIPHER_CAST5 )
        return "CAST5";
     return NULL;
 }
 
+#endif
+
+GcryCipherSpec cipher_spec_cast5 =
+  {
+    "CAST5", GCRY_CIPHER_CAST5, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
+    cast_setkey, encrypt_block, decrypt_block,
+  };
index 1fa28c2..f7711fb 100644 (file)
 
 #include "g10lib.h"
 #include "cipher.h"
-#include "des.h"
-#include "blowfish.h"
-#include "cast5.h"
-#include "arcfour.h"
-#include "dynload.h"
+#include "ath.h"
 
 #define MAX_BLOCKSIZE 16
 #define TABLE_SIZE 14
 #define CTX_MAGIC_NORMAL 0x24091964
 #define CTX_MAGIC_SECURE 0x46919042
 
-static struct {
+static struct
+{
   const char *oidstring;
   int algo;
   int mode;
-} oid_table[] = {
-  { "1.2.840.113549.3.7",      GCRY_CIPHER_3DES,   GCRY_CIPHER_MODE_CBC },
-
-  /* OIDs from NIST. See http://csrc.nist.gov.csor/ */
-  { "2.16.840.1.101.3.4.1.1",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
-  { "2.16.840.1.101.3.4.1.2",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
-  { "2.16.840.1.101.3.4.1.3",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
-  { "2.16.840.1.101.3.4.1.4",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
-  { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
-  { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
-  { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
-  { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
-  { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
-  { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
-  { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
-  { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
-
-  /* Teletrust specific OID for 3DES. */
-  { "1.3.36.3.1.3.2.1",        GCRY_CIPHER_3DES,   GCRY_CIPHER_MODE_CBC },
-
-  {NULL}
-};
-
-
-struct cipher_table_s {
-    const char *name;
-    int algo;
-    size_t blocksize;
-    size_t keylen;
-    size_t contextsize; /* allocate this amount of context */
-    int  (*setkey)( void *c, byte *key, unsigned keylen );
-    void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
-    void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
-    void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
-    void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
-};
+} oid_table[] =
+  {
+    { "1.2.840.113549.3.7",      GCRY_CIPHER_3DES,   GCRY_CIPHER_MODE_CBC },
+
+    /* OIDs from NIST. See http://csrc.nist.gov.csor/ */
+    { "2.16.840.1.101.3.4.1.1",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.2",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.3",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.4",  GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
+    { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
+    { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
+    { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
+    { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
+    { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
+
+    /* Teletrust specific OID for 3DES. */
+    { "1.3.36.3.1.3.2.1",        GCRY_CIPHER_3DES,   GCRY_CIPHER_MODE_CBC },
+
+    { NULL }
+  };
+
+/* This is the list of the default ciphers, which are included in
+   libgcrypt.  */
+static struct
+{
+  GcryCipherSpec *cipher;
+} cipher_table[] =
+  {
+#if USE_BLOWFISH
+    { &cipher_spec_blowfish,  },
+#endif
+#if USE_DES
+    { &cipher_spec_des        },
+    { &cipher_spec_tripledes  },
+#endif
+#if USE_ARCFOUR
+    { &cipher_spec_arcfour    },
+#endif
+#if USE_CAST5
+    { &cipher_spec_cast5      },
+#endif
+#if USE_AES
+    { &cipher_spec_aes        },
+    { &cipher_spec_aes192     },
+    { &cipher_spec_aes256     },
+#endif
+#if USE_TWOFISH
+    { &cipher_spec_twofish    },
+    { &cipher_spec_twofish128 },
+#endif
+    { NULL                    },
+  };
+
+/* List of registered ciphers.  */
+static GcryModule *ciphers_registered;
+
+/* This is the lock protecting CIPHERS_REGISTERED.  */
+static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
+
+/* Flag to check wether the default ciphers have already been
+   registered.  */
+static int default_ciphers_registered;
+
+/* Convenient macro for registering the default ciphers.  */
+#define REGISTER_DEFAULT_CIPHERS                   \
+  do                                               \
+    {                                              \
+      ath_mutex_lock (&ciphers_registered_lock);   \
+      if (! default_ciphers_registered)            \
+        {                                          \
+          gcry_cipher_register_default ();         \
+          default_ciphers_registered = 1;          \
+        }                                          \
+      ath_mutex_unlock (&ciphers_registered_lock); \
+    }                                              \
+  while (0)
+
+
+/* These dummy functions are used in case a cipher implementation
+   refuses to provide it's own functions.  */
 
-static struct cipher_table_s cipher_table[TABLE_SIZE];
-static int disabled_algos[TABLE_SIZE];
-
-struct gcry_cipher_handle {
-    int magic;
-    int  algo;
-    int  mode;
-    unsigned int flags;
-    int algo_index;
-    size_t blocksize;
-    byte iv[MAX_BLOCKSIZE];    /* (this should be ulong aligned) */
-    byte lastiv[MAX_BLOCKSIZE];
-    int  unused;  /* in IV */
-    byte ctr[MAX_BLOCKSIZE];    /* for Counter (CTR) mode */
-    int  (*setkey)( void *c, byte *key, unsigned keylen );
-    void (*encrypt)( void *c, byte *outbuf, byte *inbuf );
-    void (*decrypt)( void *c, byte *outbuf, byte *inbuf );
-    void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
-    void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n );
-    PROPERLY_ALIGNED_TYPE context;
-};
+static int
+dummy_setkey (void *c, const unsigned char *key, unsigned keylen)
+{
+  return 0;
+}
 
+static void
+dummy_encrypt_block (void *c,
+                    unsigned char *outbuf, const unsigned char *inbuf)
+{
+  BUG();
+}
 
-static int
-dummy_setkey( void *c, byte *key, unsigned keylen ) { return 0; }
 static void
-dummy_encrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
+dummy_decrypt_block (void *c,
+                    unsigned char *outbuf, const unsigned char *inbuf)
+{
+  BUG();
+}
+
 static void
-dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
+dummy_encrypt_stream (void *c,
+                     unsigned char *outbuf, const unsigned char *inbuf,
+                     unsigned int n)
+{
+  BUG();
+}
+
 static void
-dummy_encrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
-{ BUG(); }
+dummy_decrypt_stream (void *c,
+                     unsigned char *outbuf, const unsigned char *inbuf,
+                     unsigned int n)
+{
+  BUG();
+}
+
+/* Internal function.  Register all the ciphers included in
+   CIPHER_TABLE.  */
 static void
-dummy_decrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n )
-{ BUG(); }
+gcry_cipher_register_default (void)
+{
+  int i, err = 0;
+  
+  for (i = 0; (! err) && cipher_table[i].cipher; i++)
+    {
+      if (! cipher_table[i].cipher->setkey)
+       cipher_table[i].cipher->setkey = dummy_setkey;
+      if (! cipher_table[i].cipher->encrypt)
+       cipher_table[i].cipher->encrypt = dummy_encrypt_block;
+      if (! cipher_table[i].cipher->decrypt)
+       cipher_table[i].cipher->decrypt = dummy_decrypt_block;
+      if (! cipher_table[i].cipher->stencrypt)
+       cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
+      if (! cipher_table[i].cipher->stdecrypt)
+       cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
+
+      err = _gcry_module_add (&ciphers_registered,
+                             (void *) cipher_table[i].cipher,
+                             NULL);
+    }
 
+  if (err)
+    BUG ();
+}
 
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_cipher_lookup_func_id (void *spec, void *data)
+{
+  GcryCipherSpec *cipher = (GcryCipherSpec *) spec;
+  int id = *((int *) data);
 
-/****************
- * Put the static entries into the table.
- */
-static void
-setup_cipher_table(void)
+  return (cipher->id == id);
+}
+
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_cipher_lookup_func_name (void *spec, void *data)
 {
-    int i;
+  GcryCipherSpec *cipher = (GcryCipherSpec *) spec;
+  char *name = (char *) data;
 
-    for (i=0; i < TABLE_SIZE; i++ ) {
-        cipher_table[i].encrypt = dummy_encrypt_block;
-        cipher_table[i].decrypt = dummy_decrypt_block;
-        cipher_table[i].stencrypt = dummy_encrypt_stream;
-        cipher_table[i].stdecrypt = dummy_decrypt_stream;
-    }
-    
-    i = 0;
-    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL;
-    cipher_table[i].name = _gcry_rijndael_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL192;
-    cipher_table[i].name = _gcry_rijndael_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL256;
-    cipher_table[i].name = _gcry_rijndael_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_TWOFISH;
-    cipher_table[i].name = _gcry_twofish_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_BLOWFISH;
-    cipher_table[i].name = _gcry_blowfish_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_CAST5;
-    cipher_table[i].name = _gcry_cast5_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_3DES;
-    cipher_table[i].name = _gcry_des_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_ARCFOUR;
-    cipher_table[i].name = _gcry_arcfour_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].stencrypt,
-                                        &cipher_table[i].stdecrypt   );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-    cipher_table[i].algo = GCRY_CIPHER_DES;
-    cipher_table[i].name = _gcry_des_get_info( cipher_table[i].algo,
-                                        &cipher_table[i].keylen,
-                                        &cipher_table[i].blocksize,
-                                        &cipher_table[i].contextsize,
-                                        &cipher_table[i].setkey,
-                                        &cipher_table[i].encrypt,
-                                        &cipher_table[i].decrypt     );
-    if( !cipher_table[i].name )
-       BUG();
-    i++;
-
-    cipher_table[i].algo = CIPHER_ALGO_DUMMY;
-    cipher_table[i].name = "DUMMY";
-    cipher_table[i].blocksize = 8;
-    cipher_table[i].keylen = 128;
-    cipher_table[i].contextsize = 0;
-    cipher_table[i].setkey = dummy_setkey;
-    i++;
-
-    for( ; i < TABLE_SIZE; i++ )
-       cipher_table[i].name = NULL;
+  return (! stricmp (cipher->name, name));
 }
 
+/* Internal function.  Lookup a cipher entry by it's ID.  */
+static GcryModule *
+gcry_cipher_lookup_id (int id)
+{
+  GcryModule *cipher;
 
-/****************
- * Try to load all modules and return true if new modules are available
- */
+  cipher = _gcry_module_lookup (ciphers_registered, (void *) &id,
+                               gcry_cipher_lookup_func_id);
+
+  return cipher;
+}
+
+/* Internal function.  Lookup a cipher entry by it's name.  */
+static GcryModule *
+gcry_cipher_lookup_name (const char *name)
+{
+  GcryModule *cipher;
+
+  cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
+                               gcry_cipher_lookup_func_name);
+
+  return cipher;
+}
+
+/* Return a new, unused cipher ID for a user-provided cipher
+   implementation.  */
 static int
-load_cipher_modules(void)
+gcry_cipher_id_new (void)
 {
-    static int done = 0;
-    static int initialized = 0;
-    void *context = NULL;
-    struct cipher_table_s *ct;
-    int ct_idx;
-    int i;
-    const char *name;
-    int any = 0;
-
-    if( !initialized ) {
-       _gcry_cipher_modules_constructor();
-       setup_cipher_table(); /* load static modules on the first call */
-       initialized = 1;
-       return 1;
-    }
+  int id, id_start = 500, id_end = 600;        /* FIXME.  */
+  
+  for (id = id_start; id < id_end; id++)
+    if (! gcry_cipher_lookup_id (id))
+      return id;
 
-    if( done )
-       return 0;
-    done = 1;
+  return 0;
+}
 
-    for(ct_idx=0, ct = cipher_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
-       if( !ct->name )
-           break;
-    }
-    if( ct_idx >= TABLE_SIZE-1 )
-       BUG(); /* table already full */
-    /* now load all extensions */
-    while( (name = _gcry_enum_gnupgext_ciphers( &context, &ct->algo,
-                               &ct->keylen, &ct->blocksize, &ct->contextsize,
-                               &ct->setkey, &ct->encrypt, &ct->decrypt)) ) {
-       if( ct->blocksize != 8 && ct->blocksize != 16 ) {
-           log_info("skipping cipher %d: unsupported blocksize\n", ct->algo);
-           continue;
-       }
-       for(i=0; cipher_table[i].name; i++ )
-           if( cipher_table[i].algo == ct->algo )
-               break;
-       if( cipher_table[i].name ) {
-           log_info("skipping cipher %d: already loaded\n", ct->algo );
-           continue;
-       }
-       /* put it into the table */
-       if( _gcry_log_verbosity( 2 ) )
-           log_info("loaded cipher %d (%s)\n", ct->algo, name);
-       ct->name = name;
-       ct_idx++;
-       ct++;
-       any = 1;
-       /* check whether there are more available table slots */
-       if( ct_idx >= TABLE_SIZE-1 ) {
-           log_info("cipher table full; ignoring other extensions\n");
-           break;
-       }
+/* Public function.  Register a provided CIPHER.  Returns zero on
+   success, in which case the chosen cipher ID has been stored in
+   CIPHER, or an error code.  */
+int
+gcry_cipher_register (GcryCipherSpec *cipher,
+                     GcryModule **module)
+{
+  int id, err = 0;
+  GcryModule *mod;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+
+  id = gcry_cipher_id_new ();
+  if (! id)
+    err = GCRYERR_INTERNAL;    /* FIXME?  */
+  else
+    {
+      cipher->id = id;
+      err = _gcry_module_add (&ciphers_registered, (void *) cipher,
+                             &mod);
     }
-    _gcry_enum_gnupgext_ciphers( &context, NULL, NULL, NULL, NULL,
-                                          NULL, NULL, NULL );
-    return any;
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  if (! err)
+    *module = mod;
+
+  return err;
+}
+
+/* Public function.  Unregister the cipher identified by MODULE, which
+   must have been registered with gcry_cipher_register.  */
+void
+gcry_cipher_unregister (GcryModule *module)
+{
+  ath_mutex_lock (&ciphers_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&ciphers_registered_lock);
 }
 
+/* The handle structure.  */
+struct gcry_cipher_handle
+{
+  int magic;
+  GcryCipherSpec *cipher;
+  GcryModule *module;
+  int  mode;
+  unsigned int flags;
+  byte iv[MAX_BLOCKSIZE];      /* (this should be ulong aligned) */
+  byte lastiv[MAX_BLOCKSIZE];
+  int  unused;  /* in IV */
+  byte ctr[MAX_BLOCKSIZE];    /* for Counter (CTR) mode */
+  PROPERLY_ALIGNED_TYPE context;
+};
+
 /* locate the OID in the oid table and return the index or -1 when not
    found */
 static int 
 search_oid (const char *string)
 {
-  int i;
   const char *s;
+  int i;
 
   if (string && (digitp (string)
                  || !strncmp (string, "oid.", 4) 
@@ -342,8 +331,8 @@ search_oid (const char *string)
 int
 gcry_cipher_map_name( const char *string )
 {
-  int i;
-  const char *s;
+  GcryModule *cipher;
+  int i, id = 0;
   
   if (!string)
     return 0;
@@ -365,15 +354,19 @@ gcry_cipher_map_name( const char *string )
   i = search_oid (string);
   if (i != -1)
     return oid_table[i].algo;
-  
-  do 
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_name (string);
+  if (cipher)
     {
-      for (i=0; (s=cipher_table[i].name); i++ )
-        if ( !stricmp( s, string ) )
-          return cipher_table[i].algo;
-    } 
-  while ( load_cipher_modules() );
-  return 0;
+      id = ((GcryCipherSpec *) cipher->spec)->id;
+      _gcry_module_release (cipher);
+    }
+  ath_mutex_unlock (&ciphers_registered_lock);
+  
+  return id;
 }
 
 int
@@ -390,16 +383,23 @@ gcry_cipher_mode_from_oid (const char *string)
  * Map a cipher algo to a string
  */
 static const char *
-cipher_algo_to_string( int algo )
+cipher_algo_to_string (int id)
 {
-    int i;
+  GcryModule *cipher;
+  const char *name = NULL;
+
+  REGISTER_DEFAULT_CIPHERS;
 
-    do {
-       for(i=0; cipher_table[i].name; i++ )
-           if( cipher_table[i].algo == algo )
-               return cipher_table[i].name;
-    } while( load_cipher_modules() );
-    return NULL;
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_id (id);
+  if (cipher)
+    {
+      name = ((GcryCipherSpec *) cipher->spec)->name;
+      _gcry_module_release (cipher);
+    }
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return name;
 }
 
 /****************
@@ -407,89 +407,105 @@ cipher_algo_to_string( int algo )
  * string when there is no algo.  It will never return NULL.
  */
 const char *
-gcry_cipher_algo_name( int algo )
+gcry_cipher_algo_name (int id)
 {
-    const char *s = cipher_algo_to_string( algo );
-    return s? s: "";
+  const char *s = cipher_algo_to_string (id);
+  return s ? s : "";
 }
 
 
-
 static void
-disable_cipher_algo( int algo )
+disable_cipher_algo (int id)
 {
-    int i;
+  GcryModule *cipher;
 
-    for(i=0; i < DIM(disabled_algos); i++ ) {
-       if( !disabled_algos[i] || disabled_algos[i] == algo ) {
-           disabled_algos[i] = algo;
-           return;
-       }
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_id (id);
+  if (cipher)
+    {
+      if (! (cipher->flags & FLAG_MODULE_DISABLED))
+       cipher->flags |= FLAG_MODULE_DISABLED;
+      _gcry_module_release (cipher);
     }
-    /* fixme: we should use a linked list */
-    log_fatal("can't disable cipher algo %d: table full\n", algo );
+  ath_mutex_unlock (&ciphers_registered_lock);
 }
 
+
 /****************
- * Return 0 if the cipher algo is available
+ * Return 0 if the cipher algo is available.
  */
+
 static int
-check_cipher_algo( int algo )
+check_cipher_algo (int id)
 {
-    int i;
+  GcryModule *cipher;
+  int err = 0;
 
-    do {
-       for(i=0; cipher_table[i].name; i++ )
-          if( cipher_table[i].algo == algo ) {
-               for(i=0; i < DIM(disabled_algos); i++ ) {
-                  if( disabled_algos[i] == algo )
-                      return GCRYERR_INV_CIPHER_ALGO;
-               }
-               return 0; /* okay */
-          }
-    } while( load_cipher_modules() );
-    return GCRYERR_INV_CIPHER_ALGO;
-}
+  REGISTER_DEFAULT_CIPHERS;
 
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_id (id);
+  if (cipher)
+    {
+      if (cipher->flags & FLAG_MODULE_DISABLED)
+       err = GCRYERR_INV_CIPHER_ALGO;
+      _gcry_module_release (cipher);
+    }
+  else
+    err = GCRYERR_INV_CIPHER_ALGO;
+  ath_mutex_unlock (&ciphers_registered_lock);
+  
+  return err;
+}
 
 static unsigned
-cipher_get_keylen( int algo )
+cipher_get_keylen (int id)
 {
-    int i;
-    unsigned len = 0;
-
-    do {
-       for(i=0; cipher_table[i].name; i++ ) {
-           if( cipher_table[i].algo == algo ) {
-               len = cipher_table[i].keylen;
-               if( !len )
-                   log_bug("cipher %d w/o key length\n", algo );
-               return len;
-           }
-       }
-    } while( load_cipher_modules() );
-    log_bug("cipher %d not found\n", algo );
-    return 0;
+  GcryModule *cipher;
+  unsigned len = 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_id (id);
+  if (cipher)
+    {
+      len = ((GcryCipherSpec *) cipher->spec)->keylen;
+      if (! len)
+       log_bug ("cipher %d w/o key length\n", id);
+      _gcry_module_release (cipher);
+    }
+  else
+    log_bug ("cipher %d not found\n", id);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return len;
 }
 
 static unsigned
-cipher_get_blocksize( int algo )
+cipher_get_blocksize (int id)
 {
-    int i;
-    unsigned len = 0;
-
-    do {
-       for(i=0; cipher_table[i].name; i++ ) {
-           if( cipher_table[i].algo == algo ) {
-               len = cipher_table[i].blocksize;
-               if( !len )
-                   log_bug("cipher %d w/o blocksize\n", algo );
-               return len;
-           }
-       }
-    } while( load_cipher_modules() );
-    log_bug("cipher %d not found\n", algo );
-    return 0;
+  GcryModule *cipher;
+  unsigned len = 0;
+
+  REGISTER_DEFAULT_CIPHERS;
+
+  ath_mutex_lock (&ciphers_registered_lock);
+  cipher = gcry_cipher_lookup_id (id);
+  if (cipher)
+    {
+      len = ((GcryCipherSpec *) cipher->spec)->blocksize;
+      if (! len)
+         log_bug ("cipher %d w/o blocksize\n", id);
+      _gcry_module_release (cipher);
+    }
+  else
+    log_bug ("cipher %d not found\n", id);
+  ath_mutex_unlock (&ciphers_registered_lock);
+
+  return len;
 }
 
 
@@ -503,16 +519,34 @@ GCRY_CIPHER_HD
 gcry_cipher_open( int algo, int mode, unsigned int flags )
 {
     GCRY_CIPHER_HD h;
-    int idx;
     int secure = (flags & GCRY_CIPHER_SECURE);
+    GcryCipherSpec *cipher;
+    GcryModule *module;
 
     fast_random_poll();
 
-    /* check whether the algo is available */
-    if( check_cipher_algo( algo ) ) {
-       set_lasterr( GCRYERR_INV_CIPHER_ALGO );
+    REGISTER_DEFAULT_CIPHERS;
+
+    /* Fetch the according module and check wether the cipher is
+       marked available for use.  */
+    ath_mutex_lock (&ciphers_registered_lock);
+    module = gcry_cipher_lookup_id (algo);
+    if (module)
+      {
+       if (module->flags & FLAG_MODULE_DISABLED)
+         {
+           set_lasterr (GCRYERR_INV_CIPHER_ALGO);
+           _gcry_module_release (module);
+           return NULL;
+         }
+      }
+    else
+      {
+       set_lasterr (GCRYERR_INV_CIPHER_ALGO);
        return NULL;
-    }
+      }
+    cipher = (GcryCipherSpec *) module->spec;
+    ath_mutex_unlock (&ciphers_registered_lock);
 
     /* check flags */
     if( (flags & ~(GCRY_CIPHER_SECURE|
@@ -524,34 +558,26 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
        return NULL;
     }
 
-    /* get the table index of the algo */
-    for(idx=0; cipher_table[idx].name; idx++ )
-       if( cipher_table[idx].algo == algo )
-           break;
-    if( !cipher_table[idx].name )
-       BUG(); /* check_cipher_algo() should have loaded the algo */
-
-    if( algo == CIPHER_ALGO_DUMMY )
-       mode = GCRY_CIPHER_MODE_NONE;  /* force this mode for dummy algo */
-
     /* check that a valid mode has been requested */
     switch( mode ) {
       case GCRY_CIPHER_MODE_ECB:
       case GCRY_CIPHER_MODE_CBC:
       case GCRY_CIPHER_MODE_CFB:
       case GCRY_CIPHER_MODE_CTR:
-        if ( cipher_table[idx].encrypt == dummy_encrypt_block
-             || cipher_table[idx].decrypt == dummy_decrypt_block ) {
+        if ((cipher->encrypt == dummy_encrypt_block)
+           || (cipher->decrypt == dummy_decrypt_block))
+         {
             set_lasterr( GCRYERR_INV_CIPHER_MODE );
             return NULL;
-        }
+         }
         break;
       case GCRY_CIPHER_MODE_STREAM:
-        if ( cipher_table[idx].stencrypt == dummy_encrypt_stream
-             || cipher_table[idx].stdecrypt == dummy_decrypt_stream ) {
+        if ((cipher->stencrypt == dummy_encrypt_stream)
+           || (cipher->stdecrypt == dummy_decrypt_stream))
+         {
             set_lasterr( GCRYERR_INV_CIPHER_MODE );
             return NULL;
-        }
+         }
        break;
       case GCRY_CIPHER_MODE_NONE:
        /* FIXME: issue a warning when this mode is used */
@@ -565,27 +591,21 @@ gcry_cipher_open( int algo, int mode, unsigned int flags )
 
     h = secure ? gcry_calloc_secure( 1,
                                     sizeof *h
-                                    + 2 * cipher_table[idx].contextsize
+                                    + 2 * cipher->contextsize
                                     - sizeof (PROPERLY_ALIGNED_TYPE) )
               : gcry_calloc( 1,
                              sizeof *h
-                             + 2 * cipher_table[idx].contextsize
+                             + 2 * cipher->contextsize
                              - sizeof (PROPERLY_ALIGNED_TYPE) );
     if( !h ) {
        set_lasterr( GCRYERR_NO_MEM );
        return NULL;
     }
     h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
-    h->algo = algo;
+    h->cipher = cipher;
+    h->module = module;
     h->mode = mode;
     h->flags = flags;
-    h->algo_index = idx;
-    h->blocksize = cipher_table[idx].blocksize;
-    h->setkey  = cipher_table[idx].setkey;
-    h->encrypt = cipher_table[idx].encrypt;
-    h->decrypt = cipher_table[idx].decrypt;
-    h->stencrypt = cipher_table[idx].stencrypt;
-    h->stdecrypt = cipher_table[idx].stdecrypt;
 
     return h;
 }
@@ -600,6 +620,10 @@ gcry_cipher_close( GCRY_CIPHER_HD h )
        _gcry_fatal_error(GCRYERR_INTERNAL,
                        "gcry_cipher_close: already closed/invalid handle");
     h->magic = 0;
+
+    ath_mutex_lock (&ciphers_registered_lock);
+    _gcry_module_release (h->module);
+    ath_mutex_unlock (&ciphers_registered_lock);
     gcry_free(h);
 }
 
@@ -609,12 +633,12 @@ cipher_setkey( GCRY_CIPHER_HD c, byte *key, unsigned keylen )
 {
     int ret;
 
-    ret = (*c->setkey)( &c->context.c, key, keylen );
+    ret = (*c->cipher->setkey)( &c->context.c, key, keylen );
     if (! ret)
       memcpy ((void *) ((char *) &c->context.c
-                       + cipher_table[c->algo_index].contextsize),
+                       + c->cipher->contextsize),
              (void *) &c->context.c,
-             cipher_table[c->algo_index].contextsize);
+             c->cipher->contextsize);
     return ret;
 }
 
@@ -622,13 +646,13 @@ cipher_setkey( GCRY_CIPHER_HD c, byte *key, unsigned keylen )
 static void
 cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen )
 {
-    memset( c->iv, 0, c->blocksize );
+    memset( c->iv, 0, c->cipher->blocksize );
     if( iv ) {
-       if( ivlen != c->blocksize )
+       if( ivlen != c->cipher->blocksize )
            log_info("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
-                                            ivlen, (unsigned)c->blocksize );
-       if( ivlen > c->blocksize )
-           ivlen = c->blocksize;
+                    ivlen, (unsigned) c->cipher->blocksize );
+       if (ivlen > c->cipher->blocksize)
+         ivlen = c->cipher->blocksize;
        memcpy( c->iv, iv, ivlen );
     }
     c->unused = 0;
@@ -640,11 +664,11 @@ cipher_reset (GCRY_CIPHER_HD c)
 {
   memcpy ((void *) &c->context.c,
          (void *) ((char *) &c->context.c
-                   + cipher_table[c->algo_index].contextsize),
-         cipher_table[c->algo_index].contextsize);
-  memset (c->iv, 0, c->blocksize);
-  memset (c->lastiv, 0, c->blocksize);
-  memset (c->ctr, 0, c->blocksize);
+                   + c->cipher->contextsize),
+         c->cipher->contextsize);
+  memset (c->iv, 0, c->cipher->blocksize);
+  memset (c->lastiv, 0, c->cipher->blocksize);
+  memset (c->ctr, 0, c->cipher->blocksize);
 }
 
 
@@ -654,9 +678,9 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
     unsigned n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
-       inbuf  += c->blocksize;
-       outbuf += c->blocksize;
+       (*c->cipher->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+       inbuf  += c->cipher->blocksize;
+       outbuf += c->cipher->blocksize;
     }
 }
 
@@ -666,9 +690,9 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
     unsigned n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
-       inbuf  += c->blocksize;
-       outbuf += c->blocksize;
+       (*c->cipher->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+       inbuf  += c->cipher->blocksize;
+       outbuf += c->cipher->blocksize;
     }
 }
 
@@ -678,7 +702,7 @@ do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
     unsigned int n;
     byte *ivp;
     int i;
-    size_t blocksize = c->blocksize;
+    size_t blocksize = c->cipher->blocksize;
     unsigned nblocks = nbytes / blocksize;
 
     if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
@@ -692,11 +716,11 @@ do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
         * API to allow for CBC handling in the backend */
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            outbuf[i] = inbuf[i] ^ *ivp++;
-       (*c->encrypt)( &c->context.c, outbuf, outbuf );
+       (*c->cipher->encrypt)( &c->context.c, outbuf, outbuf );
        memcpy(c->iv, outbuf, blocksize );
-       inbuf  += c->blocksize;
+       inbuf  += c->cipher->blocksize;
        if (!(c->flags & GCRY_CIPHER_CBC_MAC))
-         outbuf += c->blocksize;
+         outbuf += c->cipher->blocksize;
     }
 
     if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
@@ -708,15 +732,15 @@ do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
        else
          restbytes = nbytes % blocksize;
 
-       memcpy(outbuf, outbuf - c->blocksize, restbytes);
-       outbuf -= c->blocksize;
+       memcpy(outbuf, outbuf - c->cipher->blocksize, restbytes);
+       outbuf -= c->cipher->blocksize;
 
        for(ivp=c->iv,i=0; i < restbytes; i++ )
            outbuf[i] = inbuf[i] ^ *ivp++;
        for(; i < blocksize; i++ )
            outbuf[i] = 0 ^ *ivp++;
 
-       (*c->encrypt)( &c->context.c, outbuf, outbuf );
+       (*c->cipher->encrypt)( &c->context.c, outbuf, outbuf );
        memcpy(c->iv, outbuf, blocksize );
       }
 }
@@ -727,7 +751,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
     unsigned int n;
     byte *ivp;
     int i;
-    size_t blocksize = c->blocksize;
+    size_t blocksize = c->cipher->blocksize;
     unsigned nblocks = nbytes / blocksize;
 
     if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
@@ -742,12 +766,12 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
         * to save the original ciphertext block.  We use lastiv
         * for this here because it is not used otherwise */
        memcpy(c->lastiv, inbuf, blocksize );
-       (*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
+       (*c->cipher->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            outbuf[i] ^= *ivp++;
        memcpy(c->iv, c->lastiv, blocksize );
-       inbuf  += c->blocksize;
-       outbuf += c->blocksize;
+       inbuf  += c->cipher->blocksize;
+       outbuf += c->cipher->blocksize;
     }
 
     if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
@@ -761,14 +785,14 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
        memcpy(c->lastiv, c->iv, blocksize ); /* save Cn-2 */
        memcpy(c->iv, inbuf + blocksize, restbytes ); /* save Cn */
 
-       (*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
+       (*c->cipher->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
        for(ivp=c->iv,i=0; i < restbytes; i++ )
            outbuf[i] ^= *ivp++;
 
        memcpy(outbuf + blocksize, outbuf, restbytes);
        for(i=restbytes; i < blocksize; i++)
          c->iv[i] = outbuf[i];
-       (*c->decrypt)( &c->context.c, outbuf, c->iv );
+       (*c->cipher->decrypt)( &c->context.c, outbuf, c->iv );
        for(ivp=c->lastiv,i=0; i < blocksize; i++ )
            outbuf[i] ^= *ivp++;
        /* c->lastiv is now really lastlastiv, does this matter? */
@@ -781,12 +805,12 @@ do_cfb_encrypt( GCRY_CIPHER_HD c,
                 byte *outbuf, const byte *inbuf, unsigned nbytes )
 {
     byte *ivp;
-    size_t blocksize = c->blocksize;
+    size_t blocksize = c->cipher->blocksize;
 
     if( nbytes <= c->unused ) {
        /* short enough to be encoded by the remaining XOR mask */
        /* XOR the input with the IV and store input into IV */
-       for(ivp=c->iv+c->blocksize - c->unused; nbytes; nbytes--, c->unused-- )
+       for(ivp=c->iv+c->cipher->blocksize - c->unused; nbytes; nbytes--, c->unused-- )
            *outbuf++ = (*ivp++ ^= *inbuf++);
        return;
     }
@@ -803,7 +827,7 @@ do_cfb_encrypt( GCRY_CIPHER_HD c,
        int i;
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->encrypt)( &c->context.c, c->iv, c->iv );
+       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
        /* XOR the input with the IV and store input into IV */
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            *outbuf++ = (*ivp++ ^= *inbuf++);
@@ -812,7 +836,7 @@ do_cfb_encrypt( GCRY_CIPHER_HD c,
     if( nbytes ) { /* process the remaining bytes */
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->encrypt)( &c->context.c, c->iv, c->iv );
+       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
        c->unused = blocksize;
        /* and apply the xor */
        c->unused -= nbytes;
@@ -827,7 +851,7 @@ do_cfb_decrypt( GCRY_CIPHER_HD c,
 {
     byte *ivp;
     ulong temp;
-    size_t blocksize = c->blocksize;
+    size_t blocksize = c->cipher->blocksize;
 
     if( nbytes <= c->unused ) {
        /* short enough to be encoded by the remaining XOR mask */
@@ -855,7 +879,7 @@ do_cfb_decrypt( GCRY_CIPHER_HD c,
        int i;
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->encrypt)( &c->context.c, c->iv, c->iv );
+       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
        /* XOR the input with the IV and store input into IV */
        for(ivp=c->iv,i=0; i < blocksize; i++ ) {
            temp = *inbuf++;
@@ -867,7 +891,7 @@ do_cfb_decrypt( GCRY_CIPHER_HD c,
     if( nbytes ) { /* process the remaining bytes */
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->encrypt)( &c->context.c, c->iv, c->iv );
+       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
        c->unused = blocksize;
        /* and apply the xor */
        c->unused -= nbytes;
@@ -889,11 +913,11 @@ do_ctr_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
 
   for(n=0; n < nbytes; n++)
     {
-      if ((n % c->blocksize) == 0)
+      if ((n % c->cipher->blocksize) == 0)
        {
-         (*c->encrypt) (&c->context.c, tmp, c->ctr);
+         (*c->cipher->encrypt) (&c->context.c, tmp, c->ctr);
 
-         for (i = c->blocksize; i > 0; i--)
+         for (i = c->cipher->blocksize; i > 0; i--)
            {
              c->ctr[i-1]++;
              if (c->ctr[i-1] != 0)
@@ -902,7 +926,7 @@ do_ctr_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt
        }
 
       /* XOR input with encrypted counter and store in output */
-      outbuf[n] = inbuf[n] ^ tmp[n % c->blocksize];
+      outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
     }
 }
 
@@ -926,13 +950,13 @@ cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
 
     switch( c->mode ) {
       case GCRY_CIPHER_MODE_ECB:
-       if (!(nbytes%c->blocksize))
-            do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+       if (!(nbytes%c->cipher->blocksize))
+            do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
         else 
             rc = GCRYERR_INV_ARG;
        break;
       case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->blocksize) || (nbytes > c->blocksize && 
+       if (!(nbytes%c->cipher->blocksize) || (nbytes > c->cipher->blocksize && 
                                       (c->flags & GCRY_CIPHER_CBC_CTS)))
             do_cbc_encrypt(c, outbuf, inbuf, nbytes );
         else 
@@ -945,8 +969,8 @@ cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf,
        do_ctr_encrypt(c, outbuf, inbuf, nbytes );
        break;
       case GCRY_CIPHER_MODE_STREAM:
-        (*c->stencrypt)( &c->context.c,
-                         outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        (*c->cipher->stencrypt)( &c->context.c,
+                                outbuf, (byte*)/*arggg*/inbuf, nbytes );
         break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
@@ -980,15 +1004,15 @@ gcry_cipher_encrypt (GcryCipherHd h, byte *out, size_t outsize,
     }
   else
     {
-      if ( outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ? h->blocksize : inlen))
+      if ( outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ? h->cipher->blocksize : inlen))
         rc = GCRYERR_TOO_SHORT;
       else if ((h->mode == GCRY_CIPHER_MODE_ECB
                 || (h->mode == GCRY_CIPHER_MODE_CBC
                     && !((h->flags & GCRY_CIPHER_CBC_CTS)
-                         && (inlen > h->blocksize))
+                         && (inlen > h->cipher->blocksize))
                     )
                 )  
-               && (inlen % h->blocksize))
+               && (inlen % h->cipher->blocksize))
         rc = GCRYERR_INV_ARG;
       else
         rc = cipher_encrypt (h, out, in, inlen);
@@ -1017,14 +1041,14 @@ cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
 
     switch( c->mode ) {
       case GCRY_CIPHER_MODE_ECB:
-       if (!(nbytes%c->blocksize))
-            do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->blocksize );
+       if (!(nbytes%c->cipher->blocksize))
+            do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
         else 
             rc = GCRYERR_INV_ARG;
        break;
       case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->blocksize) || (nbytes > c->blocksize && 
-                                      (c->flags & GCRY_CIPHER_CBC_CTS)))
+       if (!(nbytes%c->cipher->blocksize) || (nbytes > c->cipher->blocksize && 
+                                              (c->flags & GCRY_CIPHER_CBC_CTS)))
             do_cbc_decrypt(c, outbuf, inbuf, nbytes );
         else 
             rc = GCRYERR_INV_ARG;
@@ -1036,8 +1060,8 @@ cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf,
        do_ctr_decrypt(c, outbuf, inbuf, nbytes );
        break;
       case GCRY_CIPHER_MODE_STREAM:
-        (*c->stdecrypt)( &c->context.c,
-                         outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        (*c->cipher->stdecrypt)( &c->context.c,
+                                outbuf, (byte*)/*arggg*/inbuf, nbytes );
         break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
@@ -1070,8 +1094,8 @@ gcry_cipher_decrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize,
         if ( ( h->mode == GCRY_CIPHER_MODE_ECB ||
                (h->mode == GCRY_CIPHER_MODE_CBC && 
                !((h->flags & GCRY_CIPHER_CBC_CTS) &&
-                 (inlen > h->blocksize)))) &&
-            (inlen % h->blocksize) != 0 )
+                 (inlen > h->cipher->blocksize)))) &&
+            (inlen % h->cipher->blocksize) != 0 )
             return set_lasterr( GCRYERR_INV_ARG );
 
        rc = cipher_decrypt( h, out, in, inlen );
@@ -1089,8 +1113,8 @@ static void
 cipher_sync( GCRY_CIPHER_HD c )
 {
     if( (c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused ) {
-       memmove(c->iv + c->unused, c->iv, c->blocksize - c->unused );
-       memcpy(c->iv, c->lastiv + c->blocksize - c->unused, c->unused);
+       memmove(c->iv + c->unused, c->iv, c->cipher->blocksize - c->unused );
+       memcpy(c->iv, c->lastiv + c->cipher->blocksize - c->unused, c->unused);
        c->unused = 0;
     }
 }
@@ -1142,10 +1166,10 @@ gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen)
       disable_cipher_algo( *(int*)buffer );
       break;
     case GCRYCTL_SET_CTR:
-      if (buffer && buflen == h->blocksize)
-       memcpy (h->ctr, buffer, h->blocksize);
+      if (buffer && buflen == h->cipher->blocksize)
+       memcpy (h->ctr, buffer, h->cipher->blocksize);
       else if (buffer == NULL || buflen == 0)
-       memset (h->ctr, 0, h->blocksize);
+       memset (h->ctr, 0, h->cipher->blocksize);
       else
        rc = GCRYERR_INV_ARG;
       break;
@@ -1243,6 +1267,3 @@ gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes)
     }
     return -1;
 }
-
-
-
index 37f0d38..1f1dc4b 100644 (file)
@@ -26,7 +26,7 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-#include "dynload.h"
+#include "cipher.h"
 
 #include "bithelp.h"
 
@@ -149,28 +149,32 @@ CRC_CONTEXT;
 /* CRC32 */
 
 static void
-crc32_init (CRC_CONTEXT * ctx)
+crc32_init (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->CRC = 0 ^ 0xffffffffL;
 }
 
 static void
-crc32_write (CRC_CONTEXT * ctx, byte * inbuf, size_t inlen)
+crc32_write (void *context, byte * inbuf, size_t inlen)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   if (!inbuf)
     return;
   ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
 }
 
 static byte *
-crc32_read (CRC_CONTEXT * ctx)
+crc32_read (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   return ctx->buf;
 }
 
 static void
-crc32_final (CRC_CONTEXT * ctx)
+crc32_final (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->CRC ^= 0xffffffffL;
   ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
   ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
@@ -180,14 +184,16 @@ crc32_final (CRC_CONTEXT * ctx)
 
 /* CRC32 a'la RFC 1510 */
 static void
-crc32rfc1510_init (CRC_CONTEXT * ctx)
+crc32rfc1510_init (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->CRC = 0;
 }
 
 static void
-crc32rfc1510_final (CRC_CONTEXT * ctx)
+crc32rfc1510_final (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
   ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
   ctx->buf[2] = (ctx->CRC >>  8) & 0xFF;
@@ -231,15 +237,17 @@ crc32rfc1510_final (CRC_CONTEXT * ctx)
 #define CRC24_POLY 0x1864cfbL
 
 static void
-crc24rfc2440_init (CRC_CONTEXT * ctx)
+crc24rfc2440_init (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->CRC = CRC24_INIT;
 }
 
 static void
-crc24rfc2440_write (CRC_CONTEXT * ctx, byte * inbuf, size_t inlen)
+crc24rfc2440_write (void *context, byte * inbuf, size_t inlen)
 {
   int i;
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
 
   if (!inbuf)
     return;
@@ -255,117 +263,33 @@ crc24rfc2440_write (CRC_CONTEXT * ctx, byte * inbuf, size_t inlen)
 }
 
 static void
-crc24rfc2440_final (CRC_CONTEXT * ctx)
+crc24rfc2440_final (void *context)
 {
+  CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
   ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
   ctx->buf[1] = (ctx->CRC >>  8) & 0xFF;
   ctx->buf[2] = (ctx->CRC      ) & 0xFF;
 }
 
-static const char *
-crc_get_info (int algo, size_t * contextsize,
-             byte ** r_asnoid, int *r_asnlen, int *r_mdlen,
-             void (**r_init) (void *c),
-             void (**r_write) (void *c, byte * buf, size_t nbytes),
-             void (**r_final) (void *c), byte * (**r_read) (void *c))
-{
-  *contextsize = sizeof (CRC_CONTEXT);
-  *r_asnoid = NULL;
-  *r_asnlen = 0;
-
-  switch (algo)
-    {
-    case 302:
-      *r_mdlen = 4;
-      *(void (**)(CRC_CONTEXT *)) r_init = crc32_init;
-      *(void (**)(CRC_CONTEXT *)) r_final = crc32_final;
-      *(void (**)(CRC_CONTEXT *, byte *, size_t)) r_write = crc32_write;
-      *(byte * (**)(CRC_CONTEXT *)) r_read = crc32_read;
-      return "CRC32";
-
-    case 303:
-      *r_mdlen = 4;
-      *(void (**)(CRC_CONTEXT *)) r_init = crc32rfc1510_init;
-      *(void (**)(CRC_CONTEXT *)) r_final = crc32rfc1510_final;
-      *(void (**)(CRC_CONTEXT *, byte *, size_t)) r_write = crc32_write;
-      *(byte * (**)(CRC_CONTEXT *)) r_read = crc32_read;
-      return "CRC32RFC1510";
-
-    case 304:
-      *r_mdlen = 3;
-      *(void (**)(CRC_CONTEXT *)) r_init = crc24rfc2440_init;
-      *(void (**)(CRC_CONTEXT *)) r_final = crc24rfc2440_final;
-      *(void (**)(CRC_CONTEXT *, byte *, size_t)) r_write = crc24rfc2440_write;
-      *(byte * (**)(CRC_CONTEXT *)) r_read = crc32_read;
-      return "CRC24RFC2440";
-
-    default:
-      return NULL;
-    }
-
-  return NULL;
-}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char *const gnupgext_version = "CRC ($Revision$)";
-
-static struct
-{
-  int class;
-  int version;
-  int value;
-  void (*func) (void);
-} func_table[] = {
-  { 10, 1, 0, (void (*)(void)) crc_get_info },
-  { 11, 1, 302 },
-  { 11, 1, 303 },
-  { 11, 1, 304 },
-};
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func (int what, int *sequence, int *class, int *vers)
-{
-  void *ret;
-  int i = *sequence;
-
-  do
-    {
-      if (i >= DIM (func_table) || i < 0)
-       return NULL;
-      *class = func_table[i].class;
-      *vers = func_table[i].version;
-      switch (*class)
-       {
-       case 11:
-       case 21:
-       case 31:
-         ret = &func_table[i].value;
-         break;
-       default:
-         ret = func_table[i].func;
-         break;
-       }
-      i++;
-    }
-  while (what && what != *class);
-
-  *sequence = i;
-  return ret;
-}
-
-#ifndef IS_MODULE
-void
-_gcry_crc_constructor (void)
-{
-  _gcry_register_internal_cipher_extension (gnupgext_version,
-                                           gnupgext_enum_func);
-}
-#endif
-
-/* end of file */
+GcryDigestSpec digest_spec_crc32 =
+  {
+    "CRC32", GCRY_MD_CRC32, NULL, 0, 4,
+    crc32_init, crc32_write, crc32_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
+
+GcryDigestSpec digest_spec_crc32_rfc1510 =
+  {
+    "CRC32RFC1510", GCRY_MD_CRC32_RFC1510, NULL, 0, 4,
+    crc32rfc1510_init, crc32_write,
+    crc32rfc1510_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
+
+GcryDigestSpec digest_spec_crc24_rfc2440 =
+  {
+    "CRC24RFC2440", GCRY_MD_CRC24_RFC2440, NULL, 0, 3,
+    crc24rfc2440_init, crc24rfc2440_write,
+    crc24rfc2440_final, crc32_read,
+    sizeof (CRC_CONTEXT)
+  };
index 7ec8644..79de0e0 100644 (file)
 #include <string.h>           /* memcpy, memcmp */
 #include "types.h"             /* for byte and u32 typedefs */
 #include "g10lib.h"
-#include "des.h"
+#include "cipher.h"
 
 #if defined(__GNUC__) && defined(__GNU_LIBRARY__)
 #define working_memcmp memcmp
@@ -135,27 +135,6 @@ working_memcmp( const char *a, const char *b, size_t n )
 }
 #endif
 
-
-/* Some defines/checks to support standalone modules */
-
-#ifndef GCRY_CIPHER_3DES
-# define CIPHER_ALGO_3DES 2
-#elif GCRY_CIPHER_3DES != 2
-# error CIPHER_ALGO_3DES is defined to a wrong value.
-#endif
-
-#ifndef GCRY_CIPHER_DES
-# define CIPHER_ALGO_DES 302
-#elif GCRY_CIPHER_DES != 302
-# error CIPHER_ALGO_DES is defined to a wrong value.
-#endif
-
-
-/* Macros used by the info function. */
-#define FNCCAST_SETKEY(f)  ((int(*)(void*, byte*, unsigned))(f))
-#define FNCCAST_CRYPT(f)   ((void(*)(void*, byte*, byte*))(f))
-
-
 /*
  * Encryption/Decryption context of DES
  */
@@ -176,8 +155,6 @@ typedef struct _tripledes_ctx
   }
 tripledes_ctx[1];
 
-static const char *selftest_failed;
-
 static void des_key_schedule (const byte *, u32 *);
 static int des_setkey (struct _des_ctx *, const byte *);
 static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
@@ -187,7 +164,7 @@ static int tripledes_ecb_crypt (struct _tripledes_ctx *, const byte *, byte *, i
 static int is_weak_key ( const byte *key );
 static const char *selftest (void);
 
-
+static int initialized;
 
 
 
@@ -594,8 +571,10 @@ des_setkey (struct _des_ctx *ctx, const byte * key)
 {
   int i;
 
+#ifdef FIXME
   if( selftest_failed )
     return GCRYERR_SELFTEST;
+#endif
 
   des_key_schedule (key, ctx->encrypt_subkeys);
   _gcry_burn_stack (32);
@@ -994,10 +973,15 @@ selftest (void)
 
 
 static int
-do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
+do_tripledes_setkey ( void *context, const byte *key, unsigned keylen )
 {
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+#ifdef FIXME
     if( selftest_failed )
        return GCRYERR_SELFTEST;
+#endif
+
     if( keylen != 24 )
        return GCRYERR_INV_KEYLEN;
 
@@ -1014,108 +998,79 @@ do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen )
 
 
 static void
-do_tripledes_encrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
+do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
 {
-    tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
-    _gcry_burn_stack (32);
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+  tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
 }
 
 static void
-do_tripledes_decrypt( struct _tripledes_ctx *ctx, byte *outbuf, byte *inbuf )
+do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
 {
-    tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
-    _gcry_burn_stack (32);
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+  tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
 }
 
-
-
-
 static int
-do_des_setkey ( struct _des_ctx *ctx, byte *key, unsigned keylen )
+do_des_setkey (void *context, const byte *key, unsigned keylen)
 {
-    if( selftest_failed )
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
+  static const char *selftest_failed;
+
+  if (! initialized)
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+       log_error ("%s\n", selftest_failed); 
+      if (selftest_failed)
        return GCRYERR_SELFTEST;
-    if( keylen != 8 )
-       return GCRYERR_INV_KEYLEN;
+   }
 
-    des_setkey (ctx, key);
+  if (keylen != 8)
+    return GCRYERR_INV_KEYLEN;
 
-    if( is_weak_key( key ) ) {
-        _gcry_burn_stack (64);
-       return GCRYERR_WEAK_KEY;
-    }
+  des_setkey (ctx, key);
+
+  if (is_weak_key (key)) {
     _gcry_burn_stack (64);
+    return GCRYERR_WEAK_KEY;
+  }
+  _gcry_burn_stack (64);
 
-    return 0;
+  return 0;
 }
 
 
 static void
-do_des_encrypt( struct _des_ctx *ctx, byte *outbuf, byte *inbuf )
+do_des_encrypt( void *context, byte *outbuf, const byte *inbuf )
 {
-    des_ecb_encrypt ( ctx, inbuf, outbuf );
-    _gcry_burn_stack (32);
-}
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
 
-static void
-do_des_decrypt( struct _des_ctx *ctx, byte *outbuf, byte *inbuf )
-{
-    des_ecb_decrypt ( ctx, inbuf, outbuf );
-    _gcry_burn_stack (32);
+  des_ecb_encrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
 }
 
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-const char *
-_gcry_des_get_info( int algo, size_t *keylen,
-                  size_t *blocksize, size_t *contextsize,
-                  int  (**r_setkey)( void *c, byte *key, unsigned keylen ),
-                  void (**r_encrypt)( void *c, byte *outbuf, byte *inbuf ),
-                  void (**r_decrypt)( void *c, byte *outbuf, byte *inbuf )
-                )
+static void
+do_des_decrypt( void *context, byte *outbuf, const byte *inbuf )
 {
-    static int did_selftest = 0;
-
-    if( !did_selftest ) {
-       const char *s = selftest();
-       did_selftest = 1;
-       if( s ) {
-           log_error ("%s\n", s );
-           selftest_failed = s;
-           return NULL;
-       }
-    }
-
+  struct _des_ctx *ctx = (struct _des_ctx *) context;
 
-    if( algo == GCRY_CIPHER_3DES ) {
-       *keylen = 192;
-       *blocksize = 8;
-       *contextsize = sizeof(struct _tripledes_ctx);
-       *(int  (**)(struct _tripledes_ctx*, byte*, unsigned))r_setkey
-                                                       = do_tripledes_setkey;
-       *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_encrypt
-                                                       = do_tripledes_encrypt;
-       *(void (**)(struct _tripledes_ctx*, byte*, byte*))r_decrypt
-                                                       = do_tripledes_decrypt;
-       return "3DES";
-    }
-    else if( algo == GCRY_CIPHER_DES ) {
-       *keylen = 64;
-       *blocksize = 8;
-       *contextsize = sizeof(struct _des_ctx);
-       *(int  (**)(struct _des_ctx*, byte*, unsigned))r_setkey
-                                                       = do_des_setkey;
-       *(void (**)(struct _des_ctx*, byte*, byte*))r_encrypt
-                                                       = do_des_encrypt;
-       *(void (**)(struct _des_ctx*, byte*, byte*))r_decrypt
-                                                       = do_des_decrypt;
-       return "DES";
-    }
-    return NULL;
+  des_ecb_decrypt ( ctx, inbuf, outbuf );
+  _gcry_burn_stack (32);
 }
 
+GcryCipherSpec cipher_spec_des =
+  {
+    "DES", GCRY_CIPHER_DES, 8, 64, sizeof (struct _des_ctx),
+    do_des_setkey, do_des_encrypt, do_des_decrypt
+  };
+
+GcryCipherSpec cipher_spec_tripledes =
+  {
+    "3DES", GCRY_CIPHER_3DES, 8, 192, sizeof (struct _tripledes_ctx),
+    do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
+  };
index 61d0c37..b2adae4 100644 (file)
@@ -1,5 +1,5 @@
 /* dsa.c  -  DSA signature scheme
- *     Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -27,7 +27,6 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "dsa.h"
 
 typedef struct {
     MPI p;         /* prime */
@@ -361,7 +360,7 @@ _gcry_dsa_generate( int algo, unsigned nbits, unsigned long dummy,
 {
     DSA_secret_key sk;
 
-    if( algo != PUBKEY_ALGO_DSA )
+    if( algo != GCRY_PK_DSA )
        return GCRYERR_INV_PK_ALGO;
 
     generate( &sk, nbits, retfactors );
@@ -379,7 +378,7 @@ _gcry_dsa_check_secret_key( int algo, MPI *skey )
 {
     DSA_secret_key sk;
 
-    if( algo != PUBKEY_ALGO_DSA )
+    if( algo != GCRY_PK_DSA )
        return GCRYERR_INV_PK_ALGO;
     if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
        return GCRYERR_BAD_MPI;
@@ -402,7 +401,7 @@ _gcry_dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
 {
     DSA_secret_key sk;
 
-    if( algo != PUBKEY_ALGO_DSA )
+    if( algo != GCRY_PK_DSA )
        return GCRYERR_INV_PK_ALGO;
     if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] )
        return GCRYERR_BAD_MPI;
@@ -424,7 +423,7 @@ _gcry_dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
 {
     DSA_public_key pk;
 
-    if( algo != PUBKEY_ALGO_DSA )
+    if( algo != GCRY_PK_DSA )
        return GCRYERR_INV_PK_ALGO;
     if( !data[0] || !data[1] || !hash
        || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] )
@@ -444,33 +443,20 @@ _gcry_dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
 unsigned int
 _gcry_dsa_get_nbits( int algo, MPI *pkey )
 {
-    if( algo != PUBKEY_ALGO_DSA )
+    if( algo != GCRY_PK_DSA )
        return 0;
     return mpi_get_nbits( pkey[0] );
 }
 
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- *           1 set : allows encryption
- */
-const char *
-_gcry_dsa_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
-                                                        int *use )
-{
-    *npkey = 4;
-    *nskey = 5;
-    *nenc = 0;
-    *nsig = 2;
-
-    switch( algo ) {
-      case PUBKEY_ALGO_DSA:   *use = GCRY_PK_USAGE_SIGN; return "DSA";
-      default: *use = 0; return NULL;
-    }
-}
-
-
+GcryPubkeySpec pubkey_spec_dsa =
+  {
+    "DSA", GCRY_PK_DSA, 4, 5, 0, 2,
+    GCRY_PK_USAGE_SIGN,
+    _gcry_dsa_generate,
+    _gcry_dsa_check_secret_key,
+    NULL,
+    NULL,
+    _gcry_dsa_sign,
+    _gcry_dsa_verify,
+    _gcry_dsa_get_nbits,
+  };
index a4b5425..f9e6396 100644 (file)
@@ -1,5 +1,5 @@
 /* elgamal.c  -  ElGamal Public Key encryption
- * Copyright (C) 1998, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -29,7 +29,6 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "elgamal.h"
 
 typedef struct {
     MPI p;         /* prime */
@@ -626,36 +625,15 @@ _gcry_elg_get_nbits( int algo, MPI *pkey )
     return mpi_get_nbits( pkey[0] );
 }
 
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- *           1 set : allows encryption
- * NOTE: This function allows signing also for ELG-E, which is not
- * okay but a bad hack to allow to work with old gpg keys. The real check
- * is done in the gnupg ocde depending on the packet version.
- */
-const char *
-_gcry_elg_get_info( int algo, int *npkey, int *nskey, int *nenc, int *nsig,
-                                                        int *use )
-{
-    *npkey = 3;
-    *nskey = 4;
-    *nenc = 2;
-    *nsig = 2;
-
-    switch( algo ) {
-      case GCRY_PK_ELG:
-       *use = GCRY_PK_USAGE_SIGN|GCRY_PK_USAGE_ENCR;
-       return "ELG";
-      case GCRY_PK_ELG_E:
-       *use = GCRY_PK_USAGE_SIGN|GCRY_PK_USAGE_ENCR;
-       return "ELG-E";
-      default: *use = 0; return NULL;
-    }
-}
-
-
+GcryPubkeySpec pubkey_spec_elg =
+  {
+    "ELG", GCRY_PK_ELG, 3, 4, 2, 2,
+    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+    _gcry_elg_generate,
+    _gcry_elg_check_secret_key,
+    _gcry_elg_encrypt,
+    _gcry_elg_decrypt,
+    _gcry_elg_sign,
+    _gcry_elg_verify,
+    _gcry_elg_get_nbits,
+  };
index 0cb4f34..f12f1b6 100644 (file)
@@ -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;
-
-
-\f
-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_writeGCRY_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_writeGCRY_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_ctlGCRY_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;
+}
index 7bb31a8..0135e34 100644 (file)
@@ -54,7 +54,7 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-#include "dynload.h"
+#include "cipher.h"
 
 #include "bithelp.h"
 
@@ -68,15 +68,17 @@ typedef struct {
 
 
 static void
-md4_init( MD4_CONTEXT *ctx )
+md4_init( void *context )
 {
-    ctx->A = 0x67452301;
-    ctx->B = 0xefcdab89;
-    ctx->C = 0x98badcfe;
-    ctx->D = 0x10325476;
+  MD4_CONTEXT *ctx = (MD4_CONTEXT *) context;
 
-    ctx->nblocks = 0;
-    ctx->count = 0;
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+
+  ctx->nblocks = 0;
+  ctx->count = 0;
 }
 
 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
@@ -188,8 +190,9 @@ transform( MD4_CONTEXT *ctx, byte *data )
  * in the message whose digest is being computed.
  */
 static void
-md4_write( MD4_CONTEXT *hd, byte *inbuf, size_t inlen)
+md4_write( void *context, byte *inbuf, size_t inlen)
 {
+  MD4_CONTEXT *hd = (MD4_CONTEXT *) context;
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
         _gcry_burn_stack (80+6*sizeof(void*));
@@ -228,8 +231,9 @@ md4_write( MD4_CONTEXT *hd, byte *inbuf, size_t inlen)
  */
 
 static void
-md4_final( MD4_CONTEXT *hd )
+md4_final( void *context )
 {
+  MD4_CONTEXT *hd = (MD4_CONTEXT *) context;
     u32 t, msb, lsb;
     byte *p;
 
@@ -289,96 +293,21 @@ md4_final( MD4_CONTEXT *hd )
 }
 
 static byte *
-md4_read( MD4_CONTEXT *hd )
-{
-    return hd->buf;
-}
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-md4_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
-{
-    static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
-                   { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
-                     0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
-
-    if( algo != 301 )
-       return NULL;
-
-    *contextsize = sizeof(MD4_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 16;
-    *(void  (**)(MD4_CONTEXT *))r_init                = md4_init;
-    *(void  (**)(MD4_CONTEXT *, byte*, size_t))r_write = md4_write;
-    *(void  (**)(MD4_CONTEXT *))r_final               = md4_final;
-    *(byte *(**)(MD4_CONTEXT *))r_read                = md4_read;
-
-    return "MD4";
-}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "MD4 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))md4_get_info },
-    { 11, 1, 301 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
+md4_read (void *context)
 {
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 )
-           return NULL;
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11: case 21: case 31: ret = &func_table[i].value; break;
-         default:                   ret = func_table[i].func; break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
+  MD4_CONTEXT *hd = (MD4_CONTEXT *) context;
+  return hd->buf;
 }
 
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
+  { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+    0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
 
-
-
-#ifndef IS_MODULE
-void
-_gcry_md4_constructor(void)
-{
-    _gcry_register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
+GcryDigestSpec digest_spec_md4 =
+  {
+    "MD4", GCRY_MD_MD4, asn, DIM (asn), 16,
+    md4_init, md4_write, md4_final, md4_read,
+    sizeof (MD4_CONTEXT)
+  };
 
 /* end of file */
index 9d2f7c8..248df68 100644 (file)
@@ -37,7 +37,7 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-#include "dynload.h"
+#include "cipher.h"
 
 #include "bithelp.h"
 
@@ -51,8 +51,10 @@ typedef struct {
 
 
 static void
-md5_init( MD5_CONTEXT *ctx )
+md5_init( void *context )
 {
+  MD5_CONTEXT *ctx = (MD5_CONTEXT *) context;
+
     ctx->A = 0x67452301;
     ctx->B = 0xefcdab89;
     ctx->C = 0x98badcfe;
@@ -213,8 +215,9 @@ transform( MD5_CONTEXT *ctx, byte *data )
  * in the message whose digest is being computed.
  */
 static void
-md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
+md5_write( void *context, byte *inbuf, size_t inlen)
 {
+  MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
         _gcry_burn_stack (80+6*sizeof(void*));
@@ -253,8 +256,9 @@ md5_write( MD5_CONTEXT *hd, byte *inbuf, size_t inlen)
  */
 
 static void
-md5_final( MD5_CONTEXT *hd )
+md5_final( void *context)
 {
+  MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
     u32 t, msb, lsb;
     byte *p;
 
@@ -314,96 +318,20 @@ md5_final( MD5_CONTEXT *hd )
 }
 
 static byte *
-md5_read( MD5_CONTEXT *hd )
+md5_read( void *context )
 {
-    return hd->buf;
+  MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
+  return hd->buf;
 }
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-md5_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
-{
     static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
                    { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
                      0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
 
-    if( algo != 1 )
-       return NULL;
-
-    *contextsize = sizeof(MD5_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 16;
-    *(void  (**)(MD5_CONTEXT *))r_init                = md5_init;
-    *(void  (**)(MD5_CONTEXT *, byte*, size_t))r_write = md5_write;
-    *(void  (**)(MD5_CONTEXT *))r_final               = md5_final;
-    *(byte *(**)(MD5_CONTEXT *))r_read                = md5_read;
-
-    return "MD5";
-}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "MD5 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))md5_get_info },
-    { 11, 1, 1 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 )
-           return NULL;
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11: case 21: case 31: ret = &func_table[i].value; break;
-         default:                   ret = func_table[i].func; break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-_gcry_md5_constructor(void)
-{
-    _gcry_register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
 
-/* end of file */
+GcryDigestSpec digest_spec_md5 =
+  {
+    "MD5", GCRY_MD_MD5, asn, DIM (asn), 16,
+    md5_init, md5_write, md5_final, md5_read,
+    sizeof (MD5_CONTEXT)
+  };
index a0497d6..4727260 100644 (file)
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "elgamal.h"
-#include "dsa.h"
-#include "rsa.h"
-#include "dynload.h"
+#include "ath.h"
 
 /* FIXME: use set_lasterr() */
 
-#define TABLE_SIZE 10
-
-
-
-struct pubkey_table_s {
-    const char *name;
-    int algo;
-    int npkey;
-    int nskey;
-    int nenc;
-    int nsig;
-    int use;
-    int (*generate)(int algo, unsigned int nbits, unsigned long use_e,
-                    MPI *skey, MPI **retfactors );
-    int (*check_secret_key)( int algo, MPI *skey );
-    int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey, int flags);
-    int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey, int flags);
-    int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
-    int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey,
-                  int (*cmp)(void *, MPI), void *opaquev );
-    unsigned (*get_nbits)( int algo, MPI *pkey );
-};
-
-static struct pubkey_table_s pubkey_table[TABLE_SIZE];
-static int disabled_algos[TABLE_SIZE];
-
-static struct {
-  const char* name; int algo;
+static struct
+{
+  const char* name;
+  int algo;
   const char* common_elements;
   const char* public_elements;
   const char* secret_elements;
   const char* grip_elements;
 } algo_info_table[] = {
-  { "dsa"        ,      PUBKEY_ALGO_DSA       , "pqgy", "", "x",    "pqgy" },
-  { "rsa"        ,      PUBKEY_ALGO_RSA       , "ne",   "", "dpqu", "n" },
-  { "elg"        ,      PUBKEY_ALGO_ELGAMAL   , "pgy",  "", "x",    "pgy"  },
-  { "openpgp-dsa",      PUBKEY_ALGO_DSA       , "pqgy", "", "x",    "pqgy" },
-  { "openpgp-rsa",      PUBKEY_ALGO_RSA       , "ne",   "", "dpqu"  "n"},
-  { "openpgp-elg",      PUBKEY_ALGO_ELGAMAL_E , "pgy",  "", "x",    "pgy" },
-  { "openpgp-elg-sig",  PUBKEY_ALGO_ELGAMAL   , "pgy",  "", "x",    "pgy" },
+  { "dsa"        ,      GCRY_PK_DSA       , "pqgy", "", "x",    "pqgy" },
+  { "rsa"        ,      GCRY_PK_RSA       , "ne",   "", "dpqu", "n" },
+  { "elg"        ,      GCRY_PK_ELG   , "pgy",  "", "x",    "pgy"  },
+  { "openpgp-dsa",      GCRY_PK_DSA       , "pqgy", "", "x",    "pqgy" },
+  { "openpgp-rsa",      GCRY_PK_RSA       , "ne",   "", "dpqu"  "n"},
+  { "openpgp-elg",      GCRY_PK_ELG_E , "pgy",  "", "x",    "pgy" },
+  { "openpgp-elg-sig",  GCRY_PK_ELG   , "pgy",  "", "x",    "pgy" },
   { "oid.1.2.840.113549.1.1.1",
-                        PUBKEY_ALGO_RSA       , "ne",   "", "dpqu", "n" },
+                        GCRY_PK_RSA       , "ne",   "", "dpqu", "n" },
   { NULL }
 };
 
@@ -84,13 +57,13 @@ static struct {
     const char* name; int algo;
     const char* elements;
 } sig_info_table[] = {
-  { "dsa"                     , PUBKEY_ALGO_DSA       , "rs" },
-  { "rsa"                     , PUBKEY_ALGO_RSA       , "s"  },
-  { "elg"                     , PUBKEY_ALGO_ELGAMAL   , "rs" },
-  { "openpgp-dsa"             , PUBKEY_ALGO_DSA       , "rs" },
-  { "openpgp-rsa"             , PUBKEY_ALGO_RSA       , "s"  },
-  { "openpgp-elg-sig"         , PUBKEY_ALGO_ELGAMAL   , "rs" },
-  { "oid.1.2.840.113549.1.1.1", PUBKEY_ALGO_RSA       , "s"  },
+  { "dsa"                     , GCRY_PK_DSA       , "rs" },
+  { "rsa"                     , GCRY_PK_RSA       , "s"  },
+  { "elg"                     , GCRY_PK_ELG   , "rs" },
+  { "openpgp-dsa"             , GCRY_PK_DSA       , "rs" },
+  { "openpgp-rsa"             , GCRY_PK_RSA       , "s"  },
+  { "openpgp-elg-sig"         , GCRY_PK_ELG   , "rs" },
+  { "oid.1.2.840.113549.1.1.1", GCRY_PK_RSA       , "s"  },
   { NULL }
 };
 
@@ -98,272 +71,276 @@ static struct {
     const char* name; int algo;
     const char* elements;
 } enc_info_table[] = {
-  { "elg"            ,          PUBKEY_ALGO_ELGAMAL   , "ab" },
-  { "rsa"            ,          PUBKEY_ALGO_RSA       , "a"  },
-  { "openpgp-rsa"    ,          PUBKEY_ALGO_RSA       , "a"  },
-  { "openpgp-elg"    ,          PUBKEY_ALGO_ELGAMAL_E , "ab" },
-  { "openpgp-elg-sig",          PUBKEY_ALGO_ELGAMAL   , "ab" },
-  { "oid.1.2.840.113549.1.1.1", PUBKEY_ALGO_RSA       , "a"  },
+  { "elg"            ,          GCRY_PK_ELG   , "ab" },
+  { "rsa"            ,          GCRY_PK_RSA       , "a"  },
+  { "openpgp-rsa"    ,          GCRY_PK_RSA       , "a"  },
+  { "openpgp-elg"    ,          GCRY_PK_ELG_E , "ab" },
+  { "openpgp-elg-sig",          GCRY_PK_ELG   , "ab" },
+  { "oid.1.2.840.113549.1.1.1", GCRY_PK_RSA       , "a"  },
   { NULL }
 };
 
-
 static int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags);
 static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
 static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
                      int (*cmp)(void *, MPI), void *opaque );
 
+/* This is the list of the default public-key ciphers included in
+   libgcrypt.  */
+static struct
+{
+  GcryPubkeySpec *pubkey;
+} pubkey_table[] =
+  {
+#if USE_RSA
+    { &pubkey_spec_rsa },
+#endif
+#if USE_ELGAMAL
+    { &pubkey_spec_elg },
+#endif
+#if USE_DSA
+    { &pubkey_spec_dsa },
+#endif
+  };
+
+/* List of registered ciphers.  */
+static GcryModule *pubkeys_registered;
+
+/* This is the lock protecting PUBKEYS_REGISTERED.  */
+static ath_mutex_t pubkeys_registered_lock;
+
+/* Flag to check wether the default pubkeys have already been
+   registered.  */
+static int default_pubkeys_registered;
+
+/* Convenient macro for registering the default digests.  */
+#define REGISTER_DEFAULT_PUBKEYS                   \
+  do                                               \
+    {                                              \
+      ath_mutex_lock (&pubkeys_registered_lock);   \
+      if (! default_pubkeys_registered)            \
+        {                                          \
+          gcry_pubkey_register_default ();         \
+          default_pubkeys_registered = 1;          \
+        }                                          \
+      ath_mutex_unlock (&pubkeys_registered_lock); \
+    }                                              \
+  while (0)
+
+/* These dummy functions are used in case a cipher implementation
+   refuses to provide it's own functions.  */
+
 static int
-dummy_generate( int algo, unsigned int nbits, unsigned long dummy,
-                MPI *skey, MPI **retfactors )
-{ log_bug("no generate() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_generate (int id, unsigned int nbits, unsigned long dummy,
+                MPI *skey, MPI **retfactors)
+{
+  log_bug ("no generate() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static int
-dummy_check_secret_key( int algo, MPI *skey )
-{ log_bug("no check_secret_key() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_check_secret_key (int id, MPI *skey)
+{
+  log_bug ("no check_secret_key() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static int
-dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags)
-{ log_bug("no encrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_encrypt (int id, MPI *resarr, MPI data, MPI *pkey, int flags)
+{
+  log_bug ("no encrypt() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static int
-dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags)
-{ log_bug("no decrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_decrypt (int id, MPI *result, MPI *data, MPI *skey, int flags)
+{
+  log_bug ("no decrypt() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static int
-dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
-{ log_bug("no sign() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_sign (int id, MPI *resarr, MPI data, MPI *skey)
+{
+  log_bug ("no sign() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static int
-dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
-               int (*cmp)(void *, MPI), void *opaquev )
-{ log_bug("no verify() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
+dummy_verify (int id, MPI hash, MPI *data, MPI *pkey,
+             int (*cmp)(void *, MPI), void *opaquev)
+{
+  log_bug ("no verify() for %d\n", id);
+  return GCRYERR_INV_PK_ALGO;
+}
 
 static unsigned
-dummy_get_nbits( int algo, MPI *pkey )
-{ log_bug("no get_nbits() for %d\n", algo ); return 0; }
+dummy_get_nbits (int id, MPI *pkey)
+{
+  log_bug ("no get_nbits() for %d\n", id);
+  return 0;
+}
 
 
-/****************
- * Put the static entries into the table.
- * This is out constructor function which fill the table
- * of algorithms with the one we have statically linked.
- */
+/* Internal function.  Register all the pubkeys included in
+   PUBKEY_TABLE.  Returns zero on success or an error code.  */
 static void
-setup_pubkey_table(void)
+gcry_pubkey_register_default (void)
 {
-    int i;
-
-    i = 0;
-    pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL;
-    pubkey_table[i].name = _gcry_elg_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_elg_generate;
-    pubkey_table[i].check_secret_key = _gcry_elg_check_secret_key;
-    pubkey_table[i].encrypt         = _gcry_elg_encrypt;
-    pubkey_table[i].decrypt         = _gcry_elg_decrypt;
-    pubkey_table[i].sign            = _gcry_elg_sign;
-    pubkey_table[i].verify          = _gcry_elg_verify;
-    pubkey_table[i].get_nbits       = _gcry_elg_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-    pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL_E;
-    pubkey_table[i].name = _gcry_elg_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_elg_generate;
-    pubkey_table[i].check_secret_key = _gcry_elg_check_secret_key;
-    pubkey_table[i].encrypt         = _gcry_elg_encrypt;
-    pubkey_table[i].decrypt         = _gcry_elg_decrypt;
-    pubkey_table[i].sign            = _gcry_elg_sign;
-    pubkey_table[i].verify          = _gcry_elg_verify;
-    pubkey_table[i].get_nbits       = _gcry_elg_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-    pubkey_table[i].algo = PUBKEY_ALGO_DSA;
-    pubkey_table[i].name = _gcry_dsa_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_dsa_generate;
-    pubkey_table[i].check_secret_key = _gcry_dsa_check_secret_key;
-    pubkey_table[i].encrypt         = dummy_encrypt;
-    pubkey_table[i].decrypt         = dummy_decrypt;
-    pubkey_table[i].sign            = _gcry_dsa_sign;
-    pubkey_table[i].verify          = _gcry_dsa_verify;
-    pubkey_table[i].get_nbits       = _gcry_dsa_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-
-    pubkey_table[i].algo = PUBKEY_ALGO_RSA;
-    pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_rsa_generate;
-    pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
-    pubkey_table[i].encrypt         = _gcry_rsa_encrypt;
-    pubkey_table[i].decrypt         = _gcry_rsa_decrypt;
-    pubkey_table[i].sign            = _gcry_rsa_sign;
-    pubkey_table[i].verify          = _gcry_rsa_verify;
-    pubkey_table[i].get_nbits       = _gcry_rsa_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-    pubkey_table[i].algo = PUBKEY_ALGO_RSA_E;
-    pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_rsa_generate;
-    pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
-    pubkey_table[i].encrypt         = _gcry_rsa_encrypt;
-    pubkey_table[i].decrypt         = _gcry_rsa_decrypt;
-    pubkey_table[i].sign            = dummy_sign;
-    pubkey_table[i].verify          = dummy_verify;
-    pubkey_table[i].get_nbits       = _gcry_rsa_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-    pubkey_table[i].algo = PUBKEY_ALGO_RSA_S;
-    pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
-                                        &pubkey_table[i].npkey,
-                                        &pubkey_table[i].nskey,
-                                        &pubkey_table[i].nenc,
-                                        &pubkey_table[i].nsig,
-                                        &pubkey_table[i].use );
-    pubkey_table[i].generate        = _gcry_rsa_generate;
-    pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
-    pubkey_table[i].encrypt         = dummy_encrypt;
-    pubkey_table[i].decrypt         = dummy_decrypt;
-    pubkey_table[i].sign            = _gcry_rsa_sign;
-    pubkey_table[i].verify          = _gcry_rsa_verify;
-    pubkey_table[i].get_nbits       = _gcry_rsa_get_nbits;
-    if( !pubkey_table[i].name )
-       BUG();
-    i++;
-
-    for( ; i < TABLE_SIZE; i++ )
-       pubkey_table[i].name = NULL;
+  int i, err = 0;
+  
+  for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
+    {
+      if (! pubkey_table[i].pubkey->generate)
+       pubkey_table[i].pubkey->generate = dummy_generate;
+      if (! pubkey_table[i].pubkey->check_secret_key)
+       pubkey_table[i].pubkey->check_secret_key = dummy_check_secret_key;
+      if (! pubkey_table[i].pubkey->encrypt)
+       pubkey_table[i].pubkey->encrypt = dummy_encrypt;
+      if (! pubkey_table[i].pubkey->decrypt)
+       pubkey_table[i].pubkey->decrypt = dummy_decrypt;
+      if (! pubkey_table[i].pubkey->sign)
+       pubkey_table[i].pubkey->sign = dummy_sign;
+      if (! pubkey_table[i].pubkey->verify)
+       pubkey_table[i].pubkey->verify = dummy_verify;
+      if (! pubkey_table[i].pubkey->get_nbits)
+       pubkey_table[i].pubkey->get_nbits = dummy_get_nbits;
+
+      err = _gcry_module_add (&pubkeys_registered,
+                             (void *) pubkey_table[i].pubkey,
+                             NULL);
+    }
+
+  if (err)
+    BUG ();
 }
 
-static void
-release_mpi_array( MPI *array )
+/* Internal callback function.  Used via _gcry_module_lookup.  */
+static int
+gcry_pubkey_lookup_func_id (void *spec, void *data)
 {
-    for( ; *array; array++ ) {
-       mpi_free(*array);
-       *array = NULL;
-    }
+  GcryPubkeySpec *pubkey = (GcryPubkeySpec *) spec;
+  int id = *((int *) data);
+
+  return (pubkey->id == id);
 }
 
-/****************
- * Try to load all modules and return true if new modules are available
- */
+/* Internal callback function.  Used via _gcry_module_lookup.  */
 static int
-load_pubkey_modules(void)
+gcry_pubkey_lookup_func_name (void *spec, void *data)
 {
-    static int initialized = 0;
-    static int done = 0;
-    void *context = NULL;
-    struct pubkey_table_s *ct;
-    int ct_idx;
-    int i;
-    const char *name;
-    int any = 0;
+  GcryPubkeySpec *pubkey = (GcryPubkeySpec *) spec;
+  char *name = (char *) data;
 
+  return (! stricmp (pubkey->name, name));
+}
 
-    if( !initialized ) {
-       _gcry_cipher_modules_constructor();
-       setup_pubkey_table();
-       initialized = 1;
-       return 1;
-    }
-    if( done )
-       return 0;
-    done = 1;
-    for(ct_idx=0, ct = pubkey_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
-       if( !ct->name )
-           break;
-    }
-    if( ct_idx >= TABLE_SIZE-1 )
-       BUG(); /* table already full */
-    /* now load all extensions */
-    while( (name = _gcry_enum_gnupgext_pubkeys( &context, &ct->algo,
-                               &ct->npkey, &ct->nskey, &ct->nenc,
-                               &ct->nsig,  &ct->use,
-                               &ct->generate,
-                               &ct->check_secret_key,
-                               &ct->encrypt,
-                               &ct->decrypt,
-                               &ct->sign,
-                               &ct->verify,
-                               &ct->get_nbits )) ) {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == ct->algo )
-               break;
-       if( pubkey_table[i].name ) {
-           log_info("skipping pubkey %d: already loaded\n", ct->algo );
-           continue;
-       }
+/* Internal function.  Lookup a pubkey entry by it's ID.  */
+static GcryModule *
+gcry_pubkey_lookup_id (int id)
+{
+  GcryModule *pubkey;
 
-       if( !ct->generate  )  ct->generate = dummy_generate;
-       if( !ct->check_secret_key )  ct->check_secret_key =
-                                                   dummy_check_secret_key;
-       if( !ct->encrypt   )  ct->encrypt  = dummy_encrypt;
-       if( !ct->decrypt   )  ct->decrypt  = dummy_decrypt;
-       if( !ct->sign      )  ct->sign     = dummy_sign;
-       if( !ct->verify    )  ct->verify   = dummy_verify;
-       if( !ct->get_nbits )  ct->get_nbits= dummy_get_nbits;
-       /* put it into the table */
-       if( _gcry_log_verbosity( 2 ) )
-           log_info("loaded pubkey %d (%s)\n", ct->algo, name);
-       ct->name = name;
-       ct_idx++;
-       ct++;
-       any = 1;
-       /* check whether there are more available table slots */
-       if( ct_idx >= TABLE_SIZE-1 ) {
-           log_info("pubkey table full; ignoring other extensions\n");
-           break;
-       }
+  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) &id,
+                               gcry_pubkey_lookup_func_id);
+
+  return pubkey;
+}
+
+/* Internal function.  Lookup a pubkey entry by it's name.  */
+static GcryModule *
+gcry_pubkey_lookup_name (const char *name)
+{
+  GcryModule *pubkey;
+
+  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
+                               gcry_pubkey_lookup_func_name);
+
+  return pubkey;
+}
+
+/* Return a new, unused pubkey ID for a user-provided pubkey
+   implementation.  */
+static int
+gcry_pubkey_id_new (void)
+{
+  int id, id_start = 500, id_end = 600;        /* FIXME.  */
+  
+  for (id = id_start; id < id_end; id++)
+    if (! gcry_pubkey_lookup_id (id))
+      return id;
+
+  return 0;
+}
+
+/* Public function.  Register a provided PUBKEY.  Returns zero on
+   success, in which case the chosen pubkey ID has been stored in
+   PUBKEY, or an error code.  */
+int
+gcry_pubkey_register (GcryPubkeySpec *pubkey, GcryModule **module)
+{
+  int id, err = 0;
+  GcryModule *mod;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  id = gcry_pubkey_id_new ();
+  if (! id)
+    err = GCRYERR_INTERNAL;    /* FIXME.  */
+  else
+    {
+      pubkey->id = id;
+      err = _gcry_module_add (&pubkeys_registered, (void *) pubkey,
+                             &mod);
     }
-    _gcry_enum_gnupgext_pubkeys( &context, NULL, NULL, NULL, NULL, NULL, NULL,
-                              NULL, NULL, NULL, NULL, NULL, NULL, NULL );
-    return any;
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (! err)
+    *module = mod;
+
+  return err;
 }
 
+/* Public function.  Unregister the pubkey identified by ID, which
+   must have been registered with gcry_pubkey_register.  */
+void
+gcry_pubkey_unregister (GcryModule *module)
+{
+  ath_mutex_lock (&pubkeys_registered_lock);
+  _gcry_module_release (module);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+static void
+release_mpi_array (MPI *array)
+{
+  for (; *array; array++)
+    {
+      mpi_free(*array);
+      *array = NULL;
+    }
+}
 
 /****************
  * Map a string to the pubkey algo
  */
 int
-gcry_pk_map_name( const char *string )
+gcry_pk_map_name (const char *string)
 {
-    int i;
-    const char *s;
+  GcryModule *pubkey;
+  int id = 0;
 
-    do {
-       for(i=0; (s=pubkey_table[i].name); i++ )
-           if( !stricmp( s, string ) )
-               return pubkey_table[i].algo;
-    } while( load_pubkey_modules() );
-    return 0;
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_name (string);
+  if (pubkey)
+    {
+      id = ((GcryPubkeySpec *) pubkey->spec)->id;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return id;
 }
 
 
@@ -371,31 +348,40 @@ gcry_pk_map_name( const char *string )
  * Map a pubkey algo to a string
  */
 const char *
-gcry_pk_algo_name( int algo )
+gcry_pk_algo_name (int id)
 {
-    int i;
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return pubkey_table[i].name;
-    } while( load_pubkey_modules() );
-    return NULL;
+  const char *name = NULL;
+  GcryModule *pubkey;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      name = ((GcryPubkeySpec *) pubkey->spec)->name;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return name;
 }
 
 
 static void
-disable_pubkey_algo( int algo )
+disable_pubkey_algo (int id)
 {
-    int i;
+  GcryModule *pubkey;
 
-    for(i=0; i < DIM(disabled_algos); i++ ) {
-       if( !disabled_algos[i] || disabled_algos[i] == algo ) {
-           disabled_algos[i] = algo;
-           return;
-       }
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
+       pubkey->flags |= FLAG_MODULE_DISABLED;
+      _gcry_module_release (pubkey);
     }
-    log_fatal("can't disable pubkey algo %d: table full\n", algo );
+  ath_mutex_unlock (&pubkeys_registered_lock);
 }
 
 
@@ -403,121 +389,170 @@ disable_pubkey_algo( int algo )
  * a use of 0 means: don't care
  */
 static int
-check_pubkey_algo( int algo, unsigned use )
+check_pubkey_algo (int id, unsigned use)
 {
-    int i;
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               if( (use & GCRY_PK_USAGE_SIGN)
-                   && !(pubkey_table[i].use & GCRY_PK_USAGE_SIGN) )
-                   return GCRYERR_WRONG_PK_ALGO;
-               if( (use & GCRY_PK_USAGE_ENCR)
-                   && !(pubkey_table[i].use & GCRY_PK_USAGE_ENCR) )
-                   return GCRYERR_WRONG_PK_ALGO;
-
-               for(i=0; i < DIM(disabled_algos); i++ ) {
-                   if( disabled_algos[i] == algo )
-                       return GCRYERR_INV_PK_ALGO;
-               }
-               return 0; /* okay */
-           }
-    } while( load_pubkey_modules() );
-    return GCRYERR_INV_PK_ALGO;
-}
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int err = 0;
 
+  REGISTER_DEFAULT_PUBKEYS;
 
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+
+      if (((use & GCRY_PK_USAGE_SIGN)
+          && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
+         || ((use & GCRY_PK_USAGE_ENCR)
+             && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
+       err = GCRYERR_WRONG_PK_ALGO;
+      else if (module->flags & FLAG_MODULE_DISABLED)
+       err = GCRYERR_INV_PK_ALGO;
+      _gcry_module_release (module);
+    }
+  else
+    err = GCRYERR_INV_PK_ALGO;
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
 
 
 /****************
  * Return the number of public key material numbers
  */
 static int
-pubkey_get_npkey( int algo )
+pubkey_get_npkey (int id)
 {
-    int i;
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return pubkey_table[i].npkey;
-    } while( load_pubkey_modules() );
-    return 0;
+  GcryModule *pubkey;
+  int npkey = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      npkey = ((GcryPubkeySpec *) pubkey->spec)->npkey;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return npkey;
 }
 
 /****************
  * Return the number of secret key material numbers
  */
 static int
-pubkey_get_nskey( int algo )
+pubkey_get_nskey (int id)
 {
-    int i;
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return pubkey_table[i].nskey;
-    } while( load_pubkey_modules() );
-    return 0;
+  GcryModule *pubkey;
+  int nskey = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      nskey = ((GcryPubkeySpec *) pubkey->spec)->nskey;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nskey;
 }
 
 /****************
  * Return the number of signature material numbers
  */
 static int
-pubkey_get_nsig( int algo )
+pubkey_get_nsig (int id)
 {
-    int i;
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return pubkey_table[i].nsig;
-    } while( load_pubkey_modules() );
-    return 0;
+  GcryModule *pubkey;
+  int nsig = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      nsig = ((GcryPubkeySpec *) pubkey->spec)->nsig;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nsig;
 }
 
 /****************
  * Return the number of encryption material numbers
  */
 static int
-pubkey_get_nenc( int algo )
+pubkey_get_nenc (int id)
 {
-    int i;
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return pubkey_table[i].nenc;
-    } while( load_pubkey_modules() );
-    return 0;
+  GcryModule *pubkey;
+  int nenc = 0;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      nenc = ((GcryPubkeySpec *) pubkey->spec)->nenc;
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return nenc;
 }
 
 
 static int
-pubkey_generate( int algo, unsigned int nbits, unsigned long use_e,
-                 MPI *skey, MPI **retfactors )
+pubkey_generate (int id, unsigned int nbits, unsigned long use_e,
+                 MPI *skey, MPI **retfactors)
 {
-    int i;
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-                return (*pubkey_table[i].generate)( algo, nbits, use_e,
-                                                   skey, retfactors );
-    } while( load_pubkey_modules() );
-    return GCRYERR_INV_PK_ALGO;
-}
+  GcryModule *pubkey;
+  int err = GCRYERR_INV_PK_ALGO;
 
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      err = (*((GcryPubkeySpec *) pubkey->spec)->generate) (id, nbits, use_e, skey,
+                                                           retfactors);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
+}
 
 static int
-pubkey_check_secret_key( int algo, MPI *skey )
+pubkey_check_secret_key (int id, MPI *skey)
 {
-    int i;
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo )
-               return (*pubkey_table[i].check_secret_key)( algo, skey );
-    } while( load_pubkey_modules() );
-    return GCRYERR_INV_PK_ALGO;
+  GcryModule *pubkey;
+  int err = GCRYERR_INV_PK_ALGO;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  pubkey = gcry_pubkey_lookup_id (id);
+  if (pubkey)
+    {
+      err = (*((GcryPubkeySpec *) pubkey->spec)->check_secret_key) (id, skey);
+      _gcry_module_release (pubkey);
+    }
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  return err;
 }
 
 
@@ -528,34 +563,44 @@ pubkey_check_secret_key( int algo, MPI *skey )
  * algorithm allows this - check with pubkey_get_nenc() )
  */
 static int
-pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey,
-               int flags )
+pubkey_encrypt (int id, MPI *resarr, MPI data, MPI *pkey,
+               int flags)
 {
-    int i, rc;
-
-    if( DBG_CIPHER ) {
-       log_debug("pubkey_encrypt: algo=%d\n", algo );
-       for(i=0; i < pubkey_get_npkey(algo); i++ )
-           log_mpidump("  pkey:", pkey[i] );
-       log_mpidump("  data:", data );
-    }
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey, flags);
-               goto ready;
-           }
-    } while( load_pubkey_modules() );
-    rc = GCRYERR_INV_PK_ALGO;
-  ready:
-    if( !rc && DBG_CIPHER ) {
-       for(i=0; i < pubkey_get_nenc(algo); i++ )
-           log_mpidump("  encr:", resarr[i] );
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int i, rc;
+
+  if (DBG_CIPHER)
+    {
+      log_debug ("pubkey_encrypt: algo=%d\n", id);
+      for(i = 0; i < pubkey_get_npkey (id); i++)
+       log_mpidump ("  pkey:", pkey[i]);
+      log_mpidump ("  data:", data);
     }
-    return rc;
-}
 
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+      rc = (*pubkey->encrypt) (id, resarr, data, pkey, flags);
+      _gcry_module_release (module);
+      goto ready;
+    }
+  rc = GCRYERR_INV_PK_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (!rc && DBG_CIPHER)
+    {
+      for(i = 0; i < pubkey_get_nenc (id); i++)
+       log_mpidump("  encr:", resarr[i] );
+    }
+  return rc;
+}
 
 
 /****************
@@ -566,33 +611,44 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey,
  * newly allocated mpi or NULL in case of an error.
  */
 static int
-pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey,
+pubkey_decrypt (int id, MPI *result, MPI *data, MPI *skey,
                int flags)
 {
-    int i, rc;
-
-    *result = NULL; /* so the caller can always do a mpi_free */
-    if( DBG_CIPHER ) {
-       log_debug("pubkey_decrypt: algo=%d\n", algo );
-       for(i=0; i < pubkey_get_nskey(algo); i++ )
-           log_mpidump("  skey:", skey[i] );
-       for(i=0; i < pubkey_get_nenc(algo); i++ )
-           log_mpidump("  data:", data[i] );
-    }
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               rc = (*pubkey_table[i].decrypt)( algo, result, data, skey, flags );
-               goto ready;
-           }
-    } while( load_pubkey_modules() );
-    rc = GCRYERR_INV_PK_ALGO;
-  ready:
-    if( !rc && DBG_CIPHER ) {
-       log_mpidump(" plain:", *result );
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int i, rc;
+
+  *result = NULL; /* so the caller can always do a mpi_free */
+  if (DBG_CIPHER)
+    {
+      log_debug ("pubkey_decrypt: algo=%d\n", id);
+      for(i = 0; i < pubkey_get_nskey (id); i++)
+       log_mpidump ("  skey:", skey[i]);
+      for(i = 0; i < pubkey_get_nenc (id); i++)
+       log_mpidump ("  data:", data[i]);
     }
-    return rc;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+      rc = (*pubkey->decrypt) (id, result, data, skey, flags);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GCRYERR_INV_PK_ALGO;
+  
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (! rc && DBG_CIPHER)
+    log_mpidump (" plain:", *result);
+
+  return rc;
 }
 
 
@@ -603,31 +659,42 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey,
  * algorithm allows this - check with pubkey_get_nsig() )
  */
 static int
-pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
+pubkey_sign (int id, MPI *resarr, MPI data, MPI *skey)
 {
-    int i, rc;
-
-    if( DBG_CIPHER ) {
-       log_debug("pubkey_sign: algo=%d\n", algo );
-       for(i=0; i < pubkey_get_nskey(algo); i++ )
-           log_mpidump("  skey:", skey[i] );
-       log_mpidump("  data:", data );
-    }
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               rc = (*pubkey_table[i].sign)( algo, resarr, data, skey );
-               goto ready;
-           }
-    } while( load_pubkey_modules() );
-    rc = GCRYERR_INV_PK_ALGO;
-  ready:
-    if( !rc && DBG_CIPHER ) {
-       for(i=0; i < pubkey_get_nsig(algo); i++ )
-           log_mpidump("   sig:", resarr[i] );
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int i, rc;
+
+  if (DBG_CIPHER)
+    {
+      log_debug ("pubkey_sign: algo=%d\n", id);
+      for(i = 0; i < pubkey_get_nskey (id); i++)
+       log_mpidump ("  skey:", skey[i]);
+      log_mpidump("  data:", data );
     }
-    return rc;
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+      rc = (*pubkey->sign) (id, resarr, data, skey);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GCRYERR_INV_PK_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  if (! rc && DBG_CIPHER)
+    for (i = 0; i < pubkey_get_nsig (id); i++)
+      log_mpidump ("   sig:", resarr[i]);
+
+  return rc;
 }
 
 /****************
@@ -635,33 +702,41 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
  * Return 0 if the signature is good
  */
 static int
-pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
-                   int (*cmp)(void *, MPI), void *opaquev )
+pubkey_verify (int id, MPI hash, MPI *data, MPI *pkey,
+              int (*cmp)(void *, MPI), void *opaquev)
 {
-    int i, rc;
-
-    if( DBG_CIPHER ) {
-       log_debug("pubkey_verify: algo=%d\n", algo );
-       for(i=0; i < pubkey_get_npkey(algo); i++ )
-           log_mpidump("  pkey:", pkey[i] );
-       for(i=0; i < pubkey_get_nsig(algo); i++ )
-           log_mpidump("   sig:", data[i] );
-       log_mpidump("  hash:", hash );
-    }
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               rc = (*pubkey_table[i].verify)( algo, hash, data, pkey,
-                                                           cmp, opaquev );
-               goto ready;
-           }
-    } while( load_pubkey_modules() );
-    rc = GCRYERR_INV_PK_ALGO;
-  ready:
-    return rc;
-}
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int i, rc;
 
+  if (DBG_CIPHER)
+    {
+      log_debug ("pubkey_verify: algo=%d\n", id);
+      for (i = 0; i < pubkey_get_npkey (id); i++)
+       log_mpidump ("  pkey:", pkey[i]);
+      for (i = 0; i < pubkey_get_nsig (id); i++)
+       log_mpidump ("   sig:", data[i]);
+      log_mpidump ("  hash:", hash);
+    }
+
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+      rc = (*pubkey->verify) (id, hash, data, pkey, cmp, opaquev);
+      _gcry_module_release (module);
+      goto ready;
+    }
+
+  rc = GCRYERR_INV_PK_ALGO;
+
+ ready:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  return rc;
+}
 
 
 /****************
@@ -1865,33 +1940,44 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
  * different propoerties of the key?
  */
 unsigned int
-gcry_pk_get_nbits( GCRY_SEXP key )
+gcry_pk_get_nbits (GCRY_SEXP key)
 {
-    int rc, i, algo;
-    MPI *keyarr;
-    unsigned int nbits = 0;
+  GcryPubkeySpec *pubkey;
+  GcryModule *module;
+  int rc, id;
+  MPI *keyarr;
+  unsigned int nbits = 0;
+
+  rc = sexp_to_key (key, 0, &keyarr, &id, NULL);
+  if (rc == GCRYERR_INV_OBJ)
+    rc = sexp_to_key (key, 1, &keyarr, &id, NULL);
+  if (rc)
+    return 0;
 
-    rc = sexp_to_key( key, 0, &keyarr, &algo, NULL );
-    if( rc == GCRYERR_INV_OBJ )
-       rc = sexp_to_key( key, 1, &keyarr, &algo, NULL );
-    if( rc )
-       return 0;
-
-    do {
-       for(i=0; pubkey_table[i].name; i++ )
-           if( pubkey_table[i].algo == algo ) {
-               nbits = (*pubkey_table[i].get_nbits)( algo, keyarr );
-               goto leave;
-           }
-    } while( load_pubkey_modules() );
-    if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
-       nbits = mpi_get_nbits( keyarr[0] );
-  leave:
-    release_mpi_array( keyarr );
-    gcry_free (keyarr);
-    return nbits;
+  REGISTER_DEFAULT_PUBKEYS;
+
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pubkey_lookup_id (id);
+  if (module)
+    {
+      pubkey = (GcryPubkeySpec *) module->spec;
+      nbits = (*pubkey->get_nbits) (id, keyarr);
+      _gcry_module_release (module);
+      goto leave;
+    }
+
+  if (is_RSA (id))     /* we always wanna see the length of a key :-) */
+    nbits = mpi_get_nbits (keyarr[0]);
+
+ leave:
+  ath_mutex_unlock (&pubkeys_registered_lock);
+
+  release_mpi_array (keyarr);
+  gcry_free (keyarr);
+  return nbits;
 }
 
+
 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
    key parameters expressed in a way depended on the algorithm.
 
@@ -1936,7 +2022,7 @@ gcry_pk_get_keygrip (GCRY_SEXP key, unsigned char *array)
   if(!s)
     goto fail; /* unknown algorithm */
 
-  is_rsa = algo_info_table[i].algo == PUBKEY_ALGO_RSA;
+  is_rsa = algo_info_table[i].algo == GCRY_PK_RSA;
   elems = algo_info_table[i].grip_elements;
   if (!elems)
     goto fail; /* no grip parameter */
@@ -2037,42 +2123,57 @@ gcry_pk_ctl( int cmd, void *buffer, size_t buflen)
  * the block size)
  */
 int
-gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes)
+gcry_pk_algo_info (int id, int what, void *buffer, size_t *nbytes)
 {
-    switch( what ) {
-      case GCRYCTL_TEST_ALGO: {
-           int use = nbytes? *nbytes: 0;
-           if( buffer ) {
-               set_lasterr( GCRYERR_INV_ARG );
-               return -1;
-           }
-           if( check_pubkey_algo( algo, use ) ) {
-               set_lasterr( GCRYERR_INV_PK_ALGO );
-               return -1;
-           }
-       }
-       break;
-
-      case GCRYCTL_GET_ALGO_USAGE: 
-          do {
-              int i;
-              for(i=0; pubkey_table[i].name; i++ )
-                  if( pubkey_table[i].algo == algo ) 
-                      return pubkey_table[i].use;
-          } while( load_pubkey_modules() );
-          return 0;
-         
-      case GCRYCTL_GET_ALGO_NPKEY: return pubkey_get_npkey( algo );
-      case GCRYCTL_GET_ALGO_NSKEY: return pubkey_get_nskey( algo );
-      case GCRYCTL_GET_ALGO_NSIGN: return pubkey_get_nsig( algo );
-      case GCRYCTL_GET_ALGO_NENCR: return pubkey_get_nenc( algo );
+  switch (what)
+    {
+    case GCRYCTL_TEST_ALGO:
+      {
+       int use = nbytes ? *nbytes: 0;
+       if (buffer)
+         {
+           set_lasterr( GCRYERR_INV_ARG );
+           return -1;
+         }
+       if (check_pubkey_algo (id, use))
+         {
+           set_lasterr( GCRYERR_INV_PK_ALGO );
+           return -1;
+         }
+      }
+      break;
 
-      default:
-       set_lasterr( GCRYERR_INV_OP );
-       return -1;
-    }
-    return 0;
-}
+    case GCRYCTL_GET_ALGO_USAGE:
+      {
+       GcryModule *pubkey;
+       int use = 0;
+
+       REGISTER_DEFAULT_PUBKEYS;
+
+       ath_mutex_lock (&pubkeys_registered_lock);
+       pubkey = gcry_pubkey_lookup_id (id);
+       if (pubkey)
+         {
+           use = ((GcryPubkeySpec *) pubkey->spec)->use;
+           _gcry_module_release (pubkey);
+         }
+       ath_mutex_unlock (&pubkeys_registered_lock);
+       return use;
+      }
 
+    case GCRYCTL_GET_ALGO_NPKEY:
+      return pubkey_get_npkey (id);
+    case GCRYCTL_GET_ALGO_NSKEY:
+      return pubkey_get_nskey (id);
+    case GCRYCTL_GET_ALGO_NSIGN:
+      return pubkey_get_nsig (id);
+    case GCRYCTL_GET_ALGO_NENCR:
+      return pubkey_get_nenc (id);
 
+    default:
+      set_lasterr (GCRYERR_INV_OP);
+      return -1;
+    }
 
+  return 0;
+}
index 43c6087..8c9abb6 100644 (file)
 #ifndef G10_RAND_INTERNAL_H
 #define G10_RAND_INTERNAL_H
 
-void rndlinux_constructor(void);
-void rndunix_constructor(void);
-void rndw32_constructor(void);
-void rndos2_constructor(void);
-void rndatari_constructor(void);
-void rndmvs_constructor(void);
-
 void _gcry_random_progress (const char *what, int printchar,
                             int current, int total);
 
index 60445fb..8df2c56 100644 (file)
@@ -53,7 +53,7 @@
 #include "rmd.h"
 #include "random.h"
 #include "rand-internal.h"
-#include "dynload.h"
+//#include "dynload.h"
 #include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
 #include "ath.h"
 
@@ -133,7 +133,6 @@ static struct {
 static void (*progress_cb) (void *,const char*,int,int, int );
 static void *progress_cb_data;
 
-
 /* Note, we assume that this function is used before any concurrent
    access happens */
 static void
@@ -153,7 +152,8 @@ initialize(void)
   keypool = secure_alloc ? gcry_xcalloc_secure(1,POOLSIZE+BLOCKLEN)
                          : gcry_xcalloc(1,POOLSIZE+BLOCKLEN);
   is_initialized = 1;
-  _gcry_cipher_modules_constructor ();
+
+  //_gcry_cipher_modules_constructor ();
 }
 
 
@@ -732,6 +732,85 @@ random_poll()
     read_random_source( 2, POOLSIZE/5, 1 );
 }
 
+static int (*
+getfnc_gather_random (void))(void (*)(const void*, size_t, int), int,
+                            size_t, int)
+{
+#if USE_RNDLINUX
+  int rndlinux_gather_random (void (*add) (const void *, size_t, int),
+                             int requester, size_t length, int level);
+#endif
+#if USE_RNDUNIX
+  int rndunix_gather_random (void (*add) (const void *, size_t, int),
+                            int requester, size_t length, int level);
+#endif
+#if USE_RNDEGD
+  int rndegd_gather_random (void (*add) (const void *, size_t, int),
+                           int requester, size_t length, int level);
+  int rndegd_connect_socket (int nofail);
+#endif
+#if USE_RNDW32
+  int rndw32_gather_random (void (*add) (const void *, size_t, int),
+                           int requester, size_t length, int level);
+#endif
+
+#ifdef USE_ALL_RANDOM_MODULES
+  static int (*fnc)(void (*)(const void*, size_t, int), int, size_t, int);
+  
+  if (fnc)
+    return fnc;
+# if USE_RNDLINUX
+  if ( !access (NAME_OF_DEV_RANDOM, R_OK)
+       && !access (NAME_OF_DEV_RANDOM, R_OK))
+    {
+      fnc = rndlinux_gather_random;
+      return fnc;
+    }
+# endif
+# if USE_RNDEGD
+  if ( rndegd_connect_socket (1) != -1 )
+    {
+      fnc = rndegd_gather_random;
+      return fnc;
+    }
+# endif
+# if USE_RNDUNIX
+  fnc = rndunix_gather_random;
+  return fnc;
+# endif
+
+  log_fatal (_("no entropy gathering module detected\n"));
+
+#else
+# if USE_RNDLINUX
+  return rndlinux_gather_random;
+# endif
+# if USE_RNDUNIX
+  return rndunix_gather_random;
+# endif
+# if USE_RNDEGD
+  return rndegd_gather_random;
+# endif
+# if USE_RNDW32
+  return rndw32_gather_random;
+# endif
+# if USE_RNDRISCOS
+  return rndriscos_gather_random;
+# endif
+#endif
+  return NULL;
+}
+
+static void (*
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t, int), int)
+{
+#if USE_RNDW32
+  int rndw32_gather_random_fast (void (*add) (const void *, size_t, int),
+                                int requester);
+  return rndw32_gather_random_fast;
+#endif
+  return NULL;
+}
 
 
 static void
@@ -746,7 +825,7 @@ do_fast_random_poll ()
        if( !is_initialized )
            initialize();
        initialized = 1;
-       fnc = _gcry_dynload_getfnc_fast_random_poll();
+       fnc = getfnc_fast_random_poll ();
     }
     if( fnc ) {
        (*fnc)( add_randomness, 1 );
@@ -846,8 +925,10 @@ read_random_source( int requester, size_t length, int level )
                                                    size_t, int) = NULL;
     if( !fnc ) {
        if( !is_initialized )
-           initialize();
-       fnc = _gcry_dynload_getfnc_gather_random();
+         initialize();
+       fnc = getfnc_gather_random ();
+       //fnc = ((GcryRandomSpec *) randoms_registered->spec)->add;
+       //fnc = _gcry_dynload_getfnc_gather_random();
        if( !fnc ) {
            faked_rng = 1;
            fnc = gather_faked;
index b7c7d18..d7814cb 100644 (file)
@@ -40,7 +40,7 @@
 
 #include "types.h"  /* for byte and u32 typedefs */
 #include "g10lib.h"
-#include "dynload.h"
+#include "cipher.h"
 
 #define MAXKC                  (256/32)
 #define MAXROUNDS              14
@@ -1811,11 +1811,12 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
 }
 
 static int
-rijndael_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
+rijndael_setkey (void *context, const byte *key, const unsigned keylen)
 {
-    int rc = do_setkey (ctx, key, keylen);
-    _gcry_burn_stack ( 100 + 16*sizeof(int));
-    return rc;
+  RIJNDAEL_context *ctx = (RIJNDAEL_context *) context;
+  int rc = do_setkey (ctx, key, keylen);
+  _gcry_burn_stack ( 100 + 16*sizeof(int));
+  return rc;
 }
 
 
@@ -1936,10 +1937,11 @@ do_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
 }
 
 static void
-rijndael_encrypt (const RIJNDAEL_context *ctx, byte *b, const byte *a)
+rijndael_encrypt (void *context, byte *b, const byte *a)
 {
-    do_encrypt (ctx, b, a);
-    _gcry_burn_stack (16 + 2*sizeof(int));
+  RIJNDAEL_context *ctx = (RIJNDAEL_context *) context;
+  do_encrypt (ctx, b, a);
+  _gcry_burn_stack (16 + 2*sizeof(int));
 }
 
 
@@ -2031,10 +2033,11 @@ do_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
 }
 
 static void
-rijndael_decrypt (RIJNDAEL_context *ctx, byte *b, const byte *a)
+rijndael_decrypt (void *context, byte *b, const byte *a)
 {
-    do_decrypt (ctx, b, a);
-    _gcry_burn_stack (16+2*sizeof(int));
+  RIJNDAEL_context *ctx = (RIJNDAEL_context *) context;
+  do_decrypt (ctx, b, a);
+  _gcry_burn_stack (16+2*sizeof(int));
 }
 \f
 /* Test a single encryption and decryption with each key size. */
@@ -2048,11 +2051,11 @@ selftest (void)
     /* The test vectors are from the AES supplied ones; more or less 
      * randomly taken from ecb_tbl.txt (I=42,81,14)
      */
-    static const byte plaintext[16] = {
+    static byte plaintext[16] = {
        0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,
        0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A
     };
-    static const byte key[16] = {
+    static byte key[16] = {
         0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,
         0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA
     };
@@ -2061,11 +2064,11 @@ selftest (void)
         0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD
     };
 
-    static const byte plaintext_192[16] = {
+    static byte plaintext_192[16] = {
         0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4,
         0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72
     };
-    static const byte key_192[24] = {
+    static byte key_192[24] = {
         0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,
         0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,
         0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20
@@ -2075,11 +2078,11 @@ selftest (void)
         0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
     };
     
-    static const byte plaintext_256[16] = {
+    static byte plaintext_256[16] = {
         0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
         0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
     };
-    static const byte key_256[32] = {
+    static byte key_256[32] = {
         0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,
         0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,
         0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,
@@ -2116,97 +2119,23 @@ selftest (void)
     
     return NULL;
 }
-\f
-#ifdef IS_MODULE
-static
-#endif
-       const char *
-_gcry_rijndael_get_info (int algo, size_t *keylen,
-                 size_t *blocksize, size_t *contextsize,
-                 int  (**r_setkey) (void *c, byte *key, unsigned keylen),
-                 void (**r_encrypt) (void *c, byte *outbuf, byte *inbuf),
-                 void (**r_decrypt) (void *c, byte *outbuf, byte *inbuf)
-                )
-{
-    *keylen = algo==7? 128 :  algo==8? 192 : 256;
-    *blocksize = 16;
-    *contextsize = sizeof (RIJNDAEL_context);
-
-    *(int  (**)(RIJNDAEL_context*, const byte*, const unsigned))r_setkey
-                                                       = rijndael_setkey;
-    *(void (**)(const RIJNDAEL_context*, byte*, const byte*))r_encrypt
-                                                       = rijndael_encrypt;
-    *(void (**)(RIJNDAEL_context*, byte*, const byte*))r_decrypt
-                                                       = rijndael_decrypt;
-
-    if( algo == 7 )
-       return "AES";
-    if (algo == 8)
-        return "AES192";
-    if (algo == 9)
-        return "AES256";
-    return NULL;
-}
-
-
-#ifdef IS_MODULE
-const char * const gnupgext_version = "RIJNDAEL ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 20, 1, 0, (void(*)(void))_gcry_rijndael_get_info },
-    { 21, 1, 7  },
-    { 21, 1, 8  },
-    { 21, 1, 9  },
-};
-
 
+\f
 
-/****************
- * Enumerate the names of the functions together with information about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- *                        10 = message digest algorithm info function
- *                        11 = integer with available md algorithms
- *                        20 = cipher algorithm info function
- *                        21 = integer with available cipher algorithms
- *                        30 = public key algorithm info function
- *                        31 = integer with available pubkey algorithms
- *               version = interface version of the function/pointer
- *                         (currently this is 1 for all functions)
- */
-void *
-gnupgext_enum_func ( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
+GcryCipherSpec cipher_spec_aes =
+  {
+    "AES", GCRY_CIPHER_AES, 16, 128, sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+  };
 
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while ( what && what != *class );
+GcryCipherSpec cipher_spec_aes192 =
+  {
+    "AES192", GCRY_CIPHER_AES192, 16, 192, sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+  };
 
-    *sequence = i;
-    return ret;
-}
-#endif
+GcryCipherSpec cipher_spec_aes256 =
+  {
+    "AES256", GCRY_CIPHER_AES256, 16, 256, sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+  };
index d2938bf..6c44017 100644 (file)
@@ -29,7 +29,7 @@ typedef struct {
     int  count;
 } RMD160_CONTEXT;
 
-void _gcry_rmd160_init( RMD160_CONTEXT *hd );
+void _gcry_rmd160_init( void *context );
 void _gcry_rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer );
 
 #endif /*G10_RMD_H*/
index 4cf52c5..23c730f 100644 (file)
@@ -27,7 +27,6 @@
 #include "memory.h"
 #include "rmd.h"
 #include "cipher.h" /* only used for the rmd160_hash_buffer() prototype */
-#include "dynload.h"
 
 #include "bithelp.h"
 
 
 
 void
-_gcry_rmd160_init( RMD160_CONTEXT *hd )
+_gcry_rmd160_init (void *context)
 {
+  RMD160_CONTEXT *hd = (RMD160_CONTEXT *) context;
     hd->h0 = 0x67452301;
     hd->h1 = 0xEFCDAB89;
     hd->h2 = 0x98BADCFE;
@@ -398,8 +398,9 @@ transform( RMD160_CONTEXT *hd, byte *data )
  * of INBUF with length INLEN.
  */
 static void
-rmd160_write( RMD160_CONTEXT *hd, byte *inbuf, size_t inlen)
+rmd160_write( void *context, byte *inbuf, size_t inlen)
 {
+  RMD160_CONTEXT *hd = (RMD160_CONTEXT *) context;
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
         _gcry_burn_stack (108+5*sizeof(void*));
@@ -453,8 +454,9 @@ _gcry_rmd160_mixblock( RMD160_CONTEXT *hd, char *buffer )
  */
 
 static void
-rmd160_final( RMD160_CONTEXT *hd )
+rmd160_final( void *context )
 {
+  RMD160_CONTEXT *hd = (RMD160_CONTEXT *) context;
     u32 t, msb, lsb;
     byte *p;
 
@@ -514,8 +516,9 @@ rmd160_final( RMD160_CONTEXT *hd )
 }
 
 static byte *
-rmd160_read( RMD160_CONTEXT *hd )
+rmd160_read( void *context )
 {
+  RMD160_CONTEXT *hd = (RMD160_CONTEXT *) context;
     return hd->buf;
 }
 
@@ -536,98 +539,13 @@ _gcry_rmd160_hash_buffer( char *outbuf, const char *buffer, size_t length )
     memcpy( outbuf, hd.buf, 20 );
 }
 
+static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
+  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+    0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-rmd160_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
-{
-    static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
-         { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
-           0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
-
-    if( algo != 3 )
-       return NULL;
-
-    *contextsize = sizeof(RMD160_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 20;
-    *(void  (**)(RMD160_CONTEXT *))r_init                = _gcry_rmd160_init;
-    *(void  (**)(RMD160_CONTEXT *, byte*, size_t))r_write = rmd160_write;
-    *(void  (**)(RMD160_CONTEXT *))r_final               = rmd160_final;
-    *(byte *(**)(RMD160_CONTEXT *))r_read                = rmd160_read;
-
-    return "RIPEMD160";
-}
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RMD160 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))rmd160_get_info },
-    { 11, 1, 3 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-_gcry_rmd160_constructor(void)
-{
-    _gcry_register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
-
+GcryDigestSpec digest_spec_rmd160 =
+  {
+    "RIPEMD160", GCRY_MD_RMD160, asn, DIM (asn), 20,
+    _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
+    sizeof (RMD160_CONTEXT)
+  };
index f2a3d3f..7b32042 100644 (file)
 #include <sys/un.h>
 #include "types.h"
 #include "g10lib.h"
-#include "dynload.h"
 #include "cipher.h"
 
 #ifndef offsetof
 #define offsetof(type, member) ((size_t) &((type *)0)->member)
 #endif
 
+static int egd_socket = -1;
 
 /* FIXME: this is duplicated code from util/fileutil
  * I don't think that this code should go into libgcrypt anyway.
@@ -74,9 +74,6 @@ my_make_filename( const char *first_part, ... )
 }
 
 
-
-
-
 static int
 do_write( int fd, void *buf, size_t nbytes )
 {
@@ -105,14 +102,69 @@ do_read( int fd, void *buf, size_t nbytes )
        do {
            n = read(fd, (char*)buf + nread, nbytes );
        } while( n == -1 && errno == EINTR );
-       if( n == -1 )
+       if( n == -1)
+           return nread? nread:-1;
+       if( n == 0)
            return -1;
        nread += n;
+       nbytes -= n;
     } while( nread < nbytes );
     return nbytes;
 }
 
 
+/* Connect to the EGD and return the file descriptor.  Return -1 on
+   error.  With NOFAIL set to true, silently fail and return the
+   error, otherwise print an error message and die. */
+int
+rndegd_connect_socket (int nofail)
+{
+  int fd;
+  const char *bname = NULL;
+  char *name;
+  struct sockaddr_un addr;
+  int addr_len;
+
+  if (egd_socket != -1)
+    {
+      close (egd_socket);
+      egd_socket = -1;
+    }
+
+#ifdef EGD_SOCKET_NAME
+  bname = EGD_SOCKET_NAME;
+#endif
+  if ( !bname || !*bname )
+    name = my_make_filename ("~/.gnupg", "entropy", NULL); /* FIXME?  */
+  else
+    name = my_make_filename (bname, NULL);
+
+  if (strlen(name)+1 >= sizeof addr.sun_path)
+    log_fatal ("EGD socketname is too long\n");
+  
+  memset( &addr, 0, sizeof addr );
+  addr.sun_family = AF_UNIX;
+  strcpy( addr.sun_path, name );         
+  addr_len = (offsetof( struct sockaddr_un, sun_path )
+              + strlen( addr.sun_path ));
+  
+  fd = socket(AF_UNIX, SOCK_STREAM, 0);
+  if (fd == -1 && !nofail)
+    log_fatal("can't create unix domain socket: %s\n",
+             strerror(errno) );
+  else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1)
+    {
+      if (!nofail)
+        log_fatal("can't connect to `%s': %s\n",
+                 name, strerror(errno) );
+      close (fd);
+      fd = -1;
+    }
+  gcry_free(name);
+  if (fd != -1)
+    egd_socket = fd;
+  return fd;
+}
 
 /****************
  * Note: we always use the highest level.
@@ -122,11 +174,11 @@ do_read( int fd, void *buf, size_t nbytes )
  * Using a level of 0 should never block and better add nothing
  * to the pool.  So this is just a dummy for EGD.
  */
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-                                         size_t length, int level )
+int
+rndegd_gather_random( void (*add)(const void*, size_t, int), int requester,
+                     size_t length, int level )
 {
-    static int fd = -1;
+    int fd = egd_socket;
     int n;
     byte buffer[256+2];
     int nbytes;
@@ -138,35 +190,9 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
        return 0;
 
   restart:
-    if( do_restart ) {
-       if( fd != -1 ) {
-           close( fd );
-           fd = -1;
-       }
-    }
-    if( fd == -1 ) {
-#if __GNUC__ >= 2
-       #warning Fixme: make the filename configurable
-#endif
-       char *name = my_make_filename( "~/.gnupg-test", "entropy", NULL );
-       struct sockaddr_un addr;
-       int addr_len;
-
-       memset( &addr, 0, sizeof addr );
-       addr.sun_family = AF_UNIX;
-       strcpy( addr.sun_path, name );    /* fixme: check that it is long enough */
-       addr_len = offsetof( struct sockaddr_un, sun_path )
-                  + strlen( addr.sun_path );
+    if (fd == -1 || do_restart)
+      fd = rndegd_connect_socket (0);
 
-       fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if( fd == -1 )
-           log_fatal("can't create unix domain socket: %s\n",
-                                                           strerror(errno) );
-       if( connect( fd, (struct sockaddr*)&addr, addr_len) == -1 )
-           log_fatal("can't connect to `%s': %s\n",
-                                                   name, strerror(errno) );
-       gcry_free(name);
-    }
     do_restart = 0;
 
     nbytes = length < 255? length : 255;
@@ -219,62 +245,3 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
 
     return 0; /* success */
 }
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDEGD ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    void *func;
-} func_table[] = {
-    { 40, 1, gather_random },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       ret = func_table[i].func;
-       i++;
-    } while ( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-#ifndef IS_MODULE
-void
-_gcry_rndegd_constructor(void)
-{
-  _gcry_register_internal_cipher_extension (gnupgext_version,
-                                            gnupgext_enum_func);
-}
-#endif
-
-
-
-
-
-
-
-
-
-
-
index aa984a8..64c8435 100644 (file)
 #endif
 #include "types.h"
 #include "g10lib.h"
-#include "dynload.h"
 #include "rand-internal.h"
 
 static int open_device( const char *name, int minor );
-static int gather_random( void (*add)(const void*, size_t, int), int requester,
-                                         size_t length, int level );
+int rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
+                           size_t length, int level );
 
 #if 0
 #ifdef HAVE_DEV_RANDOM_IOCTL
@@ -84,9 +83,9 @@ open_device( const char *name, int minor )
 }
 
 
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-                                         size_t length, int level )
+int
+rndlinux_gather_random( void (*add)(const void*, size_t, int), int requester,
+                       size_t length, int level )
 {
     static int fd_urandom = -1;
     static int fd_random = -1;
@@ -157,71 +156,3 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
 
     return 0; /* success */
 }
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDLINUX ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    void *func;
-} func_table[] = {
-    { 40, 1, gather_random },
-};
-
-
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- *                        10 = message digest algorithm info function
- *                        11 = integer with available md algorithms
- *                        20 = cipher algorithm info function
- *                        21 = integer with available cipher algorithms
- *                        30 = public key algorithm info function
- *                        31 = integer with available pubkey algorithms
- *                        40 = get gather_random function
- *                        41 = get fast_random_poll function
- *               version = interface version of the function/pointer
- *                         (currently this is 1 for all functions)
- */
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       ret = func_table[i].func;
-       i++;
-    } while ( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-#ifndef IS_MODULE
-void
-_gcry_rndlinux_constructor(void)
-{
-    _gcry_register_internal_cipher_extension( gnupgext_version,
-                                       gnupgext_enum_func );
-}
-#endif
-
index e66fa0c..b9b12c9 100644 (file)
@@ -99,9 +99,6 @@
 #include <errno.h>
 
 #include "types.h"  /* for byte and u32 typedefs */
-#ifndef IS_MODULE
-#include "dynload.h"
-#endif
 #include "g10lib.h"
 
 #ifndef EAGAIN
@@ -770,9 +767,9 @@ read_a_msg( int fd, GATHER_MSG *msg )
  * Using a level of 0 should never block and better add nothing
  * to the pool.  So this is just a dummy for this gatherer.
  */
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-              size_t length, int level )
+int
+rndunix_gather_random( void (*add)(const void*, size_t, int), int requester,
+                      size_t length, int level )
 {
     static pid_t gatherer_pid = 0;
     static int pipedes[2];
@@ -847,71 +844,3 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
 
     return 0;
 }
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDUNIX ($Revision$)";
-
-
-static struct {
-    int class;
-    int version;
-    void *func;
-} func_table[] = {
-    { 40, 1, gather_random },
-};
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- *                        10 = message digest algorithm info function
- *                        11 = integer with available md algorithms
- *                        20 = cipher algorithm info function
- *                        21 = integer with available cipher algorithms
- *                        30 = public key algorithm info function
- *                        31 = integer with available pubkey algorithms
- *                        40 = get read_random_source() function
- *                        41 = get fast_random_poll function
- *               version = interface version of the function/pointer
- *                         (currently this is 1 for all functions)
- */
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       ret = func_table[i].func;
-       i++;
-    } while ( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-#ifndef IS_MODULE
-void
-_gcry_rndunix_constructor(void)
-{
-  _gcry_register_internal_cipher_extension (gnupgext_version,
-                                            gnupgext_enum_func);
-}
-#endif
-
-
index b7582be..c50e0bd 100644 (file)
@@ -1,5 +1,5 @@
 /* rndw32.c  - W32 entropy gatherer
- *     Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
+ *     Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
  *     Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-1999
  *
  * This file is part of Libgcrypt.
@@ -57,7 +57,6 @@
 
 #include "types.h"
 #include "g10lib.h"
-#include "dynload.h"
 
 /* We do not use the netropy DLL anymore because a standalone program is
  * easier to maintain and */
@@ -194,9 +193,9 @@ load_and_init_winseed( void )
  * TO boost the performance we may want to add some
  * additional code for level 1
  */
-static int
-gather_random( void (*add)(const void*, size_t, int), int requester,
-                                         size_t length, int level )
+int
+rndw32_gather_random( void (*add)(const void*, size_t, int), int requester,
+                     size_t length, int level )
 {
     unsigned int result;
     unsigned int nbytes;
@@ -255,8 +254,8 @@ gather_random( void (*add)(const void*, size_t, int), int requester,
     }
 }
 
-static int
-gather_random_fast( void (*add)(const void*, size_t, int), int requester )
+int
+rndw32_gather_random_fast( void (*add)(const void*, size_t, int), int requester )
 {
     unsigned int result;
     unsigned int nbytes;
@@ -894,58 +893,4 @@ gather_random_fast( void (*add)(const void*, size_t, int), int requester )
 }
 
 
-
-
-
 #endif /* !USE_ENTROPY_DLL */
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "RNDW32 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    void *func;
-} func_table[] = {
-    { 40, 1, gather_random },
-    { 41, 1, gather_random_fast },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    debug_me = !!getenv("DEBUG_RNDW32");
-
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       ret = func_table[i].func;
-       i++;
-    } while ( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-#ifndef IS_MODULE
-void
-_gcry_rndw32_constructor(void)
-{
-  _gcry_register_internal_cipher_extension( gnupgext_version,
-                                            gnupgext_enum_func );
-}
-#endif
-
index 57aedaf..9aea3dd 100644 (file)
@@ -31,7 +31,6 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-#include "rsa.h"
 
 
 typedef struct {
@@ -618,27 +617,15 @@ _gcry_rsa_get_nbits( int algo, MPI *pkey )
 }
 
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- * Usage: Bit 0 set : allows signing
- *           1 set : allows encryption
- */
-const char *
-_gcry_rsa_get_info( int algo,
-             int *npkey, int *nskey, int *nenc, int *nsig, int *r_usage )
-{
-    *npkey = 2;
-    *nskey = 6;
-    *nenc = 1;
-    *nsig = 1;
-
-    switch( algo ) {
-      case 1: *r_usage = GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR; return "RSA";
-      case 2: *r_usage = GCRY_PK_USAGE_ENCR; return "RSA-E";
-      case 3: *r_usage = GCRY_PK_USAGE_SIGN; return "RSA-S";
-      default:*r_usage = 0; return NULL;
-    }
-}
+GcryPubkeySpec pubkey_spec_rsa =
+  {
+    "RSA", GCRY_PK_RSA, 2, 6, 1, 1,
+    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+    _gcry_rsa_generate,
+    _gcry_rsa_check_secret_key,
+    _gcry_rsa_encrypt,
+    _gcry_rsa_decrypt,
+    _gcry_rsa_sign,
+    _gcry_rsa_verify,
+    _gcry_rsa_get_nbits,
+  };
index a6339b3..cacbd82 100644 (file)
@@ -36,9 +36,8 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-#include "dynload.h"
 #include "bithelp.h"
-
+#include "cipher.h"
 
 typedef struct {
     u32  h0,h1,h2,h3,h4;
@@ -49,15 +48,16 @@ typedef struct {
 
 
 static void
-sha1_init( SHA1_CONTEXT *hd )
+sha1_init (void *context)
 {
-    hd->h0 = 0x67452301;
-    hd->h1 = 0xefcdab89;
-    hd->h2 = 0x98badcfe;
-    hd->h3 = 0x10325476;
-    hd->h4 = 0xc3d2e1f0;
-    hd->nblocks = 0;
-    hd->count = 0;
+  SHA1_CONTEXT *hd = (SHA1_CONTEXT *) context;
+  hd->h0 = 0x67452301;
+  hd->h1 = 0xefcdab89;
+  hd->h2 = 0x98badcfe;
+  hd->h3 = 0x10325476;
+  hd->h4 = 0xc3d2e1f0;
+  hd->nblocks = 0;
+  hd->count = 0;
 }
 
 
@@ -206,8 +206,9 @@ transform( SHA1_CONTEXT *hd, byte *data )
  * of INBUF with length INLEN.
  */
 static void
-sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
+sha1_write( void *context, byte *inbuf, size_t inlen)
 {
+  SHA1_CONTEXT *hd = (SHA1_CONTEXT *) context;
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
         _gcry_burn_stack (88+4*sizeof(void*));
@@ -245,8 +246,9 @@ sha1_write( SHA1_CONTEXT *hd, byte *inbuf, size_t inlen)
  */
 
 static void
-sha1_final(SHA1_CONTEXT *hd)
+sha1_final(void *context)
 {
+  SHA1_CONTEXT *hd = (SHA1_CONTEXT *) context;
     u32 t, msb, lsb;
     byte *p;
 
@@ -307,102 +309,19 @@ sha1_final(SHA1_CONTEXT *hd)
 }
 
 static byte *
-sha1_read( SHA1_CONTEXT *hd )
+sha1_read( void *context )
 {
+  SHA1_CONTEXT *hd = (SHA1_CONTEXT *) context;
     return hd->buf;
 }
 
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-sha1_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
-{
-    static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */
-                   { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
-                     0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
-    if( algo != 2 )
-       return NULL;
-
-    *contextsize = sizeof(SHA1_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 20;
-    *(void  (**)(SHA1_CONTEXT *))r_init                = sha1_init;
-    *(void  (**)(SHA1_CONTEXT *, byte*, size_t))r_write = sha1_write;
-    *(void  (**)(SHA1_CONTEXT *))r_final               = sha1_final;
-    *(byte *(**)(SHA1_CONTEXT *))r_read                = sha1_read;
-
-    return "SHA1";
-}
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "SHA1 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))sha1_get_info },
-    { 11, 1, 2 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-_gcry_sha1_constructor(void)
-{
-    _gcry_register_internal_cipher_extension( gnupgext_version, gnupgext_enum_func );
-}
-#endif
+static byte asn[15] = /* Object ID is 1.3.14.3.2.26 */
+  { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+    0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
 
+GcryDigestSpec digest_spec_sha1 =
+  {
+    "SHA1", GCRY_MD_SHA1, asn, DIM (asn), 20,
+    sha1_init, sha1_write, sha1_final, sha1_read,
+    sizeof (SHA1_CONTEXT)
+  };
index 1aafd33..260ecd7 100644 (file)
@@ -40,9 +40,8 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-#include "dynload.h"
 #include "bithelp.h"
-
+#include "cipher.h"
 
 typedef struct {
   u32  h0,h1,h2,h3,h4,h5,h6,h7;
@@ -53,8 +52,10 @@ typedef struct {
 
 
 static void
-sha256_init (SHA256_CONTEXT *hd)
+sha256_init (void *context)
 {
+  SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
+
   hd->h0 = 0x6a09e667;
   hd->h1 = 0xbb67ae85;
   hd->h2 = 0x3c6ef372;
@@ -173,8 +174,9 @@ transform (SHA256_CONTEXT *hd, byte *data)
 /* Update the message digest with the contents of INBUF with length
   INLEN.  */
 static void
-sha256_write (SHA256_CONTEXT *hd, byte *inbuf, size_t inlen)
+sha256_write (void *context, byte *inbuf, size_t inlen)
 {
+  SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
   if (hd->count == 64)
     { /* flush the buffer */
       transform (hd, hd->buf);
@@ -213,8 +215,9 @@ sha256_write (SHA256_CONTEXT *hd, byte *inbuf, size_t inlen)
    to the handle will the destroy the returned buffer.  Returns: 32
    bytes with the message the digest.  */
 static void
-sha256_final(SHA256_CONTEXT *hd)
+sha256_final(void *context)
 {
+  SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
   u32 t, msb, lsb;
   byte *p;
   
@@ -279,102 +282,20 @@ sha256_final(SHA256_CONTEXT *hd)
 }
 
 static byte *
-sha256_read (SHA256_CONTEXT *hd)
+sha256_read (void *context)
 {
+  SHA256_CONTEXT *hd = (SHA256_CONTEXT *) context;
   return hd->buf;
 }
 
-/*
-   Return some information about the algorithm.  We need algo here to
-   distinguish different flavors of the algorithm.  Returns: A pointer
-   to string describing the algorithm or NULL if the ALGO is invalid.  */
-static const char *
-sha256_get_info (int algo, size_t *contextsize,
-                 byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-                 void (**r_init)( void *c ),
-                 void (**r_write)( void *c, byte *buf, size_t nbytes ),
-                 void (**r_final)( void *c ),
-                 byte *(**r_read)( void *c )
-                 )
-{
-  static byte asn[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
+static byte asn[19] = /* Object ID is  2.16.840.1.101.3.4.2.1 */
   { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
     0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
     0x00, 0x04, 0x20 };
 
-  if(algo != 8)
-    return NULL;
-
-  *contextsize = sizeof(SHA256_CONTEXT);
-  *r_asnoid = asn;
-  *r_asnlen = DIM(asn);
-  *r_mdlen = 32;
-  *(void  (**)(SHA256_CONTEXT *))r_init                  = sha256_init;
-  *(void  (**)(SHA256_CONTEXT *, byte*, size_t))r_write = sha256_write;
-  *(void  (**)(SHA256_CONTEXT *))r_final                 = sha256_final;
-  *(byte *(**)(SHA256_CONTEXT *))r_read                  = sha256_read;
-  
-  return "SHA256";
-}
-
-
-
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "SHA256 ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))sha256_get_info },
-    { 11, 1, 8 },
-};
-
-
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-
-
-
-
-#ifndef IS_MODULE
-void
-_gcry_sha256_constructor(void)
-{
-  _gcry_register_internal_cipher_extension (gnupgext_version,
-                                            gnupgext_enum_func );
-}
-#endif
+GcryDigestSpec digest_spec_sha256 =
+  {
+    "SHA256", GCRY_MD_SHA256, asn, DIM (asn), 32,
+    sha256_init, sha256_write, sha256_final, sha256_read,
+    sizeof (SHA256_CONTEXT)
+  };
index 432948b..af0fdd7 100644 (file)
@@ -25,7 +25,7 @@
 #include <assert.h>
 #include "g10lib.h"
 #include "memory.h"
-
+#include "cipher.h"
 
 #ifdef HAVE_U64_TYPEDEF
 
@@ -591,8 +591,9 @@ static u64 sbox4[256] = {
 
 
 static void
-tiger_init( TIGER_CONTEXT *hd )
+tiger_init( void *context )
 {
+  TIGER_CONTEXT *hd = (TIGER_CONTEXT *) context;
     hd->a = 0x0123456789abcdefLL;
     hd->b = 0xfedcba9876543210LL;
     hd->c = 0xf096a5b4c3b2e187LL;
@@ -718,8 +719,9 @@ transform( TIGER_CONTEXT *hd, byte *data )
  * of INBUF with length INLEN.
  */
 static void
-tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen)
+tiger_write( void *context, byte *inbuf, size_t inlen)
 {
+  TIGER_CONTEXT *hd = (TIGER_CONTEXT *) context;
     if( hd->count == 64 ) { /* flush the buffer */
        transform( hd, hd->buf );
         _gcry_burn_stack (21*8+11*sizeof(void*));
@@ -754,8 +756,9 @@ tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen)
  */
 
 static void
-tiger_final( TIGER_CONTEXT *hd )
+tiger_final( void *context )
 {
+  TIGER_CONTEXT *hd = (TIGER_CONTEXT *) context;
     u32 t, msb, lsb;
     byte *p;
 
@@ -815,124 +818,23 @@ tiger_final( TIGER_CONTEXT *hd )
 }
 
 static byte *
-tiger_read( TIGER_CONTEXT *hd )
-{
-    return hd->buf;
-}
-
-/****************
- * Return some information about the algorithm.  We need algo here to
- * distinguish different flavors of the algorithm.
- * Returns: A pointer to string describing the algorithm or NULL if
- *         the ALGO is invalid.
- */
-static const char *
-tiger_get_info( int algo, size_t *contextsize,
-              byte **r_asnoid, int *r_asnlen, int *r_mdlen,
-              void (**r_init)( void *c ),
-              void (**r_write)( void *c, byte *buf, size_t nbytes ),
-              void (**r_final)( void *c ),
-              byte *(**r_read)( void *c )
-            )
+tiger_read( void *context )
 {
-    static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
-                         { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
-                           0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
-                           0x05, 0x00, 0x04, 0x18 };
-
-    if( algo != 6 )
-       return NULL;
-
-    *contextsize = sizeof(TIGER_CONTEXT);
-    *r_asnoid = asn;
-    *r_asnlen = DIM(asn);
-    *r_mdlen = 24;
-    *(void  (**)(TIGER_CONTEXT *))r_init                = tiger_init;
-    *(void  (**)(TIGER_CONTEXT *, byte*, size_t))r_write = tiger_write;
-    *(void  (**)(TIGER_CONTEXT *))r_final               = tiger_final;
-    *(byte *(**)(TIGER_CONTEXT *))r_read                = tiger_read;
-
-    return "TIGER192";
+  TIGER_CONTEXT *hd = (TIGER_CONTEXT *) context;
+  return hd->buf;
 }
 
+static byte asn[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
+  { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
+    0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
+    0x05, 0x00, 0x04, 0x18 };
 
 
-#ifndef IS_MODULE
-static
-#endif
-const char * const gnupgext_version = "TIGER ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 10, 1, 0, (void(*)(void))tiger_get_info },
-    { 11, 1, 6 },
-};
-
-
-
-/****************
- * Enumerate the names of the functions together with informations about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- *                        10 = message digest algorithm info function
- *                        11 = integer with available md algorithms
- *                        20 = cipher algorithm info function
- *                        21 = integer with available cipher algorithms
- *                        30 = public key algorithm info function
- *                        31 = integer with available pubkey algorithms
- *               version = interface version of the function/pointer
- *                         (currently this is 1 for all functions)
- */
-#ifndef IS_MODULE
-static
-#endif
-void *
-gnupgext_enum_func( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if( i >= DIM(func_table) || i < 0 ) {
-           /*fprintf(stderr, "failed\n");*/
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while( what && what != *class );
-
-    *sequence = i;
-    /*fprintf(stderr, "success\n");*/
-    return ret;
-}
-
-
-
-#ifndef IS_MODULE
-void
-_gcry_tiger_constructor(void)
-{
-  _gcry_register_internal_cipher_extension( gnupgext_version,
-                                            gnupgext_enum_func );
-}
-#endif
-
+GcryDigestSpec digest_spec_tiger =
+  {
+    "TIGER192", GCRY_MD_TIGER, asn, DIM (asn), 24,
+    tiger_init, tiger_write, tiger_final, tiger_read,
+    sizeof (TIGER_CONTEXT)
+  };
 
 #endif /* HAVE_U64_TYPEDEF */
index 8fb5f4b..9795abe 100644 (file)
@@ -43,8 +43,7 @@
 
 #include "types.h"  /* for byte and u32 typedefs */
 #include "g10lib.h"
-#include "dynload.h"
-
+#include "cipher.h"
 
 /* Prototype for the self-test function. */
 static const char *selftest(void);
@@ -700,11 +699,12 @@ do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
 }
 
 static int
-twofish_setkey (TWOFISH_context *ctx, const byte *key, unsigned int keylen)
+twofish_setkey (void *context, const byte *key, unsigned int keylen)
 {
-    int rc = do_twofish_setkey (ctx, key, keylen);
-    _gcry_burn_stack (23+6*sizeof(void*));
-    return rc;
+  TWOFISH_context *ctx = (TWOFISH_context *) context;
+  int rc = do_twofish_setkey (ctx, key, keylen);
+  _gcry_burn_stack (23+6*sizeof(void*));
+  return rc;
 }
 
 
@@ -802,10 +802,11 @@ do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 }
 
 static void
-twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+twofish_encrypt (void *context, byte *out, const byte *in)
 {
-    do_twofish_encrypt (ctx, out, in);
-    _gcry_burn_stack (24+3*sizeof (void*));
+  TWOFISH_context *ctx = (TWOFISH_context *) context;
+  do_twofish_encrypt (ctx, out, in);
+  _gcry_burn_stack (24+3*sizeof (void*));
 }
 
 \f
@@ -844,10 +845,11 @@ do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 }
 
 static void
-twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+twofish_decrypt (void *context, byte *out, const byte *in)
 {
-    do_twofish_decrypt (ctx, out, in);
-    _gcry_burn_stack (24+3*sizeof (void*));
+  TWOFISH_context *ctx = (TWOFISH_context *) context;
+  do_twofish_decrypt (ctx, out, in);
+  _gcry_burn_stack (24+3*sizeof (void*));
 }
 
 \f
@@ -864,11 +866,11 @@ selftest (void)
     * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
     * "intermediate value test", because an all-0 key would trigger all the
     * special cases in the RS matrix multiply, leaving the math untested. */
-   static const byte plaintext[16] = {
+   static  byte plaintext[16] = {
       0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
       0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
    };
-   static const byte key[16] = {
+   static byte key[16] = {
       0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
       0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A
    };
@@ -876,11 +878,11 @@ selftest (void)
       0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
       0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
    };
-   static const byte plaintext_256[16] = {
+   static byte plaintext_256[16] = {
       0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
       0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
    };
-   static const byte key_256[32] = {
+   static byte key_256[32] = {
       0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
       0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
       0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
@@ -1014,94 +1016,17 @@ main()
 }
 
 #endif /* TEST */
-\f
-#ifdef IS_MODULE
-static
-#endif
-       const char *
-_gcry_twofish_get_info (int algo, size_t *keylen,
-                 size_t *blocksize, size_t *contextsize,
-                 int  (**r_setkey) (void *c, byte *key, unsigned keylen),
-                 void (**r_encrypt) (void *c, byte *outbuf, byte *inbuf),
-                 void (**r_decrypt) (void *c, byte *outbuf, byte *inbuf)
-                )
-{
-    *keylen = algo==10? 256 : 128;
-    *blocksize = 16;
-    *contextsize = sizeof (TWOFISH_context);
-
-    *(int  (**)(TWOFISH_context*, const byte*, const unsigned))r_setkey
-                                                       = twofish_setkey;
-    *(void (**)(const TWOFISH_context*, byte*, const byte*))r_encrypt
-                                                       = twofish_encrypt;
-    *(void (**)(const TWOFISH_context*, byte*, const byte*))r_decrypt
-                                                       = twofish_decrypt;
-
-    if( algo == 10 )
-       return "TWOFISH";
-    if (algo == 102) /* This algorithm number is assigned for
-                     * experiments, so we can use it */
-       return "TWOFISH128";
-    return NULL;
-}
-
-#ifdef IS_MODULE
-const char * const gnupgext_version = "TWOFISH ($Revision$)";
-
-static struct {
-    int class;
-    int version;
-    int  value;
-    void (*func)(void);
-} func_table[] = {
-    { 20, 1, 0, (void(*)(void))_gcry_twofish_get_info },
-    { 21, 1, 10  },
-    { 21, 1, 102 },
-};
-
 
+\f
 
-/****************
- * Enumerate the names of the functions together with information about
- * this function. Set sequence to an integer with a initial value of 0 and
- * do not change it.
- * If what is 0 all kind of functions are returned.
- * Return values: class := class of function:
- *                        10 = message digest algorithm info function
- *                        11 = integer with available md algorithms
- *                        20 = cipher algorithm info function
- *                        21 = integer with available cipher algorithms
- *                        30 = public key algorithm info function
- *                        31 = integer with available pubkey algorithms
- *               version = interface version of the function/pointer
- *                         (currently this is 1 for all functions)
- */
-void *
-gnupgext_enum_func ( int what, int *sequence, int *class, int *vers )
-{
-    void *ret;
-    int i = *sequence;
-
-    do {
-       if ( i >= DIM(func_table) || i < 0 ) {
-           return NULL;
-       }
-       *class = func_table[i].class;
-       *vers  = func_table[i].version;
-       switch( *class ) {
-         case 11:
-         case 21:
-         case 31:
-           ret = &func_table[i].value;
-           break;
-         default:
-           ret = func_table[i].func;
-           break;
-       }
-       i++;
-    } while ( what && what != *class );
-
-    *sequence = i;
-    return ret;
-}
-#endif /*IS_MODULE*/
+GcryCipherSpec cipher_spec_twofish =
+  {
+    "TWOFISH", GCRY_CIPHER_TWOFISH, 16, 256, sizeof (TWOFISH_context),
+    twofish_setkey, twofish_encrypt, twofish_decrypt,
+  };
+
+GcryCipherSpec cipher_spec_twofish128 =
+  {
+    "TWOFISH128", GCRY_CIPHER_TWOFISH, 16, 128, sizeof (TWOFISH_context),
+    twofish_setkey, twofish_encrypt, twofish_decrypt,
+  };