4 years ago I was writing about getting an eKey to generate more entropy. Well, I never bought the eKey, and it took me 4 years to look at entropy generation again, but I found some interesting results today.
I was trying to set up /dev/hw_random on an Intel Xeon E3-1270. While /proc/cpuinfo indicates support for rdrand instructions, intel-rng refuses to load and I am still figuring out why.
While reading the readme of rng-tools, I stumbled across "The VIA Hardware RNG". Remembering that my Dedibox from online.fr uses a VIA Nano processor U2250, I ssh-ed into it, and discovered the awesomeness of this tiny CPU.
# cat /proc/cpuinfo processor : 0 vendor_id : CentaurHauls cpu family : 6 model : 15 model name : VIA Nano processor U2250 (1.6GHz Capable) < ... snip ...> flags : ... rng rng_en ... < ... snip ...>
Note the 'rng' cpu flag above. That all that's needed to use the hwrng. Well, that and a few kernel modules:
# modprobe rng-core # modprobe via_rng # file /dev/hwrng /dev/hwrng: character special
The harware RNG is loaded in /dev/hwrng. Using the tools from the 'rng-tools' package, we can test the quality of the randomness provided.
# rngtest -c 100 < /dev/hwrng rngtest 2-unofficial-mt.14 Copyright (c) 2004 by Henrique de Moraes Holschuh This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. rngtest: starting FIPS tests... rngtest: bits received from input: 2000032 rngtest: FIPS 140-2 successes: 100 rngtest: FIPS 140-2 failures: 0 rngtest: FIPS 140-2(2001-10-10) Monobit: 0 rngtest: FIPS 140-2(2001-10-10) Poker: 0 rngtest: FIPS 140-2(2001-10-10) Runs: 0 rngtest: FIPS 140-2(2001-10-10) Long run: 0 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=140.395; avg=339.623; max=369.441)Kibits/s rngtest: FIPS tests speed: (min=3.289; avg=48.125; max=57.798)Mibits/s rngtest: Program run time: 5790927 microseconds
All FIPS tests pass. Now a small bandwidth test:
# dd if=/dev/hwrng of=awesomerandom bs=128 count=10240 10240+0 enregistrements lus 10240+0 enregistrements écrits 1310720 octets (1,3 MB) copiés, 27,9087 s, 47,0 kB/s
47kB/s, or 385024 bits per second, is pretty damn good for a random number generator! Now let's feed that into the kernel's entropy pool using rngd.
The initial entropy pool, while using SSH on the server:
# cat /proc/sys/kernel/random/entropy_avail 153
RNGD being installed, I configured the default parameters in /etc/default/rng-tools as shown below. I tried using the more recent viapadlock driver, but it doesn't seem to be supported on my architecture. The viakernel worked fine.
# cat /etc/default/rng-tools # Configuration for the rng-tools initscript # $Id: rng-tools.default,v 18.104.22.168 2008-06-10 19:51:37 hmh Exp $ # This is a POSIX shell fragment # Set to the input source for random data, leave undefined # for the initscript to attempt auto-detection. Set to /dev/null # for the viapadlock driver. HRNGDEVICE=/dev/hwrng #HRNGDEVICE=/dev/null # Additional options to send to rngd. See the rngd(8) manpage for # more information. Do not specify -r/--rng-device here, use # HRNGDEVICE for that instead. #RNGDOPTIONS="--hrng=intelfwh --fill-watermark=90% --feed-interval=1" RNGDOPTIONS="--hrng=viakernel --fill-watermark=90% --feed-interval=1" #RNGDOPTIONS="--hrng=viapadlock --fill-watermark=90% --feed-interval=1"
Then restart rngd:
# /etc/init.d/rng-tools restart Stopping Hardware RNG entropy gatherer daemon: rngd. Starting Hardware RNG entropy gatherer daemon: rngd. # ps aux|grep rngd root 6539 3.2 0.0 30628 616 ? SLsl 17:42 0:00 /usr/sbin/rngd -r /dev/hwrng --hrng=viakernel --fill-watermark=90% --feed-interval=1
And, as a result, the entropy pool filled up immediatly:
# cat /proc/sys/kernel/random/entropy_avail 3968
A simple test shows the immense difference in entropy available. The results below show that retrieving 120kB of randomness takes 3.4s with rngd enabled, and forever without it. I had to kill dd after several minutes because it was getting nowhere. As soon as I restarted rngd, the pool filled up again.
# dd if=/dev/random of=randomstuff bs=128 count=1024 768+256 enregistrements lus 768+256 enregistrements écrits 120181 octets (120 kB) copiés, 3,47491 s, 34,6 kB/s # /etc/init.d/rng-tools stop Stopping Hardware RNG entropy gatherer daemon: rngd. # dd if=/dev/random of=randomstuff bs=128 count=1024 ^C2+10 enregistrements lus 2+10 enregistrements écrits 450 octets (450 B) copiés, 114,238 s, 0,0 kB/s # cat /proc/sys/kernel/random/entropy_avail 103 # /etc/init.d/rng-tools start Starting Hardware RNG entropy gatherer daemon: rngd. # cat /proc/sys/kernel/random/entropy_avail 3968
I've had this server for 3 years, and I never thought it supported a hardware RNG. Today is a good day :)