Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
libgcrypt.20076
libgcrypt-CVE-2016-6313-2.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libgcrypt-CVE-2016-6313-2.patch of Package libgcrypt.20076
From 8dd45ad957b54b939c288a68720137386c7f6501 Mon Sep 17 00:00:00 2001 From: Werner Koch <wk@gnupg.org> Date: Mon, 8 Aug 2016 12:54:08 +0200 Subject: [PATCH] random: Hash continuous areas in the csprng pool. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * random/random-csprng.c (mix_pool): Store the first hash at the end of the pool. -- This fixes a long standing bug (since 1998) in Libgcrypt and GnuPG. An attacker who obtains 580 bytes of the random number from the standard RNG can trivially predict the next 20 bytes of output. For use in GnuPG this bug does not affect the default generation of keys because running gpg for key creation creates at most 2 keys from the pool: For a single 4096 bit RSA key 512 byte of random are required and thus for the second key (encryption subkey), 20 bytes could be predicted from the the first key. However, the security of an OpenPGP key depends on the primary key (which was generated first) and thus the 20 predictable bytes should not be a problem. For the default key length of 2048 bit nothing will be predictable. For the former default of DSA+Elgamal key it is complicate to give an answer: For 2048 bit keys a pool of 30 non-secret candidate primes of about 300 bits each are first created. This reads at least 1140 bytes from the pool and thus parts could be predicted. At some point a 256 bit secret is read from the pool; which in the worst case might be partly predictable. The bug was found and reported by Felix Dörre and Vladimir Klebanov, Karlsruhe Institute of Technology. A paper describing the problem in detail will shortly be published. CVE-id: CVE-2016-6313 Signed-off-by: Werner Koch <wk@gnupg.org> --- random/random-csprng.c | 52 +++++++++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/random/random-csprng.c b/random/random-csprng.c index 54ec277..5a771c2 100644 --- a/random/random-csprng.c +++ b/random/random-csprng.c @@ -553,23 +553,22 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * bytes. * <................600...............> <.64.> * pool |------------------------------------| |------| - * <..44..> <20> - * | | - * | +-----+ - * +-----------------------------------|--+ - * v v + * <20><.24.> <20> + * | | +-----+ + * +-----|-------------------------------|-+ + * +-------------------------------|-|-+ + * v v v * |------| * <hash> - * | * +---------------------------------------+ * v * <20> * pool' |------------------------------------| - * <20><20><..44..> - * | | - * | +------------------------------+ - * +-------------------------------------+ | - * v v + * <20><20><.24.> + * +---|-----|---------------------------+ + * +-----|---------------------------|-+ + * +---------------------------|-|-+ + * v v v * |------| * <hash> * | @@ -577,13 +576,11 @@ _gcry_rngcsprng_randomize (void *buffer, size_t length, * v * <20> * pool'' |------------------------------------| - * <20><20><20><..44..> - * | | - * | +--------------------------+ - * +---------------------------------+ | - * v v - * |------| - * <hash> + * <20><20><20><.24.> + * +---|-----|-----------------------+ + * +-----|-----------------------|-+ + * +-----------------------|-|-+ + * v v v * * and so on until we did this for all 30 blocks. * @@ -611,9 +608,9 @@ mix_pool(unsigned char *pool) gcry_assert (pool_is_locked); _gcry_rmd160_init( &md ); - /* Loop over the pool. */ + /* pool_0 -> pool'. */ pend = pool + POOLSIZE; - memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN ); + memcpy (hashbuf, pend - DIGESTLEN, DIGESTLEN); memcpy (hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN); _gcry_rmd160_mixblock( &md, hashbuf); memcpy (pool, hashbuf, DIGESTLEN); @@ -624,19 +621,17 @@ mix_pool(unsigned char *pool) pool[i] ^= failsafe_digest[i]; } + /* Loop for the remaining iterations. */ p = pool; for (n=1; n < POOLBLOCKS; n++) { - memcpy (hashbuf, p, DIGESTLEN); - - p += DIGESTLEN; - if (p+DIGESTLEN+BLOCKLEN < pend) - memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN); + if (p + BLOCKLEN < pend) + memcpy (hashbuf, p, BLOCKLEN); else { - unsigned char *pp = p + DIGESTLEN; + unsigned char *pp = p; - for (i=DIGESTLEN; i < BLOCKLEN; i++ ) + for (i=0; i < BLOCKLEN; i++ ) { if ( pp >= pend ) pp = pool; @@ -645,7 +640,8 @@ mix_pool(unsigned char *pool) } _gcry_rmd160_mixblock ( &md, hashbuf); - memcpy(p, hashbuf, DIGESTLEN); + p += DIGESTLEN; + memcpy (p, hashbuf, DIGESTLEN); } /* Our hash implementation does only leave small parts (64 bytes) -- 2.8.0.rc3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor