summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2007-04-16 15:09:30 +0000
committerWerner Koch <wk@gnupg.org>2007-04-16 15:09:30 +0000
commit591697fc7621e8aa16abb3f60dc297ea9af1048f (patch)
tree76fb0761768c69d50818ff9f88f6aeeb8fb83b33
parentef72b801762550f0ec1dd483e36ab95fe8f6629e (diff)
downloadlibgcrypt-591697fc7621e8aa16abb3f60dc297ea9af1048f.tar.gz
./
* 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.
-rw-r--r--ChangeLog6
-rw-r--r--acinclude.m482
-rw-r--r--cipher/ChangeLog15
-rw-r--r--cipher/ecc.c100
-rw-r--r--cipher/pubkey.c92
-rw-r--r--cipher/sha1.c2
-rw-r--r--configure.ac2
-rw-r--r--mpi/ec.c20
-rw-r--r--src/ChangeLog5
-rw-r--r--src/cipher.h3
-rw-r--r--src/secmem.c11
-rw-r--r--tests/ChangeLog3
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/benchmark.c25
-rw-r--r--tests/pkbench.c113
15 files changed, 376 insertions, 107 deletions
diff --git a/ChangeLog b/ChangeLog
index 2c672096..290df023 100644
--- 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.
diff --git a/acinclude.m4 b/acinclude.m4
index 7fb5c7d8..dae5e223 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -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);
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 5ae12bd2..7d7a2e34 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -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
@@ -8,10 +12,21 @@
(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>
diff --git a/cipher/ecc.c b/cipher/ecc.c
index cc4d8f63..0012f796 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -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;
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 82df226b..dd8330f1 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -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. */
diff --git a/cipher/sha1.c b/cipher/sha1.c
index c393a570..9c81f680 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -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 },
};
diff --git a/configure.ac b/configure.ac
index 1ad646ba..2c9fabd0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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)
diff --git a/mpi/ec.c b/mpi/ec.c
index 6addb66f..b76dd520 100644
--- 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
}
+
diff --git a/src/ChangeLog b/src/ChangeLog
index e7968c49..194a941e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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.
diff --git a/src/cipher.h b/src/cipher.h
index 91a44c31..bd0cd747 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -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,
diff --git a/src/secmem.c b/src/secmem.c
index 0c11f826..2d603a2a 100644
--- a/src/secmem.c
+++ b/src/secmem.c
@@ -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);
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 215409ae..95f38157 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ecd77c35..adc9d74b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
diff --git a/tests/benchmark.c b/tests/benchmark.c
index dc231295..601d48ab 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -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"))
{
diff --git a/tests/pkbench.c b/tests/pkbench.c
index dcdc436e..1dbc28a6 100644
--- a/tests/pkbench.c
+++ b/tests/pkbench.c
@@ -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;
}