Bug 118062

Summary: /dev/random can be sniffed by an unprivileged user
Product: Base System Reporter: Robert Woolley <freebsd-pr0711>
Component: kernAssignee: Christian S.J. Peron <csjp>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Unspecified   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Robert Woolley 2007-11-15 01:10:01 UTC
It's possible for an unprivileged user to make /dev/random replay part of its most recent output. (This applies to Yarrow, not the hardware version.)

The first read must be 32 bytes or more, and the second 31 bytes or fewer.  The worst case is when 32 bytes (256 bits) are followed by 31 bytes.  It also appears to be possible, in theory, for an attacker to manipulate the state of the Yarrow implementation to maximize the number of replayed bytes, reducing 256 bits of entropy to 8bits. (it's actually easier to follow in the source)

Fix: The problem occurs in sys/dev/random/yarrow.c:random_yarrow_read()

This function handles requests based on the number of bytes requested. If less than 32 bytes, the random data is read out of a static buffer (genval[]) - keeping track of the remaining bytes in a variable called "cur". When cur is zero, the Yarrow cipher refills genval. 

When larger requests are made, the genval buffer is immediately overwritten by the Yarrow cipher and copied into the output buffer. The is repeated until the request is satisfied. The problem is that this block of code leaves "cur" unmodified. This may cause the next request to reuse part of genval that's already been written-out. 

cur should be set to the number of unused bytes (or just zeroed).

See patch.

Patch attached with submission follows:
How-To-Repeat: $ dd if=/dev/random bs=32 count=1  2> /dev/null | hexdump ; dd if=/dev/random bs=31 count=1  2> /dev/null | hexdump
0000000 0ba3 af33 40ee b94e 0142 26f7 6ba1 3eba
0000010 38f6 3314 de4d 58a2 8f2a c4c1 b400 47f7
0000020
0000000 6ba1 3eba 38f6 3314 de4d 58a2 8f2a c4c1
0000010 b400 47f7 f937 985c 7f77 a7ae 8640 007c

Note that the sequence "6ba1 3eba 38f6 3314 de4d 58a2 8f2a c4c1 b400 47f7" appears in both outputs. 

This might have to be run a few times if something else is reading from /dev/random.
Comment 1 Christian S.J. Peron freebsd_committer freebsd_triage 2007-11-15 15:43:15 UTC
Responsible Changed
From-To: freebsd-bugs->csjp

I will look into this.
Comment 2 Christian S.J. Peron freebsd_committer freebsd_triage 2007-11-29 17:07:22 UTC
State Changed
From-To: open->closed

Commtted fix to all supported branches.  An advisory has 
beeen released. Note that a slightly more conservative 
patch has been committed. 

See FreeBSD-SA-07:09.random for more details.