* pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
authorWerner Koch <wk@gnupg.org>
Tue, 9 Dec 2003 13:17:03 +0000 (13:17 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 9 Dec 2003 13:17:03 +0000 (13:17 +0000)
by straightforward gotos. Other cleanups.
(gcry_pk_decrypt): Ditto.
(gcry_pk_sign): Ditto.
(gcry_pk_verify): Ditto.
(gcry_pk_genkey): Ditto.  Use strtoul instead of strtol.
(gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.

cipher/ChangeLog
cipher/cipher.c
cipher/pubkey.c

index 422f452..e35bc76 100644 (file)
@@ -1,3 +1,28 @@
+2003-12-09  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
+       by straightforward gotos. Other cleanups.
+       (gcry_pk_decrypt): Ditto.
+       (gcry_pk_sign): Ditto.
+       (gcry_pk_verify): Ditto.
+       (gcry_pk_genkey): Ditto.  Use strtoul instead of strtol.
+       (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
+
+2003-12-07  Werner Koch  <wk@gnupg.org>
+
+       * pubkey.c (gcry_pk_register_default): Undef the helper macro.
+       (gcry_pk_map_name): Allow NULL for string.
+       (sexp_to_key): Use memcpy and not strncpy.  Use gcry_free and not
+       free.
+       (sexp_to_sig): Ditto.
+       (sexp_to_enc): Ditto.  Replaced the chain of if(!err) tests by
+       straightforward gotos.
+
+2003-12-05  Werner Koch  <wk@gnupg.org>
+
+       * cipher.c: Documentation cleanups.
+       (gcry_cipher_mode_from_oid): Allow NULL for STRING.
+
 2003-12-03  Werner Koch  <wk@gnupg.org>
 
        * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
index a1d8e5e..0c8db78 100644 (file)
@@ -104,13 +104,14 @@ struct gcry_cipher_handle
   gcry_module_t module;
   int mode;
   unsigned int flags;
-  byte iv[MAX_BLOCKSIZE];      /* (this should be ulong aligned) */
-  byte lastiv[MAX_BLOCKSIZE];
+  unsigned char iv[MAX_BLOCKSIZE];     /* (this should be ulong aligned) */
+  unsigned char lastiv[MAX_BLOCKSIZE];
   int unused;  /* in IV */
-  byte ctr[MAX_BLOCKSIZE];    /* for Counter (CTR) mode */
+  unsigned char ctr[MAX_BLOCKSIZE];     /* For Counter (CTR) mode. */
   PROPERLY_ALIGNED_TYPE context;
 };
 
+\f
 /* These dummy functions are used in case a cipher implementation
    refuses to provide it's own functions.  */
 
@@ -150,15 +151,17 @@ dummy_decrypt_stream (void *c,
   BUG();
 }
 
+\f
 /* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  */
+   CIPHER_TABLE.  Note, that this function gets only used by the macro
+   REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
 static void
 gcry_cipher_register_default (void)
 {
   gcry_err_code_t err = GPG_ERR_NO_ERROR;
   int i;
   
-  for (i = 0; (! err) && cipher_table[i].cipher; i++)
+  for (i = 0; !err && cipher_table[i].cipher; i++)
     {
       if (! cipher_table[i].cipher->setkey)
        cipher_table[i].cipher->setkey = dummy_setkey;
@@ -273,8 +276,13 @@ gcry_cipher_unregister (gcry_module_t module)
   ath_mutex_unlock (&ciphers_registered_lock);
 }
 
-/* locate the OID in the oid table and return the index or -1 when not
-   found */
+/* Locate the OID in the oid table and return the index or -1 when not
+   found.  An opitonal "oid." or "OID." prefix in OID is ignored, the
+   OID is expected to be in standard IETF dotted notation.  The
+   internal algorithm number is returned in ALGORITHM unless it
+   ispassed as NULL.  A pointer to the specification of the module
+   implementing this algorithm is return in OID_SPEC unless passed as
+   NULL.*/
 static int 
 search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
 {
@@ -291,7 +299,7 @@ search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
       gcry_cipher_spec_t *cipher = module->spec;
       int i;
 
-      for (i = 0; cipher->oids[i].oid && (! ret); i++)
+      for (i = 0; cipher->oids[i].oid && !ret; i++)
        if (! stricmp (oid, cipher->oids[i].oid))
          {
            if (algorithm)
@@ -306,11 +314,10 @@ search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
   return ret;
 }
 
-/****************
- * Map a string to the cipher algo.
- * Returns: The algo ID of the cipher for the gioven name or
- *         0 if the name is not known.
- */
+/* Map STRING to the cipher algorithm identifier.  Returns the
+   algorithm ID of the cipher for the given name or 0 if the name is
+   not known.  It is valid to pass NULL for STRING which results in a
+   return value of 0. */
 int
 gcry_cipher_map_name (const char *string)
 {
@@ -344,12 +351,20 @@ gcry_cipher_map_name (const char *string)
   return algorithm;
 }
 
+
+/* Given a STRING with an OID in dotted decimal notation, this
+   function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
+   with that OID or 0 if no mode is known.  Passing NULL for string
+   yields a return value of 0. */
 int
 gcry_cipher_mode_from_oid (const char *string)
 {
   gcry_cipher_oid_spec_t oid_spec;
   int ret = 0, mode = 0;
 
+  if (!string)
+    return 0;
+
   ath_mutex_lock (&ciphers_registered_lock);
   ret = search_oid (string, NULL, &oid_spec);
   if (ret)
@@ -360,9 +375,9 @@ gcry_cipher_mode_from_oid (const char *string)
 }
 
 
-/****************
- * Map a cipher algo to a string
- */
+/* Map the cipher algorithm identifier ALGORITHM to a string
+   representing this algorithm.  This string is the default name as
  used by Libgcrypt.  NULL is returned for an unknown algorithm.  */
 static const char *
 cipher_algo_to_string (int algorithm)
 {
@@ -383,10 +398,10 @@ cipher_algo_to_string (int algorithm)
   return name;
 }
 
-/****************
- * This function simply returns the name of the algorithm or some constant
- * string when there is no algo.  It will never return NULL.
- */
+/* Map the cipher algorithm identifier ALGORITHM to a string
+   representing this algorithm.  This string is the default name as
+   used by Libgcrypt.  An pointer to an empty string is returned for
  an unknown algorithm.  NULL is never returned. */
 const char *
 gcry_cipher_algo_name (int algorithm)
 {
@@ -395,6 +410,10 @@ gcry_cipher_algo_name (int algorithm)
 }
 
 
+/* Flag the cipher algorithm with the identifier ALGORITHM as
+   disabled.  There is no error return, the function does nothing for
+   unknown algorithms.  Disabled algorithms are vitually not available
+   in Libgcrypt. */
 static void
 disable_cipher_algo (int algorithm)
 {
@@ -414,10 +433,8 @@ disable_cipher_algo (int algorithm)
 }
 
 
-/****************
- * Return 0 if the cipher algo is available.
- */
-
+/* Return 0 if the cipher algorithm with indentifier ALGORITHM is
+   available. Returns a basic error code value if it is not available.  */
 static gcry_err_code_t
 check_cipher_algo (int algorithm)
 {
@@ -441,7 +458,12 @@ check_cipher_algo (int algorithm)
   return err;
 }
 
-static unsigned
+
+/* Return the standard length of the key for the cipher algorithm with
+   the identifier ALGORITHM.  This function expects a valid algorithm
+   and will abort if the algorithm is not available or the length of
+   the key is not known. */
+static unsigned int
 cipher_get_keylen (int algorithm)
 {
   gcry_module_t cipher;
@@ -465,7 +487,11 @@ cipher_get_keylen (int algorithm)
   return len;
 }
 
-static unsigned
+/* Return the block length of the cipher algorithm with the identifier
+   ALGORITHM.  This function expects a valid algorithm and will abort
+   if the algorithm is not available or the length of the key is not
+   known. */
+static unsigned int
 cipher_get_blocksize (int algorithm)
 {
   gcry_module_t cipher;
@@ -490,11 +516,20 @@ cipher_get_blocksize (int algorithm)
 }
 
 
-/****************
- * Open a cipher handle for use with algorithm ALGO, in mode MODE and
- * return the handle.  Put NULL into HANDLER and return and error code
- * if something goes wrong.  */
+/*
+   Open a cipher handle for use with cipher algorithm ALGORITHM, using
+   the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
+   handle in HANDLE.  Put NULL into HANDLE and return an error code if
+   something goes wrong.  FLAGS may be used to modify the
+   operation.  The defined flags are:
+
+   GCRY_CIPHER_SECURE:  allocate all internal buffers in secure memory.
+   GCRY_CIPHER_ENABLE_SYNC:  Enable the sync operation as used in OpenPGP.
+   GCRY_CIPHER_CBC_CTS:  Enable CTS mode.
+   GCRY_CIPHER_CBC_MAC:  Enable MAC mode.
 
+   Values for these flags may be combined using OR.
+ */
 gcry_error_t
 gcry_cipher_open (gcry_cipher_hd_t *handle,
                  int algo, int mode, unsigned int flags)
@@ -505,7 +540,9 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
   gcry_cipher_hd_t h = NULL;
   gcry_err_code_t err = 0;
 
-  _gcry_fast_random_poll();
+  /* If the application missed to call the random poll function, we do
+     it here to ensure that it is used once in a while. */
+  _gcry_fast_random_poll ();
   
   REGISTER_DEFAULT_CIPHERS;
 
@@ -612,6 +649,8 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
 }
 
 
+/* Release all resources associated with the cipher handle H. H may be
+   NULL in which case this is a no-operation. */
 void
 gcry_cipher_close (gcry_cipher_hd_t h)
 {
@@ -634,6 +673,8 @@ gcry_cipher_close (gcry_cipher_hd_t h)
 }
 
 
+/* Set the key to be used for the encryption context C to KEY with
+   length KEYLEN.  The length should match the required length. */
 static gcry_error_t
 cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned keylen)
 {
@@ -650,6 +691,8 @@ cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned keylen)
 }
 
 
+/* Set the IV to be used for the encryption context C to IV with
+   length IVLEN.  The length should match the required length. */
 static void
 cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
 {
@@ -666,11 +709,13 @@ cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
 }
 
 
+/* Reset the cipher context to the initial contex.  This is basically
+   the same as an release followed by a new. */
 static void
 cipher_reset (gcry_cipher_hd_t c)
 {
-  memcpy ((void *) &c->context.c,
-         (void *) ((char *) &c->context.c + c->cipher->contextsize),
+  memcpy (&c->context.c,
+         (char *) &c->context.c + c->cipher->contextsize,
          c->cipher->contextsize);
   memset (c->iv, 0, c->cipher->blocksize);
   memset (c->lastiv, 0, c->cipher->blocksize);
@@ -679,31 +724,34 @@ cipher_reset (gcry_cipher_hd_t c)
 
 
 static void
-do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nblocks )
+do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nblocks )
 {
-    unsigned n;
+    unsigned int n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->cipher->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+       c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
        inbuf  += c->cipher->blocksize;
        outbuf += c->cipher->blocksize;
     }
 }
 
 static void
-do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nblocks )
+do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nblocks )
 {
     unsigned n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->cipher->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+       c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
        inbuf  += c->cipher->blocksize;
        outbuf += c->cipher->blocksize;
     }
 }
 
 static void
-do_cbc_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_cbc_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
 {
     unsigned int n;
     byte *ivp;
@@ -717,12 +765,12 @@ do_cbc_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
     }
 
     for(n=0; n < nblocks; n++ ) {
-       /* fixme: the xor should works on words and not on
+       /* fixme: the xor should work on words and not on
         * bytes.  Maybe it is a good idea to enhance the cipher backend
-        * API to allow for CBC handling in the backend */
+        * API to allow for CBC handling direct in the backend */
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            outbuf[i] = inbuf[i] ^ *ivp++;
-       (*c->cipher->encrypt)( &c->context.c, outbuf, outbuf );
+       c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
        memcpy(c->iv, outbuf, blocksize );
        inbuf  += c->cipher->blocksize;
        if (!(c->flags & GCRY_CIPHER_CBC_MAC))
@@ -746,19 +794,20 @@ do_cbc_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
        for(; i < blocksize; i++ )
            outbuf[i] = 0 ^ *ivp++;
 
-       (*c->cipher->encrypt)( &c->context.c, outbuf, outbuf );
+       c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
        memcpy(c->iv, outbuf, blocksize );
       }
 }
 
 static void
-do_cbc_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_cbc_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
 {
     unsigned int n;
     byte *ivp;
     int i;
     size_t blocksize = c->cipher->blocksize;
-    unsigned nblocks = nbytes / blocksize;
+    unsigned int nblocks = nbytes / blocksize;
 
     if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
       nblocks--;
@@ -768,11 +817,11 @@ do_cbc_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
     }
 
     for(n=0; n < nblocks; n++ ) {
-       /* because outbuf and inbuf might be the same, we have
+       /* Because outbuf and inbuf might be the same, we have
         * to save the original ciphertext block.  We use lastiv
-        * for this here because it is not used otherwise */
+        * for this here because it is not used otherwise. */
        memcpy(c->lastiv, inbuf, blocksize );
-       (*c->cipher->decrypt)( &c->context.c, outbuf, inbuf );
+       c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            outbuf[i] ^= *ivp++;
        memcpy(c->iv, c->lastiv, blocksize );
@@ -791,14 +840,14 @@ do_cbc_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
        memcpy(c->lastiv, c->iv, blocksize ); /* save Cn-2 */
        memcpy(c->iv, inbuf + blocksize, restbytes ); /* save Cn */
 
-       (*c->cipher->decrypt)( &c->context.c, outbuf, inbuf );
+       c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
        for(ivp=c->iv,i=0; i < restbytes; i++ )
            outbuf[i] ^= *ivp++;
 
        memcpy(outbuf + blocksize, outbuf, restbytes);
        for(i=restbytes; i < blocksize; i++)
          c->iv[i] = outbuf[i];
-       (*c->cipher->decrypt)( &c->context.c, outbuf, c->iv );
+       c->cipher->decrypt ( &c->context.c, outbuf, c->iv );
        for(ivp=c->lastiv,i=0; i < blocksize; i++ )
            outbuf[i] ^= *ivp++;
        /* c->lastiv is now really lastlastiv, does this matter? */
@@ -814,10 +863,12 @@ do_cfb_encrypt( gcry_cipher_hd_t c,
     size_t blocksize = c->cipher->blocksize;
 
     if( nbytes <= c->unused ) {
-       /* short enough to be encoded by the remaining XOR mask */
-       /* XOR the input with the IV and store input into IV */
-       for(ivp=c->iv+c->cipher->blocksize - c->unused; nbytes; nbytes--, c->unused-- )
-           *outbuf++ = (*ivp++ ^= *inbuf++);
+       /* Short enough to be encoded by the remaining XOR mask. */
+       /* XOR the input with the IV and store input into IV. */
+       for (ivp=c->iv+c->cipher->blocksize - c->unused;
+             nbytes;
+             nbytes--, c->unused-- )
+          *outbuf++ = (*ivp++ ^= *inbuf++);
        return;
     }
 
@@ -828,12 +879,12 @@ do_cfb_encrypt( gcry_cipher_hd_t c,
            *outbuf++ = (*ivp++ ^= *inbuf++);
     }
 
-    /* now we can process complete blocks */
+    /* Now we can process complete blocks. */
     while( nbytes >= blocksize ) {
        int i;
-       /* encrypt the IV (and save the current one) */
+       /* Encrypt the IV (and save the current one). */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
+       c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
        /* XOR the input with the IV and store input into IV */
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            *outbuf++ = (*ivp++ ^= *inbuf++);
@@ -842,7 +893,7 @@ do_cfb_encrypt( gcry_cipher_hd_t c,
     if( nbytes ) { /* process the remaining bytes */
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
+       c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
        c->unused = blocksize;
        /* and apply the xor */
        c->unused -= nbytes;
@@ -853,16 +904,16 @@ do_cfb_encrypt( gcry_cipher_hd_t c,
 
 static void
 do_cfb_decrypt( gcry_cipher_hd_t c,
-                byte *outbuf, const byte *inbuf, unsigned nbytes )
+                byte *outbuf, const byte *inbuf, unsigned int nbytes )
 {
     byte *ivp;
     ulong temp;
     size_t blocksize = c->cipher->blocksize;
 
     if( nbytes <= c->unused ) {
-       /* short enough to be encoded by the remaining XOR mask */
-       /* XOR the input with the IV and store input into IV */
-       for(ivp=c->iv+blocksize - c->unused; nbytes; nbytes--,c->unused--){
+       /* Short enough to be encoded by the remaining XOR mask. */
+       /* XOR the input with the IV and store input into IV. */
+       for(ivp=c->iv+blocksize - c->unused; nbytes; nbytes--,c->unused--) {
            temp = *inbuf++;
            *outbuf++ = *ivp ^ temp;
            *ivp++ = temp;
@@ -871,7 +922,7 @@ do_cfb_decrypt( gcry_cipher_hd_t c,
     }
 
     if( c->unused ) {
-       /* XOR the input with the IV and store input into IV */
+       /* XOR the input with the IV and store input into IV. */
        nbytes -= c->unused;
        for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- ) {
            temp = *inbuf++;
@@ -885,7 +936,7 @@ do_cfb_decrypt( gcry_cipher_hd_t c,
        int i;
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
+       c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
        /* XOR the input with the IV and store input into IV */
        for(ivp=c->iv,i=0; i < blocksize; i++ ) {
            temp = *inbuf++;
@@ -897,7 +948,7 @@ do_cfb_decrypt( gcry_cipher_hd_t c,
     if( nbytes ) { /* process the remaining bytes */
        /* encrypt the IV (and save the current one) */
        memcpy( c->lastiv, c->iv, blocksize );
-       (*c->cipher->encrypt)( &c->context.c, c->iv, c->iv );
+       c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
        c->unused = blocksize;
        /* and apply the xor */
        c->unused -= nbytes;
@@ -911,7 +962,8 @@ do_cfb_decrypt( gcry_cipher_hd_t c,
 
 
 static void
-do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
 {
   unsigned int n;
   byte tmp[MAX_BLOCKSIZE];
@@ -921,7 +973,7 @@ do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
     {
       if ((n % c->cipher->blocksize) == 0)
        {
-         (*c->cipher->encrypt) (&c->context.c, tmp, c->ctr);
+         c->cipher->encrypt (&c->context.c, tmp, c->ctr);
 
          for (i = c->cipher->blocksize; i > 0; i--)
            {
@@ -931,13 +983,14 @@ do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nb
            }
        }
 
-      /* XOR input with encrypted counter and store in output */
+      /* XOR input with encrypted counter and store in output. */
       outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
     }
 }
 
 static void
-do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf, unsigned nbytes )
+do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
+                unsigned int nbytes )
 {
   do_ctr_encrypt (c, outbuf, inbuf, nbytes);
 }
@@ -962,8 +1015,9 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
             rc = GPG_ERR_INV_ARG;
        break;
       case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->cipher->blocksize) || (nbytes > c->cipher->blocksize && 
-                                      (c->flags & GCRY_CIPHER_CBC_CTS)))
+       if (!(nbytes%c->cipher->blocksize)
+            || (nbytes > c->cipher->blocksize
+                && (c->flags & GCRY_CIPHER_CBC_CTS)))
             do_cbc_encrypt(c, outbuf, inbuf, nbytes );
         else 
             rc = GPG_ERR_INV_ARG;
@@ -975,8 +1029,8 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
        do_ctr_encrypt(c, outbuf, inbuf, nbytes );
        break;
       case GCRY_CIPHER_MODE_STREAM:
-        (*c->cipher->stencrypt)( &c->context.c,
-                                outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        c->cipher->stencrypt ( &c->context.c,
+                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
         break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
@@ -993,20 +1047,21 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
 
 /****************
  * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
- * been requested,
+ * been requested.
  */
 gcry_error_t
 gcry_cipher_encrypt (gcry_cipher_hd_t h, byte *out, size_t outsize,
-                     const byte  *in, size_t inlen)
+                     const byte *in, size_t inlen)
 {
   gcry_err_code_t err;
 
   if (!in)
-    /* caller requested in-place encryption */
-    /* actullay cipher_encrypt() does not need to know about it, but
-     * we may change this to get better performace */
+    /* Caller requested in-place encryption. */
+    /* Actullay cipher_encrypt() does not need to know about it, but
+     * we may change this to get better performance. */
     err = cipher_encrypt (h, out, out, outsize);
-  else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ? h->cipher->blocksize : inlen))
+  else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ?
+                      h->cipher->blocksize : inlen))
     err = GPG_ERR_TOO_SHORT;
   else if ((h->mode == GCRY_CIPHER_MODE_ECB
            || (h->mode == GCRY_CIPHER_MODE_CBC
@@ -1034,7 +1089,7 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, byte *out, size_t outsize,
  */
 static gcry_err_code_t
 cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
-               unsigned nbytes)
+               unsigned int nbytes)
 {
     gcry_err_code_t rc = GPG_ERR_NO_ERROR;
 
@@ -1046,8 +1101,9 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
             rc = GPG_ERR_INV_ARG;
        break;
       case GCRY_CIPHER_MODE_CBC:
-       if (!(nbytes%c->cipher->blocksize) || (nbytes > c->cipher->blocksize && 
-                                              (c->flags & GCRY_CIPHER_CBC_CTS)))
+       if (!(nbytes%c->cipher->blocksize)
+            || (nbytes > c->cipher->blocksize
+                && (c->flags & GCRY_CIPHER_CBC_CTS)))
             do_cbc_decrypt(c, outbuf, inbuf, nbytes );
         else 
             rc = GPG_ERR_INV_ARG;
@@ -1059,8 +1115,8 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
        do_ctr_decrypt(c, outbuf, inbuf, nbytes );
        break;
       case GCRY_CIPHER_MODE_STREAM:
-        (*c->cipher->stdecrypt)( &c->context.c,
-                                outbuf, (byte*)/*arggg*/inbuf, nbytes );
+        c->cipher->stdecrypt ( &c->context.c,
+                               outbuf, (byte*)/*arggg*/inbuf, nbytes );
         break;
       case GCRY_CIPHER_MODE_NONE:
        if( inbuf != outbuf )
@@ -1082,9 +1138,9 @@ gcry_cipher_decrypt (gcry_cipher_hd_t h, byte *out, size_t outsize,
   gcry_err_code_t err = GPG_ERR_NO_ERROR;
 
   if (! in)
-    /* caller requested in-place encryption */
-    /* actullay cipher_encrypt() does not need to know about it, but
-     * we may chnage this to get better performace */
+    /* Caller requested in-place encryption. */
+    /* Actullay cipher_encrypt() does not need to know about it, but
+     * we may chnage this to get better performance. */
     err = cipher_decrypt (h, out, out, outsize);
   else if (outsize < inlen)
     err = GPG_ERR_TOO_SHORT;
index 8197419..45e816b 100644 (file)
 #include "cipher.h"
 #include "ath.h"
 
-static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags);
-static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t hash, gcry_mpi_t *skey);
-static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-                                    int (*cmp) (void *, gcry_mpi_t), void *opaque);
+static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
+                                       gcry_mpi_t *data, gcry_mpi_t *skey,
+                                       int flags);
+static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
+                                    gcry_mpi_t hash, gcry_mpi_t *skey);
+static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
+                                      gcry_mpi_t *data, gcry_mpi_t *pkey,
+                                    int (*cmp) (void *, gcry_mpi_t),
+                                      void *opaque);
 
 /* This is the list of the default public-key ciphers included in
    libgcrypt.  */
@@ -98,28 +103,32 @@ dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
 }
 
 static gcry_err_code_t
-dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+               gcry_mpi_t *pkey, int flags)
 {
   log_bug ("no encrypt() for %d\n", algorithm);
   return GPG_ERR_PUBKEY_ALGO;
 }
 
 static gcry_err_code_t
-dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
+dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+               gcry_mpi_t *skey, int flags)
 {
   log_bug ("no decrypt() for %d\n", algorithm);
   return GPG_ERR_PUBKEY_ALGO;
 }
 
 static gcry_err_code_t
-dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+            gcry_mpi_t *skey)
 {
   log_bug ("no sign() for %d\n", algorithm);
   return GPG_ERR_PUBKEY_ALGO;
 }
 
 static gcry_err_code_t
-dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+              gcry_mpi_t *pkey,
              int (*cmp) (void *, gcry_mpi_t), void *opaquev)
 {
   log_bug ("no verify() for %d\n", algorithm);
@@ -154,7 +163,7 @@ gcry_pk_register_default (void)
       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);
@@ -245,6 +254,9 @@ gcry_pk_map_name (const char *string)
   gcry_module_t pubkey;
   int algorithm = 0;
 
+  if (!string)
+    return 0;
+
   REGISTER_DEFAULT_PUBKEYS;
 
   ath_mutex_lock (&pubkeys_registered_lock);
@@ -330,7 +342,7 @@ disable_pubkey_algo (int algorithm)
 
 
 /****************
- * a use of 0 means: don't care
+ * A USE of 0 means: don't care.
  */
 static gcry_err_code_t
 check_pubkey_algo (int algorithm, unsigned use)
@@ -470,8 +482,8 @@ pubkey_generate (int algorithm, unsigned int nbits, unsigned long use_e,
   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
   if (pubkey)
     {
-      err = (*((gcry_pk_spec_t *) pubkey->spec)->generate) (algorithm, nbits, use_e, skey,
-                                                           retfactors);
+      err = ((gcry_pk_spec_t *) pubkey->spec)->generate 
+        (algorithm, nbits, use_e, skey, retfactors);
       _gcry_module_release (pubkey);
     }
   ath_mutex_unlock (&pubkeys_registered_lock);
@@ -491,7 +503,8 @@ pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
   if (pubkey)
     {
-      err = (*((gcry_pk_spec_t *) pubkey->spec)->check_secret_key) (algorithm, skey);
+      err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
+        (algorithm, skey);
       _gcry_module_release (pubkey);
     }
   ath_mutex_unlock (&pubkeys_registered_lock);
@@ -507,8 +520,8 @@ 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, gcry_mpi_t *pkey,
-               int flags)
+pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+                gcry_mpi_t *pkey, int flags)
 {
   gcry_pk_spec_t *pubkey;
   gcry_module_t module;
@@ -528,7 +541,7 @@ pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *
   if (module)
     {
       pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = (*pubkey->encrypt) (algorithm, resarr, data, pkey, flags);
+      rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
       _gcry_module_release (module);
       goto ready;
     }
@@ -554,8 +567,8 @@ pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *
  * 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, gcry_mpi_t *skey,
-               int flags)
+pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+                gcry_mpi_t *skey, int flags)
 {
   gcry_pk_spec_t *pubkey;
   gcry_module_t module;
@@ -577,7 +590,7 @@ pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t
   if (module)
     {
       pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = (*pubkey->decrypt) (algorithm, result, data, skey, flags);
+      rc = pubkey->decrypt (algorithm, result, data, skey, flags);
       _gcry_module_release (module);
       goto ready;
     }
@@ -601,7 +614,8 @@ pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, gcry_mpi_t
  * 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, gcry_mpi_t *skey)
+pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+             gcry_mpi_t *skey)
 {
   gcry_pk_spec_t *pubkey;
   gcry_module_t module;
@@ -621,7 +635,7 @@ pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *ske
   if (module)
     {
       pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = (*pubkey->sign) (algorithm, resarr, data, skey);
+      rc = pubkey->sign (algorithm, resarr, data, skey);
       _gcry_module_release (module);
       goto ready;
     }
@@ -643,7 +657,8 @@ pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *ske
  * Return 0 if the signature is good
  */
 static gcry_err_code_t
-pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+               gcry_mpi_t *pkey,
               int (*cmp)(void *, gcry_mpi_t), void *opaquev)
 {
   gcry_pk_spec_t *pubkey;
@@ -666,7 +681,7 @@ pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pke
   if (module)
     {
       pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = (*pubkey->verify) (algorithm, hash, data, pkey, cmp, opaquev);
+      rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
       _gcry_module_release (module);
       goto ready;
     }
@@ -678,6 +693,7 @@ pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pke
   return rc;
 }
 
+
 /* Internal function.   */
 static gcry_err_code_t
 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
@@ -688,7 +704,7 @@ sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
   const char *name;
   gcry_sexp_t list;
 
-  for (name = element_names, idx = 0; *name && (! err); name++, idx++)
+  for (name = element_names, idx = 0; *name && !err; name++, idx++)
     {
       list = gcry_sexp_find_token (key_sexp, name, 1);
       if (! list)
@@ -722,8 +738,8 @@ sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
  *    openpgp-elg
  *    openpgp-elg-sig
  * Provide a SE with the first element be either "private-key" or
- * or "public-key". the followed by a list with its first element
- * be one of the above algorithm identifiers and the following
+ * or "public-key". It is followed by a list with its first element
+ * be one of the above algorithm identifiers and the remaning
  * elements are pairs with parameter-id and value.
  * NOTE: we look through the list to find a list beginning with
  * "private-key" or "public-key" - the first one found is used.
@@ -761,7 +777,8 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
     list = gcry_sexp_find_token( sexp, want_private? "private-key"
                                                    :"public-key", 0 );
     if( !list )
-       return GPG_ERR_INV_OBJ; /* Does not contain a public- or private-key object */
+       return GPG_ERR_INV_OBJ; /* Does not contain a public-
+                                   or private-key object */
     l2 = gcry_sexp_cadr( list );
     gcry_sexp_release ( list );
     list = l2;
@@ -773,14 +790,14 @@ sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
 
     {
       char *name_terminated = gcry_xmalloc (n + 1);
-      strncpy (name_terminated, name, n);
+      memcpy (name_terminated, name, n);
       name_terminated[n] = 0;
 
       ath_mutex_lock (&pubkeys_registered_lock);
       module = gcry_pk_lookup_name (name_terminated);
       ath_mutex_unlock (&pubkeys_registered_lock);
 
-      free (name_terminated);
+      gcry_free (name_terminated);
     }
 
     if (! module)
@@ -850,7 +867,7 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
     }
     else if (n == 5 && (! memcmp (name, "flags", 5))) {
       /* Skip flags, since they are not used but just here for the
-        sake of consisten S-expressions.  */
+        sake of consistent S-expressions.  */
       gcry_sexp_release (l2);
       l2 = gcry_sexp_nth (list, 2);
       if (! l2)
@@ -863,14 +880,14 @@ sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
       
     {
       char *name_terminated = gcry_xmalloc (n + 1);
-      strncpy (name_terminated, name, n);
+      memcpy (name_terminated, name, n);
       name_terminated[n] = 0;
       
       ath_mutex_lock (&pubkeys_registered_lock);
       module = gcry_pk_lookup_name (name_terminated);
       ath_mutex_unlock (&pubkeys_registered_lock);
 
-      free (name_terminated);
+      gcry_free (name_terminated);
     }
 
     if (! module)
@@ -944,102 +961,103 @@ sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
   /* check that the first element is valid */
   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
   if (! list)
-    err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */
-
-  if (! err)
     {
-      l2 = gcry_sexp_nth (list, 1);
-      if (! l2)
-       err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
+      err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */
+      goto leave;
     }
 
-  if (! err)
+  l2 = gcry_sexp_nth (list, 1);
+  if (! l2)
     {
-      /* Extract identifier of sublist.  */
-      name = gcry_sexp_nth_data (l2, 0, &n);
-      if (! name)
-       err = GPG_ERR_INV_OBJ; /* invalid structure of object */
+      err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
+      goto leave;
     }
 
-  if (! err)
+  /* Extract identifier of sublist.  */
+  name = gcry_sexp_nth_data (l2, 0, &n);
+  if (! name)
     {
-      if ((n == 5) && (! memcmp (name, "flags", 5)))
-       {
-         /* There is a flags element - process it */
-         const char *s;
-         int i;
-
-         *ret_modern = 1;
-         for (i = gcry_sexp_length (l2) - 1; i > 0 && (! err); i--)
-           {
-             s = gcry_sexp_nth_data (l2, i, &n);
-             if (! s)
-               ; /* not a data element - ignore */
-             else if (n == 3 && ! memcmp (s, "raw", 3))
-               ; /* just a dummy because it is the default */
-             else if (n == 5 && ! memcmp (s, "pkcs1", 5))
-               *ret_want_pkcs1 = 1;
-             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
-               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
-             else
-               err = GPG_ERR_INV_FLAG;
-           }
-      
-         if (! err)
-           {
-             /* Get the next which has the actual data */
-             gcry_sexp_release (l2);
-             l2 = gcry_sexp_nth (list, 2);
-             if (! l2)
-               err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
-           }
-      
-         if (! err)
-           {
-             /* Extract sublist identifier.  */
-             name = gcry_sexp_nth_data (l2, 0, &n);
-             if (! name)
-               err = GPG_ERR_INV_OBJ; /* invalid structure of object */
-           }
-       }
-
-      if (! err)
-       {
-         gcry_sexp_release (list);
-         list = l2;
-         l2 = NULL;
-       }
+      err = GPG_ERR_INV_OBJ; /* invalid structure of object */
+      goto leave;
     }
-
-  if (! err)
+  
+  if ((n == 5) && (! memcmp (name, "flags", 5)))
     {
-      char *name_terminated = gcry_xmalloc (n + 1);
-      strncpy (name_terminated, name, n);
-      name_terminated[n] = 0;
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      module = gcry_pk_lookup_name (name_terminated);
-      ath_mutex_unlock (&pubkeys_registered_lock);
+      /* There is a flags element - process it */
+      const char *s;
+      int i;
+      
+      *ret_modern = 1;
+      for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
+        {
+          s = gcry_sexp_nth_data (l2, i, &n);
+          if (! s)
+            ; /* not a data element - ignore */
+          else if (n == 3 && ! memcmp (s, "raw", 3))
+            ; /* just a dummy because it is the default */
+          else if (n == 5 && ! memcmp (s, "pkcs1", 5))
+            *ret_want_pkcs1 = 1;
+          else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+            parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
+          else
+            {
+              err = GPG_ERR_INV_FLAG;
+              goto leave;
+            }
+        }
+      
+      /* Get the next which has the actual data */
+      gcry_sexp_release (l2);
+      l2 = gcry_sexp_nth (list, 2);
+      if (! l2)
+        {
+          err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
+          goto leave;
+        }
 
-      free (name_terminated);
+      /* Extract sublist identifier.  */
+      name = gcry_sexp_nth_data (l2, 0, &n);
+      if (! name)
+        {
+          err = GPG_ERR_INV_OBJ; /* invalid structure of object */
+          goto leave;
+        }
 
-      if (! module)
-       err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
-      else
-       pubkey = (gcry_pk_spec_t *) module->spec;
+      gcry_sexp_release (list);
+      list = l2;
+      l2 = NULL;
     }
 
-  if (! err)
+  {
+    char *name_terminated = gcry_xmalloc (n + 1);
+    memcpy (name_terminated, name, n);
+    name_terminated[n] = 0;
+    
+    ath_mutex_lock (&pubkeys_registered_lock);
+    module = gcry_pk_lookup_name (name_terminated);
+    ath_mutex_unlock (&pubkeys_registered_lock);
+    
+    gcry_free (name_terminated);
+    
+    if (! module)
+      {
+        err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
+        goto leave;
+      }
+    pubkey = (gcry_pk_spec_t *) module->spec;
+  }
+
+  elems = pubkey->elements_enc;
+  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
+  if (! array)
     {
-      elems = pubkey->elements_enc;
-      array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
-      if (! array)
-       err = gpg_err_code_from_errno (errno);
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
     }
 
-  if (! err)
-    err = sexp_elements_extract (list, elems, array);
+  err = sexp_elements_extract (list, elems, array);
 
+ leave:
   if (list)
     gcry_sexp_release (list);
   if (l2)
@@ -1149,7 +1167,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
         rc = GPG_ERR_INV_OBJ;
     }
   else if (is_pkcs1 && lvalue && for_encryption)
-    { /* create pkcs#1 block type 2 padding */
+    { /* Create pkcs#1 block type 2 padding. */
       unsigned char *frame = NULL;
       size_t nframe = (nbits+7) / 8;
       const void * value;
@@ -1173,22 +1191,22 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
           i = nframe - 3 - valuelen;
           assert (i > 0);
           p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
-          /* replace zero bytes by new values*/
+          /* Replace zero bytes by new values. */
           for (;;)
             {
               int j, k;
               unsigned char *pp;
               
-              /* count the zero bytes */
+              /* Count the zero bytes. */
               for (j=k=0; j < i; j++)
                 {
                   if (!p[j])
                     k++;
                 }
               if (!k)
-                break; /* okay: no (more) zero bytes */
+                break; /* Okay: no (more) zero bytes. */
               
-              k += k/128; /* better get some more */
+              k += k/128; /* Better get some more. */
               pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
               for (j=0; j < i && k; j++)
                 {
@@ -1213,7 +1231,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
       gcry_free(frame);
     }
   else if (is_pkcs1 && lhash && !for_encryption)
-    { /* create pkcs#1 block type 1 padding */
+    { /* Create pkcs#1 block type 1 padding. */
       if (gcry_sexp_length (lhash) != 3)
         rc = GPG_ERR_INV_OBJ;
       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
@@ -1258,22 +1276,26 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
                     || !valuelen )
             rc = GPG_ERR_INV_OBJ;
           else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
-            rc = GPG_ERR_NOT_IMPLEMENTED; /* we don't have all of the above algos */
+            {
+              /* We don't have yet all of the above algorithms.  */
+              rc = GPG_ERR_NOT_IMPLEMENTED;
+            }
           else if ( valuelen != dlen )
             {
-              /* hash value does not match the length of digest for
-                 the given algo */
+              /* Hash value does not match the length of digest for
+                 the given algorithm. */
               rc = GPG_ERR_CONFLICT;
             }
           else if( !dlen || dlen + asnlen + 4 > nframe)
             {
-              /* can't encode an DLEN byte digest MD into a NFRAME byte frame */
+              /* Can't encode an DLEN byte digest MD into a NFRAME
+                 byte frame. */
               rc = GPG_ERR_TOO_SHORT;
             }
           else if ( !(frame = gcry_malloc (nframe)) )
             rc = gpg_err_code_from_errno (errno);
           else
-            { /* assemble the pkcs#1 block type 1 */
+            { /* Assemble the pkcs#1 block type 1. */
               n = 0;
               frame[n++] = 0;
               frame[n++] = 1; /* block type */
@@ -1302,7 +1324,7 @@ sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
   gcry_sexp_release (lhash);
   gcry_sexp_release (lvalue);
 
-  if (! rc)
+  if (!rc)
     *flags = parsed_flags;
 
   return rc;
@@ -1346,78 +1368,79 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
   *r_ciph = NULL;
   /* get the key */
   rc = sexp_to_key (s_pkey, 0, &pkey, &module);
-  if (! rc)
-    {
-      assert (module);
-      pubkey = (gcry_pk_spec_t *) module->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;
-      if (!algo_name || !*algo_name)
-        algo_name = pubkey->name;
-
-      algo_elems = pubkey->elements_enc;
-      
-      /* get the stuff we want to encrypt */
-      rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
-                            &flags);
-    }
+  if (rc)
+    goto leave;
+
+  assert (module);
+  pubkey = (gcry_pk_spec_t *) module->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;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  
+  algo_elems = pubkey->elements_enc;
+  
+  /* Get the stuff we want to encrypt. */
+  rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
+                         &flags);
+  if (rc)
+    goto leave;
 
-  if (! rc)
-    {
-      /* Now we can encrypt data to ciph */
-      ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
-      rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
-      mpi_free (data);
-    }
+  /* Now we can encrypt DATA to CIPH. */
+  ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
+  rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
+  mpi_free (data);
+  data = NULL;
+  if (rc)
+    goto leave;
 
   /* We did it.  Now build the return list */
-  if (! rc)
-    {
-      char *string, *p;
-      int i;
-      size_t nelem = strlen (algo_elems);
-      size_t needed = 19 + strlen (algo_name) + (nelem * 5);
-
-      /* Build the string.  */
-      string = p = gcry_xmalloc (needed);
-      p = stpcpy ( p, "(enc-val(" );
-      p = stpcpy ( p, algo_name );
-      for(i=0; algo_elems[i]; i++ ) {
-       *p++ = '(';
-       *p++ = algo_elems[i];
-       p = stpcpy ( p, "%m)" );
+  {
+    char *string, *p;
+    int i;
+    size_t nelem = strlen (algo_elems);
+    size_t needed = 19 + strlen (algo_name) + (nelem * 5);
+    void **arg_list;
+    
+    /* Build the string.  */
+    string = p = gcry_xmalloc (needed);
+    p = stpcpy ( p, "(enc-val(" );
+    p = stpcpy ( p, algo_name );
+    for (i=0; algo_elems[i]; i++ )
+      {
+        *p++ = '(';
+        *p++ = algo_elems[i];
+        p = stpcpy ( p, "%m)" );
       }
-      strcpy ( p, "))" );
-
-      /* and now the ugly part:  we don't have a function to
-       * pass an array to a format string, so we have to do it this way :-(
-       */
-
+    strcpy ( p, "))" );
+    
+    /* And now the ugly part: We don't have a function to pass an
+     * array to a format string, so we have to do it this way :-(.  */
+    /* FIXME: There is now such a format spefier, so we can could
+       change the code to be more clear. */
+    arg_list = malloc (nelem * sizeof *arg_list);
+    if (!arg_list)
       {
-       void **arg_list = malloc (nelem * sizeof *arg_list);
-       if (arg_list)
-         {
-           for (i = 0; i < nelem; i++)
-             arg_list[i] = &ciph[i];
-
-           rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
-
-           free (arg_list);
-         }
-       else
-         rc = gpg_err_code_from_errno (errno);
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
       }
 
-      if (rc)
-       BUG ();
-      gcry_free (string);
-    }
+    for (i = 0; i < nelem; i++)
+      arg_list[i] = ciph + i;
+    
+    rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
+    free (arg_list);
+    if (rc)
+      BUG ();
+    gcry_free (string);
+  }
 
+ leave:
   if (pkey)
     {
       release_mpi_array (pkey);
@@ -1440,29 +1463,30 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
   return gcry_error (rc);
 }
 
-/****************
- * Do a PK decrypt operation
- *
- * Caller has to provide a secret key as the SEXP skey and data in a
- * format as created by gcry_pk_encrypt.  For historic reasons the
- * function returns simply an MPI as an S-expression part; this is
- * deprecated and the new method should be used which returns a real
- * S-expressionl this is selected by adding at least an empty flags
- * list to S_DATA.
- * 
- * Returns: 0 or an errorcode.
- *
- * s_data = (enc-val
- *            [(flags)]
- *           (<algo>
- *             (<param_name1> <mpi>)
- *             ...
- *             (<param_namen> <mpi>)
- *           ))
- * s_skey = <key-as-defined-in-sexp_to_key>
- * r_plain= Either an incomplete S-expression without the parentheses
- *          or if the flags list is used (even if empty) a real S-expression:
- *          (value PLAIN).  */
+/* 
+   Do a PK decrypt operation
+  
+   Caller has to provide a secret key as the SEXP skey and data in a
+   format as created by gcry_pk_encrypt.  For historic reasons the
+   function returns simply an MPI as an S-expression part; this is
+   deprecated and the new method should be used which returns a real
+   S-expressionl this is selected by adding at least an empty flags
+   list to S_DATA.
+   
+   Returns: 0 or an errorcode.
+  
+   s_data = (enc-val
+              [(flags)]
+              (<algo>
+                (<param_name1> <mpi>)
+                ...
+                (<param_namen> <mpi>)
+              ))
+   s_skey = <key-as-defined-in-sexp_to_key>
+   r_plain= Either an incomplete S-expression without the parentheses
+            or if the flags list is used (even if empty) a real S-expression:
+            (value PLAIN). 
+ */
 gcry_error_t
 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 {
@@ -1476,35 +1500,29 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 
   *r_plain = NULL;
   rc = sexp_to_key (s_skey, 1, &skey, &module_key);
+  if (rc)
+    goto leave;
 
-  if (! rc)
-    rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
-
-  if (! rc)
+  rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
+  if (rc)
+    goto leave;
+  
+  if (module_key->mod_id != module_enc->mod_id)
     {
-      if (module_key->mod_id != module_enc->mod_id)
-       rc = GPG_ERR_CONFLICT; /* key algo does not match data algo */
-      else
-       pubkey = (gcry_pk_spec_t *) module_key->spec;
+      rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
+      goto leave;
     }
 
-  if (! rc)
-    rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
+  pubkey = (gcry_pk_spec_t *) module_key->spec;
 
-  if (! rc)
-    {
-      if (! modern)
-       {
-         if (gcry_sexp_build (r_plain, NULL, "%m", plain))
-           BUG ();
-       }
-      else
-       {
-         if (gcry_sexp_build (r_plain, NULL, "(value %m)", plain))
-           BUG ();
-       }
-    }
+  rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
+  if (rc)
+    goto leave;
 
+  if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
+    BUG ();
+  
+ leave:
   if (skey)
     {
       release_mpi_array (skey);
@@ -1535,31 +1553,31 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 
 
 
-/****************
* Create a signature.
- *
* Caller has to provide a secret key as the SEXP skey and data
* expressed as a SEXP list hash with only one element which should
* instantly be available as a MPI. Alternatively the structure given
* below may be used for S_HASH, it provides the abiliy to pass flags
* to the operation; the only flag defined by now is "pkcs1" which
* does PKCS#1 block type 1 style padding.
- *
* Returns: 0 or an errorcode.
*         In case of 0 the function returns a new SEXP with the
*         signature value; the structure of this signature depends on the
*         other arguments but is always suitable to be passed to
*         gcry_pk_verify
- *
* s_hash = See comment for sexp_data_to_mpi
- *             
* s_skey = <key-as-defined-in-sexp_to_key>
* r_sig  = (sig-val
*           (<algo>
*             (<param_name1> <mpi>)
*             ...
- *             (<param_namen> <mpi>)
- * )) */
+/*
  Create a signature.
+  
  Caller has to provide a secret key as the SEXP skey and data
  expressed as a SEXP list hash with only one element which should
  instantly be available as a MPI. Alternatively the structure given
  below may be used for S_HASH, it provides the abiliy to pass flags
  to the operation; the only flag defined by now is "pkcs1" which
  does PKCS#1 block type 1 style padding.
+  
  Returns: 0 or an errorcode.
           In case of 0 the function returns a new SEXP with the
           signature value; the structure of this signature depends on the
           other arguments but is always suitable to be passed to
           gcry_pk_verify
+  
  s_hash = See comment for sexp_data_to_mpi
+               
  s_skey = <key-as-defined-in-sexp_to_key>
  r_sig  = (sig-val
             (<algo>
               (<param_name1> <mpi>)
               ...
+                (<param_namen> <mpi>))) 
+*/
 gcry_error_t
 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 {
@@ -1570,76 +1588,73 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
   int i;
   gcry_err_code_t rc;
 
-
   REGISTER_DEFAULT_PUBKEYS;
 
   *r_sig = NULL;
   rc = sexp_to_key (s_skey, 1, &skey, &module);
+  if (rc)
+    goto leave;
 
-  if (! rc)
-    {
-      assert (module);
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-      if (!algo_name || !*algo_name)
-        algo_name = pubkey->name;
-
-      algo_elems = pubkey->elements_sig;
+  assert (module);
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  
+  algo_elems = pubkey->elements_sig;
 
-      /* get the stuff we want to sign */
-      /* Note that pk_get_nbits does also work on a private key */
-      rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
+  /* Get the stuff we want to sign.  Note that pk_get_nbits does also
+      work on a private key. */
+  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
                              &hash, 0, NULL);
-    }
-
-  if (! rc)
-    {
-      result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
-      rc = pubkey_sign (module->mod_id, result, hash, skey);
-    }
-
-  if (! rc)
-    {
-      char *string, *p;
-      size_t nelem, needed = strlen (algo_name) + 20;
-
-      nelem = strlen (algo_elems);
+  if (rc)
+    goto leave;
 
-      /* count elements, so that we can allocate enough space */
-      needed += 10 * nelem;
+  result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
+  rc = pubkey_sign (module->mod_id, result, hash, skey);
+  if (rc)
+    goto leave;
 
-      /* build the string */
-      string = p = gcry_xmalloc (needed);
-      p = stpcpy (p, "(sig-val(");
-      p = stpcpy (p, algo_name);
-      for(i = 0; algo_elems[i]; i++)
-       {
-         *p++ = '(';
-         *p++ = algo_elems[i];
-         p = stpcpy (p, "%m)");
-       }
-      strcpy (p, "))");
+  {
+    char *string, *p;
+    size_t nelem, needed = strlen (algo_name) + 20;
+    void **arg_list;
 
+    nelem = strlen (algo_elems);
+    
+    /* Count elements, so that we can allocate enough space. */
+    needed += 10 * nelem;
+
+    /* Build the string. */
+    string = p = gcry_xmalloc (needed);
+    p = stpcpy (p, "(sig-val(");
+    p = stpcpy (p, algo_name);
+    for (i = 0; algo_elems[i]; i++)
       {
-       void **arg_list = malloc (nelem * sizeof *arg_list);
-       if (arg_list)
-         {
-           for (i = 0; i < nelem; i++)
-             arg_list[i] = &result[i];
-
-           rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
+        *p++ = '(';
+        *p++ = algo_elems[i];
+        p = stpcpy (p, "%m)");
+      }
+    strcpy (p, "))");
 
-           free (arg_list);
-         }
-       else
-         rc = gpg_err_code_from_errno (errno);
+    arg_list = malloc (nelem * sizeof *arg_list);
+    if (!arg_list)
+      {
+        rc = gpg_err_code_from_errno (errno);
+        goto leave;
       }
 
-      if (rc)
-       BUG ();
-      gcry_free (string);
-    }
+    for (i = 0; i < nelem; i++)
+      arg_list[i] = result + i;
+
+    rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
+    free (arg_list);
+    if (rc)
+      BUG ();
+    gcry_free (string);
+  }
 
+ leave:
   if (skey)
     {
       release_mpi_array (skey);
@@ -1656,13 +1671,13 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 }
 
 
-/****************
- * Verify a signature.  Caller has to supply the public key pkey, the
- * signature sig and his hashvalue data.  Public key has to be a
- * standard public key given as an S-Exp, sig is a S-Exp as returned
* from gcry_pk_sign and data must be an S-Exp like the one in sign
- * too.
- */
+/*
+   Verify a signature.
+
+   Caller has to supply the public key pkey, the signature sig and his
  hashvalue data.  Public key has to be a standard public key given
+   as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
  must be an S-Exp like the one in sign too.  */
 gcry_error_t
 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 {
@@ -1673,19 +1688,26 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
   REGISTER_DEFAULT_PUBKEYS;
  
   rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
-  if (rc)
-    rc = sexp_to_sig (s_sig, &sig, &module_sig);
+  if (rc)
+    goto leave;
 
-  if ((! rc)
-      && (module_key->mod_id != module_sig->mod_id))
-    rc = GPG_ERR_CONFLICT;
+  rc = sexp_to_sig (s_sig, &sig, &module_sig);
+  if (rc)
+    goto leave;
 
-  if (! rc)
-    rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
+  if (module_key->mod_id != module_sig->mod_id)
+    {
+      rc = GPG_ERR_CONFLICT;
+      goto leave;
+    }
 
-  if (! rc)
-    rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
+  rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
+  if (rc)
+    goto leave;
 
+  rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
+
+ leave:
   if (pkey)
     {
       release_mpi_array (pkey);
@@ -1713,14 +1735,15 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 }
 
 
-/****************
- * Test a key. This may be used either for a public or a secret key
- * to see whether internal structre is valid.
- *
- * Returns: 0 or an errorcode.
- *
- * s_key = <key-as-defined-in-sexp_to_key>
- */
+/*
+   Test a key.
+
+   This may be used either for a public or a secret key to see whether
+   internal structre is valid.
+  
+   Returns: 0 or an errorcode.
+  
+   s_key = <key-as-defined-in-sexp_to_key> */
 gcry_error_t
 gcry_pk_testkey (gcry_sexp_t s_key)
 {
@@ -1730,7 +1753,7 @@ gcry_pk_testkey (gcry_sexp_t s_key)
   
   REGISTER_DEFAULT_PUBKEYS;
 
-  /* Note we currently support only secret key checking */
+  /* Note we currently support only secret key checking. */
   rc = sexp_to_key (s_key, 1, &key, &module);
   if (! rc)
     {
@@ -1742,39 +1765,38 @@ gcry_pk_testkey (gcry_sexp_t s_key)
 }
 
 
-/****************
- * Create a public key pair and return it in r_key.
- * How the key is created depends on s_parms:
- * (genkey
- *  (algo
- *    (parameter_name_1 ....)
- *     ....
- *    (parameter_name_n ....)
- * ))
- * The key is returned in a format depending on the
- * algorithm. Both, private and secret keys are returned
- * and optionally some additional informatin.
- * For elgamal we return this structure:
- * (key-data
- *  (public-key
- *    (elg
- *     (p <mpi>)
- *     (g <mpi>)
- *     (y <mpi>)
- *    )
- *  )
- *  (private-key
- *    (elg
- *     (p <mpi>)
- *     (g <mpi>)
- *     (y <mpi>)
- *     (x <mpi>)
- *    )
- *  )
- *  (misc-key-info
- *     (pm1-factors n1 n2 ... nn)
- *  )
- * )
+/*
+  Create a public key pair and return it in r_key.
+  How the key is created depends on s_parms:
+  (genkey
+   (algo
+     (parameter_name_1 ....)
+      ....
+     (parameter_name_n ....)
+  ))
+  The key is returned in a format depending on the
+  algorithm. Both, private and secret keys are returned
+  and optionally some additional informatin.
+  For elgamal we return this structure:
+  (key-data
+   (public-key
+     (elg
+       (p <mpi>)
+       (g <mpi>)
+       (y <mpi>)
+     )
+   )
+   (private-key
+     (elg
+       (p <mpi>)
+       (g <mpi>)
+       (y <mpi>)
+       (x <mpi>)
+     )
+   )
+   (misc-key-info
+      (pm1-factors n1 n2 ... nn)
+   ))
  */
 gcry_error_t
 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
@@ -1789,203 +1811,206 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   const char *algo_name = NULL;
   int algo;
   const char *sec_elems = NULL, *pub_elems = NULL;
-  gcry_mpi_t skey[10] = { NULL }, *factors = NULL;
+  gcry_mpi_t skey[10], *factors = NULL;
   unsigned int nbits = 0;
   unsigned long use_e = 0;
+  char *name_terminated;
 
   REGISTER_DEFAULT_PUBKEYS;
 
+  skey[0] = NULL;
   *r_key = NULL;
-  list = gcry_sexp_find_token (s_parms, "genkey", 0);
-  if (! list)
-    rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data */
 
-  if (! rc)
+  list = gcry_sexp_find_token (s_parms, "genkey", 0);
+  if (!list)
     {
-      l2 = gcry_sexp_cadr (list);
-      gcry_sexp_release (list);
-      list = l2;
-      l2 = NULL;
-      if (! list)
-       rc = GPG_ERR_NO_OBJ; /* no cdr for the genkey */
+      rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
+      goto leave;
     }
 
-  if (! rc)
+  l2 = gcry_sexp_cadr (list);
+  gcry_sexp_release (list);
+  list = l2;
+  l2 = NULL;
+  if (! list)
     {
-      name = gcry_sexp_nth_data (list, 0, &n);
-      if (! name)
-       rc = GPG_ERR_INV_OBJ; /* algo string missing */
+      rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
+      goto leave;
     }
 
-  if (! rc)
+  name = gcry_sexp_nth_data (list, 0, &n);
+  if (! name)
     {
-      char *name_terminated = gcry_xmalloc (n + 1);
-      strncpy (name_terminated, name, n);
-      name_terminated[n] = 0;
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      module = gcry_pk_lookup_name (name_terminated);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-
-      free (name_terminated);
-
-      if (! module)
-       rc = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
-      else
-       {
-         pubkey = (gcry_pk_spec_t *) module->spec;
-         algo = module->mod_id;
-          algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-          if (!algo_name || !*algo_name)
-            algo_name = pubkey->name;
-         pub_elems = pubkey->elements_pkey;
-         sec_elems = pubkey->elements_skey;
-       }
+      rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
+      goto leave;
     }
 
-  if (! rc)
+  name_terminated = gcry_xmalloc (n + 1);
+  memcpy (name_terminated, name, n);
+  name_terminated[n] = 0;
+  ath_mutex_lock (&pubkeys_registered_lock);
+  module = gcry_pk_lookup_name (name_terminated);
+  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_free (name_terminated);
+
+  if (! module)
     {
-      l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
-      if (l2)
-       {
-         char buf[50];
-
-         name = gcry_sexp_nth_data (l2, 1, &n);
-         if ((! name) || (n >= DIM (buf) - 1))
-           rc = GPG_ERR_INV_OBJ; /* no value or value too large */
-         else
-           {
-             memcpy (buf, name, n);
-             buf[n] = 0;
-             use_e = strtoul (buf, NULL, 0);
-           }
-         gcry_sexp_release (l2);
-         l2 = NULL;
-       }
-      else
-       use_e = 65537; /* not given, use the value generated by old versions. */
+      rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+      goto leave;
     }
-
-  if (! rc)
+  
+  pubkey = (gcry_pk_spec_t *) module->spec;
+  algo = module->mod_id;
+  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+  if (!algo_name || !*algo_name)
+    algo_name = pubkey->name;
+  pub_elems = pubkey->elements_pkey;
+  sec_elems = pubkey->elements_skey;
+
+  /* Handle the optional rsa-use-e element. */
+  l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
+  if (l2)
     {
-      l2 = gcry_sexp_find_token (list, "nbits", 0);
-      gcry_sexp_release (list);
-      list = l2;
+      char buf[50];
+
+      name = gcry_sexp_nth_data (l2, 1, &n);
+      if ((! name) || (n >= DIM (buf) - 1))
+        {
+          rc = GPG_ERR_INV_OBJ; /* No value or value too large. */
+          goto leave;
+        }
+      memcpy (buf, name, n);
+      buf[n] = 0;
+      use_e = strtoul (buf, NULL, 0);
+      gcry_sexp_release (l2);
       l2 = NULL;
-      if (! list)
-       rc = GPG_ERR_NO_OBJ; /* no nbits parameter */
-      else
-       {
-         name = gcry_sexp_nth_data (list, 1, &n);
-         if (! name)
-           rc = GPG_ERR_INV_OBJ; /* nbits without a cdr */
-         else
-           {
-             char *p = gcry_xmalloc (n + 1);
-             memcpy (p, name, n);
-             p[n] = 0;
-             nbits = (unsigned int) strtol (p, NULL, 0);
-             gcry_free (p);
-           }
-       }
     }
+  else
+    use_e = 65537; /* Not given, use the value generated by old versions. */
 
-  if (! rc)
-    rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
-
-  if (! rc)
+  l2 = gcry_sexp_find_token (list, "nbits", 0);
+  gcry_sexp_release (list);
+  list = l2;
+  l2 = NULL;
+  
+  if (! list)
     {
-      char *string, *p;
-      size_t nelem=0, nelem_cp = 0, needed=0;
-      gcry_mpi_t mpis[30];
-
-      nelem = strlen (pub_elems) + strlen (sec_elems);
-      for (i = 0; factors[i]; i++)
-       nelem++;
-      nelem_cp = nelem;
-
-      needed += nelem * 10;
-      needed += 2 * strlen (algo_name) + 300;
-      if (nelem > DIM (mpis))
-       BUG ();
+      rc = GPG_ERR_NO_OBJ; /* No nbits parameter. */
+      goto leave;
+    }
 
-      /* build the string */
-      nelem = 0;
-      string = p = gcry_xmalloc (needed);
-      p = stpcpy (p, "(key-data");
-      p = stpcpy (p, "(public-key(");
-      p = stpcpy (p, algo_name);
-      for(i = 0; pub_elems[i]; i++)
-       {
-         *p++ = '(';
-         *p++ = pub_elems[i];
-         p = stpcpy (p, "%m)");
-         mpis[nelem++] = skey[i];
-       }
-      p = stpcpy (p, "))");
-      p = stpcpy (p, "(private-key(");
-      p = stpcpy (p, algo_name);
-      for (i = 0; sec_elems[i]; i++)
-       {
-         *p++ = '(';
-         *p++ = sec_elems[i];
-         p = stpcpy (p, "%m)");
-         mpis[nelem++] = skey[i];
-       }
-      p = stpcpy (p, "))");
+  name = gcry_sexp_nth_data (list, 1, &n);
+  if (! name)
+    {
+      rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */
+      goto leave;
+    }
+  
+  name_terminated = gcry_xmalloc (n + 1);
+  memcpy (name_terminated, name, n);
+  name_terminated[n] = 0;
+  nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
+  gcry_free (name_terminated);
 
-      /* Very ugly hack to make release_mpi_array() work FIXME */
-      skey[i] = NULL;
+  rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
+  if (rc)
+    goto leave;
 
-      p = stpcpy (p, "(misc-key-info(pm1-factors");
-      for(i = 0; factors[i]; i++)
-       {
-         p = stpcpy (p, "%m");
-         mpis[nelem++] = factors[i];
-       }
-      strcpy (p, ")))");
+  {
+    char *string, *p;
+    size_t nelem=0, nelem_cp = 0, needed=0;
+    gcry_mpi_t mpis[30];
+    
+    nelem = strlen (pub_elems) + strlen (sec_elems);
+    for (i = 0; factors[i]; i++)
+      nelem++;
+    nelem_cp = nelem;
+
+    needed += nelem * 10;
+    needed += 2 * strlen (algo_name) + 300;
+    if (nelem > DIM (mpis))
+      BUG ();
+
+    /* Build the string. */
+    nelem = 0;
+    string = p = gcry_xmalloc (needed);
+    p = stpcpy (p, "(key-data");
+    p = stpcpy (p, "(public-key(");
+    p = stpcpy (p, algo_name);
+    for(i = 0; pub_elems[i]; i++)
+      {
+        *p++ = '(';
+        *p++ = pub_elems[i];
+        p = stpcpy (p, "%m)");
+        mpis[nelem++] = skey[i];
+      }
+    p = stpcpy (p, "))");
+    p = stpcpy (p, "(private-key(");
+    p = stpcpy (p, algo_name);
+    for (i = 0; sec_elems[i]; i++)
+      {
+        *p++ = '(';
+        *p++ = sec_elems[i];
+        p = stpcpy (p, "%m)");
+        mpis[nelem++] = skey[i];
+      }
+    p = stpcpy (p, "))");
 
-      while (nelem < DIM (mpis))
-       mpis[nelem++] = NULL;
+    /* Very ugly hack to make release_mpi_array() work FIXME */
+    skey[i] = NULL;
 
+    p = stpcpy (p, "(misc-key-info(pm1-factors");
+    for(i = 0; factors[i]; i++)
       {
-       int elem_n = strlen (pub_elems) + strlen (sec_elems);
-       void **arg_list = malloc (nelem_cp * sizeof *arg_list);
-       if (arg_list)
-         {
-           for (i = 0; i < elem_n; i++)
-             arg_list[i] = &mpis[i];
-           for (; i < nelem_cp; i++)
-             arg_list[i] = &factors[i - elem_n];
+        p = stpcpy (p, "%m");
+        mpis[nelem++] = factors[i];
+      }
+    strcpy (p, ")))");
 
-           rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
+    while (nelem < DIM (mpis))
+      mpis[nelem++] = NULL;
 
-           free (arg_list);
-         }
-       else
-         rc = gpg_err_code_from_errno (errno);
-      }
+    {
+      int elem_n = strlen (pub_elems) + strlen (sec_elems);
+      void **arg_list;
 
+      arg_list = malloc (nelem_cp * sizeof *arg_list);
+      if (!arg_list)
+        {
+          rc = gpg_err_code_from_errno (errno);
+          goto leave;
+        }
+      for (i = 0; i < elem_n; i++)
+        arg_list[i] = mpis + i;
+      for (; i < nelem_cp; i++)
+        arg_list[i] = factors + i - elem_n;
+      
+      rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
+      free (arg_list);
       if (rc)
        BUG ();
-      assert (DIM (mpis) == 30);       /* ? */
-      gcry_free (string);
+      assert (DIM (mpis) == 30); /* Reminder to make sure that the
+                                    array gets increased if new
+                                    parameters are added. */
     }
+    gcry_free (string);
+  }
 
+ leave:
   release_mpi_array (skey);
-  /* no free:  skey is a static array */
-
+  /* Don't free SKEY itself, it is a static array. */
+    
   if (factors)
     {
       release_mpi_array ( factors );
       gcry_free (factors);
     }
-
+  
   if (l2)
     gcry_sexp_release (l2);
   if (list)
     gcry_sexp_release (list);
-
+  
   if (module)
     {
       ath_mutex_lock (&pubkeys_registered_lock);
@@ -1996,12 +2021,12 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   return gcry_error (rc);
 }
 
-/****************
- * Get the number of nbits from the public key
- * Hmmm: Should we have really this function or is it
- * better to have a more general function to retrieve
- * different propoerties of the key?
- */
+
+/* 
+   Get the number of nbits from the public key.
+
+   Hmmm: Should we have really this function or is it better to have a
  more general function to retrieve different propoerties of the key?  */
 unsigned int
 gcry_pk_get_nbits (gcry_sexp_t key)
 {
@@ -2017,16 +2042,14 @@ gcry_pk_get_nbits (gcry_sexp_t key)
   if (rc == GPG_ERR_INV_OBJ)
     rc = sexp_to_key (key, 1, &keyarr, &module);
   if (rc)
-    return 0;
-  else
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
+    return 0; /* Error - 0 is a suitable indication for that. */
 
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
+  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);
 
   release_mpi_array (keyarr);
   gcry_free (keyarr);
@@ -2057,14 +2080,14 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
 
   REGISTER_DEFAULT_PUBKEYS;
 
-  /* check that the first element is valid */
+  /* Check that the first element is valid. */
   list = gcry_sexp_find_token (key, "public-key", 0);
   if (! list)
     list = gcry_sexp_find_token (key, "private-key", 0);
   if (! list)
     list = gcry_sexp_find_token (key, "protected-private-key", 0);
   if (! list)
-    return NULL; /* no public- or private-key object */
+    return NULL; /* No public- or private-key object. */
 
   l2 = gcry_sexp_cadr (list);
   gcry_sexp_release (list);
@@ -2073,25 +2096,22 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
 
   name = gcry_sexp_nth_data (list, 0, &n);
   if (! name)
-    goto fail; /* invalid structure of object */
+    goto fail; /* Invalid structure of object. */
 
-  
   {
     char *name_terminated = gcry_xmalloc (n + 1);
-    strncpy (name_terminated, name, n);
+    memcpy (name_terminated, name, n);
     name_terminated[n] = 0;
-
     ath_mutex_lock (&pubkeys_registered_lock);
     module = gcry_pk_lookup_name (name_terminated);
     ath_mutex_unlock (&pubkeys_registered_lock);
-
-    free (name_terminated);
+    gcry_free (name_terminated);
   }
 
   if (! module)
     goto fail; /* unknown algorithm */
-  else
-    pubkey = (gcry_pk_spec_t *) module->spec;
+
+  pubkey = (gcry_pk_spec_t *) module->spec;
 
   /* FIXME, special handling should be implemented by the algorithms,
      not by the libgcrypt core.  */
@@ -2121,10 +2141,11 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
           sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
           gcry_md_write (md, buf, strlen (buf));
         }
-      /* pkcs-15 says that for RSA only the modulus should be hashed -
+  
+      /* PKCS-15 says that for RSA only the modulus should be hashed -
          however, it is not clear wether this is meant to has the raw
          bytes assuming this is an unsigned integer or whether the DER
-         required 0 should be prefixed. We hash th raw bytes.  For
+         required 0 should be prefixed. We hash the raw bytes.  For
          non-RSA we hash S-expressions. */
       gcry_md_write (md, data, datalen);
       gcry_sexp_release (l2);
@@ -2138,10 +2159,11 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
       if (! array)
         goto fail;
     }
+
   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
   gcry_md_close (md);
   gcry_sexp_release (list);
-   return array;
+  return array;
 
  fail:
   if (l2)
@@ -2163,11 +2185,10 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
   switch (cmd)
     {
     case GCRYCTL_DISABLE_ALGO:
-      /* this one expects a buffer pointing to an integer with the
-       * algo number.
-       */
+      /* This one expects a buffer pointing to an integer with the
+         algo number.  */
       if ((! buffer) || (buflen != sizeof (int)))
-       err = GPG_ERR_CIPHER_ALGO;  /* FIXME?  */
+       err = GPG_ERR_INV_ARG;
       else
        disable_pubkey_algo (*((int *) buffer));
       break;
@@ -2180,26 +2201,25 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
 }
 
 
-/****************
- * Return information about the given algorithm
- * WHAT select the kind of information returned:
- *  GCRYCTL_TEST_ALGO:
- *     Returns 0 when the specified algorithm is available for use.
- *     Buffer must be NULL, nbytes  may have the address of a variable
- *     with the required usage of the algorithm. It may be 0 for don't
- *     care or a combination of the GCRY_PK_USAGE_xxx flags;
- *  GCRYCTL_GET_ALGO_USAGE:
- *      Return the usage glafs for the give algo.  An invalid alog
- *      does return 0.  Disabled algos are ignored here becuase we
- *      only want to know whether the algo is at all capable of
- *      the usage.
- *
- * Note:  Because this function is in most cases used to return an
- * integer value, we can make it easier for the caller to just look at
- * the return value.  The caller will in all cases consult the value
- * and thereby detecting whether a error occured or not (i.e. while checking
- * the block size)
- */
+/*
+   Return information about the given algorithm
+   WHAT select the kind of information returned:
+    GCRYCTL_TEST_ALGO:
+        Returns 0 when the specified algorithm is available for use.
+        Buffer must be NULL, nbytes  may have the address of a variable
+        with the required usage of the algorithm. It may be 0 for don't
+        care or a combination of the GCRY_PK_USAGE_xxx flags;
+    GCRYCTL_GET_ALGO_USAGE:
+        Return the usage glafs for the give algo.  An invalid alog
+        does return 0.  Disabled algos are ignored here becuase we
+        only want to know whether the algo is at all capable of
+        the usage.
+  
+   Note: Because this function is in most cases used to return an
+   integer value, we can make it easier for the caller to just look at
+   the return value.  The caller will in all cases consult the value
+   and thereby detecting whether a error occured or not (i.e. while
+   checking the block size) */
 gcry_error_t
 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
 {
@@ -2273,6 +2293,7 @@ gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
   return gcry_error (err);
 }
 
+
 gcry_err_code_t
 _gcry_pk_init (void)
 {
@@ -2283,6 +2304,7 @@ _gcry_pk_init (void)
   return err;
 }
 
+
 gcry_err_code_t
 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
 {
@@ -2302,6 +2324,7 @@ _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
   return err;
 }
 
+
 void
 _gcry_pk_module_release (gcry_module_t module)
 {