From 483c4e0682d95e59369fe3e8839be0b25b2ea0a1 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 9 Jul 2001 14:36:30 +0000 Subject: Add security patch and create release. Tags will be OpenSSL_0_9_6b and OpenSSL-engine-0_9_6b --- CHANGES | 27 ++++++++++++++++++++++++++- FAQ | 2 +- NEWS | 17 +++++++++++++++++ README | 4 ++-- crypto/opensslv.h | 6 +++--- crypto/rand/md_rand.c | 50 +++++++++++++++++++++++++++++--------------------- doc/crypto/rand.pod | 13 ++++++------- 7 files changed, 84 insertions(+), 35 deletions(-) diff --git a/CHANGES b/CHANGES index 0a4d18cbea..f88867b065 100644 --- a/CHANGES +++ b/CHANGES @@ -2,7 +2,32 @@ OpenSSL CHANGES _______________ - Changes between 0.9.6a and 0.9.6b [XX xxx XXXX] + Changes between 0.9.6a and 0.9.6b [9 Jul 2001] + + *) Change ssleay_rand_bytes (crypto/rand/md_rand.c) + to avoid a SSLeay/OpenSSL PRNG weakness pointed out by + Markku-Juhani O. Saarinen : + PRNG state recovery was possible based on the output of + one PRNG request appropriately sized to gain knowledge on + 'md' followed by enough consecutive 1-byte PRNG requests + to traverse all of 'state'. + + 1. When updating 'md_local' (the current thread's copy of 'md') + during PRNG output generation, hash all of the previous + 'md_local' value, not just the half used for PRNG output. + + 2. Make the number of bytes from 'state' included into the hash + independent from the number of PRNG bytes requested. + + The first measure alone would be sufficient to avoid + Markku-Juhani's attack. (Actually it had never occurred + to me that the half of 'md_local' used for chaining was the + half from which PRNG output bytes were taken -- I had always + assumed that the secret half would be used.) The second + measure makes sure that additional data from 'state' is never + mixed into 'md_local' in small portions; this heuristically + further strengthens the PRNG. + [Bodo Moeller] *) Fix crypto/bn/asm/mips3.s. [Andy Polyakov] diff --git a/FAQ b/FAQ index 8b3d540335..23e212fb4e 100644 --- a/FAQ +++ b/FAQ @@ -57,7 +57,7 @@ OpenSSL - Frequently Asked Questions * Which is the current version of OpenSSL? The current version is available from . -OpenSSL 0.9.6a was released on April 5th, 2001. +OpenSSL 0.9.6b was released on July 9th, 2001. In addition to the current stable release, you can also access daily snapshots of the OpenSSL development version at state_num) state_index %= state_num; - /* state[st_idx], ..., state[(st_idx + num - 1) % st_num] + /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] * are now ours (but other threads may use them too) */ md_count[0] += 1; @@ -434,6 +440,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) while (num > 0) { + /* num_ceil -= MD_DIGEST_LENGTH/2 */ j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; num-=j; MD_Init(&m); @@ -444,27 +451,28 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) curr_pid = 0; } #endif - MD_Update(&m,&(local_md[MD_DIGEST_LENGTH/2]),MD_DIGEST_LENGTH/2); + MD_Update(&m,local_md,MD_DIGEST_LENGTH); MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); #ifndef PURIFY MD_Update(&m,buf,j); /* purify complains */ #endif - k=(st_idx+j)-st_num; + k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; if (k > 0) { - MD_Update(&m,&(state[st_idx]),j-k); + MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); MD_Update(&m,&(state[0]),k); } else - MD_Update(&m,&(state[st_idx]),j); + MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); MD_Final(local_md,&m); - for (i=0; i= st_num) st_idx=0; + if (i < j) + *(buf++)=local_md[i+MD_DIGEST_LENGTH/2]; } } diff --git a/doc/crypto/rand.pod b/doc/crypto/rand.pod index 9545f0e109..96901f109e 100644 --- a/doc/crypto/rand.pod +++ b/doc/crypto/rand.pod @@ -127,13 +127,12 @@ function and xor). When bytes are extracted from the RNG, the following process is used. For each group of 10 bytes (or less), we do the following: -Input into the hash function the top 10 bytes from the local 'md' -(which is initialized from the global 'md' before any bytes are -generated), the bytes that are to be overwritten by the random bytes, -and bytes from the 'state' (incrementing looping index). From this -digest output (which is kept in 'md'), the top (up to) 10 bytes are -returned to the caller and the bottom (up to) 10 bytes are xored into -the 'state'. +Input into the hash function the local 'md' (which is initialized from +the global 'md' before any bytes are generated), the bytes that are to +be overwritten by the random bytes, and bytes from the 'state' +(incrementing looping index). From this digest output (which is kept +in 'md'), the top (up to) 10 bytes are returned to the caller and the +bottom 10 bytes are xored into the 'state'. Finally, after we have finished 'num' random bytes for the caller, 'count' (which is incremented) and the local and global 'md' are fed -- cgit v1.2.3