summaryrefslogtreecommitdiff
path: root/random
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-09-06 09:47:02 +0200
committerJustus Winter <justus@gnupg.org>2016-09-06 09:47:02 +0200
commit4fb81a7e92d0cd6d854a4a020f34b948ad6ce29b (patch)
treed7f273362f8c413b312bf25710e205c944a9e6cc /random
parent349b9c4fdcb49add63ec71cabd6e4e4dbe6b262d (diff)
random: Hash continuous areas in the csprng pool.
* random/gnupg-random.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. 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. This is a port of c6dbfe89 from the GnuPG classic branch. CVE-id: CVE-2016-6313
Diffstat (limited to 'random')
-rw-r--r--random/gnupg-random.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/random/gnupg-random.c b/random/gnupg-random.c
index 3cf78121..a4df6947 100644
--- a/random/gnupg-random.c
+++ b/random/gnupg-random.c
@@ -276,23 +276,21 @@ mix_pool(byte *pool)
#if DIGESTLEN != 20
#error must have a digest length of 20 for ripe-md-160
#endif
- /* loop over the pool */
+ /* pool -> pool' */
pend = pool + POOLSIZE;
memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
rmd160_mixblock( &md, hashbuf);
- memcpy(pool, hashbuf, 20 );
+ memcpy(pool, hashbuf, DIGESTLEN);
+ /* 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 {
- byte *pp = p+DIGESTLEN;
- for(i=DIGESTLEN; i < BLOCKLEN; i++ ) {
+ byte *pp = p;
+ for(i=0; i < BLOCKLEN; i++ ) {
if( pp >= pend )
pp = pool;
hashbuf[i] = *pp++;
@@ -300,7 +298,8 @@ mix_pool(byte *pool)
}
rmd160_mixblock( &md, hashbuf);
- memcpy(p, hashbuf, 20 );
+ p += DIGESTLEN;
+ memcpy(p, hashbuf, DIGESTLEN);
}
burn_stack (200); /* for the rmd160_mixblock() */
}