Randomness on Apple Platforms (2024)

A deep dive into the journey of discovering the best way to obtain randomness on Apple platforms by stripping away layers of abstraction down to the hardware level.
In this post I’d like to lead you through my journey trying to discover the “best” way to obtain randomness on Apple platforms. The goal throughout will be to get as close to the underlying hardware random number generators as the system allows by stripping away layers of abstraction one by one. Once we have a comprehensive picture of the entire system, I’ll walk you through my opinions on which use-cases are best served by which APIs.
Starting with rand(3)
Let’s begin with the most obvious choice: rand(3). A quick trip to the manual page, though, assures us that our journey will not come to an end so quickly: rand, rand_r, srand, sranddev – bad random number generator. These interfaces are obsoleted by arc4random(3).
The Power of arc4random(3)
According to the documentation, arc4random uses a cryptographic pseudo-random number generator to generate high quality random bytes very quickly. The subsystem is re-seeded from the kernel random number subsystem on a regular basis, and also upon fork(2). This family of functions provides higher quality random data than those described in rand(3), random(3), and rand48(3). Their use is encouraged over all other standard library functions for random numbers.
It is worth noting that rand(3), random(3) and rand48(3) (dating back to 1983) don’t automatically seed themselves with random data from the OS. If you call them before passing in a seed you always get the same result!
Deep Dive: The corecrypto Layer
Peeking into Apple's libc, we find that arc4random is a wrapper around ccrng. These functions come from the private corecrypto project. Although corecrypto does not directly provide programming interfaces for developers, it is included in libSystem, meaning every binary on the system (apart from the kernel) links to it and can access its functions.
However, corecrypto is a private API, and its license forbids use for anything other than security research.
Direct Access via /dev/random and getentropy(2)
On Apple platforms, /dev/random and /dev/urandom are identical cryptographic random number generators, both implemented in XNU using the Fortuna RNG. An intriguing detail is that getentropy(2) returns the same data but is resistant to file descriptor exhaustion or sandboxing issues. Apple suggests that arc4random(3) is preferred over directly accessing the system’s random device because it is a fast userspace generator built on top of the kernel source.
Source: Hacker News












