# How many bits of entropy can I expect from /dev/urandom in iOS?

Apple's latest security documentation indicates that it now uses CTR_DRBG for generating pseudo-random numbers (previously Yarrow instead of CTR_DRBG), using "timing variations during boot" and "interrupt timing once the device has booted" as seeds. Calls to the iOS API SecRandomCopyBytes will retrieve random bytes from /dev/random by default. Apple's random(4) man page seems to suggest that their /dev/random is non-blocking, but that it somehow does not need to block in order to ensure fresh entropic bytes:

/dev/urandom is a compatibility nod to Linux. On Linux, /dev/urandom will produce lower quality output if the entropy pool drains, while /dev/random will prefer to block and wait for additional entropy to be collected. With Yarrow, this choice and distinction is not necessary, and the two devices behave identically. You may use either.

NIST's DRBG validation list indicates that Apple is using AES-128 in counter mode as a pseudo-random function for CTR_DRBG.

So, how many bits of entropy can we expect out of SecRandomCopyBytes? If I query it for 256 bits of entropy, will I instead get 128 bits of reasonably entropic data, potentially followed by another 128 bits of less entropy data due to the lack of blocking in iOS's /dev/random?

• I "inlined" the links #3 and #4. If the previous formating was on intent please roll-back. – SEJPM May 25 '15 at 19:24
• I think if CTR_DRBG is used there's even another implication. This Intel document on the difference between seeding and RNG output may be interesting for you. (Note: RDRAND uses CTR_DRBG, whereas RDSEED outputs TRNG data) – SEJPM May 25 '15 at 19:29
• Once you've collected, say, 256 bits of entropy, you can use that to generate essentially arbitrary amounts of pseudorandom bits that are secure for all practical purposes. CTR_DRBG is a perfectly good way to go about doing this. Concerns over "running out" of entropy are misplaced. Others have put it more elegantly than I can: gist.github.com/tarcieri/6347417, sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers – Seth May 25 '15 at 20:14
• @Kristov Atlas, pls mark answer if correct – Woodstock Nov 23 '19 at 19:20

I mailed Craig Federighi recently about this, concerned that macOS wasn’t capable of generating >128bit quality keys.

He responded!

“The source you were referencing is out of date. You can find more current informations here: FIPS certification document, section 7: "The NDRNG feeds entropy from the pool into the DRBG on demand. The NDRNG provides 256-bits of entropy.””

NIST requires 128 bits of entropy to seed CTR_DRBG with AES-128, so you can safely assume that. If you ask for 256 bits of data, there is theoretically a chance that an attacker could be able to attack the RNG with a 128-bit attack:

Suppose a 256-bit random value is requested twice and the attacker sees the first one, which we denote by $x_1||x_2$ (two 128-bit AES outputs). Then they could iterate all 128-bit keys and pick the one(s) for which $D_k(x_1) + 1 = D_k(x_2)$ (there's at least one, probably not many). They can then predict the next state of the PRNG and its next output (as being derived from one of those matching states).

Of course, in practice a 128-bit complexity attack is not doable either, so you should be safe. However, strictly speaking you cannot assume you have 256-bit security with that key. At least unless you also assume no previous PRNG output has been seen by an attacker.

As an aside, this:

On Linux, /dev/urandom will produce lower quality output if the entropy pool drains, while /dev/random will prefer to block and wait for additional entropy to be collected.

is basically FUD. The output is no lower quality regardless of how much the entropy pool is drained. As long as enough entropy has been collected in advance, the state of the random number generator is unpredictable even if you request enough data to drain the entropy count. The pools are 4096 bits, which is way more than necessarily needed for a secure scheme.

• This is now out of date. Check out the link below. – Woodstock Jul 28 '19 at 20:03
• @Woodstock good to know. But if that's an implementation change rather than just improved documentation (any idea?) then both can be correct depending on hardware and/or software versions. – otus Jul 29 '19 at 5:53