From cvs at cvs.gnupg.org Wed Dec 2 12:01:58 2015 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 02 Dec 2015 12:01:58 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-291-g468a579 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 468a5796ffb1a7776db4004d534376c1b981d740 (commit) from 3658afd09c3b03b4398aaa5748387220c93b1a94 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 468a5796ffb1a7776db4004d534376c1b981d740 Author: Justus Winter Date: Wed Dec 2 11:54:40 2015 +0100 random: Fix selection of entropy gathering function. * random/random-csprng.c (getfnc_gather_random): Do return NULL if no usable entropy gathering function is found. The callsite then installs the fake gather function. Signed-off-by: Justus Winter diff --git a/random/random-csprng.c b/random/random-csprng.c index dbebe98..88c5ff8 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -1151,9 +1151,9 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, return fnc; #endif - log_fatal (_("no entropy gathering module detected\n")); + log_info (_("no entropy gathering module detected\n")); - return NULL; /*NOTREACHED*/ + return NULL; } /* Runtime determination of the fast entropy gathering function. ----------------------------------------------------------------------- Summary of changes: random/random-csprng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Wed Dec 2 12:27:20 2015 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Wed, 02 Dec 2015 12:27:20 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-292-gd421ac2 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via d421ac283ec46d0ecaf6278ba4c24843f65fb2fa (commit) from 468a5796ffb1a7776db4004d534376c1b981d740 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d421ac283ec46d0ecaf6278ba4c24843f65fb2fa Author: Justus Winter Date: Wed Dec 2 12:12:55 2015 +0100 random: Drop fake entropy gathering function. * random/random-csprng.c (faked_rng): Drop variable. (gather_faked): Drop prototype and function. (initialize): Drop fallback code. (_gcry_rngcsprng_is_faked): Change accordingly. -- The fake entropy gathering function is deemed too dangerous to be used by accident, and is therefore removed. This reverts commit 468a5796ffb1a7776db4004d534376c1b981d740. Signed-off-by: Justus Winter diff --git a/random/random-csprng.c b/random/random-csprng.c index 88c5ff8..e7b751a 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -173,12 +173,6 @@ static void (*fast_gather_fnc)(void (*)(const void*, size_t, used by regular applications. */ static int quick_test; -/* On systems without entropy gathering modules, this flag is set to - indicate that the random generator is not working properly. A - warning message is issued as well. This is useful only for - debugging and during development. */ -static int faked_rng; - /* This is the lock we use to protect all pool operations. */ GPGRT_LOCK_DEFINE (pool_lock); @@ -241,8 +235,6 @@ static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t, enum random_origins); static void read_random_source (enum random_origins origin, size_t length, int level); -static int gather_faked (void (*add)(const void*, size_t, enum random_origins), - enum random_origins, size_t length, int level ); @@ -326,11 +318,6 @@ initialize(void) /* Setup the slow entropy gathering function. The code requires that this function exists. */ slow_gather_fnc = getfnc_gather_random (); - if (!slow_gather_fnc) - { - faked_rng = 1; - slow_gather_fnc = gather_faked; - } /* Setup the fast entropy gathering function. */ fast_gather_fnc = getfnc_fast_random_poll (); @@ -453,7 +440,7 @@ _gcry_rngcsprng_is_faked (void) /* We need to initialize due to the runtime determination of available entropy gather modules. */ initialize(); - return (faked_rng || quick_test); + return quick_test; } @@ -1151,9 +1138,9 @@ getfnc_gather_random (void))(void (*)(const void*, size_t, return fnc; #endif - log_info (_("no entropy gathering module detected\n")); + log_fatal (_("no entropy gathering module detected\n")); - return NULL; + return NULL; /*NOTREACHED*/ } /* Runtime determination of the fast entropy gathering function. @@ -1283,40 +1270,3 @@ read_random_source (enum random_origins origin, size_t length, int level) if (slow_gather_fnc (add_randomness, origin, length, level) < 0) log_fatal ("No way to gather entropy for the RNG\n"); } - - -static int -gather_faked (void (*add)(const void*, size_t, enum random_origins), - enum random_origins origin, size_t length, int level ) -{ - static int initialized=0; - size_t n; - char *buffer, *p; - - (void)add; - (void)level; - - if ( !initialized ) - { - log_info(_("WARNING: using insecure random number generator!!\n")); - initialized=1; -#ifdef HAVE_RAND - srand( time(NULL)*getpid()); -#else - srandom( time(NULL)*getpid()); -#endif - } - - p = buffer = xmalloc( length ); - n = length; -#ifdef HAVE_RAND - while ( n-- ) - *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1); -#else - while ( n-- ) - *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); -#endif - add_randomness ( buffer, length, origin ); - xfree (buffer); - return 0; /* okay */ -} ----------------------------------------------------------------------- Summary of changes: random/random-csprng.c | 56 +++----------------------------------------------- 1 file changed, 3 insertions(+), 53 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Thu Dec 3 20:22:28 2015 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Thu, 03 Dec 2015 20:22:28 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-294-g6fadbcd Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 6fadbcd088e2af3e48407b95d8d0c2a8b7ad6c38 (commit) via 2cba0dbda462237f55438d4199eccd10c5e3f6ca (commit) from d421ac283ec46d0ecaf6278ba4c24843f65fb2fa (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6fadbcd088e2af3e48407b95d8d0c2a8b7ad6c38 Author: Jussi Kivilinna Date: Thu Dec 3 21:06:50 2015 +0200 chacha20: fix alignment of self-test context * cipher/chacha20.c (selftest): Ensure 16-byte alignment for chacha20 context structure. -- Signed-off-by: Jussi Kivilinna diff --git a/cipher/chacha20.c b/cipher/chacha20.c index e25e239..613fa82 100644 --- a/cipher/chacha20.c +++ b/cipher/chacha20.c @@ -514,7 +514,8 @@ chacha20_encrypt_stream (void *context, byte * outbuf, const byte * inbuf, static const char * selftest (void) { - CHACHA20_context_t ctx; + byte ctxbuf[sizeof(CHACHA20_context_t) + 15]; + CHACHA20_context_t *ctx; byte scratch[127 + 1]; byte buf[512 + 64 + 4]; int i; @@ -565,46 +566,49 @@ selftest (void) 0x05, 0x3c, 0x84, 0xe4, 0x9a, 0x4a, 0x33 }; - chacha20_setkey (&ctx, key_1, sizeof key_1); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); + /* 16-byte alignment required for amd64 implementation. */ + ctx = (CHACHA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); + + chacha20_setkey (ctx, key_1, sizeof key_1); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); scratch[sizeof (scratch) - 1] = 0; - chacha20_encrypt_stream (&ctx, scratch, plaintext_1, sizeof plaintext_1); + chacha20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1)) return "ChaCha20 encryption test 1 failed."; if (scratch[sizeof (scratch) - 1]) return "ChaCha20 wrote too much."; - chacha20_setkey (&ctx, key_1, sizeof (key_1)); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (&ctx, scratch, scratch, sizeof plaintext_1); + chacha20_setkey (ctx, key_1, sizeof (key_1)); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) return "ChaCha20 decryption test 1 failed."; for (i = 0; i < sizeof buf; i++) buf[i] = i; - chacha20_setkey (&ctx, key_1, sizeof key_1); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); + chacha20_setkey (ctx, key_1, sizeof key_1); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); /*encrypt */ - chacha20_encrypt_stream (&ctx, buf, buf, sizeof buf); + chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); /*decrypt */ - chacha20_setkey (&ctx, key_1, sizeof key_1); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (&ctx, buf, buf, 1); - chacha20_encrypt_stream (&ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1); - chacha20_encrypt_stream (&ctx, buf + (sizeof buf) - 1, + chacha20_setkey (ctx, key_1, sizeof key_1); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, buf, buf, 1); + chacha20_encrypt_stream (ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1); + chacha20_encrypt_stream (ctx, buf + (sizeof buf) - 1, buf + (sizeof buf) - 1, 1); for (i = 0; i < sizeof buf; i++) if (buf[i] != (byte) i) return "ChaCha20 encryption test 2 failed."; - chacha20_setkey (&ctx, key_1, sizeof key_1); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); + chacha20_setkey (ctx, key_1, sizeof key_1); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); /* encrypt */ for (i = 0; i < sizeof buf; i++) - chacha20_encrypt_stream (&ctx, &buf[i], &buf[i], 1); + chacha20_encrypt_stream (ctx, &buf[i], &buf[i], 1); /* decrypt */ - chacha20_setkey (&ctx, key_1, sizeof key_1); - chacha20_setiv (&ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (&ctx, buf, buf, sizeof buf); + chacha20_setkey (ctx, key_1, sizeof key_1); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); for (i = 0; i < sizeof buf; i++) if (buf[i] != (byte) i) return "ChaCha20 encryption test 3 failed."; commit 2cba0dbda462237f55438d4199eccd10c5e3f6ca Author: Jussi Kivilinna Date: Thu Dec 3 21:06:50 2015 +0200 salsa20: fix alignment of self-test context * cipher/salsa20.c (selftest): Ensure 16-byte alignment for salsa20 context structure. -- Reported-by: Carlos J Puga Medina Signed-off-by: Jussi Kivilinna diff --git a/cipher/salsa20.c b/cipher/salsa20.c index fa3d23b..9768198 100644 --- a/cipher/salsa20.c +++ b/cipher/salsa20.c @@ -501,7 +501,8 @@ salsa20r12_encrypt_stream (void *context, static const char* selftest (void) { - SALSA20_context_t ctx; + byte ctxbuf[sizeof(SALSA20_context_t) + 15]; + SALSA20_context_t *ctx; byte scratch[8+1]; byte buf[256+64+4]; int i; @@ -518,32 +519,35 @@ selftest (void) static const byte ciphertext_1[] = { 0xE3, 0xBE, 0x8F, 0xDD, 0x8B, 0xEC, 0xA2, 0xE3}; - salsa20_setkey (&ctx, key_1, sizeof key_1); - salsa20_setiv (&ctx, nonce_1, sizeof nonce_1); + /* 16-byte alignment required for amd64 implementation. */ + ctx = (SALSA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); + + salsa20_setkey (ctx, key_1, sizeof key_1); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); scratch[8] = 0; - salsa20_encrypt_stream (&ctx, scratch, plaintext_1, sizeof plaintext_1); + salsa20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); if (memcmp (scratch, ciphertext_1, sizeof ciphertext_1)) return "Salsa20 encryption test 1 failed."; if (scratch[8]) return "Salsa20 wrote too much."; - salsa20_setkey( &ctx, key_1, sizeof(key_1)); - salsa20_setiv (&ctx, nonce_1, sizeof nonce_1); - salsa20_encrypt_stream (&ctx, scratch, scratch, sizeof plaintext_1); + salsa20_setkey( ctx, key_1, sizeof(key_1)); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + salsa20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) return "Salsa20 decryption test 1 failed."; for (i = 0; i < sizeof buf; i++) buf[i] = i; - salsa20_setkey (&ctx, key_1, sizeof key_1); - salsa20_setiv (&ctx, nonce_1, sizeof nonce_1); + salsa20_setkey (ctx, key_1, sizeof key_1); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); /*encrypt*/ - salsa20_encrypt_stream (&ctx, buf, buf, sizeof buf); + salsa20_encrypt_stream (ctx, buf, buf, sizeof buf); /*decrypt*/ - salsa20_setkey (&ctx, key_1, sizeof key_1); - salsa20_setiv (&ctx, nonce_1, sizeof nonce_1); - salsa20_encrypt_stream (&ctx, buf, buf, 1); - salsa20_encrypt_stream (&ctx, buf+1, buf+1, (sizeof buf)-1-1); - salsa20_encrypt_stream (&ctx, buf+(sizeof buf)-1, buf+(sizeof buf)-1, 1); + salsa20_setkey (ctx, key_1, sizeof key_1); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + salsa20_encrypt_stream (ctx, buf, buf, 1); + salsa20_encrypt_stream (ctx, buf+1, buf+1, (sizeof buf)-1-1); + salsa20_encrypt_stream (ctx, buf+(sizeof buf)-1, buf+(sizeof buf)-1, 1); for (i = 0; i < sizeof buf; i++) if (buf[i] != (byte)i) return "Salsa20 encryption test 2 failed."; ----------------------------------------------------------------------- Summary of changes: cipher/chacha20.c | 46 +++++++++++++++++++++++++--------------------- cipher/salsa20.c | 34 +++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 36 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From gniibe at fsij.org Fri Dec 4 06:58:02 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 04 Dec 2015 14:58:02 +0900 Subject: ecc: Montgomery curve always uses the prefix 0x40 In-Reply-To: <565672EF.10400@fsij.org> References: <56494B98.4020103@fsij.org> <565672EF.10400@fsij.org> Message-ID: <56612B6A.7050904@fsij.org> Hello, I think that this is the final version. This patch supports data created older development version of libgcrypt. It was possible that the zero octets were removed when parsed as MPI. This patch recovers the value for such a data. diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 2f2e593..67e3b3d 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -292,6 +292,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { + unsigned char *a; unsigned char *rawmpi; unsigned int rawmpilen; @@ -311,8 +312,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) buf++; } - rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); - if (!rawmpi) + a = rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); + if (!a) return gpg_err_code_from_syserror (); p = rawmpi + rawmpilen; @@ -321,16 +322,47 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) } else { - /* Note: Without using an opaque MPI it is not reliable possible - to find out whether the public key has been given in - uncompressed format. Thus we expect native EdDSA format. */ - rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); - if (!rawmpi) + a = rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); + if (!a) return gpg_err_code_from_syserror (); + /* + * It is not reliable to assume that 0x40 means the prefix. + * + * For newer implementation, it is reliable since we always put + * 0x40 for x-only coordinate. + * + * For data with older implementation (non-released development + * version), it is possibe to have the 0x40 as a part of data. + * Besides, when data was parsed as MPI, we might have 0x00 + * prefix. + * + * So, we need to check if it's really the prefix or not. + * Only when it's the prefix, we remove it. + */ + if (ctx->nbits/8 == rawmpilen - 1) + rawmpi++; + else if (rawmpilen < ctx->nbits/8) + {/* + * It is possible for data created by older implementation + * to have shorter length when it was parsed as MPI. + */ + unsigned int new_rawmpilen = ctx->nbits/8; + + rawmpi = xtrymalloc (new_rawmpilen); + if (!rawmpi) + { + gpg_err_code_t err = gpg_err_code_from_syserror (); + xfree (a); + return err; + } + + memset (rawmpi, 0, new_rawmpilen - rawmpilen); + memcpy (rawmpi + new_rawmpilen - rawmpilen, a, rawmpilen); + } } _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0); - xfree (rawmpi); + xfree (a); mpi_set_ui (result->z, 1); return 0; diff --git a/cipher/ecc.c b/cipher/ecc.c index bd3e754..51621f8 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -606,17 +606,14 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) &encpk, &encpklen); else { - int off = !!(flags & PUBKEY_FLAG_COMP); - - encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, off?-1:0, + encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, -1, &encpklen, NULL); if (encpk == NULL) rc = gpg_err_code_from_syserror (); else { - if (off) - encpk[0] = 0x40; - encpklen += off; + encpk[0] = 0x40; + encpklen++; } } if (rc) @@ -1374,11 +1371,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; mpi_s = mpi_new (0); mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8); } @@ -1393,11 +1392,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; mpi_e = mpi_new (0); mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8); } @@ -1587,11 +1588,13 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) unsigned char *rawmpi; unsigned int rawmpilen; - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; r = mpi_new (0); mpi_set_opaque (r, rawmpi, rawmpilen*8); } -- From cvs at cvs.gnupg.org Sat Dec 5 02:18:40 2015 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Sat, 05 Dec 2015 02:18:40 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-295-gdd3d06e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via dd3d06e7f113cf7608f060ceb043262efd0b0c9d (commit) from 6fadbcd088e2af3e48407b95d8d0c2a8b7ad6c38 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit dd3d06e7f113cf7608f060ceb043262efd0b0c9d Author: NIIBE Yutaka Date: Sat Dec 5 10:08:51 2015 +0900 ecc: CHANGE point representation of Curve25519. * cipher/ecc-misc.c (_gcry_ecc_mont_decodepoint): Decode point with the prefix 0x40, additional 0x00 by MPI handling, and shorter octets by MPI normalization. * cipher/ecc.c (ecc_generate, ecc_encrypt_raw, ecc_decrypt_raw): Always add the prefix 0x40. -- Curve25519 native little-endian point representation is not friendly to existing practice of OpenPGP code, where MPI is assumed. MPI handling might insert 0x00 in the beginning to avoid sign confusion. MPI handling also might remove 0x00s in the front. So, it is safe to put the prefix 0x40. While we support old point representation of no prefix in ecc_mont_decodepoint, new libgcrypt always put the prefix. diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 2f2e593..67e3b3d 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -292,6 +292,7 @@ _gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec, gpg_err_code_t _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) { + unsigned char *a; unsigned char *rawmpi; unsigned int rawmpilen; @@ -311,8 +312,8 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) buf++; } - rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); - if (!rawmpi) + a = rawmpi = xtrymalloc (rawmpilen? rawmpilen:1); + if (!a) return gpg_err_code_from_syserror (); p = rawmpi + rawmpilen; @@ -321,16 +322,47 @@ _gcry_ecc_mont_decodepoint (gcry_mpi_t pk, mpi_ec_t ctx, mpi_point_t result) } else { - /* Note: Without using an opaque MPI it is not reliable possible - to find out whether the public key has been given in - uncompressed format. Thus we expect native EdDSA format. */ - rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); - if (!rawmpi) + a = rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL); + if (!a) return gpg_err_code_from_syserror (); + /* + * It is not reliable to assume that 0x40 means the prefix. + * + * For newer implementation, it is reliable since we always put + * 0x40 for x-only coordinate. + * + * For data with older implementation (non-released development + * version), it is possibe to have the 0x40 as a part of data. + * Besides, when data was parsed as MPI, we might have 0x00 + * prefix. + * + * So, we need to check if it's really the prefix or not. + * Only when it's the prefix, we remove it. + */ + if (ctx->nbits/8 == rawmpilen - 1) + rawmpi++; + else if (rawmpilen < ctx->nbits/8) + {/* + * It is possible for data created by older implementation + * to have shorter length when it was parsed as MPI. + */ + unsigned int new_rawmpilen = ctx->nbits/8; + + rawmpi = xtrymalloc (new_rawmpilen); + if (!rawmpi) + { + gpg_err_code_t err = gpg_err_code_from_syserror (); + xfree (a); + return err; + } + + memset (rawmpi, 0, new_rawmpilen - rawmpilen); + memcpy (rawmpi + new_rawmpilen - rawmpilen, a, rawmpilen); + } } _gcry_mpi_set_buffer (result->x, rawmpi, rawmpilen, 0); - xfree (rawmpi); + xfree (a); mpi_set_ui (result->z, 1); return 0; diff --git a/cipher/ecc.c b/cipher/ecc.c index bd3e754..51621f8 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -606,17 +606,14 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) &encpk, &encpklen); else { - int off = !!(flags & PUBKEY_FLAG_COMP); - - encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, off?-1:0, + encpk = _gcry_mpi_get_buffer_extra (Qx, ctx->nbits/8, -1, &encpklen, NULL); if (encpk == NULL) rc = gpg_err_code_from_syserror (); else { - if (off) - encpk[0] = 0x40; - encpklen += off; + encpk[0] = 0x40; + encpklen++; } } if (rc) @@ -1374,11 +1371,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; mpi_s = mpi_new (0); mpi_set_opaque (mpi_s, rawmpi, rawmpilen*8); } @@ -1393,11 +1392,13 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p); else { - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; mpi_e = mpi_new (0); mpi_set_opaque (mpi_e, rawmpi, rawmpilen*8); } @@ -1587,11 +1588,13 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) unsigned char *rawmpi; unsigned int rawmpilen; - rawmpi = _gcry_mpi_get_buffer (x, ec->nbits/8, &rawmpilen, NULL); + rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, + &rawmpilen, NULL); if (!rawmpi) rc = gpg_err_code_from_syserror (); else { + rawmpi[0] = 0x40; r = mpi_new (0); mpi_set_opaque (r, rawmpi, rawmpilen*8); } ----------------------------------------------------------------------- Summary of changes: cipher/ecc-misc.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- cipher/ecc.c | 21 ++++++++++++--------- 2 files changed, 52 insertions(+), 17 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From hanno at hboeck.de Sat Dec 5 11:11:58 2015 From: hanno at hboeck.de (Hanno =?UTF-8?B?QsO2Y2s=?=) Date: Sat, 5 Dec 2015 11:11:58 +0100 Subject: [PATCH] fix api doc for gcry_mpi_ec_new Message-ID: <20151205111158.096164b7@pc1> Hi, I think I found an error in the API doc of libgcrypt. See here: https://gnupg.org/documentation/manuals/gcrypt/EC-functions.html This page is as far as I assume somehow autogenerated from gcrypt.texi in the libgcrypt source: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=blob;f=doc/gcrypt.texi;h=cdb76445aae77f41702a3fe22939faeaa87d7a9e;hb=HEAD The function gcry_mpi_ec_p_new does not exist in current versions of libgcrypt. The function that should be documented here is called gcry_mpi_ec_new now. Also the type of the context is not gpg_ctx_t (that type doesn't exist, at least not in the public gcrypt api), it is gcry_ctx_t. Patch attached, please apply. Hanno -- Hanno B?ck http://hboeck.de/ mail/jabber: hanno at hboeck.de GPG: BBB51E42 -------------- next part -------------- A non-text attachment was scrubbed... Name: libgcrypt-fix-gcry_mpi_ec_new-apidoc.diff Type: text/x-patch Size: 458 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From hanno at hboeck.de Mon Dec 7 09:09:32 2015 From: hanno at hboeck.de (Hanno =?UTF-8?B?QsO2Y2s=?=) Date: Mon, 7 Dec 2015 09:09:32 +0100 Subject: wrong results and hang in gcry_mpi_invm() Message-ID: <20151207090932.2263bc68@pc1> Hi, I want to report two issues with the function gcry_mpi_invm(). In many cases where there exists no inverse the function will not detect that and produce a wrong result. A very simple example is calculating the inverse of 2 mod 4. gcry_mpi_inv will calculate the inverse to be 1, which is obviously wrong. It will set the return value to 1, while it should set it to 0 if no inverse exists. A second issue is that when one sets the modulus to zero the function will hang forever. This may be seen as okay, because this is an invalid input, but I think it would still be better to return an "inverse doesn't exist" / 0 return code. I have attached simple example files for both issues. -- Hanno B?ck http://hboeck.de/ mail/jabber: hanno at hboeck.de GPG: BBB51E42 -------------- next part -------------- A non-text attachment was scrubbed... Name: gcrypt-invm-hang.c Type: text/x-c++src Size: 351 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: gcrypt-invm-wrongresult.c Type: text/x-c++src Size: 351 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From cvs at cvs.gnupg.org Mon Dec 7 13:01:32 2015 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 07 Dec 2015 13:01:32 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-297-gb9c02fb Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via b9c02fbeb7efb7d0593b33485fb30c298291cf80 (commit) via ca06cd7f77acb317c2649c58918908f043dfe6bd (commit) from dd3d06e7f113cf7608f060ceb043262efd0b0c9d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b9c02fbeb7efb7d0593b33485fb30c298291cf80 Author: Justus Winter Date: Mon Dec 7 12:44:48 2015 +0100 cipher: Improve error handling. * cipher/ecc.c (ecc_decrypt_raw): Improve error handling. -- Found using the Clang Static Analyzer. Signed-off-by: Justus Winter diff --git a/cipher/ecc.c b/cipher/ecc.c index e4e9139..105650e 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1591,7 +1591,10 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) rawmpi = _gcry_mpi_get_buffer_extra (x, ec->nbits/8, -1, &rawmpilen, NULL); if (!rawmpi) - rc = gpg_err_code_from_syserror (); + { + rc = gpg_err_code_from_syserror (); + goto leave; + } else { rawmpi[0] = 0x40; commit ca06cd7f77acb317c2649c58918908f043dfe6bd Author: Justus Winter Date: Mon Dec 7 12:39:41 2015 +0100 cipher: Initialize 'flags'. * cipher/ecc.c (ecc_encrypt_raw): Initialize 'flags' to 0. -- Found using the Clang Static Analyzer. Signed-off-by: Justus Winter diff --git a/cipher/ecc.c b/cipher/ecc.c index 51621f8..e4e9139 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1242,7 +1242,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) gcry_mpi_t data = NULL; ECC_public_key pk; mpi_ec_t ec = NULL; - int flags; + int flags = 0; memset (&pk, 0, sizeof pk); _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, ----------------------------------------------------------------------- Summary of changes: cipher/ecc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Mon Dec 7 13:02:43 2015 From: cvs at cvs.gnupg.org (by Justus Winter) Date: Mon, 07 Dec 2015 13:02:43 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-298-gb384f1a Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via b384f1a10cbf806cc889f5929b489a6c9efc0bd1 (commit) from b9c02fbeb7efb7d0593b33485fb30c298291cf80 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b384f1a10cbf806cc889f5929b489a6c9efc0bd1 Author: Justus Winter Date: Wed Dec 2 12:49:59 2015 +0100 doc: Fix typo. -- Signed-off-by: Justus Winter diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index cdb7644..f60be77 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -4180,7 +4180,7 @@ logging stream. @noindent Often canonical encoding is used in the external representation. The following function can be used to check for valid encoding and to learn -the length of the S-expression" +the length of the S-expression. @deftypefun size_t gcry_sexp_canon_len (@w{const unsigned char *@var{buffer}}, @w{size_t @var{length}}, @w{size_t *@var{erroff}}, @w{int *@var{errcode}}) ----------------------------------------------------------------------- Summary of changes: doc/gcrypt.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From gniibe at fsij.org Tue Dec 8 09:07:31 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 08 Dec 2015 17:07:31 +0900 Subject: ecc: compact representation of an elliptic curve point Message-ID: <56668FC3.7000203@fsij.org> Hello, This week, I look ECC implementation and I found a bug in compact representation handling. The reference is now: https://www.ietf.org/archive/id/draft-jivsov-ecc-compact-05.txt The problem is that we have a path for MPI_EC_EDWARDS which handles x-coordinate. But comparison will be done with y-coordinate. I wrote a patch like following. I think that other Edwards curves would follow the practice of Ed25519 for its secret key tweak, so, this is likely to be a dead path. Nevertheless, to avoid confusion, it makes sence to appy this fix. diff --git a/cipher/ecc.c b/cipher/ecc.c index 51621f8..1933978 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -195,15 +195,22 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, else { gcry_mpi_t negative; + int comparison; negative = mpi_new (pbits); if (E->model == MPI_EC_WEIERSTRASS) - mpi_sub (negative, E->p, y); /* negative = p - y */ + { + mpi_sub (negative, E->p, y); /* negative = p - y */ + comparison = mpi_cmp (negative, y); + } else - mpi_sub (negative, E->p, x); /* negative = p - x */ + { + mpi_sub (negative, E->p, x); /* negative = p - x */ + comparison = mpi_cmp (negative, x); + } - if (mpi_cmp (negative, y) < 0) /* p - y < p */ + if (comparison < 0) /* p - y < p (or p - x < p) */ { /* We need to end up with -Q; this assures that new Q's y is the smallest one */ -- From wk at gnupg.org Tue Dec 8 20:13:52 2015 From: wk at gnupg.org (Werner Koch) Date: Tue, 08 Dec 2015 20:13:52 +0100 Subject: wrong results and hang in gcry_mpi_invm() In-Reply-To: <20151207090932.2263bc68@pc1> ("Hanno =?utf-8?Q?B=C3=B6ck=22'?= =?utf-8?Q?s?= message of "Mon, 7 Dec 2015 09:09:32 +0100") References: <20151207090932.2263bc68@pc1> Message-ID: <87si3clpn3.fsf@vigenere.g10code.de> On Mon, 7 Dec 2015 09:09, hanno at hboeck.de said: > I want to report two issues with the function gcry_mpi_invm(). Thanks. Actually, we know about this and I have a fix stashed for quite some time. However, there are backward compatibility problems which is the reason why it has been delayed. The MPI functions have originally been written for internal use by Libgcrypt and thus they have some restrictions (e.g. no ENOMEM and that limited invm) Thanks for raising this again. We should fix it for 1.7. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From xxiao8 at fosiao.com Tue Dec 8 21:27:25 2015 From: xxiao8 at fosiao.com (xxiao8) Date: Tue, 8 Dec 2015 14:27:25 -0600 Subject: libgcrypt cavs test vector In-Reply-To: References: Message-ID: <56673D2D.1030304@fosiao.com> Is there some pre-made testing vectors to run cavs_test.sh with? something like openssl's test_vector zip file. Thanks, xxiao From xxiao8 at fosiao.com Tue Dec 8 22:50:55 2015 From: xxiao8 at fosiao.com (xxiao8) Date: Tue, 8 Dec 2015 15:50:55 -0600 Subject: libgcrypt cavs test vector In-Reply-To: References: <56673D2D.1030304@fosiao.com> Message-ID: <566750BF.5010800@fosiao.com> Those are executables not the vector files such as the CBCGFSbox128.req, i.e. those KAT(know-answer-testing) vector sets. For example openssl has fips-2.0-tv.tar.gz at the bottom from https://www.openssl.org/docs/fips/ Thanks, xxiao On 12/08/2015 03:21 PM, davide alessio wrote: > yes, there is. > look into the test directory, you'll find cav_driver.pl > and cavs_test.sh. > They use the fipsdrv binary to run all the tests. > > On 8 December 2015 at 21:27, xxiao8 > wrote: > > Is there some pre-made testing vectors to run cavs_test.sh with? > something like openssl's test_vector zip file. > > Thanks, > xxiao > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > > > > > -- > Me. From affensoldat at gmail.com Tue Dec 8 22:21:54 2015 From: affensoldat at gmail.com (davide alessio) Date: Tue, 8 Dec 2015 22:21:54 +0100 Subject: libgcrypt cavs test vector In-Reply-To: <56673D2D.1030304@fosiao.com> References: <56673D2D.1030304@fosiao.com> Message-ID: yes, there is. look into the test directory, you'll find cav_driver.pl and cavs_test.sh. They use the fipsdrv binary to run all the tests. On 8 December 2015 at 21:27, xxiao8 wrote: > Is there some pre-made testing vectors to run cavs_test.sh with? something > like openssl's test_vector zip file. > > Thanks, > xxiao > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > -- Me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From affensoldat at gmail.com Tue Dec 8 23:00:13 2015 From: affensoldat at gmail.com (davide alessio) Date: Tue, 8 Dec 2015 23:00:13 +0100 Subject: libgcrypt cavs test vector In-Reply-To: <566750BF.5010800@fosiao.com> References: <56673D2D.1030304@fosiao.com> <566750BF.5010800@fosiao.com> Message-ID: On 8 December 2015 at 22:50, xxiao8 wrote: > Those are executables not the vector files such as the CBCGFSbox128.req, > i.e. those KAT(know-answer-testing) vector sets. > Ok, sorry, I misunderstood the question. BTW you can use the same req file, tests are implemented in the same way under libgcrypt. > > For example openssl has fips-2.0-tv.tar.gz at the bottom from > https://www.openssl.org/docs/fips/ > > Thanks, > xxiao > > > On 12/08/2015 03:21 PM, davide alessio wrote: > >> yes, there is. >> look into the test directory, you'll find cav_driver.pl >> and cavs_test.sh. >> They use the fipsdrv binary to run all the tests. >> >> On 8 December 2015 at 21:27, xxiao8 > > wrote: >> >> Is there some pre-made testing vectors to run cavs_test.sh with? >> something like openssl's test_vector zip file. >> >> Thanks, >> xxiao >> >> >> _______________________________________________ >> Gcrypt-devel mailing list >> Gcrypt-devel at gnupg.org >> http://lists.gnupg.org/mailman/listinfo/gcrypt-devel >> >> >> >> >> -- >> Me. >> > > -- Me. -------------- next part -------------- An HTML attachment was scrubbed... URL: From gniibe at fsij.org Wed Dec 9 04:12:01 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 09 Dec 2015 12:12:01 +0900 Subject: ecc: effort so that we can enable barret reduction Message-ID: <56679C01.8040300@fsij.org> Hello, Following patch is the one which allow a user to enable GCRYPT_BARRETT. With this patch, it goes well for make check. IIUC, the implementation of Barrett reduction assumes positive MPI. It would be worth to consider applying this when someone claims it doesn't work with GCRYPT_BARRETT. diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index a74501d..0394646 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -123,8 +123,8 @@ static const ecc_domain_parms_t domain_parms[] = "Ed25519", 256, 0, MPI_EC_EDWARDS, ECC_DIALECT_ED25519, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", + "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658", diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c index 2a52b78..f91f848 100644 --- a/cipher/ecc-eddsa.c +++ b/cipher/ecc-eddsa.c @@ -251,7 +251,7 @@ _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec) mpi_mulm (t, x, x, ec->p); mpi_mulm (t, t, v, ec->p); /* -t == u ? x = x * sqrt(-1) */ - mpi_neg (t, t); + mpi_sub (t, ec->p, t); if (!mpi_cmp (t, u)) { static gcry_mpi_t m1; /* Fixme: this is not thread-safe. */ @@ -263,7 +263,7 @@ _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec) mpi_mulm (t, x, x, ec->p); mpi_mulm (t, t, v, ec->p); /* -t == u ? x = x * sqrt(-1) */ - mpi_neg (t, t); + mpi_sub (t, ec->p, t); if (!mpi_cmp (t, u)) rc = GPG_ERR_INV_OBJ; } @@ -835,7 +835,7 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey, _gcry_mpi_ec_mul_point (&Ia, s, &pkey->E.G, ctx); _gcry_mpi_ec_mul_point (&Ib, h, &Q, ctx); - _gcry_mpi_neg (Ib.x, Ib.x); + _gcry_mpi_sub (Ib.x, ctx->p, Ib.x); _gcry_mpi_ec_add_points (&Ia, &Ia, &Ib, ctx); rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, 0, &tbuf, &tlen); if (rc) diff --git a/cipher/ecc.c b/cipher/ecc.c index 1933978..6ea77e5 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1765,6 +1765,12 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) &values[3], &values[4], &values[5]); if (rc) goto leave; + + if (!strcmp (curvename, "Ed25519")) + { + mpi_sub (values[1], values[1], values[0]); + mpi_sub (values[2], values[2], values[0]); + } } } diff --git a/mpi/ec.c b/mpi/ec.c index 40e09be..cd24e87 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -275,8 +275,9 @@ ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) static void ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec) { - (void)ec; mpi_sub (w, u, v); + while (w->sign) + mpi_add (w, w, ec->p); /*ec_mod (w, ec);*/ } @@ -790,10 +791,7 @@ dup_point_edwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx) /* E = aC */ if (ctx->dialect == ECC_DIALECT_ED25519) - { - mpi_set (E, C); - _gcry_mpi_neg (E, E); - } + mpi_sub (E, ctx->p, C); else ec_mulm (E, ctx->a, C, ctx); @@ -1071,11 +1069,7 @@ add_points_edwards (mpi_point_t result, /* Y_3 = A ? G ? (D - aC) */ if (ctx->dialect == ECC_DIALECT_ED25519) { - /* Using ec_addm (Y3, D, C, ctx) is possible but a litte bit - slower because a subm does currently skip the mod step. */ - mpi_set (Y3, C); - _gcry_mpi_neg (Y3, Y3); - ec_subm (Y3, D, Y3, ctx); + ec_addm (Y3, D, C, ctx); } else { @@ -1197,7 +1191,7 @@ sub_points_edwards (mpi_point_t result, { mpi_point_t p2i = _gcry_mpi_point_new (0); point_set (p2i, p2); - _gcry_mpi_neg (p2i->x, p2i->x); + mpi_sub (p2i->x, ctx->p, p2i->x); add_points_edwards (result, p1, p2i, ctx); _gcry_mpi_point_release (p2i); } @@ -1515,10 +1509,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) ec_pow2 (x, x, ctx); ec_pow2 (y, y, ctx); if (ctx->dialect == ECC_DIALECT_ED25519) - { - mpi_set (w, x); - _gcry_mpi_neg (w, w); - } + mpi_sub (w, ctx->p, x); else ec_mulm (w, ctx->a, x, ctx); ec_addm (w, w, y, ctx); diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index d72cd27..ccf9cc4 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -130,8 +130,8 @@ static struct { "Ed25519", "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", + "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658", -- From gniibe at fsij.org Thu Dec 10 08:47:48 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 10 Dec 2015 16:47:48 +0900 Subject: ecc: ec_addm/ec_subm improvement Message-ID: <56692E24.2090200@fsij.org> Hello, While this patch is not mature yet, I'd like to share the idea. Large picture is computing curve point with MPI which always has fixed number of limbs, so that computation can be constant time. Bonus point is it will be somewhat faster and a bit smaller memory footprint. ec_addm/ec_subm doesn't need to be reduced by the prime, and the value can be somewhat redundant. When it encounter carry to another limb, it does something with the prime. The change in this patch itself includes non-constant-time path, it should be improved. It build and works well by 'make check' when applied over the positive-value-only patch. diff --git a/mpi/ec.c b/mpi/ec.c index cd24e87..d51a69b 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -268,17 +268,114 @@ ec_mod (gcry_mpi_t w, mpi_ec_t ec) static void ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) { - mpi_add (w, u, v); - ec_mod (w, ctx); + mpi_ptr_t wp, up, vp; + mpi_size_t usize, vsize, wsize; + mpi_limb_t cy; + + gcry_assert (u->sign == 0 && v->sign == 0); + + if ( u->nlimbs < v->nlimbs ) + { /* Swap U and V. */ + usize = v->nlimbs; + vsize = u->nlimbs; + wsize = usize; + RESIZE_IF_NEEDED (w, wsize); + up = v->d; + vp = u->d; + } + else + { + usize = u->nlimbs; + vsize = v->nlimbs; + wsize = usize; + RESIZE_IF_NEEDED (w, wsize); + up = u->d; + vp = v->d; + } + wp = w->d; + + if ( !vsize ) + { + cy = 0; + MPN_COPY (wp, up, usize); + } + else + cy = _gcry_mpih_add (wp, up, usize, vp, vsize); + + w->sign = 0; + if (wsize == ctx->p->nlimbs) + { + if (cy) + _gcry_mpih_sub_n (wp, wp, ctx->p->d, wsize); + w->nlimbs = wsize; + } + else + { + if (cy) + { + wsize++; + RESIZE_IF_NEEDED (w, wsize); + w->d[usize] = cy; + } + w->nlimbs = wsize; + } } static void -ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec) +ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx) { - mpi_sub (w, u, v); - while (w->sign) - mpi_add (w, w, ec->p); - /*ec_mod (w, ec);*/ + mpi_ptr_t wp, up, vp; + mpi_size_t usize, vsize, wsize; + mpi_limb_t cy; + int sign; + + gcry_assert (u->sign == 0 && v->sign == 0); + + w->sign = 0; + wsize = ctx->p->nlimbs; + RESIZE_IF_NEEDED (w, wsize); + wp = w->d; + + if ( u->nlimbs < v->nlimbs ) + { /* Swap U and V. */ + sign = 1; + usize = v->nlimbs; + vsize = u->nlimbs; + up = v->d; + vp = u->d; + } + else + { + sign = 0; + usize = u->nlimbs; + vsize = v->nlimbs; + up = u->d; + vp = v->d; + } + + cy = _gcry_mpih_sub (wp, up, usize, vp, vsize); + memset (wp + usize, cy?~0:0, (wsize - usize) * BYTES_PER_MPI_LIMB); + + if (cy && !sign) + _gcry_mpih_add_n (wp, wp, ctx->p->d, wsize); + else if (cy && sign) + { + size_t i; + + for (i = 0; i < wsize; i++) + w->d[i] = ~w->d[i]; + + _gcry_mpih_add_1 (wp, wp, wsize, 1); + } + else if (!cy && !sign) + ; + else if (!cy && sign) + _gcry_mpih_sub_n (wp, ctx->p->d, wp, wsize); + +#if 0 + MPN_NORMALIZE (wp, wsize); +#endif + w->nlimbs = wsize; } static void @@ -1463,6 +1560,7 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) ec_mulm (w, ctx->a, x, ctx); ec_addm (w, w, ctx->b, ctx); ec_addm (w, w, xxx, ctx); + ec_mod (w, ctx); if (!mpi_cmp (y, w)) res = 1; @@ -1517,6 +1615,8 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) ec_mulm (x, x, y, ctx); ec_mulm (x, x, ctx->b, ctx); ec_subm (w, w, x, ctx); + ec_mod (w, ctx); + if (!mpi_cmp_ui (w, 0)) res = 1; } -- From wk at gnupg.org Sat Dec 12 14:27:40 2015 From: wk at gnupg.org (Werner Koch) Date: Sat, 12 Dec 2015 14:27:40 +0100 Subject: ecc: ec_addm/ec_subm improvement In-Reply-To: <56692E24.2090200@fsij.org> (NIIBE Yutaka's message of "Thu, 10 Dec 2015 16:47:48 +0900") References: <56692E24.2090200@fsij.org> Message-ID: <87poybajar.fsf@vigenere.g10code.de> On Thu, 10 Dec 2015 08:47, gniibe at fsij.org said: > The change in this patch itself includes non-constant-time path, > it should be improved. In ec.c we do not use any MPI internals. I would suggest to move the bulk of the code out to a new mpi_add_someothername function. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From gniibe at fsij.org Mon Dec 14 01:06:22 2015 From: gniibe at fsij.org (NIIBE Yutaka) Date: Mon, 14 Dec 2015 09:06:22 +0900 Subject: ecc: ec_addm/ec_subm improvement In-Reply-To: <87poybajar.fsf@vigenere.g10code.de> References: <56692E24.2090200@fsij.org> <87poybajar.fsf@vigenere.g10code.de> Message-ID: <566E07FE.7040505@fsij.org> On 12/12/2015 10:27 PM, Werner Koch wrote: > In ec.c we do not use any MPI internals. I would suggest to move the > bulk of the code out to a new mpi_add_someothername function. Yes, I think I share this view. In the scope of mine, the major targets are improvement of Ed25519 and possibly introducing Goldilocks. Although my current changes are not directly related to them, I'm learning how current implementation doesn't depend on MPI internals. Modern ECC design puts enough effort for choosing a finite field. While MPI gives us the infrastructure for any finite fields, for a specific finite field (for a modern ECC curve), it would be better to provide a set of specific dedicated routines. I think that there are three things (at least). (1) redundant representation For a implementation, it's better to relax the condition for representation (in some cases), and it will have no bad effect. It's OK not to represent a number in finite field by an exact single representation, but to allow multiple representations. In the example of ec_addm/ec_subm change, number 1 can be represented by "1" and "p+1". When we do the changes for this, I'm considering to introduce fixed-sized-limb computation, so that it will be constant-time. (2) reduce function (like ec_mod) Even before modern ECC design, a finite field had been chosen so that reduction could be done fast. It would be better to provide each reduce function for a specific finite field, for better performance. (3) reduced-radix or full-radix representation By reduced-radix approach (using more bits to represent a finite field number), addition and subtraction can be done with no-carry and multiplication can be simplified; This would be good for some popular processors. But it's not always better. Full-radix approach is better for some embedded processors, for example. I'm not sure if it's good for libgcrypt to allow different internal representations for different processors. Reduced-radix representation can be considered a variant of redundant representation, going further. -- From cvs at cvs.gnupg.org Sun Dec 27 20:31:28 2015 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sun, 27 Dec 2015 20:31:28 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-300-g5a78e7f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 5a78e7f15e0dd96a8bf64e2bb142880bf8ea6965 (commit) via a5a87d2b8627314593b06d19018484a7f7701227 (commit) from b384f1a10cbf806cc889f5929b489a6c9efc0bd1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5a78e7f15e0dd96a8bf64e2bb142880bf8ea6965 Author: Werner Koch Date: Sun Dec 27 12:39:45 2015 +0100 random: Take at max 25% from RDRAND * random/rndlinux.c (_gcry_rndlinux_gather_random): Change use of RDRAND from 50% to 25%. Signed-off-by: Werner Koch diff --git a/random/rndlinux.c b/random/rndlinux.c index 9eeec57..0cb65df 100644 --- a/random/rndlinux.c +++ b/random/rndlinux.c @@ -139,10 +139,18 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, /* First read from a hardware source. However let it account only - for up to 50% of the requested bytes. */ + for up to 50% (or 25% for RDRAND) of the requested bytes. */ n_hw = _gcry_rndhw_poll_slow (add, origin); - if (n_hw > length/2) - n_hw = length/2; + if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND)) + { + if (n_hw > length/4) + n_hw = length/4; + } + else + { + if (n_hw > length/2) + n_hw = length/2; + } if (length > 1) length -= n_hw; commit a5a87d2b8627314593b06d19018484a7f7701227 Author: Werner Koch Date: Fri Oct 2 15:05:19 2015 +0200 doc: Typo fix and .gitignore addition. -- diff --git a/.gitignore b/.gitignore index 3929e4d..b961614 100644 --- a/.gitignore +++ b/.gitignore @@ -72,6 +72,7 @@ tests/benchmark tests/fips186-dsa tests/fipsdrv tests/gchash +tests/hashtest-256g tests/hmac tests/keygen tests/keygrip diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index f60be77..39c7c9f 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -381,7 +381,7 @@ memory is not a problem, you should initialize Libgcrypt this way: @example /* Version check should be the very first call because it - makes sure that important subsystems are intialized. */ + makes sure that important subsystems are initialized. */ if (!gcry_check_version (GCRYPT_VERSION)) @{ fputs ("libgcrypt version mismatch\n", stderr); ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + doc/gcrypt.texi | 2 +- random/rndlinux.c | 14 +++++++++++--- 3 files changed, 13 insertions(+), 4 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits