2003-07-07 Moritz Schulte <moritz@g10code.com>
authorMoritz Schulte <mo@g10code.com>
Mon, 7 Jul 2003 16:16:02 +0000 (16:16 +0000)
committerMoritz Schulte <mo@g10code.com>
Mon, 7 Jul 2003 16:16:02 +0000 (16:16 +0000)
* gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list.

2003-07-05  Moritz Schulte  <moritz@g10code.com>

* gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister,
gcry_md_register, gcry_md_unregister, gcry_pk_register,
gcry_pk_unregister.
(gcry_cipher_spec): Removed member: algorithm.
(gcry_pk_spec): Likewise.
(gcry_md_spec): Likewise.
Adjusted declarations: gcry_cipher_register, gcry_pk_register,
gcry_md_register.

* module.c: Replaced all occurences of `id' with `mod_id', since
`id' is a keyword in obj-c.

* gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'.
(gcry_pk_spec): Likewise.
(gcry_md_spec): Likewise.

* cipher.h: Removed types: gcry_pubkey_generate_t,
gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t,
gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t,
gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t,
gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t,
gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
gcry_cipher_stdecrypt_t, gcry_cipher_spec_t.

* gcrypt.h: New types: gcry_pk_generate_t,
gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t,
gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t,
gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t,
gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t,
gcry_cipher_encrypt_t, gcry_cipher_decrypt_t,
gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t,
gcry_cipher_spec_t, gcry_module_t.

2003-07-04  Moritz Schulte  <moritz@g10code.com>

* module.c (_gcry_module_list): New function.

src/ChangeLog
src/cipher.h
src/g10lib.h
src/gcrypt.h
src/module.c

index 26a2608..cbb8094 100644 (file)
@@ -1,3 +1,47 @@
+2003-07-07  Moritz Schulte  <moritz@g10code.com>
+
+       * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list.
+       
+2003-07-05  Moritz Schulte  <moritz@g10code.com>
+
+       * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister,
+       gcry_md_register, gcry_md_unregister, gcry_pk_register,
+       gcry_pk_unregister.
+       (gcry_cipher_spec): Removed member: algorithm.
+       (gcry_pk_spec): Likewise.
+       (gcry_md_spec): Likewise.
+       Adjusted declarations: gcry_cipher_register, gcry_pk_register,
+       gcry_md_register.
+
+       * module.c: Replaced all occurences of `id' with `mod_id', since
+       `id' is a keyword in obj-c.
+
+       * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'.
+       (gcry_pk_spec): Likewise.
+       (gcry_md_spec): Likewise.
+
+       * cipher.h: Removed types: gcry_pubkey_generate_t,
+       gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t,
+       gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t,
+       gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t,
+       gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t,
+       gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+       gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+       gcry_cipher_stdecrypt_t, gcry_cipher_spec_t.
+
+       * gcrypt.h: New types: gcry_pk_generate_t,
+       gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t,
+       gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t,
+       gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t,
+       gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t,
+       gcry_cipher_encrypt_t, gcry_cipher_decrypt_t,
+       gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t,
+       gcry_cipher_spec_t, gcry_module_t.
+
+2003-07-04  Moritz Schulte  <moritz@g10code.com>
+
+       * module.c (_gcry_module_list): New function.
+
 2003-07-02  Moritz Schulte  <moritz@g10code.com>
 
        * module.c (_gcry_module_lookup): Fixed typo.
index 4fa21bb..392b646 100644 (file)
@@ -41,105 +41,6 @@ void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb, void *cb_data);
 /*-- primegen.c --*/
 void _gcry_register_primegen_progress (gcry_handler_progress_t cb, void *cb_data);
 
-typedef gpg_err_code_t (*gcry_pk_generate_t) (int algo,
-                                             unsigned int nbits,
-                                             unsigned long use_e,
-                                             gcry_mpi_t *skey,
-                                             gcry_mpi_t **retfactors);
-typedef gpg_err_code_t (*gcry_pk_check_secret_key_t) (int algo, gcry_mpi_t *skey);
-typedef gpg_err_code_t (*gcry_pk_encrypt_t) (int algo,
-                                            gcry_mpi_t *resarr,
-                                            gcry_mpi_t data,
-                                            gcry_mpi_t *pkey,
-                                            int flags);
-typedef gpg_err_code_t (*gcry_pk_decrypt_t) (int algo,
-                                            gcry_mpi_t *result,
-                                            gcry_mpi_t *data,
-                                            gcry_mpi_t *skey,
-                                            int flags);
-typedef gpg_err_code_t (*gcry_pk_sign_t) (int algo,
-                                         gcry_mpi_t *resarr,
-                                         gcry_mpi_t data,
-                                         gcry_mpi_t *skey);
-typedef gpg_err_code_t (*gcry_pk_verify_t) (int algo,
-                                           gcry_mpi_t hash,
-                                           gcry_mpi_t *data,
-                                           gcry_mpi_t *pkey,
-                                           int (*cmp)(void *, gcry_mpi_t),
-                                           void *opaquev);
-typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
-
-typedef struct gcry_pubkey_spec
-{
-  const char *name;
-  char **sexp_names;
-  int id;
-  const char *elements_pkey;
-  const char *elements_skey;
-  const char *elements_enc;
-  const char *elements_sig;
-  const char *elements_grip;
-  int use;
-  gcry_pk_generate_t generate;
-  gcry_pk_check_secret_key_t check_secret_key;
-  gcry_pk_encrypt_t encrypt;
-  gcry_pk_decrypt_t decrypt;
-  gcry_pk_sign_t sign;
-  gcry_pk_verify_t verify;
-  gcry_pk_get_nbits_t get_nbits;
-} gcry_pubkey_spec_t;
-
-typedef void (*gcry_md_init_t) (void *c);
-typedef void (*gcry_md_write_t) (void *c, unsigned char *buf, size_t nbytes);
-typedef void (*gcry_md_final_t) (void *c);
-typedef unsigned char *(*gcry_md_read_t) (void *c);
-
-typedef struct gcry_digest_spec
-{
-  const char *name;
-  int id;
-  unsigned char *asnoid;
-  int asnlen;
-  int mdlen;
-  gcry_md_init_t init;
-  gcry_md_write_t write;
-  gcry_md_final_t final;
-  gcry_md_read_t read;
-  size_t contextsize; /* allocate this amount of context */
-} gcry_digest_spec_t;
-
-typedef gpg_err_code_t (*gcry_cipher_setkey_t) (void *c,
-                                               const unsigned char *key,
-                                               unsigned keylen);
-typedef void (*gcry_cipher_encrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-typedef void (*gcry_cipher_decrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-typedef void (*gcry_cipher_stencrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-typedef void (*gcry_cipher_stdecrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-
-typedef struct gcry_cipher_spec
-{
-  const char *name;
-  int id;
-  size_t blocksize;
-  size_t keylen;
-  size_t contextsize;
-  gcry_cipher_setkey_t setkey;
-  gcry_cipher_encrypt_t encrypt;
-  gcry_cipher_decrypt_t decrypt;
-  gcry_cipher_stencrypt_t stencrypt;
-  gcry_cipher_stdecrypt_t stdecrypt;
-} gcry_cipher_spec_t;
-
 /* Declarations for the cipher specifications.  */
 extern gcry_cipher_spec_t cipher_spec_blowfish;
 extern gcry_cipher_spec_t cipher_spec_des;
@@ -156,21 +57,21 @@ extern gcry_cipher_spec_t cipher_spec_serpent192;
 extern gcry_cipher_spec_t cipher_spec_serpent256;
 
 /* Declarations for the digest specifications.  */
-extern gcry_digest_spec_t digest_spec_crc32;
-extern gcry_digest_spec_t digest_spec_crc32_rfc1510;
-extern gcry_digest_spec_t digest_spec_crc24_rfc2440;
-extern gcry_digest_spec_t digest_spec_md4;
-extern gcry_digest_spec_t digest_spec_md5;
-extern gcry_digest_spec_t digest_spec_rmd160;
-extern gcry_digest_spec_t digest_spec_sha1;
-extern gcry_digest_spec_t digest_spec_sha256;
-extern gcry_digest_spec_t digest_spec_sha512;
-extern gcry_digest_spec_t digest_spec_sha384;
-extern gcry_digest_spec_t digest_spec_tiger;
+extern gcry_md_spec_t digest_spec_crc32;
+extern gcry_md_spec_t digest_spec_crc32_rfc1510;
+extern gcry_md_spec_t digest_spec_crc24_rfc2440;
+extern gcry_md_spec_t digest_spec_md4;
+extern gcry_md_spec_t digest_spec_md5;
+extern gcry_md_spec_t digest_spec_rmd160;
+extern gcry_md_spec_t digest_spec_sha1;
+extern gcry_md_spec_t digest_spec_sha256;
+extern gcry_md_spec_t digest_spec_sha512;
+extern gcry_md_spec_t digest_spec_sha384;
+extern gcry_md_spec_t digest_spec_tiger;
 
 /* Declarations for the pubkey cipher specifications.  */
-extern gcry_pubkey_spec_t pubkey_spec_rsa;
-extern gcry_pubkey_spec_t pubkey_spec_elg;
-extern gcry_pubkey_spec_t pubkey_spec_dsa;
+extern gcry_pk_spec_t pubkey_spec_rsa;
+extern gcry_pk_spec_t pubkey_spec_elg;
+extern gcry_pk_spec_t pubkey_spec_dsa;
 
 #endif /*G10_CIPHER_H*/
index 8811864..307fee6 100644 (file)
@@ -199,43 +199,44 @@ struct gcry_module
   void *spec;                  /* The acctual specs.  */
   int flags;                   /* Associated flags.   */
   int counter;                 /* Use counter.        */
-  unsigned int id;             /* ID of this module.  */
+  unsigned int mod_id;         /* ID of this module.  */
 };
 
-typedef struct gcry_module gcry_module_t;
-
 /* Flags for the `flags' member of gcry_module_t.  */
 #define FLAG_MODULE_DISABLED 1 << 0
 
-gpg_err_code_t _gcry_module_add (gcry_module_t **entries,
+gpg_err_code_t _gcry_module_add (gcry_module_t *entries,
                                 unsigned int id,
                                 void *spec,
-                                gcry_module_t **module);
+                                gcry_module_t *module);
 
 typedef int (*gcry_module_lookup_t) (void *spec, void *data);
 
-/* Public function.  Lookup a module specification by it's ID.  After a
-   successfull lookup, the module has it's resource counter
-   incremented.  */
-gcry_module_t *_gcry_module_lookup_id (gcry_module_t *entries,
+/* Lookup a module specification by it's ID.  After a successfull
+   lookup, the module has it's resource counter incremented.  */
+gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
                                       unsigned int id);
 
 /* Internal function.  Lookup a module specification.  */
-gcry_module_t *_gcry_module_lookup (gcry_module_t *entries, void *data,
+gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
                                    gcry_module_lookup_t func);
 
-/* Public function.  Release a module.  In case the use-counter
-   reaches zero, destroy the module.  */
-void _gcry_module_release (gcry_module_t *entry);
+/* Release a module.  In case the use-counter reaches zero, destroy
+   the module.  */
+void _gcry_module_release (gcry_module_t entry);
+
+/* Add a reference to a module.  */
+void _gcry_module_use (gcry_module_t module);
 
-/* Public function.  Add a reference to a module.  */
-void _gcry_module_use (gcry_module_t *module);
+/* Return a list of module IDs.  */
+gpg_err_code_t _gcry_module_list (gcry_module_t modules,
+                                 int *list, int *list_length);
 
 gpg_err_code_t _gcry_cipher_init (void);
 gpg_err_code_t _gcry_md_init (void);
 gpg_err_code_t _gcry_pk_init (void);
 
-gpg_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t **module);
-void _gcry_pk_module_release (gcry_module_t *module);
+gpg_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
+void _gcry_pk_module_release (gcry_module_t module);
 
 #endif /* G10LIB_H */
index 8fff209..ce16eb3 100644 (file)
@@ -94,6 +94,9 @@ typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
 
 \f
 
+/* This type represents a `module'.  */
+typedef struct gcry_module *gcry_module_t;
+
 /* Check that the library fulfills the version requirement.  */
 const char *gcry_check_version (const char *req_version);
 
@@ -650,6 +653,65 @@ size_t gcry_cipher_get_algo_blklen (int algo);
 #define gcry_cipher_test_algo(a) \
            gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
+/* Get a list consisting of the IDs of the loaded cipher modules.  If
+   LIST is zero, write the number of loaded cipher modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less cipher modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gpg_error_t gcry_cipher_list (int *list, int *list_length);
+
+/* Type for the cipher_setkey function.  */
+typedef gpg_err_code_t (*gcry_cipher_setkey_t) (void *c,
+                                               const unsigned char *key,
+                                               unsigned keylen);
+
+/* Type for the cipher_encrypt function.  */
+typedef void (*gcry_cipher_encrypt_t) (void *c,
+                                      unsigned char *outbuf,
+                                      const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function.  */
+typedef void (*gcry_cipher_decrypt_t) (void *c,
+                                      unsigned char *outbuf,
+                                      const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function.  */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        unsigned int n);
+
+/* Type for the cipher_stdecrypt function.  */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        unsigned int n);
+
+/* Module specification structure for ciphers.  */
+typedef struct gcry_cipher_spec
+{
+  const char *name;
+  size_t blocksize;
+  size_t keylen;
+  size_t contextsize;
+  gcry_cipher_setkey_t setkey;
+  gcry_cipher_encrypt_t encrypt;
+  gcry_cipher_decrypt_t decrypt;
+  gcry_cipher_stencrypt_t stencrypt;
+  gcry_cipher_stdecrypt_t stdecrypt;
+} gcry_cipher_spec_t;
+
+/* Register a new cipher module whose specification can be found in
+   CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gpg_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher,
+                                 unsigned int *algorithm_id,
+                                 gcry_module_t *module);
+
+/* Unregister the cipher identified by MODULE, which must have been
+   registered with gcry_cipher_register.  */
+void gcry_cipher_unregister (gcry_module_t module);
 
 \f
 /************************************
@@ -723,6 +785,86 @@ unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
 #define gcry_pk_test_algo(a) \
            gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
+/* Get a list consisting of the IDs of the loaded pubkey modules.  If
+   LIST is zero, write the number of loaded pubkey modules to
+   LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less pubkey modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gpg_error_t gcry_pk_list (int *list, int *list_length);
+
+/* Type for the pk_generate function.  */
+typedef gpg_err_code_t (*gcry_pk_generate_t) (int algo,
+                                             unsigned int nbits,
+                                             unsigned long use_e,
+                                             gcry_mpi_t *skey,
+                                             gcry_mpi_t **retfactors);
+
+/* Type for the pk_check_secret_key function.  */
+typedef gpg_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+                                                     gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function.  */
+typedef gpg_err_code_t (*gcry_pk_encrypt_t) (int algo,
+                                            gcry_mpi_t *resarr,
+                                            gcry_mpi_t data,
+                                            gcry_mpi_t *pkey,
+                                            int flags);
+
+/* Type for the pk_decrypt function.  */
+typedef gpg_err_code_t (*gcry_pk_decrypt_t) (int algo,
+                                            gcry_mpi_t *result,
+                                            gcry_mpi_t *data,
+                                            gcry_mpi_t *skey,
+                                            int flags);
+
+/* Type for the pk_sign function.  */
+typedef gpg_err_code_t (*gcry_pk_sign_t) (int algo,
+                                         gcry_mpi_t *resarr,
+                                         gcry_mpi_t data,
+                                         gcry_mpi_t *skey);
+
+/* Type for the pk_verify function.  */
+typedef gpg_err_code_t (*gcry_pk_verify_t) (int algo,
+                                           gcry_mpi_t hash,
+                                           gcry_mpi_t *data,
+                                           gcry_mpi_t *pkey,
+                                           int (*cmp) (void *, gcry_mpi_t),
+                                           void *opaquev);
+
+/* Type for the pk_get_nbits function.  */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_pk_spec
+{
+  const char *name;
+  char **sexp_names;
+  const char *elements_pkey;
+  const char *elements_skey;
+  const char *elements_enc;
+  const char *elements_sig;
+  const char *elements_grip;
+  int use;
+  gcry_pk_generate_t generate;
+  gcry_pk_check_secret_key_t check_secret_key;
+  gcry_pk_encrypt_t encrypt;
+  gcry_pk_decrypt_t decrypt;
+  gcry_pk_sign_t sign;
+  gcry_pk_verify_t verify;
+  gcry_pk_get_nbits_t get_nbits;
+} gcry_pk_spec_t;
+
+/* Register a new pubkey module whose specification can be found in
+   PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gpg_error_t gcry_pk_register (gcry_pk_spec_t *pubkey,
+                             unsigned int *algorithm_id,
+                             gcry_module_t *module);
+
+/* Unregister the pubkey identified by ID, which must have been
+   registered with gcry_pk_register.  */
+void gcry_pk_unregister (gcry_module_t module);
 
 /* Alternative interface for asymetric cryptography.  */
 
@@ -1044,6 +1186,52 @@ gpg_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
 #define gcry_md_stop_debug(a,b) \
            gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
 
+/* Get a list consisting of the IDs of the loaded message digest
+   modules.  If LIST is zero, write the number of loaded message
+   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
+   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+   of according size.  In case there are less message digest modules
+   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+   number.  */
+gpg_error_t gcry_md_list (int *list, int *list_length);
+
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, unsigned char *buf, size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
+{
+  const char *name;
+  unsigned char *asnoid;
+  int asnlen;
+  int mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  size_t contextsize; /* allocate this amount of context */
+} gcry_md_spec_t;
+
+/* Register a new digest module whose specification can be found in
+   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
+   and a pointer representhing this module is stored in MODULE.  */
+gpg_error_t gcry_md_register (gcry_md_spec_t *digest,
+                             unsigned int *algorithm_id,
+                             gcry_module_t *module);
+
+/* Unregister the digest identified by ID, which must have been
+   registered with gcry_digest_register.  */
+void gcry_md_unregister (gcry_module_t module);
+
 
 \f
 /************************************
index 14b4ab9..fe97af5 100644 (file)
    that should be inserted into the module chain starting at
    MODULES.  */
 static gpg_err_code_t
-_gcry_module_id_new (gcry_module_t *modules, unsigned int *id_new)
+_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
 {
   /* FIXME, what should be the ID of the first module registered by
      the user?  */
-  unsigned int id_min = 600, id_max = (unsigned int) -1, id;
+  unsigned int id_min = 600, id_max = (unsigned int) -1, mod_id;
   gpg_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t *module;
+  gcry_module_t module;
 
   /* Search for unused ID.  */
-  for (id = id_min; id < id_max; id++)
+  for (mod_id = id_min; mod_id < id_max; mod_id++)
     {
       /* Search for a module with the current ID.  */
       for (module = modules; module; module = module->next)
-       if (id == module->id)
+       if (mod_id == module->mod_id)
          break;
 
       if (! module)
@@ -48,9 +48,9 @@ _gcry_module_id_new (gcry_module_t *modules, unsigned int *id_new)
        break;
     }
 
-  if (id < id_max)
+  if (mod_id < id_max)
     /* Done.  */
-    *id_new = id;
+    *id_new = mod_id;
   else
     /* No free ID found.  */
     err = GPG_ERR_INTERNAL;
@@ -58,21 +58,21 @@ _gcry_module_id_new (gcry_module_t *modules, unsigned int *id_new)
   return err;
 }
 
-/* Public function.  Add a module specification to the list ENTRIES.
-   The new module has it's use-counter set to one.  */
+/* Add a module specification to the list ENTRIES.  The new module has
+   it's use-counter set to one.  */
 gpg_err_code_t
-_gcry_module_add (gcry_module_t **entries, unsigned int id,
-                 void *spec, gcry_module_t **module)
+_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
+                 void *spec, gcry_module_t *module)
 {
   gpg_err_code_t err = 0;
-  gcry_module_t *entry;
+  gcry_module_t entry;
 
-  if (! id)
-    err = _gcry_module_id_new (*entries, &id);
+  if (! mod_id)
+    err = _gcry_module_id_new (*entries, &mod_id);
 
   if (! err)
     {
-      entry = gcry_malloc (sizeof (gcry_module_t));
+      entry = gcry_malloc (sizeof (struct gcry_module));
       if (! entry)
        err = gpg_err_code_from_errno (errno);
     }
@@ -83,7 +83,7 @@ _gcry_module_add (gcry_module_t **entries, unsigned int id,
       entry->flags = 0;
       entry->counter = 1;
       entry->spec = spec;
-      entry->id = id;
+      entry->mod_id = mod_id;
 
       /* Link it into the list.  */
       entry->next = *entries;
@@ -102,7 +102,7 @@ _gcry_module_add (gcry_module_t **entries, unsigned int id,
 /* Internal function.  Unlink CIPHER_ENTRY from the list of registered
    ciphers and destroy it.  */
 static void
-_gcry_module_drop (gcry_module_t *entry)
+_gcry_module_drop (gcry_module_t entry)
 {
   *entry->prevp = entry->next;
   if (entry->next)
@@ -111,16 +111,15 @@ _gcry_module_drop (gcry_module_t *entry)
   gcry_free (entry);
 }
 
-/* Public function.  Lookup a module specification by it's ID.  After a
-   successfull lookup, the module has it's resource counter
-   incremented.  */
-gcry_module_t *
-_gcry_module_lookup_id (gcry_module_t *entries, unsigned int id)
+/* Lookup a module specification by it's ID.  After a successfull
+   lookup, the module has it's resource counter incremented.  */
+gcry_module_t 
+_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
 {
-  gcry_module_t *entry;
+  gcry_module_t entry;
 
   for (entry = entries; entry; entry = entry->next)
-    if (entry->id == id)
+    if (entry->mod_id == mod_id)
       {
        entry->counter++;
        break;
@@ -129,15 +128,15 @@ _gcry_module_lookup_id (gcry_module_t *entries, unsigned int id)
   return entry;
 }
 
-/* Public function.  Lookup a module specification.  After a
-   successfull lookup, the module has it's resource counter
-   incremented.  FUNC is a function provided by the caller, which is
-   responsible for identifying the wanted module.  */
-gcry_module_t *
-_gcry_module_lookup (gcry_module_t *entries, void *data,
+/* Lookup a module specification.  After a successfull lookup, the
+   module has it's resource counter incremented.  FUNC is a function
+   provided by the caller, which is responsible for identifying the
+   wanted module.  */
+gcry_module_t 
+_gcry_module_lookup (gcry_module_t entries, void *data,
                     gcry_module_lookup_t func)
 {
-  gcry_module_t *entry;
+  gcry_module_t entry;
 
   for (entry = entries; entry; entry = entry->next)
     if ((*func) (entry->spec, data))
@@ -149,18 +148,50 @@ _gcry_module_lookup (gcry_module_t *entries, void *data,
   return entry;
 }
 
-/* Public function.  Release a module.  In case the use-counter
-   reaches zero, destroy the module.  */
+/* Release a module.  In case the use-counter reaches zero, destroy
+   the module.  */
 void
-_gcry_module_release (gcry_module_t *module)
+_gcry_module_release (gcry_module_t module)
 {
   if (! --module->counter)
     _gcry_module_drop (module);
 }
 
-/* Public function.  Add a reference to a module.  */
+/* Add a reference to a module.  */
 void
-_gcry_module_use (gcry_module_t *module)
+_gcry_module_use (gcry_module_t module)
 {
   ++module->counter;
 }
+
+/* If LIST is zero, write the number of modules identified by MODULES
+   to LIST_LENGTH and return.  If LIST is non-zero, the first
+   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+   according size.  In case there are less cipher modules than
+   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
+gpg_err_code_t
+_gcry_module_list (gcry_module_t modules,
+                  int *list, int *list_length)
+{
+  gpg_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_module_t module;
+  int length, i;
+
+  for (module = modules, length = 0; module; module = module->next, length++);
+
+  if (list)
+    {
+      if (length > *list_length)
+       length = *list_length;
+
+      for (module = modules, i = 0; i < length; module = module->next, i++)
+       list[i] = module->mod_id;
+
+      if (length < *list_length)
+       *list_length = length;
+    }
+  else
+    *list_length = length;
+
+  return err;
+}