Skip to content

crypto/rand: crash process on error reading randomness #66821

@FiloSottile

Description

@FiloSottile

On almost all our platforms, we now have crypto/rand backends that ~never fail.

  • On Linux, we primarily use the getrandom(2) system call, which never fails.

    • It may block if the pool is not initialized yet at early boot, and may be interrupted by a signal handler if requesting more than 256 bytes, but neither of those surface as errors to the application.
    • getrandom() was first available in Linux 3.17, released in October 2014. Debian oldstable is on Linux 5.10.
    • getrandom() can be blocked with seccomp. That's a bad (and weird) idea, and the default Docker profile doesn't do that. In that case we fall back to opening /dev/urandom, which might fail if the file is not available or file descriptors run out.
  • On macOS and iOS we use arc4random() since https://go.dev/cl/569655. From the man page:

    These functions are always successful, and no return value is reserved to indicate an error.

  • On Windows we use the ProcessPrng function. From the docs:

    Always returns TRUE.

  • The BSDs use similar syscalls with similar properties (whether getrandom or getentropy) although we should switch the ones we can to arc4random.

  • On js/wasm we use getRandomValues which doesn't have documented failure modes.

  • On WASIP1 there's random_get which regrettably has an error return value, making it the one platform (ignoring misconfigured Linux) where there might be errors getting platform random bytes. Since WASI rests on an underlying platform, and every underlying platform has failure-less CSPRNGs, it's hard to imagine why random_get should actually return an error.

I'm proposing we make crypto/rand throw (irrecoverably crash the program) if an error occurs, and document that the error return values of crypto/rand.Read and crypto/rand.Reader.Read are always nil.

This will free applications from having to do error handling for a condition that essentially can't happen, and that if it did happen is essentially not possible to handle securely by the application.

This will also allow introducing new APIs like a hypothetical String(charset string) string (not part of this proposal) without an error return, making them more usable and appealing.

Based on a suggestion by @rsc.

/cc @golang/security @golang/proposal-review

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Accepted

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions