diff options
author | Werner Koch <wk@gnupg.org> | 2007-04-16 15:09:30 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2007-04-16 15:09:30 +0000 |
commit | 591697fc7621e8aa16abb3f60dc297ea9af1048f (patch) | |
tree | 76fb0761768c69d50818ff9f88f6aeeb8fb83b33 | |
parent | ef72b801762550f0ec1dd483e36ab95fe8f6629e (diff) | |
download | libgcrypt-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-- | ChangeLog | 6 | ||||
-rw-r--r-- | acinclude.m4 | 82 | ||||
-rw-r--r-- | cipher/ChangeLog | 15 | ||||
-rw-r--r-- | cipher/ecc.c | 100 | ||||
-rw-r--r-- | cipher/pubkey.c | 92 | ||||
-rw-r--r-- | cipher/sha1.c | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | mpi/ec.c | 20 | ||||
-rw-r--r-- | src/ChangeLog | 5 | ||||
-rw-r--r-- | src/cipher.h | 3 | ||||
-rw-r--r-- | src/secmem.c | 11 | ||||
-rw-r--r-- | tests/ChangeLog | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 4 | ||||
-rw-r--r-- | tests/benchmark.c | 25 | ||||
-rw-r--r-- | tests/pkbench.c | 113 |
15 files changed, 376 insertions, 107 deletions
@@ -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) @@ -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; } |