summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2015-05-21 16:24:36 +0200
committerWerner Koch <wk@gnupg.org>2015-05-21 16:52:17 +0200
commit2bddd947fd1c11b4ec461576db65a5e34fea1b07 (patch)
tree55279d01ace3ac8b700f030f380794fa38df5671
parent102d68b3bd77813a3ff989526855bb1e283bf9d7 (diff)
downloadlibgcrypt-2bddd947fd1c11b4ec461576db65a5e34fea1b07.tar.gz
ecc: Add key generation flag "no-keytest".
* src/cipher.h (PUBKEY_FLAG_NO_KEYTEST): New. * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add flag "no-keytest". Return an error for invalid flags of length 10. * cipher/ecc.c (nist_generate_key): Replace arg random_level by flags set random level depending on flags. * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Ditto. * cipher/ecc.c (ecc_generate): Pass flags to generate fucntion and remove var random_level. (nist_generate_key): Implement "no-keytest" flag. * tests/keygen.c (check_ecc_keys): Add tests for transient-key and no-keytest. -- After key creation we usually run a test to check whether the keys really work. However for transient keys this might be too time consuming and given that a failed test would anyway abort the process the optional use of a flag to skip the test is appropriate. Using Ed25519 for EdDSA and the "no-keytest" flags halves the time to create such a key. This was measured by looping the last test from check_ecc_keys() 1000 times with and without the flag. Due to a bug in the flags parser unknown flags with a length of 10 characters were not detected. Thus the "no-keytest" flag can be employed by all software even for libraries before this. That bug is however solved with this version. Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r--NEWS4
-rw-r--r--cipher/ecc-common.h2
-rw-r--r--cipher/ecc-eddsa.c22
-rw-r--r--cipher/ecc.c33
-rw-r--r--cipher/pubkey-util.c6
-rw-r--r--doc/gcrypt.texi7
-rw-r--r--src/cipher.h1
-rw-r--r--tests/keygen.c40
8 files changed, 95 insertions, 20 deletions
diff --git a/NEWS b/NEWS
index 4c74533a..d90ee6d3 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,10 @@ Noteworthy changes in version 1.7.0 (unreleased)
* Added OCB mode.
+ * New flag "no-keytest" for ECC key generation. Due to a bug in the
+ parser that flag will also be accepted but ignored by older version
+ of Libgcrypt.
+
* Interface changes relative to the 1.6.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gcry_mac_get_algo NEW.
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h
index 83bf20d3..f0d97eaf 100644
--- a/cipher/ecc-common.h
+++ b/cipher/ecc-common.h
@@ -123,7 +123,7 @@ gpg_err_code_t _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
gpg_err_code_t _gcry_ecc_eddsa_genkey (ECC_secret_key *sk,
elliptic_curve_t *E,
mpi_ec_t ctx,
- gcry_random_level_t random_level);
+ int flags);
gpg_err_code_t _gcry_ecc_eddsa_sign (gcry_mpi_t input,
ECC_secret_key *sk,
gcry_mpi_t r_r, gcry_mpi_t s,
diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c
index a12ebab3..4323d8ef 100644
--- a/cipher/ecc-eddsa.c
+++ b/cipher/ecc-eddsa.c
@@ -465,15 +465,28 @@ _gcry_ecc_eddsa_compute_h_d (unsigned char **r_digest,
}
-/* Ed25519 version of the key generation. */
+/**
+ * _gcry_ecc_eddsa_genkey - EdDSA version of the key generation.
+ *
+ * @sk: A struct to receive the secret key.
+ * @E: Parameters of the curve.
+ * @ctx: Elliptic curve computation context.
+ * @flags: Flags controlling aspects of the creation.
+ *
+ * Return: An error code.
+ *
+ * The only @flags bit used by this function is %PUBKEY_FLAG_TRANSIENT
+ * to use a faster RNG.
+ */
gpg_err_code_t
_gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
- gcry_random_level_t random_level)
+ int flags)
{
gpg_err_code_t rc;
int b = 256/8; /* The only size we currently support. */
gcry_mpi_t a, x, y;
mpi_point_struct Q;
+ gcry_random_level_t random_level;
char *dbuf;
size_t dlen;
gcry_buffer_t hvec[1];
@@ -482,6 +495,11 @@ _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
point_init (&Q);
memset (hvec, 0, sizeof hvec);
+ if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ random_level = GCRY_STRONG_RANDOM;
+ else
+ random_level = GCRY_VERY_STRONG_RANDOM;
+
a = mpi_snew (0);
x = mpi_new (0);
y = mpi_new (0);
diff --git a/cipher/ecc.c b/cipher/ecc.c
index 262fcd80..5ffe84b5 100644
--- a/cipher/ecc.c
+++ b/cipher/ecc.c
@@ -1,6 +1,6 @@
/* ecc.c - Elliptic Curve Cryptography
* Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
+ * Copyright (C) 2013, 2015 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -106,12 +106,11 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
/**
- * nist_generate_key - Standard version of the key generation.
- *
+ * nist_generate_key - Standard version of the ECC key generation.
* @sk: A struct to receive the secret key.
* @E: Parameters of the curve.
* @ctx: Elliptic curve computation context.
- * @random_level: The quality of the random.
+ * @flags: Flags controlling aspects of the creation.
* @nbits: Only for testing
* @r_x: On success this receives an allocated MPI with the affine
* x-coordinate of the poblic key. On error NULL is stored.
@@ -119,19 +118,29 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
*
* Return: An error code.
*
+ * The @flags bits used by this function are %PUBKEY_FLAG_TRANSIENT to
+ * use a faster RNG, and %PUBKEY_FLAG_NO_KEYTEST to skip the assertion
+ * that the key works as expected.
+ *
* FIXME: Check whether N is needed.
*/
static gpg_err_code_t
nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
- gcry_random_level_t random_level, unsigned int nbits,
+ int flags, unsigned int nbits,
gcry_mpi_t *r_x, gcry_mpi_t *r_y)
{
mpi_point_struct Q;
+ gcry_random_level_t random_level;
gcry_mpi_t x, y;
const unsigned int pbits = mpi_get_nbits (E->p);
point_init (&Q);
+ if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ random_level = GCRY_STRONG_RANDOM;
+ else
+ random_level = GCRY_VERY_STRONG_RANDOM;
+
/* Generate a secret. */
if (ctx->dialect == ECC_DIALECT_ED25519)
{
@@ -226,7 +235,9 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx,
point_free (&Q);
/* Now we can test our keys (this should never fail!). */
- if (sk->E.model != MPI_EC_MONTGOMERY)
+ if ((flags & PUBKEY_FLAG_NO_KEYTEST))
+ ; /* User requested to skip the test. */
+ else if (sk->E.model != MPI_EC_MONTGOMERY)
test_keys (sk, nbits - 64);
else
test_ecdh_only_keys (sk, nbits - 64);
@@ -492,7 +503,6 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
gcry_mpi_t Qy = NULL;
char *curve_name = NULL;
gcry_sexp_t l1;
- gcry_random_level_t random_level;
mpi_ec_t ctx = NULL;
gcry_sexp_t curve_info = NULL;
gcry_sexp_t curve_flags = NULL;
@@ -560,17 +570,12 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
log_printpnt ("ecgen curve G", &E.G, NULL);
}
- if ((flags & PUBKEY_FLAG_TRANSIENT_KEY))
- random_level = GCRY_STRONG_RANDOM;
- else
- random_level = GCRY_VERY_STRONG_RANDOM;
-
ctx = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, 0, E.p, E.a, E.b);
if ((flags & PUBKEY_FLAG_EDDSA))
- rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, random_level);
+ rc = _gcry_ecc_eddsa_genkey (&sk, &E, ctx, flags);
else
- rc = nist_generate_key (&sk, &E, ctx, random_level, nbits, &Qx, &Qy);
+ rc = nist_generate_key (&sk, &E, ctx, flags, nbits, &Qx, &Qy);
if (rc)
goto leave;
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
index 514f1eb5..afa34542 100644
--- a/cipher/pubkey-util.c
+++ b/cipher/pubkey-util.c
@@ -1,7 +1,7 @@
/* pubkey-util.c - Supporting functions for all pubkey modules.
* Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
* 2007, 2008, 2011 Free Software Foundation, Inc.
- * Copyright (C) 2013 g10 Code GmbH
+ * Copyright (C) 2013, 2015 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -155,6 +155,10 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
case 10:
if (!memcmp (s, "igninvflag", 10))
igninvflag = 1;
+ else if (!memcmp (s, "no-keytest", 10))
+ flags |= PUBKEY_FLAG_NO_KEYTEST;
+ else if (!igninvflag)
+ rc = GPG_ERR_INV_FLAG;
break;
case 11:
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index ab4f685b..f13695a3 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -2327,6 +2327,13 @@ random number generator. This flag may be used for keys which are
only used for a short time or per-message and do not require full
cryptographic strength.
+@item no-keytest
+@cindex no-keytest
+This flag skips internal failsafe tests to assert that a generated key
+is properly working. It currently has an effect only for standard ECC
+key generation. It is mostly useful along with transient-key to
+achieve fastest ECC key generation.
+
@item use-x931
@cindex X9.31
Force the use of the ANSI X9.31 key generation algorithm instead of
diff --git a/src/cipher.h b/src/cipher.h
index 7ad0b2cd..ef183fdc 100644
--- a/src/cipher.h
+++ b/src/cipher.h
@@ -40,6 +40,7 @@
#define PUBKEY_FLAG_NOCOMP (1 << 11)
#define PUBKEY_FLAG_EDDSA (1 << 12)
#define PUBKEY_FLAG_GOST (1 << 13)
+#define PUBKEY_FLAG_NO_KEYTEST (1 << 14)
enum pk_operation
diff --git a/tests/keygen.c b/tests/keygen.c
index 4aff9c96..8b9a1d58 100644
--- a/tests/keygen.c
+++ b/tests/keygen.c
@@ -1,5 +1,6 @@
/* keygen.c - key generation regression tests
* Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2015 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
@@ -14,8 +15,7 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
@@ -432,7 +432,43 @@ check_ecc_keys (void)
show_sexp ("ECC key:\n", key);
check_generated_ecc_key (key);
+ gcry_sexp_release (key);
+
+
+ if (verbose)
+ show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve Ed25519)(flags transient-key)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating ECC key using curve Ed25519 for ECDSA"
+ " (transient-key): %s\n",
+ gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+ check_generated_ecc_key (key);
+ gcry_sexp_release (key);
+ if (verbose)
+ show ("creating ECC key using curve Ed25519 for ECDSA "
+ "(transient-key no-keytest)\n");
+ rc = gcry_sexp_build (&keyparm, NULL,
+ "(genkey(ecc(curve Ed25519)"
+ "(flags transient-key no-keytest)))");
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating ECC key using curve Ed25519 for ECDSA"
+ " (transient-key no-keytest): %s\n",
+ gpg_strerror (rc));
+ if (verbose > 1)
+ show_sexp ("ECC key:\n", key);
+ check_generated_ecc_key (key);
gcry_sexp_release (key);
}