Failure to use true entropy from the physical environment as a basis for generating random cryptographic key material would lead to a disastrous loss of security.
When a random number is required by the ZRTP protocol, the library kernel calls the Deterministic Random Bit Generator interface function zrtp_randstr(). That function requires the existance of an entropy pool that has already been seeded with sufficient entropy. This entropy pool must be seeded by calling zrtp_entropy_add().
The zrtp_entropy_add() function takes a buffer of raw unprocessed entropy provided by the caller and adds it to the entropy pool via the SHA-512 hash function.
To add entropy to the entropy pool maintained by the libzrtp random number generator, the application calls the zrtp_entropy_add() function. This entropy accumulation function may be called whenever new entropy becomes available.
For the Windows kernel mode it gathers current system state information as an entropy source. Among them are the performance counter, the current value of the system interrupt-time count, the count of the interval timer interrupts, and the values of some CPU registers.
For Unix platforms, libzrtp calls /dev/urandom
.
If you are running libzrtp on a Windows Kernel or a full-blown desktop *nix-like system - you need not do anything more to implement the RNG. If you are using some other platform - carefully read the next section.
/dev/random
or /dev/urandom
. This is because /dev/random
is seeded by entropy from keyboard timings, mouse movements, disk latency measurements, or other physical noise sources, some of them involving unpredictable human interaction.
However, some low cost embedded Linux systems have no keyboard, no mouse or trackpad, no disk drive, and are starving for high quality entropy. There are some low cost Asterisk PBX boxes that are built this way. Or hardware Analog Telephone Adapters. Or low cost consumer routers. Many of them have no /dev/random
implemented, or worse, have only a stub for /dev/random that does not actually collect any environmental entropy. This creates a dangerous illusion that entropy is available, because /dev/urandom
appears to work, but is not backed by true entropy. This is bad, and not only for ZRTP. Platforms like these might not be able to generate strong cryptographic key material for SSH or SSL.
If you are an OEM that builds hardware like this, and you wish to implement the ZRTP protocol with our libzrtp SDK, you really should provide a properly implemented /dev/random
and /dev/urandom
, properly supplied with true environmental entropy. If you are building a telephone, you can easily collect entropy from raw audio samples from the microphone. If the phone includes a video camera, you can collect entropy by sampling a few raw uncompressed video frames. If it's a mobile phone or a cordless phone, you can collect entropy from the RF noise in your wireless circuitry. If it's an embedded box like a router or low cost PBX, you can do high resolution timings of packet arrivals and use the timer readings as entropy sources. A PBX might include an analog interface to PSTN phone lines, and those interfaces usually include registers that measure analog voltage levels, which can serve as a source of entropy. The entropy sources do not need to produce much entropy, just a few bits at a time, but it can build up slowly until you have accumulated a few hundred bits of entropy. That's enough to generate cryptographically useful keys. Even if it takes some seconds or even minutes to accumulate this much entropy the first time your product is activated, it can be stored in nonvolatile storage so that it will be ready to reseed the entropy pool instantly the next time your product is powered up.
In the ideal case, if you are designing the embedded hardware yourself, you could provide a good source of entropy by including a simple ring oscillator in the hardware. A ring oscillator is a circular chain (a ring) of NOT gates, and has nothing whatsoever to do with a telephone ring generator. The oscillation frequency drifts from thermal noise, and sampling the output at some low sampling rate is a good way to get some entropy. However, most designers have to work with existing hardware designs, and don't have the luxury of adding special hardware to generate entropy, which means you have to improvise with whatever you can collect from the environment, using any of the methods described above.
If the library is used on another platform, the potential entropy sources should be thoroughly analyzed and a custom implementation must be developed for that platform. You can get your entropy collection ideas by looking at the default implementation of zrtp_add_system_state()
provided in zrtp_rng.c
. Again, microphone noise can be a good entropy source for VoIP clients. Raw, uncompressed, unfiltered audio samples should be used.
If you have entropy gathering schemes for platforms not already supported in libzrtp, or if you doubt the correctness of your entropy collection approach, contact us to discuss how it may be done. We will do our best to provide you with technical assistance.