[git] GCRYPT - branch, master, updated. libgcrypt-1.5.0-247-g85722af

by Werner Koch cvs at cvs.gnupg.org
Wed Sep 18 21:35:07 CEST 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".

The branch, master has been updated
       via  85722afb379f7a392a8117b895de273fd88c4ebc (commit)
       via  89103ce00e862cc709e80fa41f2ee13d54093ec5 (commit)
      from  2ad7ea9cb388fd31e4b0852b68d77f599ef4adce (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 85722afb379f7a392a8117b895de273fd88c4ebc
Author: Werner Koch <wk at gnupg.org>
Date:   Sat Sep 7 10:06:46 2013 +0200

    pk: Simplify the public key dispatcher pubkey.c.
    
    * src/cipher-proto.h (gcry_pk_spec_t): Add fields ALGO and FLAGS.
    * cipher/dsa.c (_gcry_pubkey_spec_dsa): Set these fields.
    * cipher/ecc.c (_gcry_pubkey_spec_ecdsa): Ditto.
    (_gcry_pubkey_spec_ecdh): Ditto.
    * cipher/rsa.c (_gcry_pubkey_spec_rsa): Ditto.
    * cipher/elgamal.c (_gcry_pubkey_spec_elg): Ditto
    (_gcry_pubkey_spec_elg_e): New.
    * cipher/pubkey.c: Change most code to replace the former module
    system by a simpler system to gain information about the algorithms.
    (disable_pubkey_algo): SImplified.  Not anymore thread-safe, though.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/NEWS b/NEWS
index 1c8793b..678805d 100644
--- a/NEWS
+++ b/NEWS
@@ -102,6 +102,7 @@ Noteworthy changes in version 1.6.0 (unreleased)
  GCRY_MD_GOSTR3411_94            NEW.
  GCRY_MD_STRIBOG256              NEW.
  GCRY_MD_STRIBOG512              NEW.
+ GCRYCTL_DISABLE_ALGO            CHANGED: Not anymore thread-safe.
 
 
 Noteworthy changes in version 1.5.0 (2011-06-29)
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 4a7ceee..ca9a4f6 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -1205,9 +1205,10 @@ static const char *dsa_names[] =
 
 gcry_pk_spec_t _gcry_pubkey_spec_dsa =
   {
+    GCRY_PK_DSA, { 0, 1 },
+    GCRY_PK_USAGE_SIGN,
     "DSA", dsa_names,
     "pqgy", "pqgyx", "", "rs", "pqgy",
-    GCRY_PK_USAGE_SIGN,
     dsa_generate,
     dsa_check_secret_key,
     NULL,
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 5340d57..66cd342 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -2003,9 +2003,10 @@ static const char *ecdh_names[] =
 
 gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
   {
+    GCRY_PK_ECDSA, { 0, 0 },
+    GCRY_PK_USAGE_SIGN,
     "ECDSA", ecdsa_names,
     "pabgnq", "pabgnqd", "", "rs", "pabgnq",
-    GCRY_PK_USAGE_SIGN,
     ecc_generate,
     ecc_check_secret_key,
     NULL,
@@ -2023,9 +2024,10 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
 
 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
   {
+    GCRY_PK_ECDH, { 0, 0 },
+    GCRY_PK_USAGE_ENCR,
     "ECDH", ecdh_names,
     "pabgnq", "pabgnqd", "se", "", "pabgnq",
-    GCRY_PK_USAGE_ENCR,
     ecc_generate,
     ecc_check_secret_key,
     ecc_encrypt_raw,
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index 44990aa..65448e0 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -840,9 +840,27 @@ static const char *elg_names[] =
 
 gcry_pk_spec_t _gcry_pubkey_spec_elg =
   {
+    GCRY_PK_ELG, { 0, 0 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
+    "ELG", elg_names,
+    "pgy", "pgyx", "ab", "rs", "pgy",
+    elg_generate,
+    elg_check_secret_key,
+    elg_encrypt,
+    elg_decrypt,
+    elg_sign,
+    elg_verify,
+    elg_get_nbits,
+    NULL,
+    elg_generate_ext
+  };
+
+gcry_pk_spec_t _gcry_pubkey_spec_elg_e =
+  {
+    GCRY_PK_ELG_E, { 0, 0 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
     "ELG", elg_names,
     "pgy", "pgyx", "ab", "rs", "pgy",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
     elg_generate,
     elg_check_secret_key,
     elg_encrypt,
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 5be6b85..c755729 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -44,253 +44,80 @@ static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
                                       struct pk_encoding_ctx *ctx);
 
 
-/* This is the list of the default public-key ciphers included in
-   libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
-   FIPS mode. */
-static struct pubkey_table_entry
-{
-  gcry_pk_spec_t *pubkey;
-  unsigned int algorithm;
-  int fips_allowed;
-} pubkey_table[] =
+/* This is the list of the public-key algorithms included in
+   Libgcrypt.  */
+static gcry_pk_spec_t *pubkey_list[] =
   {
-#if USE_RSA
-    { &_gcry_pubkey_spec_rsa,       GCRY_PK_RSA, 1},
+#if USE_ECC
+    &_gcry_pubkey_spec_ecdsa,
+    &_gcry_pubkey_spec_ecdh,
 #endif
-#if USE_ELGAMAL
-    { &_gcry_pubkey_spec_elg,       GCRY_PK_ELG   },
-    { &_gcry_pubkey_spec_elg,       GCRY_PK_ELG_E },
+#if USE_RSA
+    &_gcry_pubkey_spec_rsa,
 #endif
 #if USE_DSA
-    { &_gcry_pubkey_spec_dsa,       GCRY_PK_DSA, 1   },
+    &_gcry_pubkey_spec_dsa,
 #endif
-#if USE_ECC
-    { &_gcry_pubkey_spec_ecdsa,      GCRY_PK_ECDSA, 0 },
-    { &_gcry_pubkey_spec_ecdh,       GCRY_PK_ECDH, 0 },
+#if USE_ELGAMAL
+    &_gcry_pubkey_spec_elg,
+    &_gcry_pubkey_spec_elg,
 #endif
-    { NULL, 0 }
+    NULL
   };
 
-/* List of registered ciphers.  */
-static gcry_module_t pubkeys_registered;
-
-/* This is the lock protecting PUBKEYS_REGISTERED.  */
-static ath_mutex_t pubkeys_registered_lock;
-
-/* Flag to check whether 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)            \
-        {                                          \
-          pk_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 gcry_err_code_t
-dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
-                gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)algorithm;
-  (void)nbits;
-  (void)dummy;
-  (void)skey;
-  (void)retfactors;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
-{
-  (void)algorithm;
-  (void)skey;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-               gcry_mpi_t *pkey, int flags)
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)pkey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
 
-static gcry_err_code_t
-dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
-               gcry_mpi_t *skey, int flags)
+/* Return the spec structure for the public key algorithm ALGO.  For
+   an unknown algorithm NULL is returned.  */
+static gcry_pk_spec_t *
+spec_from_algo (int algo)
 {
-  (void)algorithm;
-  (void)result;
-  (void)data;
-  (void)skey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
-
-static gcry_err_code_t
-dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-            gcry_mpi_t *skey,
-            int flags, int hashalgo)
-
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)skey;
-  (void)flags;
-  (void)hashalgo;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
+  int idx;
+  gcry_pk_spec_t *spec;
 
-static gcry_err_code_t
-dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
-              gcry_mpi_t *pkey,
-	      int (*cmp) (void *, gcry_mpi_t), void *opaquev,
-              int flags, int hashalgo)
-{
-  (void)algorithm;
-  (void)hash;
-  (void)data;
-  (void)pkey;
-  (void)cmp;
-  (void)opaquev;
-  (void)flags;
-  (void)hashalgo;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
+  for (idx = 0; (spec = pubkey_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
 }
 
-static unsigned
-dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
-{
-  (void)algorithm;
-  (void)pkey;
-  fips_signal_error ("using dummy public key function");
-  return 0;
-}
 
-/* Internal function.  Register all the pubkeys included in
-   PUBKEY_TABLE.  Returns zero on success or an error code.  */
-static void
-pk_register_default (void)
+/* Return the spec structure for the public key algorithm with NAME.
+   For an unknown name NULL is returned.  */
+static gcry_pk_spec_t *
+spec_from_name (const char *name)
 {
-  gcry_err_code_t err = 0;
-  int i;
+  gcry_pk_spec_t *spec;
+  int idx;
+  const char **aliases;
 
-  for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
+  for (idx=0; (spec = pubkey_list[idx]); idx++)
     {
-#define pubkey_use_dummy(func)                       \
-      if (! pubkey_table[i].pubkey->func)            \
-	pubkey_table[i].pubkey->func = dummy_##func;
-
-      pubkey_use_dummy (generate);
-      pubkey_use_dummy (check_secret_key);
-      pubkey_use_dummy (encrypt);
-      pubkey_use_dummy (decrypt);
-      pubkey_use_dummy (sign);
-      pubkey_use_dummy (verify);
-      pubkey_use_dummy (get_nbits);
-#undef pubkey_use_dummy
-
-      err = _gcry_module_add (&pubkeys_registered,
-			      pubkey_table[i].algorithm,
-			      (void *) pubkey_table[i].pubkey,
-                              NULL,
-                              NULL);
+      if (!stricmp (name, spec->name))
+        return spec;
+      for (aliases = spec->aliases; *aliases; aliases++)
+        if (!stricmp (name, *aliases))
+          return spec;
     }
 
-  if (err)
-    BUG ();
+  return NULL;
 }
 
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_pk_lookup_func_name (void *spec, void *data)
-{
-  gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
-  char *name = (char *) data;
-  const char **aliases = pubkey->aliases;
-  int ret = stricmp (name, pubkey->name);
-
-  while (ret && *aliases)
-    ret = stricmp (name, *aliases++);
-
-  return ! ret;
-}
 
-/* Internal function.  Lookup a pubkey entry by it's name.  */
-static gcry_module_t
-gcry_pk_lookup_name (const char *name)
+/* Disable the use of the algorithm ALGO.  This is not thread safe and
+   should thus be called early.  */
+static void
+disable_pubkey_algo (int algo)
 {
-  gcry_module_t pubkey;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
-				gcry_pk_lookup_func_name);
-
-  return pubkey;
+  if (spec)
+    spec->flags.disabled = 1;
 }
 
-/* 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.  */
-gcry_error_t
-_gcry_pk_register (gcry_pk_spec_t *pubkey,
-                   unsigned int *algorithm_id,
-                   gcry_module_t *module)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  err = _gcry_module_add (&pubkeys_registered, 0,
-			  (void *) pubkey,
-                          NULL,
-                          &mod);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (! err)
-    {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
-    }
-
-  return err;
-}
-
-/* Unregister the pubkey identified by ID, which must have been
-   registered with gcry_pk_register.  */
-void
-_gcry_pk_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
 
+

+/* Free the MPIs stored in the NULL terminated ARRAY of MPIs and set
+   the slots to NULL.  */
 static void
 release_mpi_array (gcry_mpi_t *array)
 {
@@ -301,30 +128,24 @@ release_mpi_array (gcry_mpi_t *array)
     }
 }
 
-/****************
+
+

+/*
  * Map a string to the pubkey algo
  */
 int
 gcry_pk_map_name (const char *string)
 {
-  gcry_module_t pubkey;
-  int algorithm = 0;
+  gcry_pk_spec_t *spec;
 
   if (!string)
     return 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = gcry_pk_lookup_name (string);
-  if (pubkey)
-    {
-      algorithm = pubkey->mod_id;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return algorithm;
+  spec = spec_from_name (string);
+  if (!spec)
+    return 0;
+  if (spec->flags.disabled)
+    return 0;
+  return spec->algo;
 }
 
 
@@ -332,25 +153,14 @@ gcry_pk_map_name (const char *string)
    a string representation of the algorithm name.  For unknown
    algorithm IDs this functions returns "?". */
 const char *
-gcry_pk_algo_name (int algorithm)
+gcry_pk_algo_name (int algo)
 {
-  gcry_module_t pubkey;
-  const char *name;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      name = ((gcry_pk_spec_t *) pubkey->spec)->name;
-      _gcry_module_release (pubkey);
-    }
-  else
-    name = "?";
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_pk_spec_t *spec;
 
-  return name;
+  spec = spec_from_algo (algo);
+  if (spec)
+    return spec->name;
+  return "?";
 }
 
 
@@ -358,77 +168,44 @@ gcry_pk_algo_name (int algorithm)
    name of the algorithm.  This is required to adhere to the spki
    specs where the algorithm names are lowercase. */
 const char *
-_gcry_pk_aliased_algo_name (int algorithm)
+_gcry_pk_aliased_algo_name (int algo)
 {
-  const char *name = NULL;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_pk_spec_t *spec;
+  const char *name;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
+  spec = spec_from_algo (algo);
+  if (spec)
     {
-      gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
-
-      name = pubkey->aliases? *pubkey->aliases : NULL;
+      name = spec->aliases? *spec->aliases : NULL;
       if (!name || !*name)
-        name = pubkey->name;
-      _gcry_module_release (module);
+        name = spec->name;
     }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
+  else
+    name = NULL;
   return name;
 }
 
 
-static void
-disable_pubkey_algo (int algorithm)
-{
-  gcry_module_t pubkey;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
-	pubkey->flags |= FLAG_MODULE_DISABLED;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
-
-
 /****************
  * A USE of 0 means: don't care.
  */
 static gcry_err_code_t
-check_pubkey_algo (int algorithm, unsigned use)
+check_pubkey_algo (int algo, unsigned use)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_err_code_t err = 0;
+  gcry_pk_spec_t *spec;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
+  spec = spec_from_algo (algo);
+  if (spec)
     {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-
       if (((use & GCRY_PK_USAGE_SIGN)
-	   && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
+	   && (! (spec->use & GCRY_PK_USAGE_SIGN)))
 	  || ((use & GCRY_PK_USAGE_ENCR)
-	      && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
+	      && (! (spec->use & GCRY_PK_USAGE_ENCR))))
 	err = GPG_ERR_WRONG_PUBKEY_ALGO;
-      else if (module->flags & FLAG_MODULE_DISABLED)
-	err = GPG_ERR_PUBKEY_ALGO;
-      _gcry_module_release (module);
     }
   else
     err = GPG_ERR_PUBKEY_ALGO;
-  ath_mutex_unlock (&pubkeys_registered_lock);
 
   return err;
 }
@@ -438,96 +215,50 @@ check_pubkey_algo (int algorithm, unsigned use)
  * Return the number of public key material numbers
  */
 static int
-pubkey_get_npkey (int algorithm)
+pubkey_get_npkey (int algo)
 {
-  gcry_module_t pubkey;
-  int npkey = 0;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return npkey;
+  return spec? strlen (spec->elements_pkey) : 0;
 }
 
+
 /****************
  * Return the number of secret key material numbers
  */
 static int
-pubkey_get_nskey (int algorithm)
+pubkey_get_nskey (int algo)
 {
-  gcry_module_t pubkey;
-  int nskey = 0;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nskey;
+  return spec? strlen (spec->elements_skey) : 0;
 }
 
+
 /****************
  * Return the number of signature material numbers
  */
 static int
-pubkey_get_nsig (int algorithm)
+pubkey_get_nsig (int algo)
 {
-  gcry_module_t pubkey;
-  int nsig = 0;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nsig;
+  return spec? strlen (spec->elements_sig) : 0;
 }
 
 /****************
  * Return the number of encryption material numbers
  */
 static int
-pubkey_get_nenc (int algorithm)
+pubkey_get_nenc (int algo)
 {
-  gcry_module_t pubkey;
-  int nenc = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  return nenc;
+  return spec? strlen (spec->elements_enc) : 0;
 }
 
 
-/* Generate a new public key with algorithm ALGORITHM of size NBITS
+/* Generate a new public key with algorithm ALGO of size NBITS
    and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
    is passed to the algorithm module if it features an extended
    generation function.  RETFACTOR is used by some algorithms to
@@ -536,62 +267,44 @@ pubkey_get_nenc (int algorithm)
 
    The function returns the error code number or 0 on success. */
 static gcry_err_code_t
-pubkey_generate (int algorithm,
+pubkey_generate (int algo,
                  unsigned int nbits,
                  unsigned long use_e,
                  gcry_sexp_t genparms,
                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
                  gcry_sexp_t *r_extrainfo)
 {
-  gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      if (((gcry_pk_spec_t *) pubkey->spec)->ext_generate)
-        {
-
-          /* Use the extended generate function.  */
-          ec = ((gcry_pk_spec_t *) pubkey->spec)->ext_generate
-            (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
-        }
-      else
-        {
-          /* Use the standard generate function.  */
-          ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
-            (algorithm, nbits, use_e, skey, retfactors);
-        }
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_err_code_t rc;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+  if (spec && spec->ext_generate)
+    rc = spec->ext_generate (algo, nbits, use_e, genparms,
+                             skey, retfactors, r_extrainfo);
+  else if (spec && spec->generate)
+    rc = spec->generate (algo, nbits, use_e, skey, retfactors);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
-  return ec;
+  return rc;
 }
 
 
 static gcry_err_code_t
-pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
+pubkey_check_secret_key (int algo, gcry_mpi_t *skey)
 {
-  gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_err_code_t rc;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
-        (algorithm, skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  if (spec && spec->check_secret_key)
+    rc = spec->check_secret_key (algo, skey);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
-  return err;
+  return rc;
 }
 
 
@@ -602,12 +315,11 @@ pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
  * check with pubkey_get_nenc() )
  */
 static gcry_err_code_t
-pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+pubkey_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
                 gcry_mpi_t *pkey, int flags)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
   int i;
 
   /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
@@ -615,29 +327,23 @@ pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
      here. */
   if (DBG_CIPHER && !fips_mode ())
     {
-      log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_npkey (algorithm); i++)
+      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);
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_algo (algo);
+  if (spec && spec->encrypt)
+    rc = spec->encrypt (algo, resarr, data, pkey, flags);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
   if (!rc && DBG_CIPHER && !fips_mode ())
     {
-      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
+      for(i = 0; i < pubkey_get_nenc (algo); i++)
 	log_mpidump("  encr", resarr[i] );
     }
   return rc;
@@ -652,38 +358,30 @@ pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
  * newly allocated mpi or NULL in case of an error.
  */
 static gcry_err_code_t
-pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+pubkey_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
                 gcry_mpi_t *skey, int flags)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
   int i;
 
-  *result = NULL; /* so the caller can always do a mpi_free */
+  *result = NULL; /* So the caller can always do a mpi_free.  */
   if (DBG_CIPHER && !fips_mode ())
     {
-      log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+      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 (algorithm); i++)
+      for(i = 0; i < pubkey_get_nenc (algo); i++)
 	log_mpidump ("  data", data[i]);
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->decrypt (algorithm, result, data, skey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_algo (algo);
+  if (spec && spec->decrypt)
+    rc = spec->decrypt (algo, result, data, skey, flags);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
   if (!rc && DBG_CIPHER && !fips_mode ())
     log_mpidump (" plain", *result);
@@ -699,84 +397,68 @@ pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
  * algorithm allows this - check with pubkey_get_nsig() )
  */
 static gcry_err_code_t
-pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+pubkey_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
              gcry_mpi_t *skey, struct pk_encoding_ctx *ctx)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
   int i;
 
   if (DBG_CIPHER && !fips_mode ())
     {
-      log_debug ("pubkey_sign: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+      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 );
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->sign (algorithm, resarr, data, skey,
-                         ctx->flags, ctx->hash_algo);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_algo (algo);
+  if (spec && spec->sign)
+    rc = spec->sign (algo, resarr, data, skey, ctx->flags, ctx->hash_algo);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
   if (!rc && DBG_CIPHER && !fips_mode ())
-    for (i = 0; i < pubkey_get_nsig (algorithm); i++)
+    for (i = 0; i < pubkey_get_nsig (algo); i++)
       log_mpidump ("   sig", resarr[i]);
 
   return rc;
 }
 
+
 /****************
  * Verify a public key signature.
  * Return 0 if the signature is good
  */
 static gcry_err_code_t
-pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+pubkey_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
                gcry_mpi_t *pkey, struct pk_encoding_ctx *ctx)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
   int i;
 
   if (DBG_CIPHER && !fips_mode ())
     {
-      log_debug ("pubkey_verify: algo=%d\n", algorithm);
-      for (i = 0; i < pubkey_get_npkey (algorithm); i++)
+      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 (algorithm); i++)
+      for (i = 0; i < pubkey_get_nsig (algo); i++)
 	log_mpidump ("   sig", data[i]);
       log_mpidump ("  hash", hash);
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->verify (algorithm, hash, data, pkey,
-                           ctx->verify_cmp, ctx,
-                           ctx->flags, ctx->hash_algo);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
+  spec = spec_from_algo (algo);
+  if (spec && spec->verify)
+    rc = spec->verify (algo, hash, data, pkey,
+                       ctx->verify_cmp, ctx, ctx->flags, ctx->hash_algo);
+  else if (spec)
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+  else
+    rc = GPG_ERR_PUBKEY_ALGO;
 
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
   return rc;
 }
 
@@ -2014,15 +1696,14 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
 static gcry_err_code_t
 sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
              const char *override_elems,
-             gcry_mpi_t **retarray, gcry_module_t *retalgo, int *r_is_ecc)
+             gcry_mpi_t **retarray, gcry_pk_spec_t **r_spec, int *r_is_ecc)
 {
   gcry_err_code_t err = 0;
   gcry_sexp_t list, l2;
   char *name;
   const char *elems;
   gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
+  gcry_pk_spec_t *spec;
   int is_ecc;
 
   /* Check that the first element is valid.  If we are looking for a
@@ -2062,43 +1743,37 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
   else
     is_ecc = 0;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
   if (is_ecc == 2 && (use & GCRY_PK_USAGE_SIGN))
-    module = gcry_pk_lookup_name ("ecdsa");
+    spec = spec_from_name ("ecdsa");
   else if (is_ecc == 2 && (use & GCRY_PK_USAGE_ENCR))
-    module = gcry_pk_lookup_name ("ecdh");
+    spec = spec_from_name ("ecdh");
   else
-    module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+    spec = spec_from_name (name);
 
   gcry_free (name);
 
-  if (!module)
+  if (!spec)
     {
       gcry_sexp_release (list);
       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
     }
-  else
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-    }
 
   if (override_elems)
     elems = override_elems;
   else if (want_private)
-    elems = pubkey->elements_skey;
+    elems = spec->elements_skey;
   else
-    elems = pubkey->elements_pkey;
+    elems = spec->elements_pkey;
   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
   if (!array)
     err = gpg_err_code_from_syserror ();
   if (!err)
     {
       if (is_ecc)
-        err = sexp_elements_extract_ecc (list, elems, array, pubkey,
+        err = sexp_elements_extract_ecc (list, elems, array, spec,
                                          want_private);
       else
-        err = sexp_elements_extract (list, elems, array, pubkey->name, 0);
+        err = sexp_elements_extract (list, elems, array, spec->name, 0);
     }
 
   gcry_sexp_release (list);
@@ -2106,15 +1781,11 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
   if (err)
     {
       gcry_free (array);
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
     }
   else
     {
       *retarray = array;
-      *retalgo = module;
+      *r_spec = spec;
       if (r_is_ecc)
         *r_is_ecc = is_ecc;
     }
@@ -2128,15 +1799,14 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
    MPI as opaque data.  */
 static gcry_err_code_t
 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
-	     gcry_module_t *retalgo, int opaque)
+	     gcry_pk_spec_t **r_spec, int opaque)
 {
   gcry_err_code_t err = 0;
   gcry_sexp_t list, l2;
   char *name;
   const char *elems;
   gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
+  gcry_pk_spec_t *spec;
 
   /* Check that the first element is valid.  */
   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
@@ -2171,22 +1841,18 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
       name = _gcry_sexp_nth_string (l2, 0);
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_name (name);
   gcry_free (name);
   name = NULL;
 
-  if (!module)
+  if (!spec)
     {
       gcry_sexp_release (l2);
       gcry_sexp_release (list);
       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
     }
-  else
-    pubkey = (gcry_pk_spec_t *) module->spec;
 
-  elems = pubkey->elements_sig;
+  elems = spec->elements_sig;
   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
   if (!array)
     err = gpg_err_code_from_syserror ();
@@ -2199,16 +1865,12 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
 
   if (err)
     {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-
       gcry_free (array);
     }
   else
     {
       *retarray = array;
-      *retalgo = module;
+      *r_spec = spec;
     }
 
   return err;
@@ -2284,13 +1946,13 @@ get_hash_algo (const char *s, size_t n)
  * case raw encoding is used.
  */
 static gcry_err_code_t
-sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
+sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_pk_spec_t **r_spec,
              int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
 {
   gcry_err_code_t err = 0;
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_sexp_t list = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_pk_spec_t *spec = NULL;
   char *name = NULL;
   size_t n;
   int parsed_flags = 0;
@@ -2435,18 +2097,14 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
       l2 = NULL;
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!module)
+  spec = spec_from_name (name);
+  if (!spec)
     {
       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
       goto leave;
     }
-  pubkey = (gcry_pk_spec_t *) module->spec;
 
-  elems = pubkey->elements_enc;
+  elems = spec->elements_enc;
   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
   if (!array)
     {
@@ -2463,9 +2121,6 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
 
   if (err)
     {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
       gcry_free (array);
       gcry_free (ctx->label);
       ctx->label = NULL;
@@ -2473,7 +2128,7 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
   else
     {
       *retarray = array;
-      *retalgo = module;
+      *r_spec = spec;
       *flags = parsed_flags;
     }
 
@@ -2995,31 +2650,27 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
   const char *algo_name, *algo_elems;
   struct pk_encoding_ctx ctx;
   gcry_err_code_t rc;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_pk_spec_t *spec = NULL;
 
   *r_ciph = NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   /* Get the key. */
-  rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &module, NULL);
+  rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &spec, NULL);
   if (rc)
     goto leave;
 
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
+  gcry_assert (spec);
 
   /* If aliases for the algorithm name exists, take the first one
      instead of the regular name to adhere to SPKI conventions.  We
      assume that the first alias name is the lowercase version of the
      regular one.  This change is required for compatibility with
      1.1.12 generated S-expressions. */
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  algo_name = spec->aliases? *spec->aliases : NULL;
   if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
+    algo_name = spec->name;
 
-  algo_elems = pubkey->elements_enc;
+  algo_elems = spec->elements_enc;
 
   /* Get the stuff we want to encrypt. */
   init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
@@ -3034,7 +2685,7 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
       rc = gpg_err_code_from_syserror ();
       goto leave;
     }
-  rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
+  rc = pubkey_encrypt (spec->algo, ciph, data, pkey, ctx.flags);
   mpi_free (data);
   data = NULL;
   if (rc)
@@ -3120,18 +2771,12 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
       gcry_free (ciph);
     }
 
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
   gcry_free (ctx.label);
 
   return gcry_error (rc);
 }
 
+
 /*
    Do a PK decrypt operation
 
@@ -3163,36 +2808,37 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
 gcry_error_t
 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 {
-  gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
+  gcry_err_code_t rc;
+  gcry_mpi_t *skey = NULL;
+  gcry_mpi_t *data = NULL;
+  gcry_mpi_t plain = NULL;
   unsigned char *unpad = NULL;
   size_t unpadlen = 0;
   int modern, flags;
   struct pk_encoding_ctx ctx;
-  gcry_err_code_t rc;
-  gcry_module_t module_enc = NULL, module_key = NULL;
+  gcry_pk_spec_t *spec_enc = NULL;
+  gcry_pk_spec_t *spec_key = NULL;
 
   *r_plain = NULL;
   ctx.label = NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_ENCR, NULL,
-                    &skey, &module_key, NULL);
+                    &skey, &spec_key, NULL);
   if (rc)
     goto leave;
 
   init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
-  rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
+  rc = sexp_to_enc (s_data, &data, &spec_enc, &modern, &flags, &ctx);
   if (rc)
     goto leave;
 
-  if (module_key->mod_id != module_enc->mod_id)
+  if (spec_key->algo != spec_enc->algo)
     {
       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
       goto leave;
     }
 
-  rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
+  rc = pubkey_decrypt (spec_key->algo, &plain, data, skey, flags);
   if (rc)
     goto leave;
 
@@ -3245,16 +2891,6 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
       gcry_free (data);
     }
 
-  if (module_key || module_enc)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-	_gcry_module_release (module_key);
-      if (module_enc)
-	_gcry_module_release (module_enc);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
   gcry_free (ctx.label);
 
   return gcry_error (rc);
@@ -3293,9 +2929,10 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 gcry_error_t
 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 {
-  gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_mpi_t *skey = NULL;
+  gcry_mpi_t hash = NULL;
+  gcry_mpi_t *result = NULL;
+  gcry_pk_spec_t *spec = NULL;
   const char *algo_name, *algo_elems;
   struct pk_encoding_ctx ctx;
   int i;
@@ -3304,20 +2941,17 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 
   *r_sig = NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_SIGN, NULL,
-                    &skey, &module, &is_ecc);
+                    &skey, &spec, &is_ecc);
   if (rc)
     goto leave;
 
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  gcry_assert (spec);
+  algo_name = spec->aliases? *spec->aliases : NULL;
   if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
+    algo_name = spec->name;
 
-  algo_elems = pubkey->elements_sig;
+  algo_elems = spec->elements_sig;
 
   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
      work on a private key.  We don't need the number of bits for ECC
@@ -3334,7 +2968,7 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
       rc = gpg_err_code_from_syserror ();
       goto leave;
     }
-  rc = pubkey_sign (module->mod_id, result, hash, skey, &ctx);
+  rc = pubkey_sign (spec->algo, result, hash, skey, &ctx);
   if (rc)
     goto leave;
 
@@ -3443,15 +3077,16 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 gcry_error_t
 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 {
-  gcry_module_t module_key = NULL, module_sig = NULL;
-  gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
-  struct pk_encoding_ctx ctx;
   gcry_err_code_t rc;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_pk_spec_t *spec_key = NULL;
+  gcry_pk_spec_t *spec_sig = NULL;
+  gcry_mpi_t *pkey = NULL;
+  gcry_mpi_t hash = NULL;
+  gcry_mpi_t *sig = NULL;
+  struct pk_encoding_ctx ctx;
 
   rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_SIGN, NULL,
-                    &pkey, &module_key, NULL);
+                    &pkey, &spec_key, NULL);
   if (rc)
     goto leave;
 
@@ -3462,20 +3097,20 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
     goto leave;
 
   /* Get the signature.  */
-  rc = sexp_to_sig (s_sig, &sig, &module_sig,
+  rc = sexp_to_sig (s_sig, &sig, &spec_sig,
                     !!(ctx.flags & PUBKEY_FLAG_EDDSA));
   if (rc)
     goto leave;
   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
      of S_PKEY.  */
 
-  if (module_key->mod_id != module_sig->mod_id)
+  if (spec_key->algo != spec_sig->algo)
     {
       rc = GPG_ERR_CONFLICT;
       goto leave;
     }
 
-  rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, &ctx);
+  rc = pubkey_verify (spec_key->algo, hash, sig, pkey, &ctx);
 
  leave:
   if (pkey)
@@ -3491,16 +3126,6 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
   if (hash)
     mpi_free (hash);
 
-  if (module_key || module_sig)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-	_gcry_module_release (module_key);
-      if (module_sig)
-	_gcry_module_release (module_sig);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
   return gcry_error (rc);
 }
 
@@ -3517,17 +3142,15 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 gcry_error_t
 gcry_pk_testkey (gcry_sexp_t s_key)
 {
-  gcry_module_t module = NULL;
+  gcry_pk_spec_t *spec = NULL;
   gcry_mpi_t *key = NULL;
   gcry_err_code_t rc;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   /* Note we currently support only secret key checking. */
-  rc = sexp_to_key (s_key, 1, 0, NULL, &key, &module, NULL);
-  if (! rc)
+  rc = sexp_to_key (s_key, 1, 0, NULL, &key, &spec, NULL);
+  if (!rc)
     {
-      rc = pubkey_check_secret_key (module->mod_id, key);
+      rc = pubkey_check_secret_key (spec->algo, key);
       release_mpi_array (key);
       gcry_free (key);
     }
@@ -3571,8 +3194,7 @@ gcry_pk_testkey (gcry_sexp_t s_key)
 gcry_error_t
 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
 {
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_pk_spec_t *spec = NULL;
   gcry_sexp_t list = NULL;
   gcry_sexp_t l2 = NULL;
   gcry_sexp_t l3 = NULL;
@@ -3581,7 +3203,6 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
   int i, j;
   const char *algo_name = NULL;
-  int algo;
   const char *sec_elems = NULL, *pub_elems = NULL;
   gcry_mpi_t skey[12];
   gcry_mpi_t *factors = NULL;
@@ -3592,8 +3213,6 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   skey[0] = NULL;
   *r_key = NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   list = gcry_sexp_find_token (s_parms, "genkey", 0);
   if (!list)
     {
@@ -3618,24 +3237,20 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
       goto leave;
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_name (name);
   gcry_free (name);
   name = NULL;
-  if (!module)
+  if (!spec)
     {
       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
       goto leave;
     }
 
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo = module->mod_id;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  algo_name = spec->aliases? *spec->aliases : NULL;
   if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-  pub_elems = pubkey->elements_pkey;
-  sec_elems = pubkey->elements_skey;
+    algo_name = spec->name;
+  pub_elems = spec->elements_pkey;
+  sec_elems = spec->elements_skey;
   if (strlen (sec_elems) >= DIM(skey))
     BUG ();
 
@@ -3686,7 +3301,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     nbits = 0;
 
   /* Pass control to the algorithm module. */
-  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
+  rc = pubkey_generate (spec->algo, nbits, use_e, list, skey,
                         &factors, &extrainfo);
   gcry_sexp_release (list); list = NULL;
   if (rc)
@@ -3735,7 +3350,8 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
         p = stpcpy (p, "%m)");
         mpis[nelem++] = skey[i];
       }
-    if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+    if (extrainfo
+        && (spec->algo == GCRY_PK_ECDSA || spec->algo == GCRY_PK_ECDH))
       {
         /* Very ugly hack to insert the used curve parameter into the
            list of public key parameters.  */
@@ -3752,7 +3368,8 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
         p = stpcpy (p, "%m)");
         mpis[nelem++] = skey[i];
       }
-    if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+    if (extrainfo
+        && (spec->algo == GCRY_PK_ECDSA || spec->algo == GCRY_PK_ECDH))
       {
         percent_s_idx2 = nelem++;
         p = stpcpy (p, "%S");
@@ -3845,13 +3462,6 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   gcry_sexp_release (l2);
   gcry_sexp_release (list);
 
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
   return gcry_error (rc);
 }
 
@@ -3864,30 +3474,22 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
 unsigned int
 gcry_pk_get_nbits (gcry_sexp_t key)
 {
-  gcry_module_t module = NULL;
-  gcry_pk_spec_t *pubkey;
+  gcry_pk_spec_t *spec;
   gcry_mpi_t *keyarr = NULL;
   unsigned int nbits = 0;
   gcry_err_code_t rc;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   /* FIXME: Parsing KEY is often too much overhead.  For example for
      ECC we would only need to look at P and stop parsing right
      away.  */
 
-  rc = sexp_to_key (key, 0, 0, NULL, &keyarr, &module, NULL);
+  rc = sexp_to_key (key, 0, 0, NULL, &keyarr, &spec, NULL);
   if (rc == GPG_ERR_INV_OBJ)
-    rc = sexp_to_key (key, 1, 0, NULL, &keyarr, &module, NULL);
+    rc = sexp_to_key (key, 1, 0, NULL, &keyarr, &spec, NULL);
   if (rc)
     return 0; /* Error - 0 is a suitable indication for that. */
 
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  nbits = spec->get_nbits (spec->algo, keyarr);
 
   release_mpi_array (keyarr);
   gcry_free (keyarr);
@@ -3906,9 +3508,9 @@ gcry_pk_get_nbits (gcry_sexp_t key)
 unsigned char *
 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
 {
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_sexp_t list = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_pk_spec_t *spec = NULL;
   const char *s;
   char *name = NULL;
   int idx;
@@ -3916,8 +3518,6 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   gcry_md_hd_t md = NULL;
   int okay = 0;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   /* Check that the first element is valid. */
   list = gcry_sexp_find_token (key, "public-key", 0);
   if (! list)
@@ -3938,26 +3538,21 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   if (!name)
     goto fail; /* Invalid structure of object. */
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!module)
+  spec = spec_from_name (name);
+  if (!spec)
     goto fail; /* Unknown algorithm.  */
 
-  pubkey = (gcry_pk_spec_t *) module->spec;
-
-  elems = pubkey->elements_grip;
+  elems = spec->elements_grip;
   if (!elems)
     goto fail; /* No grip parameter.  */
 
   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
     goto fail;
 
-  if (pubkey->comp_keygrip)
+  if (spec->comp_keygrip)
     {
       /* Module specific method to compute a keygrip.  */
-      if (pubkey->comp_keygrip (md, list))
+      if (spec->comp_keygrip (md, list))
         goto fail;
     }
   else
@@ -4011,17 +3606,14 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
   gcry_mpi_t *pkey = NULL;
   gcry_sexp_t list = NULL;
   gcry_sexp_t l2;
-  gcry_module_t module = NULL;
   char *name = NULL;
   const char *result = NULL;
   int want_private = 1;
-  gcry_pk_spec_t *spec;
+  gcry_pk_spec_t *spec = NULL;
 
   if (r_nbits)
     *r_nbits = 0;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   if (key)
     {
       iterator = 0;
@@ -4047,19 +3639,16 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
       /* Get the key.  We pass the names of the parameters for
          override_elems; this allows to call this function without the
          actual public key parameter.  */
-      if (sexp_to_key (key, want_private, 0, "pabgn", &pkey, &module, NULL))
+      if (sexp_to_key (key, want_private, 0, "pabgn", &pkey, &spec, NULL))
         goto leave;
     }
   else
     {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      module = gcry_pk_lookup_name ("ecc");
-      ath_mutex_unlock (&pubkeys_registered_lock);
-      if (!module)
+      spec = spec_from_name ("ecc");
+      if (!spec)
         goto leave;
     }
 
-  spec = module->spec;
   if (!spec || !spec->get_curve)
     goto leave;
 
@@ -4071,12 +3660,6 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
       release_mpi_array (pkey);
       gcry_free (pkey);
     }
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
   gcry_free (name);
   gcry_sexp_release (list);
   return result;
@@ -4087,27 +3670,17 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
 gcry_sexp_t
 gcry_pk_get_param (int algo, const char *name)
 {
-  gcry_module_t module = NULL;
   gcry_sexp_t result = NULL;
-  gcry_pk_spec_t *spec;
+  gcry_pk_spec_t *spec = NULL;
 
   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
     return NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name ("ecc");
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  if (module)
+  spec = spec_from_name ("ecc");
+  if (spec)
     {
-      spec = module->spec;
       if (spec && spec->get_curve_param)
         result = spec->get_curve_param (name);
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
     }
   return result;
 }
@@ -4119,8 +3692,6 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
 {
   gcry_err_code_t err = GPG_ERR_NO_ERROR;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   switch (cmd)
     {
     case GCRYCTL_DISABLE_ALGO:
@@ -4180,23 +3751,10 @@ gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
 
     case GCRYCTL_GET_ALGO_USAGE:
       {
-	gcry_module_t pubkey;
-	int use = 0;
-
-	REGISTER_DEFAULT_PUBKEYS;
-
-	ath_mutex_lock (&pubkeys_registered_lock);
-	pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-	if (pubkey)
-	  {
-	    use = ((gcry_pk_spec_t *) pubkey->spec)->use;
-	    _gcry_module_release (pubkey);
-	  }
-	ath_mutex_unlock (&pubkeys_registered_lock);
-
-	/* FIXME? */
-	*nbytes = use;
+	gcry_pk_spec_t *spec;
 
+	spec = spec_from_algo (algorithm);
+        *nbytes = spec? spec->use : 0;
 	break;
       }
 
@@ -4283,15 +3841,7 @@ _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
 gcry_err_code_t
 _gcry_pk_init (void)
 {
-  gcry_err_code_t err;
-
-  err = ath_mutex_init (&pubkeys_registered_lock);
-  if (err)
-    return gpg_err_code_from_errno (err);
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  return err;
+  return 0;
 }
 
 
@@ -4300,18 +3850,9 @@ _gcry_pk_init (void)
 gpg_error_t
 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
 {
-  gcry_module_t module = NULL;
-  gcry_err_code_t ec = 0;
-  gcry_pk_spec_t *spec = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_err_code_t ec;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    spec = module->spec;
-
-  ath_mutex_unlock (&pubkeys_registered_lock);
   if (spec && spec->selftest)
     ec = spec->selftest (algo, extended, report);
   else
@@ -4319,16 +3860,11 @@ _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
       ec = GPG_ERR_PUBKEY_ALGO;
       if (report)
         report ("pubkey", algo, "module",
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                spec && !spec->flags.disabled?
                 "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
+                spec? "algorithm disabled" :
+                "algorithm not found");
     }
 
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
   return gpg_error (ec);
 }
diff --git a/cipher/rsa.c b/cipher/rsa.c
index f4d3ca1..e495cd8 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -1382,9 +1382,10 @@ static const char *rsa_names[] =
 
 gcry_pk_spec_t _gcry_pubkey_spec_rsa =
   {
+    GCRY_PK_RSA, { 0, 1 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
     "RSA", rsa_names,
     "ne", "nedpqu", "a", "s", "n",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
     rsa_generate,
     rsa_check_secret_key,
     rsa_encrypt,
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index fd7680e..4c1485c 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -2589,8 +2589,10 @@ operations.  @var{cmd} controls what is to be done. The return value is
 @table @code
 @item GCRYCTL_DISABLE_ALGO
 Disable the algorithm given as an algorithm id in @var{buffer}.
- at var{buffer} must point to an @code{int} variable with the algorithm id
-and @var{buflen} must have the value @code{sizeof (int)}.
+ at var{buffer} must point to an @code{int} variable with the algorithm
+id and @var{buflen} must have the value @code{sizeof (int)}.  This
+fucntion is not thread safe and should thus be used before any other
+threads are started.
 
 @end table
 @end deftypefun
diff --git a/src/cipher-proto.h b/src/cipher-proto.h
index eec3d35..a641a07 100644
--- a/src/cipher-proto.h
+++ b/src/cipher-proto.h
@@ -122,6 +122,12 @@ typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
 /* Module specification structure for public key algoritms.  */
 typedef struct gcry_pk_spec
 {
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  int use;
   const char *name;
   const char **aliases;
   const char *elements_pkey;
@@ -129,7 +135,6 @@ typedef struct gcry_pk_spec
   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;
@@ -181,9 +186,6 @@ gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
                                 md_extra_spec_t *extraspec,
                                 unsigned int *algorithm_id,
                                 gcry_module_t *module);
-gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
-                                unsigned int *algorithm_id,
-                                gcry_module_t *module);
 
 /* The selftest functions.  */
 gcry_error_t _gcry_cipher_selftest (int algo, int extended,
diff --git a/src/cipher.h b/src/cipher.h
index 7f10aee..8d3afbf 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -237,6 +237,7 @@ extern md_extra_spec_t _gcry_digest_extraspec_sha512;
 /* Declarations for the pubkey cipher specifications.  */
 extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg_e;
 extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;

commit 89103ce00e862cc709e80fa41f2ee13d54093ec5
Author: Werner Koch <wk at gnupg.org>
Date:   Sat Sep 7 10:06:46 2013 +0200

    pk: Merge extraspecs struct with standard specs struct.
    
    * src/gcrypt-module.h (gcry_pk_spec_t): Move this typedef and the
    corresponding function typedefs to ...
    * src/cipher-proto.h: here.
    (pk_extra_spec_t): Remove typedef and merge fields into
    gcry_pk_spec_t.
    * cipher/rsa.c, cipher/dsa.c, cipher/elg.c, cipher/ecc.c: Ditto.
    * cipher/pubkey.c: Change accordingly.
    * src/cipher.h (_gcry_pubkey_extraspec_rsa): Remove.
    (_gcry_pubkey_extraspec_dsa): Remove.
    (_gcry_pubkey_extraspec_elg): Remove.
    (_gcry_pubkey_extraspec_ecdsa): Remove.
    --
    
    Now that we don't have loadable modules anymore, we don't need to keep
    the internal API between the modules and thus can simplify the code.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/cipher/dsa.c b/cipher/dsa.c
index 3a64dda..4a7ceee 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -1214,10 +1214,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_dsa =
     NULL,
     dsa_sign,
     dsa_verify,
-    dsa_get_nbits
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
-  {
+    dsa_get_nbits,
     run_selftests,
     dsa_generate_ext
   };
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 9766e9e..5340d57 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -2012,7 +2012,13 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
     NULL,
     ecc_sign,
     ecc_verify,
-    ecc_get_nbits
+    ecc_get_nbits,
+    run_selftests,
+    ecc_generate_ext,
+    compute_keygrip,
+    _gcry_ecc_get_param,
+    _gcry_ecc_get_curve,
+    _gcry_ecc_get_param_sexp
   };
 
 gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
@@ -2026,12 +2032,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
     ecc_decrypt_raw,
     NULL,
     NULL,
-    ecc_get_nbits
-  };
-
-
-pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
-  {
+    ecc_get_nbits,
     run_selftests,
     ecc_generate_ext,
     compute_keygrip,
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index d105cb4..44990aa 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -849,12 +849,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_elg =
     elg_decrypt,
     elg_sign,
     elg_verify,
-    elg_get_nbits
-  };
-
-pk_extra_spec_t _gcry_pubkey_extraspec_elg =
-  {
+    elg_get_nbits,
     NULL,
-    elg_generate_ext,
-    NULL
+    elg_generate_ext
   };
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 8fa7ebf..5be6b85 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -44,44 +44,31 @@ static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
                                       struct pk_encoding_ctx *ctx);
 
 
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static pk_extra_spec_t dummy_extra_spec;
-
-
 /* This is the list of the default public-key ciphers included in
    libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
    FIPS mode. */
 static struct pubkey_table_entry
 {
   gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
   unsigned int algorithm;
   int fips_allowed;
 } pubkey_table[] =
   {
 #if USE_RSA
-    { &_gcry_pubkey_spec_rsa,
-      &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
+    { &_gcry_pubkey_spec_rsa,       GCRY_PK_RSA, 1},
 #endif
 #if USE_ELGAMAL
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
+    { &_gcry_pubkey_spec_elg,       GCRY_PK_ELG   },
+    { &_gcry_pubkey_spec_elg,       GCRY_PK_ELG_E },
 #endif
 #if USE_DSA
-    { &_gcry_pubkey_spec_dsa,
-      &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
+    { &_gcry_pubkey_spec_dsa,       GCRY_PK_DSA, 1   },
 #endif
 #if USE_ECC
-    { &_gcry_pubkey_spec_ecdsa,
-      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
-    { &_gcry_pubkey_spec_ecdh,
-      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
+    { &_gcry_pubkey_spec_ecdsa,      GCRY_PK_ECDSA, 0 },
+    { &_gcry_pubkey_spec_ecdh,       GCRY_PK_ECDH, 0 },
 #endif
-    { NULL, 0 },
+    { NULL, 0 }
   };
 
 /* List of registered ciphers.  */
@@ -228,7 +215,7 @@ pk_register_default (void)
       err = _gcry_module_add (&pubkeys_registered,
 			      pubkey_table[i].algorithm,
 			      (void *) pubkey_table[i].pubkey,
-			      (void *) pubkey_table[i].extraspec,
+                              NULL,
                               NULL);
     }
 
@@ -268,7 +255,6 @@ gcry_pk_lookup_name (const char *name)
    and a pointer representhing this module is stored in MODULE.  */
 gcry_error_t
 _gcry_pk_register (gcry_pk_spec_t *pubkey,
-                   pk_extra_spec_t *extraspec,
                    unsigned int *algorithm_id,
                    gcry_module_t *module)
 {
@@ -282,7 +268,7 @@ _gcry_pk_register (gcry_pk_spec_t *pubkey,
   ath_mutex_lock (&pubkeys_registered_lock);
   err = _gcry_module_add (&pubkeys_registered, 0,
 			  (void *) pubkey,
-			  (void *)(extraspec? extraspec : &dummy_extra_spec),
+                          NULL,
                           &mod);
   ath_mutex_unlock (&pubkeys_registered_lock);
 
@@ -566,12 +552,11 @@ pubkey_generate (int algorithm,
   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
   if (pubkey)
     {
-      pk_extra_spec_t *extraspec = pubkey->extraspec;
-
-      if (extraspec && extraspec->ext_generate)
+      if (((gcry_pk_spec_t *) pubkey->spec)->ext_generate)
         {
+
           /* Use the extended generate function.  */
-          ec = extraspec->ext_generate
+          ec = ((gcry_pk_spec_t *) pubkey->spec)->ext_generate
             (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
         }
       else
@@ -1877,7 +1862,7 @@ sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
    of its intimate knowledge about the ECC parameters from ecc.c. */
 static gcry_err_code_t
 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
-                           gcry_mpi_t *elements, pk_extra_spec_t *extraspec,
+                           gcry_mpi_t *elements, gcry_pk_spec_t *spec,
                            int want_private)
 
 {
@@ -1927,7 +1912,7 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
   list = gcry_sexp_find_token (key_sexp, "curve", 5);
   if (list)
     {
-      if (extraspec->get_param)
+      if (spec->get_param)
         {
           char *curve;
           gcry_mpi_t params[6];
@@ -1943,7 +1928,7 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
               err = GPG_ERR_INV_OBJ;
               goto leave;
             }
-          err = extraspec->get_param (curve, params);
+          err = spec->get_param (curve, params);
           gcry_free (curve);
           if (err)
             goto leave;
@@ -2038,7 +2023,6 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
   gcry_mpi_t *array;
   gcry_module_t module;
   gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
   int is_ecc;
 
   /* Check that the first element is valid.  If we are looking for a
@@ -2097,7 +2081,6 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
   else
     {
       pubkey = (gcry_pk_spec_t *) module->spec;
-      extraspec = module->extraspec;
     }
 
   if (override_elems)
@@ -2112,7 +2095,7 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
   if (!err)
     {
       if (is_ecc)
-        err = sexp_elements_extract_ecc (list, elems, array, extraspec,
+        err = sexp_elements_extract_ecc (list, elems, array, pubkey,
                                          want_private);
       else
         err = sexp_elements_extract (list, elems, array, pubkey->name, 0);
@@ -3926,7 +3909,6 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   gcry_sexp_t list = NULL, l2 = NULL;
   gcry_pk_spec_t *pubkey = NULL;
   gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
   const char *s;
   char *name = NULL;
   int idx;
@@ -3964,7 +3946,6 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
     goto fail; /* Unknown algorithm.  */
 
   pubkey = (gcry_pk_spec_t *) module->spec;
-  extraspec = module->extraspec;
 
   elems = pubkey->elements_grip;
   if (!elems)
@@ -3973,10 +3954,10 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
     goto fail;
 
-  if (extraspec && extraspec->comp_keygrip)
+  if (pubkey->comp_keygrip)
     {
       /* Module specific method to compute a keygrip.  */
-      if (extraspec->comp_keygrip (md, list))
+      if (pubkey->comp_keygrip (md, list))
         goto fail;
     }
   else
@@ -4031,10 +4012,10 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
   gcry_sexp_t list = NULL;
   gcry_sexp_t l2;
   gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
   char *name = NULL;
   const char *result = NULL;
   int want_private = 1;
+  gcry_pk_spec_t *spec;
 
   if (r_nbits)
     *r_nbits = 0;
@@ -4078,11 +4059,11 @@ gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
         goto leave;
     }
 
-  extraspec = module->extraspec;
-  if (!extraspec || !extraspec->get_curve)
+  spec = module->spec;
+  if (!spec || !spec->get_curve)
     goto leave;
 
-  result = extraspec->get_curve (pkey, iterator, r_nbits);
+  result = spec->get_curve (pkey, iterator, r_nbits);
 
  leave:
   if (pkey)
@@ -4107,8 +4088,8 @@ gcry_sexp_t
 gcry_pk_get_param (int algo, const char *name)
 {
   gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
   gcry_sexp_t result = NULL;
+  gcry_pk_spec_t *spec;
 
   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
     return NULL;
@@ -4120,9 +4101,9 @@ gcry_pk_get_param (int algo, const char *name)
   ath_mutex_unlock (&pubkeys_registered_lock);
   if (module)
     {
-      extraspec = module->extraspec;
-      if (extraspec && extraspec->get_curve_param)
-        result = extraspec->get_curve_param (name);
+      spec = module->spec;
+      if (spec && spec->get_curve_param)
+        result = spec->get_curve_param (name);
 
       ath_mutex_lock (&pubkeys_registered_lock);
       _gcry_module_release (module);
@@ -4320,18 +4301,19 @@ gpg_error_t
 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
 {
   gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec = NULL;
   gcry_err_code_t ec = 0;
+  gcry_pk_spec_t *spec = NULL;
 
   REGISTER_DEFAULT_PUBKEYS;
 
   ath_mutex_lock (&pubkeys_registered_lock);
   module = _gcry_module_lookup_id (pubkeys_registered, algo);
   if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
+    spec = module->spec;
+
   ath_mutex_unlock (&pubkeys_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
+  if (spec && spec->selftest)
+    ec = spec->selftest (algo, extended, report);
   else
     {
       ec = GPG_ERR_PUBKEY_ALGO;
diff --git a/cipher/rsa.c b/cipher/rsa.c
index e7c880d..f4d3ca1 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -1392,9 +1392,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_rsa =
     rsa_sign,
     rsa_verify,
     rsa_get_nbits,
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
-  {
     run_selftests,
     rsa_generate_ext,
     compute_keygrip
diff --git a/src/cipher-proto.h b/src/cipher-proto.h
index e9f4bab..eec3d35 100644
--- a/src/cipher-proto.h
+++ b/src/cipher-proto.h
@@ -23,6 +23,8 @@
 #ifndef G10_CIPHER_PROTO_H
 #define G10_CIPHER_PROTO_H
 
+
+
 /* Definition of a function used to report selftest failures.
    DOMAIN is a string describing the function block:
           "cipher", "digest", "pubkey or "random",
@@ -38,24 +40,76 @@ typedef void (*selftest_report_func_t)(const char *domain,
 typedef gpg_err_code_t (*selftest_func_t)
      (int algo, int extended, selftest_report_func_t report);
 
+

+/*
+ *
+ * Public key related definitions.
+ *
+ */
+
+/* Type for the pk_generate function.  */
+typedef gcry_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 extended generate function.  */
+typedef gcry_err_code_t (*pk_ext_generate_t) (int algo,
+                                              unsigned int nbits,
+                                              unsigned long evalue,
+                                              gcry_sexp_t genparms,
+                                              gcry_mpi_t *skey,
+                                              gcry_mpi_t **retfactors,
+                                              gcry_sexp_t *extrainfo);
+
+/* Type for the pk_check_secret_key function.  */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+						       gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function.  */
+typedef gcry_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 gcry_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 gcry_err_code_t (*gcry_pk_sign_t) (int algo,
+					   gcry_mpi_t *resarr,
+					   gcry_mpi_t data,
+					   gcry_mpi_t *skey,
+                                           int flags,
+                                           int hashalgo);
+
+/* Type for the pk_verify function.  */
+typedef gcry_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,
+                                             int flags,
+                                             int hashalgo);
+
+/* Type for the pk_get_nbits function.  */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo,
+                                         gcry_mpi_t *pkey);
 
-/* An extended type of the generate function.  */
-typedef gcry_err_code_t (*pk_ext_generate_t)
-     (int algo,
-      unsigned int nbits,
-      unsigned long evalue,
-      gcry_sexp_t genparms,
-      gcry_mpi_t *skey,
-      gcry_mpi_t **retfactors,
-      gcry_sexp_t *extrainfo);
 
 /* The type used to compute the keygrip.  */
-typedef gpg_err_code_t (*pk_comp_keygrip_t)
-     (gcry_md_hd_t md, gcry_sexp_t keyparm);
+typedef gpg_err_code_t (*pk_comp_keygrip_t) (gcry_md_hd_t md,
+                                             gcry_sexp_t keyparm);
 
 /* The type used to query ECC curve parameters.  */
-typedef gcry_err_code_t (*pk_get_param_t)
-     (const char *name, gcry_mpi_t *pkey);
+typedef gcry_err_code_t (*pk_get_param_t) (const char *name,
+                                           gcry_mpi_t *pkey);
 
 /* The type used to query an ECC curve name.  */
 typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
@@ -64,6 +118,35 @@ typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
 /* The type used to query ECC curve parameters by name.  */
 typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
 
+
+/* Module specification structure for public key algoritms.  */
+typedef struct gcry_pk_spec
+{
+  const char *name;
+  const char **aliases;
+  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;
+  selftest_func_t selftest;
+  pk_ext_generate_t ext_generate;
+  pk_comp_keygrip_t comp_keygrip;
+  pk_get_param_t get_param;
+  pk_get_curve_t get_curve;
+  pk_get_curve_param_t get_curve_param;
+} gcry_pk_spec_t;
+
+
+

 /* The type used to convey additional information to a cipher.  */
 typedef gpg_err_code_t (*cipher_set_extra_info_t)
      (void *c, int what, const void *buffer, size_t buflen);
@@ -87,16 +170,6 @@ typedef struct md_extra_spec
   selftest_func_t selftest;
 } md_extra_spec_t;
 
-typedef struct pk_extra_spec
-{
-  selftest_func_t selftest;
-  pk_ext_generate_t ext_generate;
-  pk_comp_keygrip_t comp_keygrip;
-  pk_get_param_t get_param;
-  pk_get_curve_t get_curve;
-  pk_get_curve_param_t get_curve_param;
-} pk_extra_spec_t;
-
 
 
 /* The private register functions. */
@@ -109,7 +182,6 @@ gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
                                 unsigned int *algorithm_id,
                                 gcry_module_t *module);
 gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
-                                pk_extra_spec_t *extraspec,
                                 unsigned int *algorithm_id,
                                 gcry_module_t *module);
 
diff --git a/src/cipher.h b/src/cipher.h
index dffd081..7f10aee 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -241,10 +241,5 @@ extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;
 
-extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_elg;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa;
-
 
 #endif /*G10_CIPHER_H*/
diff --git a/src/gcrypt-module.h b/src/gcrypt-module.h
index 75ca8ab..9fcb8ab 100644
--- a/src/gcrypt-module.h
+++ b/src/gcrypt-module.h
@@ -98,73 +98,6 @@ typedef struct gcry_cipher_spec
 
 /* ********************** */
 
-/* Type for the pk_generate function.  */
-typedef gcry_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 gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
-						       gcry_mpi_t *skey);
-
-/* Type for the pk_encrypt function.  */
-typedef gcry_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 gcry_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 gcry_err_code_t (*gcry_pk_sign_t) (int algo,
-					   gcry_mpi_t *resarr,
-					   gcry_mpi_t data,
-					   gcry_mpi_t *skey,
-                                           int flags,
-                                           int hashalgo);
-
-/* Type for the pk_verify function.  */
-typedef gcry_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,
-                                             int flags,
-                                             int hashalgo);
-
-/* 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;
-  const char **aliases;
-  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;
-
-
 /* ********************** */
 
 /* Type for the md_init function.  */

-----------------------------------------------------------------------

Summary of changes:
 NEWS                |    1 +
 cipher/dsa.c        |    8 +-
 cipher/ecc.c        |   21 +-
 cipher/elgamal.c    |   23 +-
 cipher/pubkey.c     | 1054 ++++++++++++++-------------------------------------
 cipher/rsa.c        |    6 +-
 doc/gcrypt.texi     |    6 +-
 src/cipher-proto.h  |  128 +++++--
 src/cipher.h        |    6 +-
 src/gcrypt-module.h |   67 ----
 10 files changed, 428 insertions(+), 892 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org




More information about the Gnupg-commits mailing list