./
authorWerner Koch <wk@gnupg.org>
Mon, 16 Apr 2007 15:09:30 +0000 (15:09 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 16 Apr 2007 15:09:30 +0000 (15:09 +0000)
* configure.ac: Check for sysconf.
* acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
page size and use getpagesize only then if available.

cipher/
* ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.

src/
* secmem.c (init_pool): Use sysconf() if available to determine
page size.

15 files changed:
ChangeLog
acinclude.m4
cipher/ChangeLog
cipher/ecc.c
cipher/pubkey.c
cipher/sha1.c
configure.ac
mpi/ec.c
src/ChangeLog
src/cipher.h
src/secmem.c
tests/ChangeLog
tests/Makefile.am
tests/benchmark.c
tests/pkbench.c

index 2c67209..290df02 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-04-16  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Cehck for sysconf.
+       * acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
+       page size and use getpagesize only then if available.
+
 2007-03-22  Werner Koch  <wk@g10code.com>
 
        * configure.ac: Add support for ECC.
index 7fb5c7d..dae5e22 100644 (file)
@@ -152,18 +152,18 @@ define(GNUPG_CHECK_MLOCK,
                     #include <sys/mman.h>
                     #endif
                 ], [
-                    int i;
-                    
-                    /* glibc defines this for functions which it implements
                    * to always fail with ENOSYS.  Some functions are actually
                    * named something starting with __ and the normal name
                    * is an alias.  */
-                    #if defined (__stub_mlock) || defined (__stub___mlock)
-                    choke me
-                    #else
-                    mlock(&i, 4);
-                    #endif
-                    ; return 0;
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS.  Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias.  */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
                 ],
                 gnupg_cv_mlock_is_in_sys_mman=yes,
                 gnupg_cv_mlock_is_in_sys_mman=no)])
@@ -174,33 +174,45 @@ define(GNUPG_CHECK_MLOCK,
         fi
     fi
     if test "$ac_cv_func_mlock" = "yes"; then
+        AC_CHECK_FUNCS(sysconf getpagesize)
         AC_MSG_CHECKING(whether mlock is broken)
           AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
              AC_TRY_RUN([
-                #include <stdlib.h>
-                #include <unistd.h>
-                #include <errno.h>
-                #include <sys/mman.h>
-                #include <sys/types.h>
-                #include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+int main()
+{
+    char *pool;
+    int err;
+    long int pgsize;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+    pgsize = sysconf (_SC_PAGESIZE);
+#elif defined (HAVE_GETPAGESIZE)
+    pgsize = getpagesize();       
+#else
+    pgsize = -1;
+#endif
 
-                int main()
-                {
-                    char *pool;
-                    int err;
-                    long int pgsize = getpagesize();
+    if (pgsize == -1)
+      pgsize = 4096;
 
-                    pool = malloc( 4096 + pgsize );
-                    if( !pool )
-                        return 2;
-                    pool += (pgsize - ((long int)pool % pgsize));
+    pool = malloc( 4096 + pgsize );
+    if( !pool )
+        return 2;
+    pool += (pgsize - ((long int)pool % pgsize));
 
-                    err = mlock( pool, 4096 );
-                    if( !err || errno == EPERM )
-                        return 0; /* okay */
+    err = mlock( pool, 4096 );
+    if( !err || errno == EPERM )
+        return 0; /* okay */
 
-                    return 1;  /* hmmm */
-                }
+    return 1;  /* hmmm */
+}
 
             ],
             gnupg_cv_have_broken_mlock="no",
@@ -317,10 +329,10 @@ AC_DEFUN([TYPE_SOCKLEN_T],
          for arg2 in "struct sockaddr" void; do
             for t in int size_t unsigned long "unsigned long"; do
                AC_TRY_COMPILE([
-                  #include <sys/types.h>
-                  #include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/socket.h>
 
-                  int getpeername (int, $arg2 *, $t *);
+int getpeername (int, $arg2 *, $t *);
                ],[
                   $t len;
                   getpeername(0,0,&len);
index 5ae12bd..7d7a2e3 100644 (file)
@@ -1,3 +1,7 @@
+2007-04-16  Werner Koch  <wk@g10code.com>
+
+       * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
+
 2007-04-13  Marcus Brinkmann  <marcus@g10code.de>
 
        * ac.c (ac_data_construct): Cast const away to suppress compiler
        (ecc_verify): Avoid compiler warning for unused arguments CMP and
        OPAQUEV.
 
+2007-04-06  Werner Koch  <wk@g10code.com>
+
+       * sha1.c (oid_spec_sha1): Add another oid from X9.62.
+
 2007-03-28  Werner Koch  <wk@g10code.com>
 
+       * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
+       empty.
+       (gcry_pk_genkey): New parameter "curve".
+
        * ecc.c: Entirely rewritten with only a few traces of the old
        code left.
+       (_gcry_ecc_generate): New.
+       (generate_key) New arg NAME.
+       (generate_curve): Ditto.  Return actual number of NBITS.
 
 2007-03-26  Werner Koch  <wk@g10code.com>
 
index cc4d8f6..0012f79 100644 (file)
@@ -86,6 +86,32 @@ typedef struct
 } ECC_secret_key;
 
 
+/* This tables defines aliases for curve names.  */
+static const struct
+{
+  const char *name;  /* Our name.  */
+  const char *other; /* Other name. */
+} curve_aliases[] = 
+  {
+    { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
+    { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
+    { "NIST P-192", "secp192r1"  },          /* SECP name.  */
+
+    { "NIST P-224", "secp224r1" },
+
+    { "NIST P-256", "1.2.840.10045.3.1.7" }, 
+    { "NIST P-256", "prime256v1" },          
+    { "NIST P-256", "secp256r1"  },          
+
+    { "NIST P-384", "secp384r1" },
+
+    { "NIST P-521", "secp521r1" },
+
+    { NULL, NULL}
+  };
+
+
+
 /* This static table defines all available curves.  */
 static const struct
 {
@@ -97,6 +123,16 @@ static const struct
   const char *g_x, *g_y;      /* Base point.  */
 } domain_parms[] =
   {
+    { "secp160r1", 160,
+      "0x",
+      "0x",
+      "0x",
+      "0x",
+
+      "0x",
+      "0x"
+    }, 
+
     {
       "NIST P-192", 192,
       "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
@@ -324,16 +360,27 @@ gen_k (gcry_mpi_t p, int security_level)
  * The subgroup generator point is in another function: gen_big_point.
  */
 static gpg_err_code_t
-generate_curve (unsigned int nbits, elliptic_curve_t *curve)
+generate_curve (unsigned int nbits, const char *name, 
+                elliptic_curve_t *curve, unsigned int *r_nbits)
 {
   int idx;
 
-  for (idx = 0; domain_parms[idx].desc; idx++)
-    if (nbits == domain_parms[idx].nbits)
-      break;
+  if (name)
+    {
+      for (idx = 0; domain_parms[idx].desc; idx++)
+        if (!strcmp (name, domain_parms[idx].desc))
+          break;
+    }
+  else
+    {
+      for (idx = 0; domain_parms[idx].desc; idx++)
+        if (nbits == domain_parms[idx].nbits)
+          break;
+    }
   if (!domain_parms[idx].desc)
     return GPG_ERR_INV_VALUE;
 
+  *r_nbits = domain_parms[idx].nbits;
   curve->p = scanval (domain_parms[idx].p);
   curve->a = scanval (domain_parms[idx].a);
   curve->b = scanval (domain_parms[idx].b);
@@ -351,7 +398,7 @@ generate_curve (unsigned int nbits, elliptic_curve_t *curve)
  * secret value, and calculate the public point.
  */
 static gpg_err_code_t
-generate_key (ECC_secret_key *sk, unsigned int nbits,
+generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
               gcry_mpi_t g_x, gcry_mpi_t g_y,
               gcry_mpi_t q_x, gcry_mpi_t q_y)
 {
@@ -361,7 +408,7 @@ generate_key (ECC_secret_key *sk, unsigned int nbits,
   mpi_point_t Q, G;
   mpi_ec_t ctx;
 
-  err = generate_curve (nbits, &E);
+  err = generate_curve (nbits, name, &E, &nbits);
   if (err)
     return err;
 
@@ -629,16 +676,28 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
 
   /* h  = s^(-1) (mod n) */
   mpi_invm (h, s, pkey->E.n);
+/*   log_mpidump ("   h", h); */
   /* h1 = hash * s^(-1) (mod n) */
   mpi_mulm (h1, input, h, pkey->E.n);
+/*   log_mpidump ("  h1", h1); */
   /* Q1 = [ hash * s^(-1) ]G  */
   _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
+/*   log_mpidump ("Q1.x", Q1.x); */
+/*   log_mpidump ("Q1.y", Q1.y); */
+/*   log_mpidump ("Q1.z", Q1.z); */
   /* h2 = r * s^(-1) (mod n) */
   mpi_mulm (h2, r, h, pkey->E.n);
+/*   log_mpidump ("  h2", h2); */
   /* Q2 = [ r * s^(-1) ]Q */
   _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
+/*   log_mpidump ("Q2.x", Q2.x); */
+/*   log_mpidump ("Q2.y", Q2.y); */
+/*   log_mpidump ("Q2.z", Q2.z); */
   /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
   _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
+/*   log_mpidump (" Q.x", Q.x); */
+/*   log_mpidump (" Q.y", Q.y); */
+/*   log_mpidump (" Q.z", Q.z); */
 
   if (!mpi_cmp_ui (Q.z, 0))
     {
@@ -658,7 +717,13 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
   if (mpi_cmp (x, r))   /* x != r */
     {
       if (DBG_CIPHER)
-        log_debug ("ecc verify: Not verified\n");
+        {
+          log_mpidump ("   x", x);
+          log_mpidump ("   y", y);
+          log_mpidump ("   r", r);
+          log_mpidump ("   s", s);
+          log_debug ("ecc verify: Not verified\n");
+        }
       err = GPG_ERR_BAD_SIGNATURE;
       goto leave;
     }
@@ -782,16 +847,18 @@ os2ec (mpi_point_t *result, gcry_mpi_t value)
   return 0;
 }
 
-static gcry_err_code_t
-ecc_generate (int algo, unsigned int nbits, unsigned long dummy,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+/* Extended version of ecc_generate which is called directly by
+   pubkey.c.  If CURVE is not NULL, that name will be used to select
+   the domain parameters.  NBITS is not used in this case.  */
+gcry_err_code_t
+_gcry_ecc_generate (int algo, unsigned int nbits, const char *curve,
+                    gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   gpg_err_code_t err;
   ECC_secret_key sk;
   gcry_mpi_t g_x, g_y, q_x, q_y;
 
   (void)algo;
-  (void)dummy;
 
   /* Make an empty list of factors.  */
   *retfactors = gcry_calloc ( 1, sizeof **retfactors );
@@ -802,7 +869,7 @@ ecc_generate (int algo, unsigned int nbits, unsigned long dummy,
   g_y = mpi_new (0);
   q_x = mpi_new (0);
   q_y = mpi_new (0);
-  err = generate_key (&sk, nbits, g_x, g_y, q_x, q_y);
+  err = generate_key (&sk, nbits, curve, g_x, g_y, q_x, q_y);
   if (err)
     {
       gcry_free (*retfactors);
@@ -823,6 +890,15 @@ ecc_generate (int algo, unsigned int nbits, unsigned long dummy,
 
 
 static gcry_err_code_t
+ecc_generate (int algo, unsigned int nbits, unsigned long dummy,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  (void)dummy;
+  return _gcry_ecc_generate (algo, nbits, NULL, skey, retfactors);
+}
+
+
+static gcry_err_code_t
 ecc_check_secret_key (int algo, gcry_mpi_t *skey)
 {
   gpg_err_code_t err;
index 82df226..dd8330f 100644 (file)
@@ -501,6 +501,7 @@ pubkey_get_nenc (int algorithm)
 static gcry_err_code_t
 pubkey_generate (int algorithm, unsigned int nbits, unsigned int qbits,
                  unsigned long use_e, gcry_mpi_t xvalue,
+                 const char *curve_name,
                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
@@ -525,6 +526,13 @@ pubkey_generate (int algorithm, unsigned int nbits, unsigned int qbits,
             (algorithm, nbits, xvalue, skey, retfactors);
         }
 #endif /*USE_ELGAMAL*/
+#ifdef USE_ECC
+      else if (curve_name && pubkey->spec == &_gcry_pubkey_spec_ecdsa)
+        {
+          err = _gcry_ecc_generate
+            (algorithm, nbits, curve_name, skey, retfactors);
+        }
+#endif /*USE_ECC*/
       else
         {
           err = ((gcry_pk_spec_t *) pubkey->spec)->generate 
@@ -1934,6 +1942,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   unsigned int qbits;
   gcry_mpi_t xvalue = NULL;
   char *name_terminated;
+  char *curve = NULL;
 
   REGISTER_DEFAULT_PUBKEYS;
 
@@ -2047,38 +2056,65 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
         }
     }
 
-  /* Now parse the required nbits element. */
+  /* Handle the optional "curve" parameter. */
+  l2 = gcry_sexp_find_token (list, "curve", 0);
+  if (l2)
+    {
+      name = gcry_sexp_nth_data (l2, 1, &n);
+      if (!name || n < 1)
+        {
+          rc = GPG_ERR_INV_OBJ; /* No name or or value too large. */
+          goto leave;
+        }
+      curve = gcry_malloc (n+1);
+      if (!curve)
+        {
+          rc = gpg_err_code_from_syserror ();
+          goto leave;
+        }
+      memcpy (curve, name, n);
+      curve[n] = 0;
+      gcry_sexp_release (l2);
+      l2 = NULL;
+    }
+
+
+  /* Unless a curve name has been given, the "nbits" parameter is
+     required.  */
   l2 = gcry_sexp_find_token (list, "nbits", 0);
   gcry_sexp_release (list);
   list = l2;
   l2 = NULL;
-  
-  if (! list)
+  if (!list && !curve)
     {
       rc = GPG_ERR_NO_OBJ; /* No nbits parameter. */
       goto leave;
     }
-
-  name = gcry_sexp_nth_data (list, 1, &n);
-  if (! name)
-    {
-      rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */
-      goto leave;
-    }
-  
-  name_terminated = gcry_malloc (n + 1);
-  if (!name_terminated)
+  if (list)
     {
-      rc = gpg_err_code_from_errno (errno);
-      goto leave;
+      name = gcry_sexp_nth_data (list, 1, &n);
+      if (! name)
+        {
+          rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */
+          goto leave;
+        }
+      
+      name_terminated = gcry_malloc (n + 1);
+      if (!name_terminated)
+        {
+          rc = gpg_err_code_from_errno (errno);
+          goto leave;
+        }
+      memcpy (name_terminated, name, n);
+      name_terminated[n] = 0;
+      nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
+      gcry_free (name_terminated);
     }
-  memcpy (name_terminated, name, n);
-  name_terminated[n] = 0;
-  nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
-  gcry_free (name_terminated);
+  else 
+    nbits = 0;
 
   rc = pubkey_generate (module->mod_id, nbits, qbits, use_e, xvalue,
-                        skey, &factors);
+                        curve, skey, &factors);
   if (rc)
     goto leave;
 
@@ -2130,13 +2166,18 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     /* Very ugly hack to make release_mpi_array() work FIXME */
     skey[i] = NULL;
 
-    p = stpcpy (p, "(misc-key-info(pm1-factors");
-    for(i = 0; factors[i]; i++)
+    if (factors[0])
       {
-        p = stpcpy (p, "%m");
-        mpis[nelem++] = factors[i];
+        p = stpcpy (p, "(misc-key-info(pm1-factors");
+        for(i = 0; factors[i]; i++)
+          {
+            p = stpcpy (p, "%m");
+            mpis[nelem++] = factors[i];
+          }
+        p = stpcpy (p, "))");
       }
-    strcpy (p, ")))");
+    strcpy (p, ")");
+    assert (p - string < needed);
 
     while (nelem < DIM (mpis))
       mpis[nelem++] = NULL;
@@ -2168,6 +2209,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   }
 
  leave:
+  gcry_free (curve);
   release_mpi_array (skey);
   /* Don't free SKEY itself, it is a static array. */
 
index c393a57..9c81f68 100644 (file)
@@ -358,6 +358,8 @@ static gcry_md_oid_spec_t oid_spec_sha1[] =
     { "1.3.14.3.2.26" },
     /* from NIST OIW (sha-1WithRSAEncryption) */
     { "1.3.14.3.2.29" },
+    /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
+    { "1.2.840.10045.4.1" },
     { NULL },
   };
 
index 1ad646b..2c9fabd 100644 (file)
@@ -583,7 +583,7 @@ AC_CHECK_FUNCS(stpcpy strcasecmp)
 # We have replacements for these in src/g10lib.h
 AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
 # Other checks
-AC_CHECK_FUNCS(strerror rand mmap getpagesize waitpid wait4)
+AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
 AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime)
 AC_CHECK_FUNCS(fcntl ftruncate)
 
index 6addb66..b76dd52 100644 (file)
--- a/mpi/ec.c
+++ b/mpi/ec.c
@@ -613,6 +613,24 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
                         gcry_mpi_t scalar, mpi_point_t *point,
                         mpi_ec_t ctx)
 {
+#if 0
+  /* Simple left to right binary method.  GECC Algorithm 3.27 */
+  unsigned int nbits;
+  int i;
+
+  nbits = mpi_get_nbits (scalar);
+  mpi_set_ui (result->x, 1);
+  mpi_set_ui (result->y, 1);
+  mpi_set_ui (result->z, 0); 
+
+  for (i=nbits-1; i >= 0; i--)
+    {
+      _gcry_mpi_ec_dup_point (result, result, ctx);
+      if (mpi_test_bit (scalar, i) == 1)
+        _gcry_mpi_ec_add_points (result, result, point, ctx); 
+    }
+
+#else 
   gcry_mpi_t x1, y1, z1, k, h, yy;
   unsigned int i, loops;
   mpi_point_t p1, p2, p1inv;
@@ -687,4 +705,6 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
   point_free (&p1inv);
   mpi_free (h);
   mpi_free (k);
+#endif
 }
+
index e7968c4..194a941 100644 (file)
@@ -1,3 +1,8 @@
+2007-04-16  Werner Koch  <wk@g10code.com>
+
+       * secmem.c (init_pool): Use sysconf() if available to determine
+       page size.
+       
 2007-03-22  Werner Koch  <wk@g10code.com>
 
        * mpi.h (mpi_mod): New.
index 91a44c3..bd0cd74 100644 (file)
@@ -54,6 +54,9 @@ gcry_err_code_t _gcry_elg_generate_using_x (int algo, unsigned int nbits,
 /*-- ecc.c --*/
 void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc,
                                      void *cb_data);
+gcry_err_code_t _gcry_ecc_generate (int algo, unsigned int nbits,
+                                    const char *curve,
+                                    gcry_mpi_t *skey, gcry_mpi_t **retfactors);
 
 /*-- primegen.c --*/
 void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
index 0c11f82..2d603a2 100644 (file)
@@ -340,6 +340,7 @@ static void
 init_pool (size_t n)
 {
   size_t pgsize;
+  long int pgsize_val;
   memblock_t *mb;
 
   pool_size = n;
@@ -347,11 +348,15 @@ init_pool (size_t n)
   if (disable_secmem)
     log_bug ("secure memory is disabled");
 
-#ifdef HAVE_GETPAGESIZE
-  pgsize = getpagesize ();
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+  pgsize_val = sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+  pgsize_val = getpagesize ();
 #else
-  pgsize = DEFAULT_PAGE_SIZE;
+  pgsize_val = -1;
 #endif
+  pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
 
 #if HAVE_MMAP
   pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
index 215409a..95f3815 100644 (file)
@@ -7,8 +7,11 @@
 
 2007-03-28  Werner Koch  <wk@g10code.com>
 
+       * pkbench.c (generate_key): Support named curves.
+
        * benchmark.c (dsa_bench): New args ITERATIONS and PRINT_HEADER.
        (main): Call dsa and ecc benchs.
+       (show_sexp): New.
 
        * Makefile.am (TESTS): Move pkbench to EXTRA_PROGRAMS.
 
index ecd77c3..adc9d74 100644 (file)
@@ -39,6 +39,6 @@ LDADD = ../src/libgcrypt.la
 
 # pkbench uses mmap for no good reason.  Needs to be fixed.  Code for
 # this can be found in libksba/tests. 
-EXTRA_PROGRAMS = testapi pkbench
-noinst_PROGRAMS = $(TESTS)
+EXTRA_PROGRAMS = testapi
+noinst_PROGRAMS = $(TESTS) pkbench
 
index dc23129..601d48a 100644 (file)
@@ -242,6 +242,22 @@ die (const char *format, ...)
   exit (1);
 }
 
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = malloc (size);
+  if (!buf)
+    die ("out of core\n");
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+}
+
 
 static void
 start_timer (void)
@@ -709,9 +725,10 @@ ecc_bench (int iterations, int print_header)
           if (err)
             {
               putchar ('\n');
-              fprintf (stderr, PGM ": verify failed: %s\n",
-                       gpg_strerror (err));
-              exit (1);
+              show_sexp ("seckey:\n", sec_key);
+              show_sexp ("data:\n", data);
+              show_sexp ("sig:\n", sig);
+              die ("verify failed: %s\n", gpg_strerror (err));
             }
         }
       stop_timer ();
@@ -826,7 +843,7 @@ main( int argc, char **argv )
       random_bench (0);
     }
   else if ( !strcmp (*argv, "--help"))
-     fputs ("usage: benchmark [md|cipher|random|mpi|dsa [algonames]]\n",
+     fputs ("usage: benchmark [md|cipher|random|mpi|dsa|ecc [algonames]]\n",
             stdout);
   else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom"))
     {
index dcdc436..1dbc28a 100644 (file)
@@ -25,6 +25,7 @@
 #include <gcrypt.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #ifndef HAVE_W32_SYSTEM
@@ -39,6 +40,7 @@
 
 static int verbose;
 static int debug;
+static int error_count;
 
 
 typedef struct context
@@ -52,6 +54,50 @@ typedef struct context
 
 typedef int (*work_t) (context_t context, unsigned int final);
 
+
+static void
+fail (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fputs ( PGM ": ", stderr);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  putchar ('\n');
+  fputs ( PGM ": ", stderr);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = malloc (size);
+  if (!buf)
+    die ("out of core\n");
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+}
+
+
+
 static void
 benchmark (work_t worker, context_t context)
 {
@@ -156,10 +202,13 @@ work_sign (context_t context, unsigned int final)
       err = GPG_ERR_NO_ERROR;
       ret = 0;
     }
+  else if (err)
+    {
+      fail ("pk_sign failed: %s\n", gpg_strerror (err));
+      ret = 0;
+    }
   else
     {
-      assert (! err);
-
       if (final)
        context->data_signed = data_signed;
       else
@@ -175,21 +224,25 @@ work_verify (context_t context, unsigned int final)
   gcry_error_t err = GPG_ERR_NO_ERROR;
   int ret = 1;
 
-  if (! context->data_signed)
-    ret = 0;
-  else
+  if (!context->data_signed)
+    return 0;
+
+  err = gcry_pk_verify (context->data_signed,
+                        context->data,
+                        context->key_public);
+  if (err)
     {
-      err = gcry_pk_verify (context->data_signed,
-                           context->data,
-                           context->key_public);
-      assert (! err);
-      if (final)
-       {
-         gcry_sexp_release (context->data_signed);
-         context->data_signed = NULL;
-       }
+      show_sexp ("data_signed:\n", context->data_signed);
+      show_sexp ("data:\n", context->data);
+      fail ("pk_verify failed: %s\n", gpg_strerror (err));
+      ret = 0;
     }
-
+  else if (final)
+    {
+      gcry_sexp_release (context->data_signed);
+      context->data_signed = NULL;
+    }
+    
   return ret;
 }
 
@@ -307,13 +360,23 @@ generate_key (const char *algorithm, const char *key_size)
   gcry_sexp_t key_spec = NULL;
   gcry_sexp_t key_pair = NULL;
 
-  err = gcry_sexp_build (&key_spec, NULL,
-                        "(genkey (%s (nbits %s)))",
-                        algorithm, key_size);
-  assert (! err);
+  if (isdigit ((unsigned int)*key_size))
+    err = gcry_sexp_build (&key_spec, NULL,
+                           "(genkey (%s (nbits %s)))",
+                           algorithm, key_size);
+  else
+    err = gcry_sexp_build (&key_spec, NULL,
+                           "(genkey (%s (curve %s)))",
+                           algorithm, key_size);
+  if (err)
+    die ("sexp_build failed: %s\n", gpg_strerror (err));
 
   err = gcry_pk_genkey (&key_pair, key_spec);
-  assert (! err);
+  if (err)
+    {
+      show_sexp ("request:\n", key_spec);
+      die ("pk_genkey failed: %s\n", gpg_strerror (err));
+    }
 
   key_pair_buffer_size = gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
                                           NULL, 0);
@@ -323,7 +386,7 @@ generate_key (const char *algorithm, const char *key_size)
   gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
                    key_pair_buffer, key_pair_buffer_size);
 
-  printf ("%.*s", key_pair_buffer_size, key_pair_buffer);
+  printf ("%.*s", (int)key_pair_buffer_size, key_pair_buffer);
 }
 
 
@@ -385,9 +448,9 @@ main (int argc, char **argv)
     {
       /* No valuable keys are create, so we can speed up our RNG. */
       gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-      if (debug)
-        gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
-    }
+    } 
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
   
@@ -409,5 +472,5 @@ main (int argc, char **argv)
       exit (1);
     }
   
-  return 0;
+  return error_count ? 1 : 0;
 }