Bug#736126: /dev/random entropy depletion on a fresh install
Package: haveged Version: 1.4.4 I installed Debian 7.3 x64 on a Core i5 laptop for some testing (real hardware, not a VM). When testing a program I wrote, I noticed it was not getting the full number of bytes requested from /dev/random: unsigned char buffer[32]; fd = open("/dev/random", O_RDONLY | O_NONBLOCK); rc = (int)read(fd, buffer, sizeof(buffer)); assert(rc == sizeof(buffer)); RAND_add(buffer, sizeof(buffer), 1.0f); OPENSSL_cleanse(buffer, sizeof(buffer)); The assert fired on nearly every run, including the first run when no previous calls were made by the test program. The number of bytes returned varied, but they included 7, 12, 16, and 19. That's really bad for a request of 32 bytes, and it would be catastrophic for a request of 128-bytes or 256-bytes for a long term private key. It appears Debian is missing an entropy gatherer out of the box. Once I installed haveged, I never experienced the issue again. I can't help but feel this is a bug (perhaps a security bug), because entropy depletion has such dire consequences. I believe a lot of folks probably don't realize they are missing an entropy gatherer because it caught me by surprise. I would not have known except for debugging the test program. To add insult to injury, this machine has RDRAND, so there's plenty of bits available to mix into /dev/random (I say 'mix in' rather than 'use' because of all the NSA goodness that's going on). It would probably be very beneficial to install an entropy gatherer by default. Its the lesser of the evils, with the evils being: suffering depletion and silent failures vs a less-than-ideal gatherer. A less-than-ideal entropy gatherer is surely better than no entropy gatherer, blocking and depletion. (For completeness, I have no problems with haveged. Folks more knowledgeable than me might point out some problems, so I simply called it (or others) 'less-than-ideal'). Finally, sorry about filling this against haveged. I could not find something better when searching dpkg for 'core', 'live', 'dvd', 'distribution' and a couple of others. $ uname -a Linux debian-q500 3.2.0-4-amd64 #1 SMP Debian 3.2.51-1 x86_64 GNU/Linux $ cat /proc/cpuinfo processor: 0 vendor_id: GenuineIntel cpu family: 6 model: 58 model name: Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz stepping: 9 microcode: 0x15 cpu MHz: 1200.000 cache size: 3072 KB physical id: 0 siblings: 4 core id: 0 cpu cores: 2 apicid: 0 initial apicid: 0 fpu: yes fpu_exception: yes cpuid level: 13 wp: yes flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm ida arat epb xsaveopt pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms bogomips: 5188.70 clflush size: 64 cache_alignment: 64 address sizes: 36 bits physical, 48 bits virtual power management: [... repeated 3 more times ...] $ sudo lspci [sudo] password for jwalton: 00:00.0 Host bridge: Intel Corporation 3rd Gen Core processor DRAM Controller (rev 09) 00:02.0 VGA compatible controller: Intel Corporation 3rd Gen Core processor Graphics Controller (rev 09) 00:14.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB xHCI Host Controller (rev 04) 00:16.0 Communication controller: Intel Corporation 7 Series/C210 Series Chipset Family MEI Controller #1 (rev 04) 00:1a.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 (rev 04) 00:1b.0 Audio device: Intel Corporation 7 Series/C210 Series Chipset Family High Definition Audio Controller (rev 04) 00:1c.0 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 1 (rev c4) 00:1c.1 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 2 (rev c4) 00:1c.2 PCI bridge: Intel Corporation 7 Series/C210 Series Chipset Family PCI Express Root Port 3 (rev c4) 00:1d.0 USB controller: Intel Corporation 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 (rev 04) 00:1f.0 ISA bridge: Intel Corporation HM76 Express Chipset LPC Controller (rev 04) 00:1f.2 SATA controller: Intel Corporation 7 Series Chipset Family 6-port SATA Controller [AHCI mode] (rev 04) 00:1f.3 SMBus: Intel Corporation 7 Series/C210 Series Chipset Family SMBus Controller (rev 04) 02:00.0 Network controller: Intel Corporation Centrino Wireless-N 2230 (rev c4) 03:00.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 07) $ $ dpkg -l haveged Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Conf-files/Unp
Bug#736126: /dev/random entropy depletion on a fresh install
Control: reassign -1 tasksel Jeffrey Walton: > It would probably be very beneficial to install an entropy gatherer by > default. I am unconvinced that haveged is the answer here, but reassigning to the proper package. -- Jérémy Bobbio.''`. jeremy.bob...@irq7.fr : : : lu...@debian.org `. `'` lu...@torproject.org `- signature.asc Description: Digital signature
Bug#736126: /dev/random entropy depletion on a fresh install
On 20.01.2014 10:22, Jérémy Bobbio wrote: > Jeffrey Walton: >> It would probably be very beneficial to install an entropy gatherer by >> default. > > I am unconvinced that haveged is the answer here, but reassigning to the > proper package. Minor data point: "SuSE SLES 11 for VMware Server" installs haveged via the default installation set. Grüße, Sven. signature.asc Description: OpenPGP digital signature
Bug#736126: Processed: Re: Bug#736126: /dev/random entropy depletion on a fresh install
noloa...@gmail.com wrote: > I installed Debian 7.3 x64 on a Core i5 laptop for some testing (real > hardware, not a VM). When testing a program I wrote, I noticed it was > not getting the full number of bytes requested from /dev/random: > > unsigned char buffer[32]; > fd = open("/dev/random", O_RDONLY | O_NONBLOCK); > > rc = (int)read(fd, buffer, sizeof(buffer)); > assert(rc == sizeof(buffer)); > > RAND_add(buffer, sizeof(buffer), 1.0f); > OPENSSL_cleanse(buffer, sizeof(buffer)); > > The assert fired on nearly every run, including the first run when no > previous calls were made by the test program. The number of bytes > returned varied, but they included 7, 12, 16, and 19. That's really > bad for a request of 32 bytes, and it would be catastrophic for a > request of 128-bytes or 256-bytes for a long term private key. [...] This is catastrophic only if people don't RTFM about read(). Yes, it can return a short length. You must call it again if you want more. (This doesn't normally happen with regular files, although it will if you specify a length >= (1U << 31).) Ben. -- Ben Hutchings One of the nice things about standards is that there are so many of them. signature.asc Description: This is a digitally signed message part
Bug#736126: Processed: Re: Bug#736126: /dev/random entropy depletion on a fresh install
On Mon, Jan 20, 2014 at 8:33 AM, Ben Hutchings wrote: > noloa...@gmail.com wrote: >> I installed Debian 7.3 x64 on a Core i5 laptop for some testing (real >> hardware, not a VM). When testing a program I wrote, I noticed it was >> not getting the full number of bytes requested from /dev/random: >> >> unsigned char buffer[32]; >> fd = open("/dev/random", O_RDONLY | O_NONBLOCK); >> >> rc = (int)read(fd, buffer, sizeof(buffer)); >> assert(rc == sizeof(buffer)); >> >> RAND_add(buffer, sizeof(buffer), 1.0f); >> OPENSSL_cleanse(buffer, sizeof(buffer)); >> >> The assert fired on nearly every run, including the first run when no >> previous calls were made by the test program. The number of bytes >> returned varied, but they included 7, 12, 16, and 19. That's really >> bad for a request of 32 bytes, and it would be catastrophic for a >> request of 128-bytes or 256-bytes for a long term private key. > [...] > > This is catastrophic only if people don't RTFM about read(). Yes, it > can return a short length. You must call it again if you want more. > (This doesn't normally happen with regular files, although it will if > you specify a length >= (1U << 31).) The root cause of the failure is the system, not the programmer or user. Read performed as expected, but the problem was with the device. The device could not provide a trivial number of bytes at the time of the request. Asking the programmer or user to recover from the system's short comings is simply passing the buck, weakening security, and hurting users. To play devil's advocate: how can Debian ensure that bytes are available under most use cases? a) provide an entropy gatherer so depletion almost never happens b) tell the programmer to RTFM and block on the device c) tell the programmer to RTFM and accept fewer bytes d) tell the programmer to RTFM and repeatedly call read e) tell the user to RTFM, audit source code, and reject deficient source code f) tell the user to RTFM and and install an entropy gatherer so depletion almost never happens Which seems like the best choice here? Jeff -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Bug#736126: Processed: Re: Bug#736126: /dev/random entropy depletion on a fresh install
On Mon, 2014-01-20 at 08:50 -0500, Jeffrey Walton wrote: > On Mon, Jan 20, 2014 at 8:33 AM, Ben Hutchings wrote: > > noloa...@gmail.com wrote: > >> I installed Debian 7.3 x64 on a Core i5 laptop for some testing (real > >> hardware, not a VM). When testing a program I wrote, I noticed it was > >> not getting the full number of bytes requested from /dev/random: > >> > >> unsigned char buffer[32]; > >> fd = open("/dev/random", O_RDONLY | O_NONBLOCK); > >> > >> rc = (int)read(fd, buffer, sizeof(buffer)); > >> assert(rc == sizeof(buffer)); > >> > >> RAND_add(buffer, sizeof(buffer), 1.0f); > >> OPENSSL_cleanse(buffer, sizeof(buffer)); > >> > >> The assert fired on nearly every run, including the first run when no > >> previous calls were made by the test program. The number of bytes > >> returned varied, but they included 7, 12, 16, and 19. That's really > >> bad for a request of 32 bytes, and it would be catastrophic for a > >> request of 128-bytes or 256-bytes for a long term private key. > > [...] > > > > This is catastrophic only if people don't RTFM about read(). Yes, it > > can return a short length. You must call it again if you want more. > > (This doesn't normally happen with regular files, although it will if > > you specify a length >= (1U << 31).) > The root cause of the failure is the system, not the programmer or > user. Read performed as expected, but the problem was with the device. > The device could not provide a trivial number of bytes at the time of > the request. > > Asking the programmer or user to recover from the system's short > comings is simply passing the buck, weakening security, and hurting > users. Calling functions without reading what they do, then complaining that they didn't meet your expectations, is passing the buck, weakening security, and hurting users. (See I can play that game too.) > To play devil's advocate: how can Debian ensure that bytes are > available under most use cases? I don't think that phrase means what you think it means. > a) provide an entropy gatherer so depletion almost never happens > b) tell the programmer to RTFM and block on the device > c) tell the programmer to RTFM and accept fewer bytes > d) tell the programmer to RTFM and repeatedly call read > e) tell the user to RTFM, audit source code, and reject deficient source code > f) tell the user to RTFM and and install an entropy gatherer so > depletion almost never happens > > Which seems like the best choice here? (a) *and* (d). You *must* *always* check for short reads. Ben. -- Ben Hutchings One of the nice things about standards is that there are so many of them. signature.asc Description: This is a digitally signed message part