I looked around in openssl/crypto/rand/ and couldn't figure out what is different about RAND_bytes() and RAND_pseudo_bytes().
I made a small program to use RAND_bytes() and RAND_pseudo_bytes():
$ cat ossl_rand.c
#include <stdlib.h>
#include <stdio.h>
#include <openssl/rand.h>
int main ()
{
unsigned char buf[8];
if (RAND_bytes(buf, 8) == 0) { exit(1); }
printf("RAND_bytes is %s\n", buf);
return 0;
}
Same thing for "RAND_pseudo_bytes", just substitute "RAND_bytes". Compile
with:
gcc -o ossl_rand ossl_rand.c -O2 -Wall -lcrypto -static
I ran strace(1) on both, there is no difference. They both use /dev/urandom.
So I copied a statically linked strace program and did:
sudo chroot $(pwd) ./strace ./ossl_rand
and
sudo chroot $(pwd) ./strace ./ossl_rand_pseudo
Both fail because they can't
open /dev/urandom, /dev/random, /dev/srandom, /var/run/egd-pool, /dev/egd-pool,
etc... the program exit's with 1 because RAND_*bytes are failing.
Then I tried symlinking /dev/zero to /dev/urandom. The output still changed
with each runtime, I think because there's a getpid()/arc4random() stirred
into RAND_poll() in crypto/rand/rand_unix.c before /dev/urandom is attempted.
I didn't find the algorithm used by the OpenSSL prng, but assuming there is a
cryptographic quality algorithm used the prng should always pass randomness
tests as long as the seed doesn't repeat... even if using getpid()
exclusively this would be very rare unless the test is run for a very very
long time.
So anyway, I'm not seeing the difference between RAND_bytes() and
RAND_pseudo_bytes(), despite what the manual page says. Maybe the manual is
out of date, or very generic for systems without urandom (windows, vms, and
who knows what else).
The RAND_bytes(3) page says RAND_bytes() will error if it doesn't get enough
seed to generate an unpredictable sequence, but it looks like the getpid() in
RAND_poll() is giving RAND_bytes() enough entropy, so RAND_bytes() is never
going to fail unless maybe it gets a 2 digit getpid.
The advantage arc4random() has is that it never returns an error, and always
returns something. But I just noticed that the arc4random() patch in the book
doesn't stir getpid/gettimeofday unconditionally, so symlinking /dev/zero
to /dev/urandom makes arc4random() return the same number. I'll need to fix
this. It's an extra syscall but it's more failsafe.
The advantage to RAND_*bytes() is that it will fail if no random device is
found. This can be a very good idea. I can't think of any application, other
than solitaire card games, where I would want the program to keep going if it
can't find /dev/urandom.
But arc4random() seems to have it's place, to provide a failsafe
if /dev/urandom exists but is outputting 0's. It's a replacement for
getpid/gettimeofday.
It's 05:30, I'm starting to go blind.
robert
pgpS3e0gknqmg.pgp
Description: PGP signature
-- http://linuxfromscratch.org/mailman/listinfo/hlfs-dev FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page
