Pages

Friday, July 5, 2013

Random Numbers and an Experiment with a True Random Number Generator at Pozitron


by Mete Balci

Random numbers are widely used in many software systems. Because of the widespread use of cryptographic operations on Internet, just consider HTTPS which requires, very roughly, such random numbers at each handshake, their importance is unquestionable.

The most common and simple way to generate random numbers include a deterministic algorithm started with -somehow- truly random seed as in java.util.Random(long seed). The default constructor Random() simply sends a deterministically derived seed depending on the system time (it can be seen at http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/util/Random.java/). In theory, randomness depends on the available entropy which we can define as the true randomness (disorder) gathered by the system. Considering java.util.Random, the initial randomness is system time up to nanosecond resolution, which is quite a bad approximation. A proper seed for Random Number Generator (RNG) has to come from a truly random source, from a high quality entropy source.

Since the computer software is deterministic, it is impossible to generate something truly random in software. Therefore, information coming from hardware (e.g. interrupt timings, input from user) or from natural/physical events (e.g. radioactive decay) has to be used. Because it is still hard to get enough truly random input from hardware, usually other mechanisms are used. For example, the great HotBits project (http://www.fourmilab.ch/hotbits/) uses radioactivity measurements to generate truly random numbers. For more widespread and "safe" use, radioactivity is not an option. Another source for randomness is the noise generated by reverse biased PN junction, because it is simple and safe, it can be produced and used more easily. One of such example is Entropy Key: http://www.entropykey.co.uk/tech/ . Also, many financial (or any industry  where handling of critical data is very important) software systems use special hardware called Hardware Security Modules. These modules also include a hardware based random number generator.

The latest practical development in random number generators is the RdRand instruction in latest (Ivy Bridge) Intel processors. This processor includes a Digital Random Number Generator (DRNG) implemented inside the CPU and it is seeded by a special circuit measuring the thermal noise, an inherently random phenomenon. Because this feature provides practically free, very high quality random numbers, I expect it will have a widespread use and, moreover, it is already included in Linux Kernel (http://lwn.net/Articles/453651/ and http://lxr.free-electrons.com/source/arch/x86/kernel/cpu/rdrand.c).

At Pozitron, we also implement and use software that use many cryptographic operations, that also involves HTTPS. That is why we are also interested in the deep technical aspects of random number generation. As an experiment, we obtained an Entropy Key USB device and installed it on a Linux Ubuntu 12.04 LTS server. This server serves many HTTPS connections, so it is a good idea to keep its entropy high (take a look at to Entropy Key website, there are also test results there). Currently, if I monitor /proc/sys/kernel/random/entropy_avail on my desktop computer, it gives values around 150. However, monitoring the same for the server which uses Entropy Key shows around 3800 even if it constantly uses the existing entropy in the system because of the HTTPS connections. On this server, we have an haproxy instance, which in turn uses openssl cryptographic library. OpenSSL documentation tells us (starting with 0.9.7) it uses /dev/urandom by default and tried /dev/random if urandom is not available. The difference between two is /dev/urandom always returns some data (even if it is not that much random) (in other words, it does not block). However /dev/random returns data directly from entropy pool, so if you do not have enough entropy, it simply blocks your call. In order to see the difference yourself, simply try "cat /dev/random" and "cat /dev/urandom". Since we were happy with the results of the experiment as well as its ease of use, we let it be like that in production also.