4 ms·
The short answer is yes: The first call to ssleay_rand_bytes() (which is what RAND_bytes() calls eventually become with the default RAND_METH) will call RAND_p
by rwg 13y ago
The short answer is yes:
The first call to ssleay_rand_bytes() (which is what RAND_bytes() calls eventually become with the default RAND_METH) will call RAND_poll(), which on Unix-but-not-OpenBSD-or-VOS will try reading ENTROPY_NEEDED (32) bytes from /dev/urandom, /dev/random, and /dev/srandom (in that order). Then, for grins, it throws getpid(), getuid(), and time() into the pool.
The longer answer is maybe:
• RAND_poll() relies on a #define named DEVRANDOM to figure out where to go looking for random devices. If DEVRANDOM is undefined, e_os.h will define it to "/dev/urandom","/dev/random","/dev/srandom". If DEVRANDOM is defined but empty, then the code in rand_unix.c's RAND_poll() ends up skipping seeding from random devices entirely and only tosses getpid(), getuid(), and time() into the pool.
• If something changes OpenSSL's default RAND_METH so it's not RAND_SSLeay(), all bets are off.
Despite staring at all of the code between Android's SecureRandom.java and their OpenSSL tree's crypto/rand directory for three hours, I can't figure out how they screwed this up.
- marshray 13y agoComplexity kills. Thank you for staring at the code for three hours BTW. :-)
- rwg 13y agoAfter staring at convoluted Java code and OpenSSL's code for three hours, I need a stiff drink...
- rwg 13y agoAs an added fun bonus, it looks like the NativeCrypto Java wrapper around OpenSSL wrongly assumes that RAND_bytes() returns 0 on failure and not-zero on success. In reality, it returns 1 on success, 0 on failure, and -1 on super ultra mega failure.
- marshray 13y agoThat evil API has bitten so many projects.
- benmmurphy 13y agothis is probably the problem :)
- deleted 13y ago[deleted]
- benmmurphy 13y agomy theory: trace what can happen if reading from /dev/urandom, etc fails. i think: a) if the RAND_seed has already been called it is possible to fail reading from /dev/random and not get a subsequent failure from RAND_bytes because RAND_bytes will believe there is enough entropy in the pool. this can happen even if YOU don't explicitly seed the SecureRandom you are using because the state of all SecureRandom instances are shared :) b) there is this lols method called throwExceptionIfNecessary in the native crypto code. RAND_bytes checks the return code and if the return code is bad it calls throwExceptionIfNecessary. however, throwExceptionIfNecessary does not always throw an exception. there are some conditions where it won't throw an exception (malloc failure...). however, i'm not sure if these conditions are possible on android openssl. c) sharing of state between forks. not sure if openssl is initialized in zygote before forking.