diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | cipher/ecc-common.h | 2 | ||||
-rw-r--r-- | cipher/ecc-eddsa.c | 22 | ||||
-rw-r--r-- | cipher/ecc.c | 33 | ||||
-rw-r--r-- | cipher/pubkey-util.c | 6 | ||||
-rw-r--r-- | doc/gcrypt.texi | 7 | ||||
-rw-r--r-- | src/cipher.h | 1 | ||||
-rw-r--r-- | tests/keygen.c | 40 |
8 files changed, 95 insertions, 20 deletions
@@ -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); } |