Editorial changes and allow building with old libgcrypts.
authorWerner Koch <wk@gnupg.org>
Fri, 21 Jan 2011 11:00:57 +0000 (12:00 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 21 Jan 2011 11:00:57 +0000 (12:00 +0100)
Changed order of some conditional to make to put the special case into
the true branch.  Indentation changes.  Minor other changes to make the
ECC code more similar to the rest of our code.

It builds but many sefltests still fail.  Need to fix that before
using it with an ECDH enabled libgcrypt.

[/]
2011-01-21  Werner Koch  <wk@g10code.com>

* configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP.
(HAVE_GCRY_PK_ECDH): Add new test.

[agent/]
2011-01-21  Werner Koch  <wk@g10code.com>

* cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New.

[include/]
2011-01-21  Werner Koch  <wk@g10code.com>

* cipher.h (GCRY_PK_USAGE_CERT): Remove compatibility macros
because we now require libgcrypt 1.4.6.
(GCRY_PK_ECDH): Add replacement.

29 files changed:
ChangeLog
agent/ChangeLog
agent/cvt-openpgp.c
agent/gpg-agent.c
agent/protect.c
common/convert.c
configure.ac
dirmngr/Makefile.am
g10/armor.c
g10/build-packet.c
g10/ecdh.c
g10/encrypt.c
g10/export.c
g10/gpg.c
g10/keygen.c
g10/keyid.c
g10/main.h
g10/misc.c
g10/parse-packet.c
g10/pkglue.c
g10/pkglue.h
g10/pubkey-enc.c
g10/seskey.c
g10/sign.c
g10/verify-stubs.c
g13/utils.c
include/ChangeLog
include/cipher.h
kbx/keybox-openpgp.c

index 656fe72..287e4d1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Need Libgcrypt 1.4.6 due to AESWRAP.
+       (HAVE_GCRY_PK_ECDH): Add new test.
+
 2011-01-03  Werner Koch  <wk@g10code.com>
 
        * README.SVN:  Rename to README.GIT.
index ce1fdcc..6992827 100644 (file)
@@ -1,3 +1,7 @@
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * cvt-openpgp.c (GCRY_PK_ECDH) [!HAVE_GCRY_PK_ECDH]: New.
+
 2010-12-02  Werner Koch  <wk@g10code.com>
 
        * gpg-agent.c (CHECK_OWN_SOCKET_INTERVAL) [W32CE]: Set to 60
index 73c31f7..02c2bc8 100644 (file)
 #include "i18n.h"
 #include "cvt-openpgp.h"
 
+/* Macros for compatibility with older libgcrypt versions. */
+#ifndef HAVE_GCRY_PK_ECDSA
+# define GCRY_PK_ECDH  302
+#endif
+
+
+
 
 /* Helper to pass data via the callback to do_unprotect. */
 struct try_do_unprotect_arg_s 
@@ -100,8 +107,8 @@ get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip)
 
 
 /* Convert a secret key given as algorithm id and an array of key
-   parameters into our s-expression based format. 
-   pubkey_algo is a libgcrypt ID
+   parameters into our s-expression based format.  Note that
+   PUBKEY_ALGO is a standard id and not an OpenPGP id.
  */
 static gpg_error_t
 convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
@@ -111,7 +118,8 @@ convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey)
 
   *r_key = NULL;
 
-  pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo );
+  /* FIXME: This is not consistent with the above comment.  */
+  pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
 
   switch (pubkey_algo)
     {
@@ -224,9 +232,9 @@ do_unprotect (const char *passphrase,
 
   *r_key = NULL;
 
- /* Unfortunately, the OpenPGP PK algorithm numbers need to be re-mapped for Libgcrypt
-  */
-  pubkey_algo = map_pk_openpgp_to_gcry( pubkey_algo );
+ /* Unfortunately, the OpenPGP PK algorithm numbers need to be
+    re-mapped for Libgcrypt.    */
+  pubkey_algo = map_pk_openpgp_to_gcry (pubkey_algo);
 
   /* Count the actual number of MPIs is in the array and set the
      remainder to NULL for easier processing later on.  */
@@ -655,7 +663,7 @@ convert_from_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp,
   string = gcry_sexp_nth_string (list, 1);
   if (!string)
     goto bad_seckey;
-  pubkey_algo = gcry_pk_map_name (string);     /* ligcrypt IDs */
+  pubkey_algo = gcry_pk_map_name (string);
   xfree (string);
 
   if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey)
@@ -1022,7 +1030,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
     }
   
   algo = gcry_pk_map_name (name);
-  log_debug ( "convert to openpgp begin for algo=%s\n", name );
   xfree (name);
 
   switch (algo)
@@ -1052,7 +1059,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
   err = apply_protection (array, npkey, nskey, passphrase,
                           GCRY_CIPHER_AES, protect_iv, sizeof protect_iv,
                           3, GCRY_MD_SHA1, salt, s2k_count);
-  ///log_debug ( "convert to openpgp: after applying protection, err = %d\n", err );
   /* Turn it into the transfer key S-expression.  Note that we always
      return a protected key.  */
   if (!err)
@@ -1082,8 +1088,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
       put_membuf_str (&mbuf, ")\n");
       put_membuf (&mbuf, "", 1);
 
-      ///log_debug ( "convert to openpgp: calling gcry_sexp_build\n" );
-
       tmpkey = NULL;
       {
         char *format = get_membuf (&mbuf, NULL);
@@ -1093,7 +1097,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
           err = gcry_sexp_build_array (&tmpkey, NULL, format, format_args);
         xfree (format);
       }
-      ///log_debug ( "convert to openpgp: calling gcry_sexp_build before err=%d\n", err );
       if (!err)
         err = gcry_sexp_build (&tmpsexp, NULL,
                                "(openpgp-private-key\n"
@@ -1106,7 +1109,6 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
                                (int)sizeof protect_iv, protect_iv,
                                (int)sizeof salt, salt,
                                countbuf);
-      ///log_debug ( "convert to openpgp: after gcry_sexp_build, err = %d\n", err );
       gcry_sexp_release (tmpkey);
       if (!err)
         err = make_canon_sexp_pad (tmpsexp, 0, r_transferkey, r_transferkeylen);
@@ -1116,8 +1118,5 @@ convert_to_openpgp (ctrl_t ctrl, gcry_sexp_t s_key, const char *passphrase,
   for (i=0; i < DIM (array); i++)
     gcry_mpi_release (array[i]);
 
-  log_debug ( "convert to openpgp end with err=%d\n", err );
-  
   return err;
 }
-
index d85283a..db90392 100644 (file)
@@ -2304,6 +2304,8 @@ check_for_running_agent (int silent, int mode)
 }
 
 /* TODO: it is also in misc, which is not linked with the agent */
+/* FIXME: The agent should not know about openpgp internals - weel
+   except for some stuff in cvt-openpgp.  */
 int
 map_pk_openpgp_to_gcry (int algo)
 {
index d146653..d0a5fe9 100644 (file)
@@ -43,7 +43,7 @@
 
 
 /* A table containing the information needed to create a protected
-   private key */
+   private key */
 static struct {
   const char *algo;
   const char *parmlist;
@@ -428,9 +428,6 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   unsigned char *p;
   gcry_md_hd_t md;
 
-  if (opt.debug & DBG_CRYPTO_VALUE)
-   log_info ("Protecting key=%s, passphrase=%s\n", plainkey, passphrase);
-
   /* Create an S-expression with the protected-at timestamp.  */
   memcpy (timestamp_exp, "(12:protected-at15:", 19);
   gnupg_get_isotime (timestamp_exp+19);
@@ -459,55 +456,41 @@ agent_protect (const unsigned char *plainkey, const char *passphrase,
   for (infidx=0; protect_info[infidx].algo
               && !smatch (&s, n, protect_info[infidx].algo); infidx++)
     ;
-  if (!protect_info[infidx].algo)  {
-    log_info ("Unsupported alg %d for protection\n", protect_info[infidx].algo);
+  if (!protect_info[infidx].algo)
     return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); 
-  }
 
   prot_begin = prot_end = NULL;
   for (i=0; (c=protect_info[infidx].parmlist[i]); i++)
     {
       if (i == protect_info[infidx].prot_from)
         prot_begin = s;
-      if (*s != '(')  {
-        log_info ("Unbalanced bracket in S-expression #1\n");
+      if (*s != '(')
         return gpg_error (GPG_ERR_INV_SEXP);
-      }
       depth++;
       s++;
       n = snext (&s);
-      if (!n)  {
-        log_info ("Cannot get the length of S-expression field\n");
+      if (!n)
         return gpg_error (GPG_ERR_INV_SEXP); 
-      }
-      if (n != 1 || c != *s)  {
-        log_info ("Invalid length in S-expression field\n");
+      if (n != 1 || c != *s)
         return gpg_error (GPG_ERR_INV_SEXP); 
-     } 
-     s += n;
+      s += n;
       n = snext (&s);
-      if (!n)  {
-        log_info ("Invalid fieled in S-expression field\n");
+      if (!n)
         return gpg_error (GPG_ERR_INV_SEXP); 
-      }
       s +=n; /* skip value */
-      if (*s != ')')  {
-        log_info ("Unbalanced bracket in S-expression #2\n");
+      if (*s != ')')
         return gpg_error (GPG_ERR_INV_SEXP); 
-      }
       depth--;
       if (i == protect_info[infidx].prot_to)
         prot_end = s;
       s++;
     }
-  if (*s != ')' || !prot_begin || !prot_end )  {
-    log_info ("Unbalanced bracket in S-expression #3\n");
+  if (*s != ')' || !prot_begin || !prot_end )
     return gpg_error (GPG_ERR_INV_SEXP); 
-  }
   depth--;
   hash_end = s;
   s++;
-  /* skip to the end of the S-exp */
+  /* Skip to the end of the S-expression.  */
   assert (depth == 1);
   rc = sskip (&s, &depth);
   if (rc)
index 0a0c46f..5df6b33 100644 (file)
@@ -23,7 +23,7 @@
 #include <ctype.h>
 
 #include "util.h"
-#include "gcrypt.h"
+#include "gcrypt.h"  /* FIXME: really needed?  */
 
 
 #define tohex(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'A'))
@@ -250,7 +250,10 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
  * caller must free with xfree 
  * Returns NULL on error, never throws
  */
-char *mpi2hex( gcry_mpi_t m )  {
+char *
+mpi2hex( gcry_mpi_t m )
+{
+#warning we have code for this in libcrypt
   size_t nbytes;
   size_t nbytes2;
   int rc;
@@ -270,7 +273,9 @@ char *mpi2hex( gcry_mpi_t m )  {
 
   bin2hex( p+2*nbytes+1, nbytes2, p );
   p[nbytes2*2] = '\0';
-//printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2, p[2*nbytes+1], p[2*nbytes+2], nbytes);
+  /*printf("%s:%d>>>> Created the string %s from %d bytes %02x %02x
+    ..., MPI was %d bytes\n", __FILE__, __LINE__, p, nbytes2,
+    p[2*nbytes+1], p[2*nbytes+2], nbytes); */
   return p;
 }    
 
index 575c1ec..ef6d2f9 100644 (file)
@@ -24,7 +24,7 @@ min_automake_version="1.10"
 # Remember to change the version number immediately *after* a release.
 # Set my_issvn to "yes" for non-released code.  Remember to run an
 # "svn up" and "autogen.sh" right before creating a distribution.
-m4_define([my_version], [2.2.0])
+m4_define([my_version], [2.1.0])
 m4_define([my_issvn], [yes])
 
 m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \
@@ -43,7 +43,7 @@ development_version=no
 NEED_GPG_ERROR_VERSION=1.8
 
 NEED_LIBGCRYPT_API=1
-NEED_LIBGCRYPT_VERSION=1.6.0
+NEED_LIBGCRYPT_VERSION=1.4.6
 
 NEED_LIBASSUAN_API=2
 NEED_LIBASSUAN_VERSION=2.0.0
@@ -724,6 +724,20 @@ AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION",
 AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION",
         have_libgcrypt=yes,have_libgcrypt=no)
 
+AC_CACHE_CHECK([whether Libgcrypt support ECDH], gnupg_cv_gcry_pk_ecdh,
+               [ _gnupg_gcry_save_cflags=$CFLAGS
+                 CFLAGS="$CFLAGS $LIBGCRYPT_CFLAGS"
+                 AC_TRY_COMPILE(
+                   [#include <gcrypt>],
+                   [ return GCRY_PK_ECDH; ],
+                   gnupg_cv_gcry_pk_ecdh=yes,
+                   gnupg_cv_gcry_pk_ecdh=no)
+                 CFLAGS=$_gnupg_gcry_save_cflags])
+if test "$gnupg_cv_gcry_pk_ecdh" = yes; then
+  AC_DEFINE([HAVE_GCRY_PK_ECDH], 1,
+            [Define if gcrypt.h has the enum value for ECDH.])
+fi
+
 
 #
 # libassuan is used for IPC
index 0285fc8..128d7c3 100644 (file)
@@ -61,7 +61,7 @@ endif
 dirmngr_LDADD = $(libcommonpth) ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \
        $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV)
 if !USE_LDAPWRAPPER
-dirmngr_LDADD += $(LDAPLIBS) -llber
+dirmngr_LDADD += $(LDAPLIBS) -llber  #FIXME:  Test for liblber first.
 endif
 dirmngr_LDFLAGS = $(extra_bin_ldflags)
 
index 8cfd35c..a6195fc 100644 (file)
@@ -1079,7 +1079,7 @@ armor_filter( void *opaque, int control,
            iobuf_writestr(a,afx->eol);
            if( !opt.no_version )
              {
-               iobuf_writestr(a, "Version: GnuPG v"  VERSION "-ecc ("
+               iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
                               PRINTABLE_OS_NAME ")" );
                iobuf_writestr(a,afx->eol);
              }
index 3a2c206..d138e06 100644 (file)
@@ -178,21 +178,20 @@ mpi_write (iobuf_t out, gcry_mpi_t a)
   return rc;
 }
 
-/*
- * Write the name OID, encoded as an mpi, to OUT. The format of the content of the MPI is
- * one byte LEN, following by LEN bytes that are DER representation of an ASN.1 OID. 
- * This is true for each of the 3 following functions.
- */
+/* Write the name OID, encoded as an mpi, to OUT. The format of the
+ * content of the MPI is one byte LEN, following by LEN bytes that are
+ * DER representation of an ASN.1 OID.  This is true for each of the 3
+ * following functions.   */
 #define iobuf_name_oid_write iobuf_write_size_body_mpi
+
 /* Write the value of KEK fields for ECDH.  */
 #define ecdh_kek_params_write iobuf_write_size_body_mpi
-/* Write the value of encrypted filed for ECDH. */
+
+/* Write the value of encrypted filed for ECDH.  */
 #define ecdh_esk_write iobuf_write_size_body_mpi
 
 
-/****************
- * calculate the length of a packet described by PKT
- */
+/* Calculate the length of a packet described by PKT.  */
 u32
 calc_packet_length( PACKET *pkt )
 {
@@ -300,24 +299,35 @@ do_key (iobuf_t out, int ctb, PKT_public_key *pk)
     }
   assert (npkey < nskey);
 
-  if( pk->pubkey_algo != PUBKEY_ALGO_ECDSA && pk->pubkey_algo != PUBKEY_ALGO_ECDH )  {
-    /* Writing the public parameters is easy, */
-    for (i=0; i < npkey; i++ )
-      if ((err = mpi_write (a, pk->pkey[i])))
-        goto leave;
-  }
-  else  {
-     /* ... except we do an adjustment for ECC OID and possibly KEK params for ECDH */
-    if( (err=iobuf_name_oid_write(a, pk->pkey[0])) || /* DER of OID with preceeding length byte */
-        (err = mpi_write (a, pk->pkey[1])) )    /* point Q, the public key */
+  /* Writing the public parameters is easy.  Except if we do an
+     adjustment for ECC OID and possibly KEK params for ECDH.  */
+  if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+      || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
     {
-       goto leave;
+      /* Write DER of OID with preceeding length byte.  */
+      err = iobuf_name_oid_write (a, pk->pkey[0]);
+      if (err)
+        goto leave;
+      /* Write point Q, the public key.  */
+      err = mpi_write (a, pk->pkey[1]);
+      if (err)
+        goto leave;
+
+      /* Write one more public field for ECDH.  */
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+        {
+          err = ecdh_kek_params_write(a,pk->pkey[2]);
+          if (err)
+            goto leave;
+        }
     }
-    if( pk->pubkey_algo == PUBKEY_ALGO_ECDH && (err=ecdh_kek_params_write(a,pk->pkey[2])))  {  /* one more public field for ECDH */
-       goto leave;
+  else
+    {
+      for (i=0; i < npkey; i++ )
+        if ((err = mpi_write (a, pk->pkey[i])))
+          goto leave;
     }
-    /* followed by possibly protected private scalar */
-  }
+
   
   if (pk->seckey_info)
     {
@@ -483,22 +493,25 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
   if ( !n )
     write_fake_data( a, enc->data[0] );
 
-  if( enc->pubkey_algo != PUBKEY_ALGO_ECDH )  {
-    for (i=0; i < n && !rc ; i++ )
-      rc = mpi_write(a, enc->data[i] );
-  }
-  else  {
-    /* the second field persists as a LEN+field structure, even though it is 
-     * stored for uniformity as an MPI internally */
-    assert( n==2 );
-    rc = mpi_write(a, enc->data[0] );
-    if( !rc ) rc = ecdh_esk_write(a, enc->data[1] ); 
-  }
+  if (enc->pubkey_algo == PUBKEY_ALGO_ECDH )
+    {
+      /* The second field persists as a LEN+field structure, even
+       * though it is stored for uniformity as an MPI internally.  */
+      assert (n == 2);
+      rc = mpi_write (a, enc->data[0]);
+      if (!rc)
+        rc = ecdh_esk_write (a, enc->data[1]); 
+    }
+  else
+    {
+      for (i=0; i < n && !rc ; i++ )
+        rc = mpi_write(a, enc->data[i] );
+    }
 
   if (!rc)
     {
-      write_header(out, ctb, iobuf_get_temp_length(a) );
-      rc = iobuf_write_temp( out, a );
+      write_header (out, ctb, iobuf_get_temp_length(a) );
+      rc = iobuf_write_temp (out, a);
     }
   iobuf_close(a);
   return rc;
index 091a28c..cb251fe 100644 (file)
@@ -1,5 +1,5 @@
 /* ecdh.c - ECDH public key operations used in public key glue code
- *     Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ *     Copyright (C) 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include "options.h"
 
 gcry_mpi_t
-pk_ecdh_default_params_to_mpi( int qbits )  {
+pk_ecdh_default_params_to_mpi (int qbits)
+{
   gpg_error_t err;
   gcry_mpi_t result;
-  /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */
+  /* Defaults are the strongest possible choices. Performance is not
+     an issue here, only interoperability.  */
   byte kek_params[4] = { 
        3       /*size of following field*/, 
        1       /*fixed version for KDF+AESWRAP*/, 
@@ -50,41 +52,49 @@ pk_ecdh_default_params_to_mpi( int qbits )  {
   } kek_params_table[] = {
     { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES    },
     { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 },
-    { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }    // 528 is 521 rounded to the 8 bit boundary
+
+    /* Note: 528 is 521 rounded to the 8 bit boundary */
+    { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }
   };
 
-  for( i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++ )  {
-    if( kek_params_table[i].qbits >= qbits )  {
-      kek_params[2] = kek_params_table[i].openpgp_hash_id;
-      kek_params[3] = kek_params_table[i].openpgp_cipher_id;
-      break;
+  for (i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++)
+    {
+      if (kek_params_table[i].qbits >= qbits)
+        {
+          kek_params[2] = kek_params_table[i].openpgp_hash_id;
+          kek_params[3] = kek_params_table[i].openpgp_cipher_id;
+          break;
+        }
     }
-  }
-  if( DBG_CIPHER )
-      log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) );
+  if (DBG_CIPHER)
+    log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) );
 
-  err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, kek_params, sizeof(kek_params), NULL);
+  err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG,
+                       kek_params, sizeof(kek_params), NULL);
   if (err)
     log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
 
   return result;
 }
 
-/* returns allocated (binary) KEK parameters; the size is returned in sizeout. 
- * The caller must free returned value with xfree. 
- * Returns NULL on error 
+
+/* Returns allocated (binary) KEK parameters; the size is returned in
+ * sizeout.  The caller must free the returned value with xfree.
+ * Returns NULL on error.
  */
 byte *
-pk_ecdh_default_params( int qbits, size_t *sizeout )  {
-  /* Defaults are the strongest possible choices. Performance is not an issue here, only interoperability. */
+pk_ecdh_default_params (int qbits, size_t *sizeout)
+{
+  /* Defaults are the strongest possible choices. Performance is not
+     an issue here, only interoperability. */
   byte kek_params[4] = { 
        3       /*size of following field*/, 
        1       /*fixed version for KDF+AESWRAP*/, 
        DIGEST_ALGO_SHA512      /* KEK MD */, 
-       CIPHER_ALGO_AES256      /*KEK AESWRAP alg*/
+       CIPHER_ALGO_AES256      /* KEK AESWRAP alg */
   };
   int i;
-
+  
   static const struct {
     int qbits;
     int openpgp_hash_id;
@@ -92,39 +102,48 @@ pk_ecdh_default_params( int qbits, size_t *sizeout )  {
   } kek_params_table[] = {
     { 256, DIGEST_ALGO_SHA256, CIPHER_ALGO_AES    },
     { 384, DIGEST_ALGO_SHA384, CIPHER_ALGO_AES256 },
-    { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }    // 528 is 521 rounded to the 8 bit boundary
+    /* Note: 528 is 521 rounded to the 8 bit boundary  */
+    { 528, DIGEST_ALGO_SHA512, CIPHER_ALGO_AES256 }    
   };
 
   byte *p;
 
   *sizeout = 0;
-
-  for( i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++ )  {
-    if( kek_params_table[i].qbits >= qbits )  {
-      kek_params[2] = kek_params_table[i].openpgp_hash_id;
-      kek_params[3] = kek_params_table[i].openpgp_cipher_id;
-      break;
+  
+  for (i=0; i<sizeof(kek_params_table)/sizeof(kek_params_table[0]); i++)
+    {
+      if (kek_params_table[i].qbits >= qbits)
+        {
+          kek_params[2] = kek_params_table[i].openpgp_hash_id;
+          kek_params[3] = kek_params_table[i].openpgp_cipher_id;
+          break;
+        }
     }
-  }
-  if( DBG_CIPHER )
-      log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params) );
+  if (DBG_CIPHER )
+    log_printhex ("ecdh kek params are", kek_params, sizeof(kek_params));
 
-  p = xtrymalloc( sizeof(kek_params) );
-  if( p == NULL )
+  p = xtrymalloc (sizeof(kek_params));
+  if (!p)
     return NULL;
-  memcpy( p, kek_params, sizeof(kek_params) );
+  memcpy (p, kek_params, sizeof(kek_params));
   *sizeout = sizeof(kek_params);
   return p;
 }
 
-/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC point using FIPS SP 800-56A compliant method, which is
- * key derivation + key wrapping. The direction is determined by the first parameter (is_encrypt=1 --> this is encryption).
- * The result is returned in out as a size+value MPI.
+
+/* Encrypts/decrypts 'data' with a key derived from shared_mpi ECC
+ * point using FIPS SP 800-56A compliant method, which is key
+ * derivation + key wrapping. The direction is determined by the first
+ * parameter (is_encrypt=1 --> this is encryption).  The result is
+ * returned in out as a size+value MPI.
+ *
  * TODO: memory leaks (x_secret).
  */
 static int
-pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi, 
-       const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey, gcry_mpi_t *out)
+pk_ecdh_encrypt_with_shared_point (int is_encrypt, gcry_mpi_t shared_mpi, 
+                                   const byte pk_fp[MAX_FINGERPRINT_LEN],
+                                   gcry_mpi_t data, gcry_mpi_t *pkey,
+                                   gcry_mpi_t *out)
 {
   byte *secret_x;
   int secret_x_size;
@@ -141,55 +160,70 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi,
 
   {
     size_t nbytes;
-    /* extract x component of the shared point: this is the actual shared secret */
+    /* Extract x component of the shared point: this is the actual
+       shared secret */
     nbytes = (mpi_get_nbits (pkey[1] /* public point */)+7)/8;
     secret_x = xmalloc_secure( nbytes );
-    rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes, &nbytes, shared_mpi);
-    if( rc )  {
-      xfree( secret_x );
-      log_error ("ec ephemeral export of shared point failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
+    rc = gcry_mpi_print (GCRYMPI_FMT_USG, secret_x, nbytes,
+                         &nbytes, shared_mpi);
+    if (rc)
+      {
+        xfree (secret_x);
+        log_error ("ec ephemeral export of shared point failed: %s\n",
+                   gpg_strerror (rc));
+        return rc;
+      }
     secret_x_size = (nbits+7)/8; 
-    assert( nbytes > secret_x_size );
-    memmove( secret_x, secret_x+1, secret_x_size );
-    memset( secret_x+secret_x_size, 0, nbytes-secret_x_size );
+    assert (nbytes > secret_x_size);
+    memmove (secret_x, secret_x+1, secret_x_size);
+    memset (secret_x+secret_x_size, 0, nbytes-secret_x_size);
 
-    if( DBG_CIPHER )
-        log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size );
+    if (DBG_CIPHER)
+      log_printhex ("ecdh shared secret X is:", secret_x, secret_x_size );
   }
 
-  /*** We have now the shared secret bytes in secret_x ***/
+  /*** We have now the shared secret bytes in secret_x. ***/
 
-  /* At this point we are done with PK encryption and the rest of the function uses symmetric 
-   *  key encryption techniques to protect the input 'data'. The following two sections will
-   *  simply replace current secret_x with a value derived from it. This will become a KEK. 
+  /* At this point we are done with PK encryption and the rest of the
+   * function uses symmetric key encryption techniques to protect the
+   * input 'data'.  The following two sections will simply replace
+   * current secret_x with a value derived from it.  This will become
+   * a KEK.
    */
   {
     IOBUF obuf = iobuf_temp(); 
     rc = iobuf_write_size_body_mpi ( obuf, pkey[2]  ); /* KEK params */
+    
+    kdf_params_size = iobuf_temp_to_buffer (obuf,
+                                            kdf_params, sizeof(kdf_params));
 
-    kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) );
-
-    if( DBG_CIPHER )
-        log_printhex ("ecdh KDF public key params are:", kdf_params, kdf_params_size );
+    if (DBG_CIPHER)
+      log_printhex ("ecdh KDF public key params are:",
+                    kdf_params, kdf_params_size );
 
-    if( kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1  )    /* expect 4 bytes  03 01 hash_alg symm_alg */
+    /* Expect 4 bytes  03 01 hash_alg symm_alg.  */
+    if (kdf_params_size != 4 || kdf_params[0] != 3 || kdf_params[1] != 1)      
       return GPG_ERR_BAD_PUBKEY;
 
     kdf_hash_algo = kdf_params[2];
     kdf_encr_algo = kdf_params[3];
 
-    if( DBG_CIPHER )
-      log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n", gcry_md_algo_name (kdf_hash_algo), openpgp_cipher_algo_name (kdf_encr_algo) );
+    if (DBG_CIPHER)
+      log_debug ("ecdh KDF algorithms %s+%s with aeswrap\n",
+                 gcry_md_algo_name (kdf_hash_algo),
+                 openpgp_cipher_algo_name (kdf_encr_algo));
 
-    if( kdf_hash_algo != GCRY_MD_SHA256 && kdf_hash_algo != GCRY_MD_SHA384 && kdf_hash_algo != GCRY_MD_SHA512 )
+    if (kdf_hash_algo != GCRY_MD_SHA256
+        && kdf_hash_algo != GCRY_MD_SHA384
+        && kdf_hash_algo != GCRY_MD_SHA512)
       return GPG_ERR_BAD_PUBKEY;
-    if( kdf_encr_algo != GCRY_CIPHER_AES128 && kdf_encr_algo != GCRY_CIPHER_AES192 && kdf_encr_algo != GCRY_CIPHER_AES256 )
+    if (kdf_encr_algo != GCRY_CIPHER_AES128
+        && kdf_encr_algo != GCRY_CIPHER_AES192
+        && kdf_encr_algo != GCRY_CIPHER_AES256)
       return GPG_ERR_BAD_PUBKEY;
   }
 
-  /* build kdf_params */
+  /* Build kdf_params.  */
   {
     IOBUF obuf;
 
@@ -205,13 +239,15 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi,
     /* fixed-length field 5, recipient fp */
     iobuf_write (obuf, pk_fp, 20);     
 
-    kdf_params_size = iobuf_temp_to_buffer( obuf, kdf_params, sizeof(kdf_params) );
-    iobuf_close( obuf );
-    if( rc )  {
+    kdf_params_size = iobuf_temp_to_buffer (obuf,
+                                            kdf_params, sizeof(kdf_params));
+    iobuf_close (obuf);
+    if (rc)
       return rc;
-    }
-    if( DBG_CIPHER )
-        log_printhex ("ecdh KDF message params are:", kdf_params, kdf_params_size );
+
+    if(DBG_CIPHER)
+      log_printhex ("ecdh KDF message params are:",
+                    kdf_params, kdf_params_size );
   }
 
   /* Derive a KEK (key wrapping key) using kdf_params and secret_x. */
@@ -231,7 +267,8 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi,
 
     assert( gcry_md_get_algo_dlen (kdf_hash_algo) >= 32 );
 
-    memcpy (secret_x, gcry_md_read (h, kdf_hash_algo), gcry_md_get_algo_dlen (kdf_hash_algo));
+    memcpy (secret_x, gcry_md_read (h, kdf_hash_algo),
+            gcry_md_get_algo_dlen (kdf_hash_algo));
     gcry_md_close (h);
 
     old_size = secret_x_size;
@@ -239,12 +276,13 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi,
     secret_x_size = gcry_cipher_get_algo_keylen( kdf_encr_algo );
     assert( secret_x_size <= gcry_md_get_algo_dlen (kdf_hash_algo) );
 
-    memset( secret_x+secret_x_size, old_size-secret_x_size, 0 );       /* we could have allocated more, so clean the tail before returning */
-    if( DBG_CIPHER )
+    /* We could have allocated more, so clean the tail before returning.  */
+    memset( secret_x+secret_x_size, old_size-secret_x_size, 0 );
+    if (DBG_CIPHER)
       log_printhex ("ecdh KEK is:", secret_x, secret_x_size );
-   }
-
-  /* And, finally, aeswrap with key secret_x */
+  }
+  
+  /* And, finally, aeswrap with key secret_x */
   {
     gcry_cipher_hd_t hd;
     size_t nbytes;
@@ -256,115 +294,134 @@ pk_ecdh_encrypt_with_shared_point ( int is_encrypt, gcry_mpi_t shared_mpi,
 
     rc = gcry_cipher_open (&hd, kdf_encr_algo, GCRY_CIPHER_MODE_AESWRAP, 0);
     if (rc)
-    {
-      log_error( "ecdh failed to initialize AESWRAP: %s\n", gpg_strerror (rc));
-      return rc;
-    }
+      {
+        log_error ("ecdh failed to initialize AESWRAP: %s\n",
+                   gpg_strerror (rc));
+        return rc;
+      }
 
     rc = gcry_cipher_setkey (hd, secret_x, secret_x_size);
     xfree( secret_x );
     if (rc)
-    {
-      gcry_cipher_close (hd);
-      log_error("ecdh failed in gcry_cipher_setkey: %s\n", gpg_strerror (rc));
-      return rc;
-    }
-
-    data_buf_size = (gcry_mpi_get_nbits(data)+7)/8;
-    assert( (data_buf_size & 7) == (is_encrypt ? 0 : 1) );
-
-    data_buf = xmalloc_secure( 1 + 2*data_buf_size + 8 );
-    if( !data_buf )  {
-      gcry_cipher_close (hd);
-      return GPG_ERR_ENOMEM;
-    }
-
-    if( is_encrypt )  {
-      byte *in = data_buf+1+data_buf_size+8;
-
-      /* write data MPI into the end of data_buf. data_buf is  size aeswrap data */
-      rc = gcry_mpi_print (GCRYMPI_FMT_USG, in, data_buf_size, &nbytes, data/*in*/);
-      if( rc )   {
-        log_error("ecdh failed to export DEK: %s\n", gpg_strerror (rc));
+      {
         gcry_cipher_close (hd);
-        xfree( data_buf );
+        log_error ("ecdh failed in gcry_cipher_setkey: %s\n",
+                   gpg_strerror (rc));
         return rc;
       }
 
-      if( DBG_CIPHER )
-         log_printhex ("ecdh encrypting  :", in, data_buf_size );
+    data_buf_size = (gcry_mpi_get_nbits(data)+7)/8;
+    assert ((data_buf_size & 7) == (is_encrypt ? 0 : 1));
 
-      rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8, in, data_buf_size);
-      memset( in, 0, data_buf_size);
-      gcry_cipher_close (hd);
-      if(rc)
+    data_buf = xtrymalloc_secure( 1 + 2*data_buf_size + 8);
+    if (!data_buf)
       {
-        log_error("ecdh failed in gcry_cipher_encrypt: %s\n", gpg_strerror (rc));
-        xfree( data_buf );
-        return rc;
+        gcry_cipher_close (hd);
+        return GPG_ERR_ENOMEM;
       }
-      data_buf[0] = data_buf_size+8;
-
-      if( DBG_CIPHER )
-         log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] );
 
-      rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, data_buf, 1+data_buf[0], NULL); /* (byte)size + aeswrap of DEK */
-      xfree( data_buf );
-      if(rc)
+    if (is_encrypt)
       {
-        log_error("ecdh failed to create an MPI: %s\n", gpg_strerror (rc));
-        return rc;
-      }
-
-      *out = result;
-    }
-    else  {
-      byte *in;
+        byte *in = data_buf+1+data_buf_size+8;
+        
+        /* Write data MPI into the end of data_buf. data_buf is size
+           aeswrap data.  */
+        rc = gcry_mpi_print (GCRYMPI_FMT_USG, in,
+                             data_buf_size, &nbytes, data/*in*/);
+        if (rc)
+          {
+            log_error ("ecdh failed to export DEK: %s\n", gpg_strerror (rc));
+            gcry_cipher_close (hd);
+            xfree (data_buf);
+            return rc;
+          }
+        
+        if (DBG_CIPHER)
+          log_printhex ("ecdh encrypting  :", in, data_buf_size );
+
+        rc = gcry_cipher_encrypt (hd, data_buf+1, data_buf_size+8,
+                                  in, data_buf_size);
+        memset (in, 0, data_buf_size);
+        gcry_cipher_close (hd);
+        if (rc)
+          {
+            log_error ("ecdh failed in gcry_cipher_encrypt: %s\n",
+                       gpg_strerror (rc));
+            xfree (data_buf);
+            return rc;
+          }
+        data_buf[0] = data_buf_size+8;
+
+        if (DBG_CIPHER)
+         log_printhex ("ecdh encrypted to:", data_buf+1, data_buf[0] );
 
-      rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size, &nbytes, data/*in*/);
-      if( nbytes != data_buf_size || data_buf[0] != data_buf_size-1 )  {
-        log_error("ecdh inconsistent size\n");
+        rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG,
+                            data_buf, 1+data_buf[0], NULL); 
+        /* (byte)size + aeswrap of DEK */
         xfree( data_buf );
-        return GPG_ERR_BAD_MPI;
+        if (rc)
+          {
+            log_error ("ecdh failed to create an MPI: %s\n", gpg_strerror (rc));
+            return rc;
+          }
+        
+        *out = result;
       }
+    else
+      {
+        byte *in;
+        
+        rc = gcry_mpi_print (GCRYMPI_FMT_USG, data_buf, data_buf_size,
+                             &nbytes, data/*in*/);
+      if (nbytes != data_buf_size || data_buf[0] != data_buf_size-1)
+        {
+          log_error ("ecdh inconsistent size\n");
+          xfree (data_buf);
+          return GPG_ERR_BAD_MPI;
+        }
       in = data_buf+data_buf_size;
       data_buf_size = data_buf[0];
-
-      if( DBG_CIPHER )
-         log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size );
       
-      rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1, data_buf_size );
+      if (DBG_CIPHER)
+        log_printhex ("ecdh decrypting :", data_buf+1, data_buf_size);
+      
+      rc = gcry_cipher_decrypt (hd, in, data_buf_size, data_buf+1,
+                                data_buf_size);
       gcry_cipher_close (hd);
-      if(rc)
-      {
-        log_error("ecdh failed in gcry_cipher_decrypt: %s\n", gpg_strerror (rc));
-        xfree( data_buf );
-        return rc;
-      }
-
-      data_buf_size-=8;
-
-      if( DBG_CIPHER )
-         log_printhex ("ecdh decrypted to :", in, data_buf_size );
-
-      /* padding is removed later */
-      //if( in[data_buf_size-1] > 8 )  {
-      //  log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", in[data_buf_size-1] );
-      //  return GPG_ERR_BAD_KEY;
-      //}
+      if (rc)
+        {
+          log_error ("ecdh failed in gcry_cipher_decrypt: %s\n",
+                     gpg_strerror (rc));
+          xfree (data_buf);
+          return rc;
+        }
+
+      data_buf_size -= 8;
+
+      if (DBG_CIPHER)
+        log_printhex ("ecdh decrypted to :", in, data_buf_size);
+
+      /* Padding is removed later.  */
+      /* if (in[data_buf_size-1] > 8 ) */
+      /*   { */
+      /*     log_error("ecdh failed at decryption: invalid padding. %02x > 8\n", */
+      /*               in[data_buf_size-1] ); */
+      /*     return GPG_ERR_BAD_KEY; */
+      /*   } */
  
       rc = gcry_mpi_scan ( &result, GCRYMPI_FMT_USG, in, data_buf_size, NULL);
-      xfree( data_buf );
-      if(rc)
-      {
-        log_error("ecdh failed to create a plain text MPI: %s\n", gpg_strerror (rc));
-        return rc;
-      }
-
+      xfree (data_buf);
+      if (rc)
+        {
+          log_error ("ecdh failed to create a plain text MPI: %s\n",
+                     gpg_strerror (rc));
+          return rc;
+        }
+      
       *out = result;
-    }
+      }
   }
-
+  
   return rc;
 }
 
@@ -380,21 +437,22 @@ gen_k (unsigned nbits)
 
   gcry_mpi_randomize (k, nbits-1, GCRY_STRONG_RANDOM);
 
-  if( DBG_CIPHER )  {
-       unsigned char *buffer;
-       if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k))
-          BUG ();
-        log_debug("ephemeral scalar MPI #0: %s\n", buffer);
-       gcry_free( buffer );
-  }
+  if (DBG_CIPHER)
+    {
+      unsigned char *buffer;
+      if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, k))
+        BUG ();
+      log_debug("ephemeral scalar MPI #0: %s\n", buffer);
+      gcry_free( buffer );
+    }
 
   return k;
 }
 
-/* Perform ECDH encryption, which involves ECDH key generation.
- */
+/* Perform ECDH encryption, which involves ECDH key generation.  */
 int
-pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey)
+pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN],
+                 gcry_mpi_t data, gcry_mpi_t * pkey)
 {
   gcry_sexp_t s_ciph, s_data, s_pkey;
 
@@ -402,9 +460,9 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr
   int rc;
   gcry_mpi_t k;
 
-  nbits = pubkey_nbits( PUBKEY_ALGO_ECDH, pkey );
+  nbits = pubkey_nbits (PUBKEY_ALGO_ECDH, pkey);
 
-  /*** Generate an ephemeral key, actually, a scalar ***/
+  /*** Generate an ephemeral key, actually, a scalar. ***/
 
   k = gen_k (nbits);
   if( k == NULL )
@@ -414,50 +472,63 @@ pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcr
    * Now use ephemeral secret to get the shared secret. ***/
 
   rc = gcry_sexp_build (&s_pkey, NULL,
-                   "(public-key(ecdh(c%m)(q%m)(p%m)))", pkey[0], pkey[1], pkey[2]);
+                        "(public-key(ecdh(c%m)(q%m)(p%m)))",
+                        pkey[0], pkey[1], pkey[2]);
   if (rc)
     BUG ();
  
-  /* put the data into a simple list */
-  if (gcry_sexp_build (&s_data, NULL, "%m", k))        /* ephemeral scalar goes as data */
+  /* Put the data into a simple list. */
+  /* Ephemeral scalar goes as data.  */
+  if (gcry_sexp_build (&s_data, NULL, "%m", k))
     BUG ();
 
-  /* pass it to libgcrypt */
+  /* Pass it to libgcrypt. */
   rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
   gcry_sexp_release (s_data);
   gcry_sexp_release (s_pkey);
   if (rc)
     return rc;
 
-  /* finally, perform encryption */
+  /* Finally, perform encryption.  */
 
   {
-    gcry_mpi_t shared = mpi_from_sexp (s_ciph, "a");           /* ... and get the shared point */
+    /* ... and get the shared point/ */
+    gcry_mpi_t shared;
+
+    shared = mpi_from_sexp (s_ciph, "a"); 
     gcry_sexp_release (s_ciph);
-    resarr[0] = mpi_from_sexp (s_ciph, "b");                   /* ephemeral public key */
+    /* Ephemeral public key. */
+    resarr[0] = mpi_from_sexp (s_ciph, "b");
 
-    if( DBG_CIPHER )  {
+    if (DBG_CIPHER)
+      {
        unsigned char *buffer;
+
        if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, resarr[0]))
           BUG ();
         log_debug("ephemeral key MPI: %s\n", buffer);
        gcry_free( buffer );
-    }
-
-    rc = pk_ecdh_encrypt_with_shared_point ( 1 /*=encrypton*/, shared, pk_fp, data, pkey, resarr+1 );
-    mpi_release( shared );
+      }
+    
+    rc = pk_ecdh_encrypt_with_shared_point (1 /*=encrypton*/, shared,
+                                            pk_fp, data, pkey, resarr+1);
+    mpi_release (shared);
   }
-
+  
   return rc;
 }
 
-/* Perform ECDH decryption. 
- */
+
+/* Perform ECDH decryption.   */
 int
-pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey)  {
+pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN],
+                 gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey)
+{
   if (!data)
     return gpg_error (GPG_ERR_BAD_MPI);
-  return pk_ecdh_encrypt_with_shared_point ( 0 /*=decryption*/, shared, sk_fp, data/*encr data as an MPI*/, skey, result );
+  return pk_ecdh_encrypt_with_shared_point (0 /*=decryption*/, shared,
+                                            sk_fp, data/*encr data as an MPI*/,
+                                            skey, result);
 }
 
 
index 3c16309..f529215 100644 (file)
@@ -894,8 +894,8 @@ write_pubkey_enc_from_list (PK_LIST pk_list, DEK *dek, iobuf_t out)
           compliance_failure();
         }
 
-      fingerprint_from_pk( pk, fp, &fpn );
-      assert( fpn == 20 );
+      fingerprint_from_pk (pk, fp, &fpn);
+      assert (fpn == 20);
 
       /* Okay, what's going on: We have the session key somewhere in
        * the structure DEK and want to encode this session key in an
index 82d9751..74a7b0c 100644 (file)
@@ -1161,18 +1161,16 @@ build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
   /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
   /*     (*indent)--; */
   /*   } */
-/*
-  else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(ecdsa\n");
-      (*indent)++; 
-      write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "d", sk->skey[7]);
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-*/
+  /* else if (sk->pubkey_algo == PUBKEY_ALGO_ECDSA && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(ecdsa\n"); */
+  /*     (*indent)++;  */
+  /*     write_sexp_keyparm (out, indent, "c", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[6]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "d", sk->skey[7]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
   /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
   /*   { */
   /*     write_sexp_line (out, indent, "(elg\n"); */
index 23b1934..3794aa2 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -813,7 +813,7 @@ my_strusage( int level )
   const char *p;
 
     switch( level ) {
-      case 11: p = "gpg (GnuPG) ecc";
+      case 11: p = "gpg (GnuPG)";
        break;
       case 13: p = VERSION; break;
       case 17: p = PRINTABLE_OS_NAME; break;
index f7f1526..e75da79 100644 (file)
@@ -18,6 +18,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#warning wk: check these changes.
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,7 +44,6 @@
 #include "keyserver-internal.h"
 #include "call-agent.h"
 #include "pkglue.h"
-#include "gcrypt.h"
 
 /* The default algorithms.  If you change them remember to change them
    also in gpg.c:gpgconf_list.  You should also check that the value
index 2a9bd19..0405b8b 100644 (file)
@@ -54,11 +54,11 @@ pubkey_letter( int algo )
     case PUBKEY_ALGO_RSA:      return 'R' ;
     case PUBKEY_ALGO_RSA_E:    return 'r' ;
     case PUBKEY_ALGO_RSA_S:    return 's' ;
-    case PUBKEY_ALGO_ELGAMAL_E: return 'g';
+    case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
     case PUBKEY_ALGO_ELGAMAL:   return 'G' ;
     case PUBKEY_ALGO_DSA:      return 'D' ;
-    case PUBKEY_ALGO_ECDSA:    return 'E' ;    // ECC DSA (sign only)
-    case PUBKEY_ALGO_ECDH:     return 'e' ;    // ECC DH (encrypt only)
+    case PUBKEY_ALGO_ECDSA:    return 'E' ;    /* ECC DSA (sign only)   */
+    case PUBKEY_ALGO_ECDH:     return 'e' ;    /* ECC DH (encrypt only) */
     default: return '?';
     }
 }
@@ -76,8 +76,6 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
   unsigned int nbits;
   size_t nbytes;
   int npkey = pubkey_get_npkey (pk->pubkey_algo);
-  /* name OID, MPI of public point, [for ECDH only: KEK params] */
-  enum gcry_mpi_format ecc_pub_format[3] = {GCRYMPI_FMT_USG, GCRYMPI_FMT_PGP, GCRYMPI_FMT_USG};
 
   /* Two extra bytes for the expiration date in v3 */
   if(pk->version<4)
@@ -92,11 +90,17 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
     }
   else
     {
-      for(i=0; i < npkey; i++ )
+      for (i=0; i < npkey; i++ )
         {
-         const enum gcry_mpi_format fmt = 
-            ((pk->pubkey_algo==PUBKEY_ALGO_ECDSA || pk->pubkey_algo==PUBKEY_ALGO_ECDH) ? ecc_pub_format[i] : GCRYMPI_FMT_PGP);
-
+         enum gcry_mpi_format fmt;
+          
+          if ((pk->pubkey_algo == PUBKEY_ALGO_ECDSA
+               || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
+              && (i == 0 || i == 2))
+            fmt = GCRYMPI_FMT_USG; /* Name of OID or KEK parms.  */
+          else
+            fmt = GCRYMPI_FMT_PGP;
+          
           if (gcry_mpi_print (fmt, NULL, 0, &nbytes, pk->pkey[i]))
             BUG ();
           pp[i] = xmalloc (nbytes);
@@ -106,7 +110,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
           n += nn[i];
         }
     }
-
+  
   gcry_md_putc ( md, 0x99 );     /* ctb */
   /* What does it mean if n is greater than than 0xFFFF ? */
   gcry_md_putc ( md, n >> 8 );   /* 2 byte length header */
@@ -724,13 +728,12 @@ keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
                              "(public-key(ecc(c%m)(q%m)))",
                              pk->pkey[0], pk->pkey[1]);
       break;
-/* 
-   case PUBKEY_ALGO_ECDH:
-      err = gcry_sexp_build (&s_pkey, NULL,
-                             "(public-key(ecdh(c%m)(q%m)(p%m)))",
-                             pk->pkey[0], pk->pkey[1], pk->pkey[2]);
-      break;
-*/
+
+   /* case PUBKEY_ALGO_ECDH: */
+   /*    err = gcry_sexp_build (&s_pkey, NULL, */
+   /*                           "(public-key(ecdh(c%m)(q%m)(p%m)))", */
+   /*                           pk->pkey[0], pk->pkey[1], pk->pkey[2]); */
+   /*    break; */
 
     default:
       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
index e336e5c..c7980ac 100644 (file)
@@ -87,9 +87,12 @@ u16 checksum_mpi( gcry_mpi_t a );
 u32 buffer_to_u32( const byte *buffer );
 const byte *get_session_marker( size_t *rlen );
 int map_cipher_openpgp_to_gcry (int algo);
-#define openpgp_cipher_open(_a,_b,_c,_d) gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
-#define openpgp_cipher_get_algo_keylen(_a) gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))
-#define openpgp_cipher_get_algo_blklen(_a) gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a)))
+#define openpgp_cipher_open(_a,_b,_c,_d) \
+  gcry_cipher_open((_a),map_cipher_openpgp_to_gcry((_b)),(_c),(_d))
+#define openpgp_cipher_get_algo_keylen(_a) \
+  gcry_cipher_get_algo_keylen(map_cipher_openpgp_to_gcry((_a)))
+#define openpgp_cipher_get_algo_blklen(_a) \
+  gcry_cipher_get_algo_blklen(map_cipher_openpgp_to_gcry((_a)))
 int openpgp_cipher_blocklen (int algo);
 int openpgp_cipher_test_algo( int algo );
 const char *openpgp_cipher_algo_name (int algo);
@@ -159,7 +162,8 @@ int pubkey_get_nenc( int algo );
 unsigned int pubkey_nbits( int algo, gcry_mpi_t *pkey );
 int mpi_print (estream_t stream, gcry_mpi_t a, int mode);
 int iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a);
-int iobuf_read_size_body(iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out);
+int iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size,
+                          int pktlen, gcry_mpi_t *out);
 
 int ecdsa_qbits_from_Q( int qbits );
 
@@ -258,7 +262,9 @@ int save_unprotected_key_to_card (PKT_public_key *sk, int keyno);
 
 #define KEYGEN_FLAG_NO_PROTECTION 1
 #define KEYGEN_FLAG_TRANSIENT_KEY 2
-int pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits);
+int pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo,
+                        int keygen_flags, char **cache_nonce_addr,
+                        unsigned nbits);
 
 /*-- openfile.c --*/
 int overwrite_filep( const char *fname );
index a09636b..6f77119 100644 (file)
@@ -1,6 +1,6 @@
 /* misc.c - miscellaneous functions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- *               2008, 2009 Free Software Foundation, Inc.
+ *               2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -366,10 +366,17 @@ map_cipher_gcry_to_openpgp (int algo)
     }
 }
 
+/* Map OpenPGP public key algorithm numbers to those used by
+   Libgcrypt.  */
 int
 map_pk_openpgp_to_gcry (int algo)
 {
-  return (algo==PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : (algo==PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo));
+  switch (algo)
+    {
+    case PUBKEY_ALGO_ECDSA: return GCRY_PK_ECDSA;
+    case PUBKEY_ALGO_ECDH:  return GCRY_PK_ECDH;
+    default: return algo;
+    }
 }
 
 
@@ -416,13 +423,7 @@ openpgp_cipher_test_algo( int algo )
 const char *
 openpgp_cipher_algo_name (int algo) 
 {
-  return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
-}
-
-const char *
-openpgp_pk_algo_name (int algo) 
-{
-  return gcry_pk_algo_name ( algo == PUBKEY_ALGO_ECDSA ? GCRY_PK_ECDSA : ( algo == PUBKEY_ALGO_ECDH ? GCRY_PK_ECDH : algo ) );
+  return gnupg_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
 }
 
 int
@@ -438,12 +439,7 @@ openpgp_pk_test_algo( int algo )
   if (algo < 0 || algo > 110)
     return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  if( algo == PUBKEY_ALGO_ECDSA )
-    algo = GCRY_PK_ECDSA;
-  else if( algo == PUBKEY_ALGO_ECDH )
-    algo = GCRY_PK_ECDH;
-
-  return gcry_pk_test_algo ( algo );
+  return gcry_pk_test_algo (map_pk_openpgp_to_gcry (algo));
 }
 
 int
@@ -461,12 +457,8 @@ openpgp_pk_test_algo2( int algo, unsigned int use )
   if (algo < 0 || algo > 110)
     return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  if( algo == PUBKEY_ALGO_ECDSA )
-    algo = GCRY_PK_ECDSA;
-  else if( algo == PUBKEY_ALGO_ECDH )
-    algo = GCRY_PK_ECDH;
-
-  return gcry_pk_algo_info ( algo, GCRYCTL_TEST_ALGO, NULL, &use_buf);
+  return gcry_pk_algo_info (map_pk_openpgp_to_gcry (algo),
+                            GCRYCTL_TEST_ALGO, NULL, &use_buf);
 }
 
 int 
@@ -507,10 +499,12 @@ openpgp_pk_algo_usage ( int algo )
 
 /* Map the OpenPGP pubkey algorithm whose ID is contained in ALGO to a
    string representation of the algorithm name.  For unknown algorithm
-   IDs this function returns "?".  
+   IDs this function returns "?".  */
 const char *
 openpgp_pk_algo_name (int algo) 
 {
+  /* We use fixed strings to have pretty names instead of those from
+     libgcrypt.  */
   switch (algo)
     {    
     case PUBKEY_ALGO_RSA:
@@ -522,10 +516,13 @@ openpgp_pk_algo_name (int algo)
 
     case PUBKEY_ALGO_DSA:  return "dsa";
 
-    default: return "?";
+    case PUBKEY_ALGO_ECDSA:return "ecdsa";
+
+    case PUBKEY_ALGO_ECDH: return "ecdh";
+
+    default: gcry_pk_algo_name (map_pk_openpgp_to_gcry (algo));
     }
 }
-*/
 
 
 int
@@ -1444,6 +1441,7 @@ pubkey_nbits( int algo, gcry_mpi_t *key )
     int rc, nbits;
     gcry_sexp_t sexp;
 
+#warning Why this assert
     assert( algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH );
 
     if( algo == GCRY_PK_DSA ) {
@@ -1506,10 +1504,12 @@ mpi_print (estream_t fp, gcry_mpi_t a, int mode)
   return n;
 }
 
+
 /*
- * Write a special size+body mpi a, to OUT. The format of the content of the MPI is
- * one byte LEN, following by LEN bytes 
+ * Write a special size+body mpi A, to OUT.  The format of the content
+ * of the MPI is one byte LEN, following by LEN bytes.
  */
+/* FIXME: Rename this function: it is not in iobuf.c */
 int
 iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a)
 {
@@ -1538,57 +1538,68 @@ iobuf_write_size_body_mpi (iobuf_t out, gcry_mpi_t a)
   return iobuf_write( out, buffer, nbytes );
 }
 
+
 /*
- * Read a special size+body from inp into body[body_max_size] and return it in a buffer and as MPI.
- * On success the number of consumed bytes will body[0]+1. 
- * The format of the content of the returned MPI is one byte LEN, following by LEN bytes.
- * Caller is expected to pre-allocate fixed-size 255 byte buffer (or smaller when appropriate).
+ * Read a special size+body from inp into body[body_max_size] and
+ * return it in a buffer and as MPI.  On success the number of
+ * consumed bytes will body[0]+1.  The format of the content of the
+ * returned MPI is one byte LEN, following by LEN bytes.  Caller is
+ * expected to pre-allocate fixed-size 255 byte buffer (or smaller
+ * when appropriate).
  */
+/* FIXME: Rename this function: it is not in iobuf.c */
 int
-iobuf_read_size_body( iobuf_t inp, byte *body, int body_max_size, int pktlen, gcry_mpi_t *out )  {
+iobuf_read_size_body (iobuf_t inp, byte *body, int body_max_size,
+                      int pktlen, gcry_mpi_t *out )
+{
   unsigned n;
   int rc;
   gcry_mpi_t result;
 
   *out = NULL;
 
-  if( (n = iobuf_readbyte(inp)) == -1 ) {
-    return G10ERR_INVALID_PACKET;
-  }
-  if( n >= body_max_size || n < 2)  {
-    log_error("invalid size+body field\n");
-    return G10ERR_INVALID_PACKET;
-  }
+  if( (n = iobuf_readbyte(inp)) == -1 )
+    {
+      return G10ERR_INVALID_PACKET;
+    }
+  if ( n >= body_max_size || n < 2)
+    {
+      log_error("invalid size+body field\n");
+      return G10ERR_INVALID_PACKET;
+    }
   body[0] = n; 
-  if( (n = iobuf_read(inp, body+1, n)) == -1 ) {
-    log_error("invalid size+body field\n");
-    return G10ERR_INVALID_PACKET;
-  }
-  if( n+1 > pktlen )  {
-    log_error("size+body field is larger than the packet\n");
-    return G10ERR_INVALID_PACKET;
-  }
+  if ((n = iobuf_read(inp, body+1, n)) == -1)
+    {
+      log_error("invalid size+body field\n");
+      return G10ERR_INVALID_PACKET;
+    }
+  if (n+1 > pktlen)
+    {
+      log_error("size+body field is larger than the packet\n");
+      return G10ERR_INVALID_PACKET;
+    }
   rc = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, body, n+1, NULL);
   if (rc)
     log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc));
-
+  
   *out = result;
-
+  
   return rc;
 }
 
 
-/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point, i.e.  04 <x> <y> */
-int ecdsa_qbits_from_Q( int qbits )  {
-       if( qbits%8>3 )  {
-               log_error(_("ECDSA public key is expected to be in SEC encoding multiple of 8 bits\n"));
-               return 0;
-       }
-       qbits -= qbits%8;
-       qbits /= 2;
-       return qbits;
+/* pkey[1] or skey[1] is Q for ECDSA, which is an uncompressed point,
+   i.e.  04 <x> <y> */
+int 
+ecdsa_qbits_from_Q (int qbits )
+{
+  if ((qbits%8) > 3)
+    {
+      log_error(_("ECDSA public key is expected to be in SEC encoding "
+                  "multiple of 8 bits\n"));
+      return 0;
+    }
+  qbits -= qbits%8;
+  qbits /= 2;
+  return qbits;
 }
-
-
-
-
index d43ab2c..5df336e 100644 (file)
@@ -939,40 +939,47 @@ parse_pubkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
     }
   else
     {
-      if( k->pubkey_algo != PUBKEY_ALGO_ECDH )  {
-        for (i = 0; i < ndata; i++)
-         {
-           n = pktlen;
-           k->data[i] = mpi_read (inp, &n, 0);
-           pktlen -= n;
-           if (list_mode)
-             {
-               es_fprintf (listfp, "\tdata: ");
-               mpi_print (listfp, k->data[i], mpi_print_mode);
-               es_putc ('\n', listfp);
-             }
-           if (!k->data[i])
-             rc = gpg_error (GPG_ERR_INV_PACKET);
-         }
-      }
-      else  
+      if (k->pubkey_algo == PUBKEY_ALGO_ECDH)
         {
-               byte encr_buf[255];
-               assert( ndata == 2 );
-               n = pktlen; k->data[0] = mpi_read(inp, &n, 0); pktlen -=n;
-               rc = iobuf_read_size_body( inp, encr_buf, sizeof(encr_buf), pktlen, k->data+1 );
-               if( rc )
-                       goto leave;
-               if( list_mode ) {
-                       es_fprintf (listfp, "\tdata: ");
-                       mpi_print(listfp, k->data[0], mpi_print_mode );
-                       es_putc ('\n', listfp);
-                       es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1);
-                       mpi_print(listfp, k->data[1], mpi_print_mode );
-                       es_putc ('\n', listfp);
-               }
-               pktlen -= (encr_buf[0]+1);
-      }
+          byte encr_buf[255];
+          
+          assert (ndata == 2);
+          n = pktlen;
+          k->data[0] = mpi_read (inp, &n, 0);
+          pktlen -= n;
+          rc = iobuf_read_size_body (inp, encr_buf, sizeof(encr_buf),
+                                     pktlen, k->data+1);
+          if (rc)
+            goto leave;
+
+          if (list_mode)
+            {
+              es_fprintf (listfp, "\tdata: ");
+              mpi_print (listfp, k->data[0], mpi_print_mode );
+              es_putc ('\n', listfp);
+              es_fprintf (listfp, "\tdata: [% 3d bytes] ", encr_buf[0]+1);
+              mpi_print (listfp, k->data[1], mpi_print_mode );
+              es_putc ('\n', listfp);
+            }
+          pktlen -= (encr_buf[0]+1);
+        }
+      else
+        {
+          for (i = 0; i < ndata; i++)
+            {
+              n = pktlen;
+              k->data[i] = mpi_read (inp, &n, 0);
+              pktlen -= n;
+              if (list_mode)
+                {
+                  es_fprintf (listfp, "\tdata: ");
+                  mpi_print (listfp, k->data[i], mpi_print_mode);
+                  es_putc ('\n', listfp);
+                }
+              if (!k->data[i])
+                rc = gpg_error (GPG_ERR_INV_PACKET);
+            }
+        }
     }
 
  leave:
@@ -1946,61 +1953,74 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
   else
     {
       /* Fill in public key parameters.  */
-      if( algorithm != PUBKEY_ALGO_ECDSA && algorithm != PUBKEY_ALGO_ECDH )  {
-        for (i = 0; i < npkey; i++)
-         {
-           n = pktlen;
-           pk->pkey[i] = mpi_read (inp, &n, 0);
-           pktlen -= n;
-           if (list_mode)
-             {
-               es_fprintf (listfp, "\tpkey[%d]: ", i);
-               mpi_print (listfp, pk->pkey[i], mpi_print_mode);
-               es_putc ('\n', listfp);
-             }
-           if (!pk->pkey[i])
-             err = gpg_error (GPG_ERR_INV_PACKET);
-         }
-      }
-      else  {
-            /* note that the code in this function ignores the errors */
-           byte name_oid[256];
-           err = iobuf_read_size_body( inp, name_oid, sizeof(name_oid), pktlen, pk->pkey+0 );
-           if( err )
-               goto leave;
-           n = name_oid[0];
-           if( list_mode )
-              es_fprintf (listfp,   "\tpkey[0]: curve OID [%d] ...%02x %02x\n", 
-                       n, name_oid[1+n-2], name_oid[1+n-1] );
-           pktlen -= (n+1);
-           /* set item [1], which corresponds to the public key; these two fields are all we need to uniquely define the key */
-           // log_debug("Parsing ecc public key in the public packet, pktlen=%lu\n", pktlen);
-           n = pktlen; pk->pkey[1] = mpi_read( inp, &n, 0 ); pktlen -=n;
-           if( pk->pkey[1]==NULL )
-               err = gpg_error(G10ERR_INVALID_PACKET);
-           else if( list_mode ) {
-               es_fprintf (listfp,   "\tpkey[1]: ");
-               mpi_print(listfp, pk->pkey[1], mpi_print_mode);
-               es_putc ('\n', listfp);
+      if (algorithm == PUBKEY_ALGO_ECDSA && algorithm == PUBKEY_ALGO_ECDH)
+        {
+          /* FIXME: The code in this function ignores the errors.  */
+          byte name_oid[256];
+          
+          err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid),
+                                      pktlen, pk->pkey+0);
+          if (err)
+            goto leave;
+          n = name_oid[0];
+          if (list_mode)
+            es_fprintf (listfp, "\tpkey[0]: curve OID [%d] ...%02x %02x\n", 
+                       n, name_oid[1+n-2], name_oid[1+n-1]);
+          pktlen -= (n+1);
+          /* Set item [1], which corresponds to the public key; these
+             two fields are all we need to uniquely define the key/ */
+          n = pktlen;
+          pk->pkey[1] = mpi_read( inp, &n, 0 );
+          pktlen -=n;
+          if (!pk->pkey[1])
+            err = gpg_error (GPG_ERR_INV_PACKET);
+          else if (list_mode)
+            {
+              es_fprintf (listfp, "\tpkey[1]: ");
+              mpi_print (listfp, pk->pkey[1], mpi_print_mode);
+              es_putc ('\n', listfp);
            }
-           /* One more field for ECDH */
-           if( algorithm == PUBKEY_ALGO_ECDH )  {
-#define kek_params name_oid
-              err = iobuf_read_size_body( inp, kek_params, sizeof(kek_params), pktlen, pk->pkey+2 );
-              if( err )
-                goto leave;
-              n = kek_params[0];
-              if( kek_params[1] != 1 ) {
-                       log_error("invalid ecdh KEK parameters field type in private key: understand type 1, but found 0x%02x\n", kek_params[1]);
-                       err = gpg_error(G10ERR_INVALID_PACKET);
-                       goto leave;
-              }
-              if( list_mode )
-                es_fprintf (listfp,   "\tpkey[2]: KEK params type=01 hash:%d sym-algo:%d\n", kek_params[1+n-2], kek_params[1+n-1] );
-              pktlen -= (n+1);
-#undef kek_params
-           }
-     }
+          /* One more field for ECDH. */
+          if (algorithm == PUBKEY_ALGO_ECDH)
+            {
+              /* (NAMEOID holds the KEK params.)  */
+              err = iobuf_read_size_body (inp, name_oid, sizeof(name_oid),
+                                          pktlen, pk->pkey+2);
+              if (err)
+                goto leave;
+              n = name_oid[0];
+              if (name_oid[1] != 1)
+                {
+                  log_error ("invalid ecdh KEK parameters field type in "
+                             "private key: understand type 1, "
+                             "but found 0x%02x\n", name_oid[1]);
+                  err = gpg_error (GPG_ERR_INV_PACKET);
+                  goto leave;
+                }
+              if (list_mode)
+                es_fprintf (listfp, "\tpkey[2]: KEK params type=01 "
+                            "hash:%d sym-algo:%d\n",
+                            name_oid[1+n-2], name_oid[1+n-1]);
+              pktlen -= (n+1);
+            }
+        }
+      else
+        {
+          for (i = 0; i < npkey; i++)
+            {
+              n = pktlen;
+              pk->pkey[i] = mpi_read (inp, &n, 0);
+              pktlen -= n;
+              if (list_mode)
+                {
+                  es_fprintf (listfp, "\tpkey[%d]: ", i);
+                  mpi_print (listfp, pk->pkey[i], mpi_print_mode);
+                  es_putc ('\n', listfp);
+                }
+              if (!pk->pkey[i])
+                err = gpg_error (GPG_ERR_INV_PACKET);
+            }
+        }
       if (err)
        goto leave;
     }
index 9050cc2..f5c8597 100644 (file)
@@ -1,5 +1,5 @@
 /* pkglue.c - public key operations glue code
- *     Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+ *     Copyright (C) 2000, 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -29,7 +29,8 @@
 #include "pkglue.h"
 #include "main.h"
 
-
+/* FIXME: Better chnage the fucntion name because mpi_ is used by
+   gcrypt macros.  */
 gcry_mpi_t
 mpi_from_sexp (gcry_sexp_t sexp, const char * item)
 {
@@ -45,101 +46,37 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item)
 }
 
 
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
-{
-  gcry_sexp_t s_sig, s_hash, s_skey;
-  int rc;
-  int gcry_pkalgo = map_pk_openpgp_to_gcry( algo );
-
-  /* make a sexp from skey */
-  if (gcry_pkalgo == GCRY_PK_DSA)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4]);
-    }
-  else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4],
-                           skey[5]);
-    }
-  else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3]);
-    }
-  else if (gcry_pkalgo == GCRY_PK_ECDSA)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(ecdsa(c%m)(q%m)(d%m)))",
-                           skey[0], skey[1], skey[2] );
-    }
-  else
-    return GPG_ERR_PUBKEY_ALGO;
-
-  if (rc)
-    BUG ();
-
-  /* put hash into a S-Exp s_hash */
-  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
-    BUG ();
-
-  rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
-  gcry_sexp_release (s_hash);
-  gcry_sexp_release (s_skey);
-
-  if (rc)
-    ;
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
-    data[0] = mpi_from_sexp (s_sig, "s");
-  else
-    {
-      data[0] = mpi_from_sexp (s_sig, "r");
-      data[1] = mpi_from_sexp (s_sig, "s");
-    }
-
-  gcry_sexp_release (s_sig);
-  return rc;
-}
 
 /****************
  * Emulate our old PK interface here - sometime in the future we might
  * change the internal design to directly fit to libgcrypt.
  */
 int
-pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
+pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey)
 {
   gcry_sexp_t s_sig, s_hash, s_pkey;
   int rc;
-  const int gcry_pkalgo = map_pk_openpgp_to_gcry( algo );
+  const int pkalgo = map_pk_openpgp_to_gcry (algo);
 
-  /* make a sexp from pkey */
-  if (gcry_pkalgo == GCRY_PK_DSA)
+  /* Make a sexp from pkey.  */
+  if (pkalgo == GCRY_PK_DSA)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
                            pkey[0], pkey[1], pkey[2], pkey[3]);
     }
-  else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E)
+  else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(elg(p%m)(g%m)(y%m)))",
                            pkey[0], pkey[1], pkey[2]);
     }
-  else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S)
+  else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]);
     }
-  else if (gcry_pkalgo == GCRY_PK_ECDSA)       /* same as GCRY_PK_ECDH */
+  else if (pkalgo == GCRY_PK_ECDSA) /* Same as GCRY_PK_ECDH */
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
                            "(public-key(ecdsa(c%m)(q%m)))", pkey[0], pkey[1]);
@@ -150,13 +87,13 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
   if (rc)
     BUG ();  /* gcry_sexp_build should never fail.  */
 
-  /* put hash into a S-Exp s_hash */
+  /* Put hash into a S-Exp s_hash. */
   if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
     BUG (); /* gcry_sexp_build should never fail.  */
 
   /* Put data into a S-Exp s_sig. */
   s_sig = NULL;
-  if (gcry_pkalgo == GCRY_PK_DSA)
+  if (pkalgo == GCRY_PK_DSA)
     {
       if (!data[0] || !data[1])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -164,7 +101,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
         rc = gcry_sexp_build (&s_sig, NULL,
                               "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
     }
-  else if (gcry_pkalgo == GCRY_PK_ECDSA)
+  else if (pkalgo == GCRY_PK_ECDSA)
     {
       if (!data[0] || !data[1])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -172,7 +109,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
         rc = gcry_sexp_build (&s_sig, NULL,
                               "(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]);
     }
-  else if (gcry_pkalgo == GCRY_PK_ELG || gcry_pkalgo == GCRY_PK_ELG_E)
+  else if (pkalgo == GCRY_PK_ELG || pkalgo == GCRY_PK_ELG_E)
     {
       if (!data[0] || !data[1])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -180,7 +117,7 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
         rc = gcry_sexp_build (&s_sig, NULL,
                               "(sig-val(elg(r%m)(s%m)))", data[0], data[1]);
     }
-  else if (gcry_pkalgo == GCRY_PK_RSA || gcry_pkalgo == GCRY_PK_RSA_S)
+  else if (pkalgo == GCRY_PK_RSA || pkalgo == GCRY_PK_RSA_S)
     {
       if (!data[0])
         rc = gpg_error (GPG_ERR_BAD_MPI);
@@ -207,12 +144,13 @@ pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t * data, gcry_mpi_t * pkey)
  * change the internal design to directly fit to libgcrypt.
  */
 int
-pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t * pkey)
+pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+            const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *pkey)
 {
   gcry_sexp_t s_ciph, s_data, s_pkey;
   int rc;
 
-  /* make a sexp from pkey */
+  /* Make a sexp from pkey.  */
   if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
     {
       rc = gcry_sexp_build (&s_pkey, NULL,
@@ -227,7 +165,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX
     }
   else if (algo == PUBKEY_ALGO_ECDH)   
     {
-      return pk_ecdh_encrypt( resarr, pk_fp, data, pkey );
+      return pk_ecdh_encrypt (resarr, pk_fp, data, pkey);
     }
   else
     return GPG_ERR_PUBKEY_ALGO;
@@ -235,11 +173,11 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX
   if (rc)
     BUG ();
 
-  /* put the data into a simple list */
+  /* Put the data into a simple list.  */
   if (gcry_sexp_build (&s_data, NULL, "%m", data))
     BUG ();
 
-  /* pass it to libgcrypt */
+  /* Pass it to libgcrypt. */
   rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
   gcry_sexp_release (s_data);
   gcry_sexp_release (s_pkey);
@@ -247,9 +185,11 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX
   if (rc)
     ;
   else
-    { /* add better error handling or make gnupg use S-Exp directly */
+    { /* Add better error handling or make gnupg use S-Exp directly.  */
       resarr[0] = mpi_from_sexp (s_ciph, "a");
-      if (algo != GCRY_PK_RSA && algo != GCRY_PK_RSA_E && algo != PUBKEY_ALGO_ECDH)
+      if (algo != GCRY_PK_RSA 
+          && algo != GCRY_PK_RSA_E
+          && algo != PUBKEY_ALGO_ECDH)
         resarr[1] = mpi_from_sexp (s_ciph, "b");
     }
 
@@ -257,6 +197,7 @@ pk_encrypt (int algo, gcry_mpi_t * resarr, gcry_mpi_t data, const byte pk_fp[MAX
   return rc;
 }
 
+
 /* Check whether SKEY is a suitable secret key. */
 int
 pk_check_secret_key (int algo, gcry_mpi_t *skey)
index a1c821d..0ceb43f 100644 (file)
@@ -1,5 +1,5 @@
 /* pkglue.h - public key operations definitions
- *     Copyright (C) 2003 Free Software Foundation, Inc.
+ *     Copyright (C) 2003, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 
 gcry_mpi_t mpi_from_sexp (gcry_sexp_t sexp, const char * item);
 
-int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash,
-             gcry_mpi_t *skey);
 int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
                gcry_mpi_t *pkey);
 int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
                const byte fp[MAX_FINGERPRINT_LEN],
                 gcry_mpi_t *pkey);
-int pk_decrypt (int algo, gcry_mpi_t *result, const byte fp[MAX_FINGERPRINT_LEN], gcry_mpi_t *data,
-                gcry_mpi_t *skey);
 int pk_check_secret_key (int algo, gcry_mpi_t *skey);
 
-int pk_ecdh_encrypt (gcry_mpi_t * resarr, const byte pk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t * pkey);
-int pk_ecdh_decrypt (gcry_mpi_t * result, const byte sk_fp[MAX_FINGERPRINT_LEN], gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey);
+int pk_ecdh_encrypt (gcry_mpi_t *resarr, const byte pk_fp[MAX_FINGERPRINT_LEN],
+                     gcry_mpi_t data, gcry_mpi_t * pkey);
+int pk_ecdh_decrypt (gcry_mpi_t *result, const byte sk_fp[MAX_FINGERPRINT_LEN],
+                     gcry_mpi_t data, gcry_mpi_t shared, gcry_mpi_t * skey);
 
-gcry_mpi_t pk_ecdh_default_params_to_mpi( int qbits );
-byte *pk_ecdh_default_params( int qbits, size_t *sizeout );
+gcry_mpi_t pk_ecdh_default_params_to_mpi (int qbits);
+byte *pk_ecdh_default_params (int qbits, size_t *sizeout);
 
 #endif /*GNUPG_G10_PKGLUE_H*/
index 24411e8..ddca41e 100644 (file)
@@ -218,68 +218,72 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
     log_printhex ("DEK frame:", frame, nframe);
   n = 0;
 
-  if( sk->pubkey_algo != PUBKEY_ALGO_ECDH )  {
-    if (!card)
-      {
-        if (n + 7 > nframe)
-          {
-            err = gpg_error (G10ERR_WRONG_SECKEY);
-            goto leave;
-          }
-        if (frame[n] == 1 && frame[nframe - 1] == 2)
-          {
-            log_info (_("old encoding of the DEK is not supported\n"));
-            err = gpg_error (G10ERR_CIPHER_ALGO);
-            goto leave;
-          }
-        if (frame[n] != 2) /* Something went wrong.  */
-          {
-            err = gpg_error (G10ERR_WRONG_SECKEY);
-            goto leave;
-          }
-        for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
-          ;
-        n++; /* Skip the zero byte.  */
-      }
-  }
-  else  {
-    gcry_mpi_t shared_mpi;
-    gcry_mpi_t decoded;
-
-    /* at the beginning the frame is the bytes of shared point MPI */
-     
-    err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
-    if (err)  {
-      log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
-      goto leave;
-    }
+  if (sk->pubkey_algo == PUBKEY_ALGO_ECDH)
+    {
+      gcry_mpi_t shared_mpi;
+      gcry_mpi_t decoded;
+      
+      /* At the beginning the frame are the bytes of shared point MPI.  */
+      err = gcry_mpi_scan (&shared_mpi, GCRYMPI_FMT_USG, frame, nframe, NULL);
+      if (err)
+        {
+          log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
+          goto leave;
+        }
 
-    err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/, shared_mpi, sk->pkey);
-    mpi_release( shared_mpi );
-    if( err )
-      goto leave;
+      err = pk_ecdh_decrypt (&decoded, fp, enc->data[1]/*encr data as an MPI*/,
+                             shared_mpi, sk->pkey);
+      mpi_release (shared_mpi);
+      if(err)
+        goto leave;
 
-    /* reuse nframe, which size is sufficient to include the session key */
-    err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
-    mpi_release( decoded );
-    if( err )
-      goto leave;
+      /* Reuse NFRAME, which size is sufficient to include the session key.  */
+      err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, decoded);
+      mpi_release (decoded);
+      if (err)
+        goto leave;
 
-    /* Now the frame is the bytes decrypted but padded session key  */
+      /* Now the frame are the bytes decrypted but padded session key.  */
 
-    /* Allow double padding for the benefit of DEK size concealment.
-     * Higher than this is wasteful.  
-     */
-    if( frame[nframe-1] > 8*2 || nframe <= 8 )  {
-      err = G10ERR_WRONG_SECKEY; goto leave; 
+      /* Allow double padding for the benefit of DEK size concealment.
+         Higher than this is wasteful. */
+      if (frame[nframe-1] > 8*2 || nframe <= 8)
+        {
+          err = gpg_error (GPG_ERR_WRONG_SECKEY);
+          goto leave; 
+        }
+      nframe -= frame[nframe-1]; /* Remove padding.  */
+      assert (n); /* (used just below) */
+    }
+  else
+    {
+      if (!card)
+        {
+          if (n + 7 > nframe)
+            {
+              err = gpg_error (GPG_ERR_WRONG_SECKEY);
+              goto leave;
+            }
+          if (frame[n] == 1 && frame[nframe - 1] == 2)
+            {
+              log_info (_("old encoding of the DEK is not supported\n"));
+              err = gpg_error (GPG_ERR_CIPHER_ALGO);
+              goto leave;
+            }
+          if (frame[n] != 2) /* Something went wrong.  */
+            {
+              err = gpg_error (GPG_ERR_WRONG_SECKEY);
+              goto leave;
+            }
+          for (n++; n < nframe && frame[n]; n++) /* Skip the random bytes.  */
+            ;
+          n++; /* Skip the zero byte.  */
+        }
     }
-    nframe -= frame[nframe-1]; /* remove padding */
-    assert( n==0 );    /* used just bellow */
-  }
 
   if (n + 4 > nframe)
     {
-      err = gpg_error (G10ERR_WRONG_SECKEY);
+      err = gpg_error (GPG_ERR_WRONG_SECKEY);
       goto leave;
     }
 
index e50cf5c..fa6765d 100644 (file)
@@ -1,6 +1,6 @@
 /* seskey.c -  make sesssion keys etc.
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2006, 2009 Free Software Foundation, Inc.
+ *               2006, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -76,109 +76,125 @@ make_session_key( DEK *dek )
 gcry_mpi_t
 encode_session_key (int openpgp_pk_algo, DEK *dek, unsigned int nbits)
 {
-    size_t nframe = (nbits+7) / 8;
-    byte *p;
-    byte *frame;
-    int i,n;
-    u16 csum = 0;
-    gcry_mpi_t a;
-
-    if( DBG_CIPHER )
-       log_debug("encode_session_key: encoding %d byte DEK", dek->keylen);
-
-    for( p = dek->key, i=0; i < dek->keylen; i++ )
-       csum += *p++;
-
-    /* Shortcut for ECDH. It's padding is minimal to simply make the output be a multiple of 8 bytes. */
-    if( openpgp_pk_algo == PUBKEY_ALGO_ECDH )  {
-       /* pad to 8 byte granulatiry; the padding byte is the number of padded bytes.
-        * A  DEK(k bytes)  CSUM(2 bytes) 0x 0x 0x 0x ... 0x
-        *                                +---- x times ---+
-        */
-       nframe = ( 1 + dek->keylen + 2 /* the value so far is always odd */ + 7 ) & (~7);
-       assert( !(nframe%8) && nframe > 1 + dek->keylen + 2 );  /* alg+key+csum fit and the size is congruent to 8 */
-       frame = xmalloc_secure( nframe );
-       n = 0;
-       frame[n++] = dek->algo;
-       memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
-       frame[n++] = csum >>8;
-       frame[n++] = csum;
-       i = nframe - n;         /* number padded bytes */
-       memset( frame+n, i, i );/* use it as the value of each padded byte */
-       assert( n+i == nframe );
-
-       if( DBG_CIPHER )
-               log_debug("encode_session_key: [%d] %02x  %02x %02x ...  %02x %02x %02x", nframe, frame[0],frame[1],frame[2], frame[nframe-3],frame[nframe-2],frame[nframe-1]);
-
-       if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, nframe, &nframe))
-               BUG();
-       xfree(frame);
-       return a;
+  size_t nframe = (nbits+7) / 8;
+  byte *p;
+  byte *frame;
+  int i,n;
+  u16 csum;
+  gcry_mpi_t a;
+  
+  if (DBG_CIPHER)
+    log_debug ("encode_session_key: encoding %d byte DEK", dek->keylen);
+
+  csum = 0;
+  for (p = dek->key, i=0; i < dek->keylen; i++)
+    csum += *p++;
+
+  /* Shortcut for ECDH.  It's padding is minimal to simply make the
+     output be a multiple of 8 bytes.  */
+  if (openpgp_pk_algo == PUBKEY_ALGO_ECDH)
+    {
+      /* Pad to 8 byte granulatiry; the padding byte is the number of
+       * padded bytes.
+       *
+       * A  DEK(k bytes)  CSUM(2 bytes) 0x 0x 0x 0x ... 0x
+       *                                +---- x times ---+
+       */
+      nframe = (( 1 + dek->keylen + 2 /* The value so far is always odd. */
+                  + 7 ) & (~7));
+      
+      /* alg+key+csum fit and the size is congruent to 8.  */
+      assert (!(nframe%8) && nframe > 1 + dek->keylen + 2 );
+      
+      frame = xmalloc_secure (nframe);
+      n = 0;
+      frame[n++] = dek->algo;
+      memcpy (frame+n, dek->key, dek->keylen);
+      n += dek->keylen;
+      frame[n++] = csum >> 8;
+      frame[n++] = csum;
+      i = nframe - n;         /* Number of padded bytes.  */
+      memset (frame+n, i, i); /* Use it as the value of each padded byte.  */
+      assert (n+i == nframe);
+
+      if (DBG_CIPHER)
+        log_debug ("encode_session_key: "
+                   "[%d] %02x  %02x %02x ...  %02x %02x %02x\n",
+                   nframe, frame[0], frame[1], frame[2],
+                   frame[nframe-3], frame[nframe-2], frame[nframe-1]);
+      
+      if (gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe))
+        BUG();
+      xfree(frame);
+      return a;
     }
-
-    /* The current limitation is that we can only use a session key
-     * whose length is a multiple of BITS_PER_MPI_LIMB
-     * I think we can live with that.
-     */
-    if( dek->keylen + 7 > nframe || !nframe )
-       log_bug("can't encode a %d bit key in a %d bits frame\n",
-                   dek->keylen*8, nbits );
-
-    /* We encode the session key in this way:
-     *
-     *    0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
-     *
-     * (But how can we store the leading 0 - the external representaion
-     * of MPIs doesn't allow leading zeroes =:-)
-     *
-     * RND are non-zero random bytes.
-     * A   is the cipher algorithm
-     * DEK is the encryption key (session key) length k depends on the
-     *    cipher algorithm (20 is used with blowfish160).
-     * CSUM is the 16 bit checksum over the DEK
-     */
-
-    frame = xmalloc_secure( nframe );
-    n = 0;
-    frame[n++] = 0;
-    frame[n++] = 2;
-    i = nframe - 6 - dek->keylen;
-    assert( i > 0 );
-    p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
-    /* Replace zero bytes by new values. */
-    for(;;) {
-       int j, k;
-       byte *pp;
-
-       /* count the zero bytes */
-       for(j=k=0; j < i; j++ )
-           if( !p[j] )
-               k++;
-       if( !k )
-           break; /* okay: no zero bytes */
-       k += k/128 + 3; /* better get some more */
-       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
-       for(j=0; j < i && k ;) {
-           if( !p[j] )
-               p[j] = pp[--k];
-            if (p[j])
-              j++;
+  
+  /* The current limitation is that we can only use a session key
+   * whose length is a multiple of BITS_PER_MPI_LIMB
+   * I think we can live with that.
+   */
+  if (dek->keylen + 7 > nframe || !nframe)
+    log_bug ("can't encode a %d bit key in a %d bits frame\n",
+             dek->keylen*8, nbits );
+  
+  /* We encode the session key in this way:
+   *
+   *      0  2  RND(n bytes)  0  A  DEK(k bytes)  CSUM(2 bytes)
+   *
+   * (But how can we store the leading 0 - the external representaion
+   *  of MPIs doesn't allow leading zeroes =:-)
+   *
+   * RND are non-zero random bytes.
+   * A   is the cipher algorithm
+   * DEK is the encryption key (session key) length k depends on the
+   *      cipher algorithm (20 is used with blowfish160).
+   * CSUM is the 16 bit checksum over the DEK
+   */
+
+  frame = xmalloc_secure( nframe );
+  n = 0;
+  frame[n++] = 0;
+  frame[n++] = 2;
+  i = nframe - 6 - dek->keylen;
+  assert( i > 0 );
+  p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+  /* Replace zero bytes by new values.  */
+  for (;;)
+    {
+      int j, k;
+      byte *pp;
+      
+      /* Count the zero bytes. */
+      for (j=k=0; j < i; j++ )
+        if (!p[j])
+          k++;
+      if (!k)
+        break; /* Okay: no zero bytes. */
+      k += k/128 + 3; /* Better get some more. */
+      pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+      for (j=0; j < i && k ;)
+        {
+          if (!p[j])
+            p[j] = pp[--k];
+          if (p[j])
+            j++;
         }
-       xfree(pp);
+      xfree (pp);
     }
-    memcpy( frame+n, p, i );
-    xfree(p);
-    n += i;
-    frame[n++] = 0;
-    frame[n++] = dek->algo;
-    memcpy( frame+n, dek->key, dek->keylen ); n += dek->keylen;
-    frame[n++] = csum >>8;
-    frame[n++] = csum;
-    assert( n == nframe );
-    if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
-      BUG();
-    xfree(frame);
-    return a;
+  memcpy (frame+n, p, i);
+  xfree (p);
+  n += i;
+  frame[n++] = 0;
+  frame[n++] = dek->algo;
+  memcpy (frame+n, dek->key, dek->keylen );
+  n += dek->keylen;
+  frame[n++] = csum >>8;
+  frame[n++] = csum;
+  assert (n == nframe);
+  if (gcry_mpi_scan( &a, GCRYMPI_FMT_USG, frame, n, &nframe))
+    BUG();
+  xfree (frame);
+  return a;
 }
 
 
@@ -192,8 +208,8 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
     gcry_mpi_t a;
 
     if( len + asnlen + 4  > nframe )
-       log_bug("can't encode a %d bit MD into a %d bits frame, algo=%d\n",
-                   (int)(len*8), (int)nbits, algo);
+      log_bug ("can't encode a %d bit MD into a %d bits frame, algo=%d\n",
+               (int)(len*8), (int)nbits, algo);
 
     /* We encode the MD in this way:
      *
@@ -240,26 +256,27 @@ gcry_mpi_t
 encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
 {
   gcry_mpi_t frame;
-  int gcry_pkalgo;
+  int pkalgo;
 
   assert (hash_algo);
   assert (pk);
 
-  gcry_pkalgo = map_pk_openpgp_to_gcry( pk->pubkey_algo );
+  pkalgo = map_pk_openpgp_to_gcry (pk->pubkey_algo);
 
-  if (gcry_pkalgo == GCRY_PK_DSA || gcry_pkalgo == GCRY_PK_ECDSA )
+  if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA)
     {
-      /* It's a DSA signature, so find out the size of q. */
+      /* It's a DSA signature, so find out the size of q.  */
 
       size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
 
-      /* pkey[1] is Q for ECDSA, which is an uncompressed point, i.e.  04 <x> <y> */
-      if( gcry_pkalgo==GCRY_PK_ECDSA )
-         qbytes = ecdsa_qbits_from_Q( qbytes );
-
+      /* pkey[1] is Q for ECDSA, which is an uncompressed point,
+         i.e.  04 <x> <y>  */
+      if (pkalgo == GCRY_PK_ECDSA)
+        qbytes = ecdsa_qbits_from_Q (qbytes);
+      
       /* Make sure it is a multiple of 8 bits. */
-
-      if(qbytes%8)
+      
+      if (qbytes%8)
        {
          log_error(_("DSA requires the hash length to be a"
                      " multiple of 8 bits\n"));
@@ -275,30 +292,38 @@ encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
       if (qbytes < 160)
        {
          log_error (_("%s key %s uses an unsafe (%zu bit) hash\n"),
-                       gcry_pk_algo_name( gcry_pkalgo ),
-                     keystr_from_pk (pk), qbytes);
+                     gcry_pk_algo_name (pkalgo), keystr_from_pk (pk), qbytes);
          return NULL;
        }
-
+      
       qbytes /= 8;
 
       /* Check if we're too short.  Too long is safe as we'll
-        automatically left-truncate. */
-      /* This checks would require the use of SHA512 with ECDSA 512. I think this is overkill to fail in this case.
-       * Therefore, relax the check, but only for ECDSA keys. We may need to adjust it later for general case.
-       * ( Note that the check will never pass for ECDSA 521 anyway as the only hash that intended to match it is SHA 512, but 512 < 521 ).
-       */
-      if (gcry_md_get_algo_dlen (hash_algo) < ((gcry_pkalgo==GCRY_PK_ECDSA && qbytes>(521)/8) ? 512/8 : qbytes) )
+        automatically left-truncate. 
+
+         FIXME:  Check against FIPS.
+         This checks would require the use of SHA512 with ECDSA 512.  I
+         think this is overkill to fail in this case.  Therefore,
+         relax the check, but only for ECDSA keys. We may need to
+         adjust it later for general case.  (Note that the check will
+         never pass for ECDSA 521 anyway as the only hash that
+         intended to match it is SHA 512, but 512 < 521).  */
+      if (gcry_md_get_algo_dlen (hash_algo) 
+          < ((pkalgo == GCRY_PK_ECDSA && qbytes > (521)/8) ? 512/8 : qbytes))
        {
-         log_error (_("%s key %s requires a %zu bit or larger hash, used hash-algo=%d\n"),
-                       gcry_pk_algo_name( gcry_pkalgo ),
-                     keystr_from_pk(pk), qbytes*8, hash_algo);
+         log_error (_("%s key %s requires a %zu bit or larger hash "
+                       "(hash is %s\n"),
+                     gcry_pk_algo_name (pkalgo),
+                     keystr_from_pk(pk), qbytes*8,
+                     gcry_md_algo_name (hash_algo));
          return NULL;
        }
 
-      /* Note that in case of ECDSA 521 hash is always smaller than the key size */
+      /* Note that in case of ECDSA 521 hash is always smaller than
+         the key size.  */
       if (gcry_mpi_scan (&frame, GCRYMPI_FMT_USG,
-                         gcry_md_read (md, hash_algo), gcry_md_get_algo_dlen (hash_algo), &qbytes))
+                         gcry_md_read (md, hash_algo),
+                         gcry_md_get_algo_dlen (hash_algo), &qbytes))
         BUG();
     }
   else
index ccf7964..30dc66d 100644 (file)
@@ -436,14 +436,15 @@ hash_for (PKT_public_key *pk)
     {
       return recipient_digest_algo;
     }
-  else if(pk->pubkey_algo==PUBKEY_ALGO_DSA || pk->pubkey_algo==PUBKEY_ALGO_ECDSA )
+  else if (pk->pubkey_algo == PUBKEY_ALGO_DSA
+           || pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
     {
       unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
 
-      if( pk->pubkey_algo==PUBKEY_ALGO_ECDSA )
-        qbytes = ecdsa_qbits_from_Q(qbytes);
+      if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+        qbytes = ecdsa_qbits_from_Q (qbytes);
       qbytes = qbytes/8;
-
+      
       /* It's a DSA key, so find a hash that is the same size as q or
         larger.  If q is 160, assume it is an old DSA key and use a
         160-bit hash unless --enable-dsa2 is set, in which case act
@@ -924,12 +925,14 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr,
 
            for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next )
              {
-               if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA )
+               if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_DSA
+                    || sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
                  {
-                   int temp_hashlen = gcry_mpi_get_nbits(sk_rover->pk->pkey[1]);
+                   int temp_hashlen = (gcry_mpi_get_nbits
+                                        (sk_rover->pk->pkey[1]));
 
-                   if( sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA )
-                     temp_hashlen = ecdsa_qbits_from_Q( temp_hashlen );
+                   if (sk_rover->pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
+                     temp_hashlen = ecdsa_qbits_from_Q (temp_hashlen);
                    temp_hashlen = (temp_hashlen+7)/8;
 
                    /* Pick a hash that is large enough for our
@@ -1482,13 +1485,14 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk,
 
        if(opt.cert_digest_algo)
          digest_algo=opt.cert_digest_algo;
-       else if(pksk->pubkey_algo==PUBKEY_ALGO_RSA
+       else if(pksk->pubkey_algo == PUBKEY_ALGO_RSA
                && pk->version<4 && sigversion<4)
          digest_algo = DIGEST_ALGO_MD5;
-       else if(pksk->pubkey_algo==PUBKEY_ALGO_DSA)
-         digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8 );
-        else if(pksk->pubkey_algo==PUBKEY_ALGO_ECDSA )
-         digest_algo = match_dsa_hash (ecdsa_qbits_from_Q( gcry_mpi_get_nbits (pksk->pkey[1]) ) / 8);
+       else if(pksk->pubkey_algo == PUBKEY_ALGO_DSA)
+         digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
+        else if(pksk->pubkey_algo == PUBKEY_ALGO_ECDSA )
+         digest_algo = match_dsa_hash (ecdsa_qbits_from_Q
+                                        (gcry_mpi_get_nbits (pksk->pkey[1]))/8);
        else
          digest_algo = DIGEST_ALGO_SHA1;
       }
index d1f0aa1..c4c657b 100644 (file)
@@ -1,6 +1,5 @@
 /* To satisfy the linker for the gpgv target 
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
- *               2007 Free Software Foundation, Inc.
+ * Copyright (C) 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -25,6 +24,8 @@
 #include "main.h"
 
 int
-pk_ecc_keypair_gen( PKT_public_key **pk_out, int algo, int keygen_flags, char **cache_nonce_addr, unsigned nbits)  {
-       return GPG_ERR_NOT_IMPLEMENTED;
+pk_ecc_keypair_gen (PKT_public_key **pk_out, int algo, int keygen_flags,
+                    char **cache_nonce_addr, unsigned nbits)
+{
+  return GPG_ERR_NOT_IMPLEMENTED;
 }
index 1ea7f32..4b374df 100644 (file)
@@ -176,7 +176,5 @@ next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length)
     }
   
   return NULL;
-} 
-
-    
+}
 
index 339800f..7c1b372 100644 (file)
@@ -1,3 +1,9 @@
+2011-01-21  Werner Koch  <wk@g10code.com>
+
+       * cipher.h (GCRY_PK_USAGE_CERT): Remove comaptibility macros
+       because we now require libgcrypt 1.4.6.
+       (GCRY_PK_ECDH): Add replacement.
+
 2009-08-20  Daiki Ueno  <ueno@unixuser.org>  (wk)
 
        * cipher.h (struct DEK): Add field S2K_CACHEID.
index 65cd59e..03d38da 100644 (file)
@@ -1,6 +1,6 @@
 /* cipher.h - Definitions for OpenPGP 
  * Copyright (C) 1998, 1999, 2000, 2001, 2006,
- *               2007  Free Software Foundation, Inc.
+ *               2007, 2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #include <gcrypt.h>
 
 /* Macros for compatibility with older libgcrypt versions. */
-#ifndef GCRY_PK_USAGE_CERT
-# define GCRY_PK_USAGE_CERT 4 
-# define GCRY_PK_USAGE_AUTH 8  
-# define GCRY_PK_USAGE_UNKN 128
+#ifndef HAVE_GCRY_PK_ECDSA
+# define GCRY_PK_ECDH  302
 #endif
 
 
@@ -56,8 +54,8 @@
 #define PUBKEY_ALGO_RSA_S        /*  3 */ GCRY_PK_RSA_S /* RSA sign only.    */
 #define PUBKEY_ALGO_ELGAMAL_E    /* 16 */ GCRY_PK_ELG_E /* Elgamal encr only */
 #define PUBKEY_ALGO_DSA          /* 17 */ GCRY_PK_DSA                          
-#define PUBKEY_ALGO_ECDH         18    /* corresponds to GCRY_PK_ECDH   ECC DH; encrypt only */
-#define PUBKEY_ALGO_ECDSA        19    /* corresponds to GCRY_PK_ECDSA  ECC DSA; sign only */
+#define PUBKEY_ALGO_ECDH            18
+#define PUBKEY_ALGO_ECDSA           19
 #define PUBKEY_ALGO_ELGAMAL      /* 20 */ GCRY_PK_ELG   /* Elgamal encr+sign */
 
 #define PUBKEY_USAGE_SIG     GCRY_PK_USAGE_SIGN  /* Good for signatures. */
index 6c9410e..f1de685 100644 (file)
@@ -245,6 +245,7 @@ parse_key (const unsigned char *data, size_t datalen,
       break;
     case 18: /* ECDH */
       npkey = 3;
+      break;
     case 19: /* ECDSA */
       npkey = 2;
       break;