New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use something better than /dev/urandom on FreeBSD #326

Open
briansmith opened this Issue Nov 1, 2016 · 10 comments

Comments

Projects
None yet
2 participants
@briansmith
Owner

briansmith commented Nov 1, 2016

The main drivers here are performance and the ability to work correctly and automatically in a chroot/jail.

This was split off from #316, which is now OpenBSD-only. Note that iOS and MacOS are issue #149.

See:

From reading various FreeBSD mailing list messages, it seems like FreeBSD doesn't have a good way to guarantee fork-safety, which is the same problem that Linux has. Therefore, it seems like we should always be getting random values from the OS. That means, AFAICT, either reading from /dev/[u]random or the KERN_ARND sysctl. Note the potential problems with KERN_ARND mentioned in the linked-to comments above.

I don't understand this issue fully, but it seems that FreeBSD has a RANDOM kernel module that can be disabled, and in that disabled state it may be problematic to do anything better than reading from /dev/[u]random: "RW mentioned kernels without RANDOM, being an awkward situation for which it seems necessary to fall back to the PRNG in userland." - https://lists.freebsd.org/pipermail/freebsd-security/2014-July/007869.html.

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Nov 8, 2016

LibreSSL just uses arc4random. The rationale was, basically, "deal with it".

But they have added locking and fork detection using pthread_atfork on FreeBSD. The comment says that atfork fails silently "if a program does not link to -lthr". That's not a problem for a Rust library — just link to thr in build.rs! Cargo is nice :) So we do have a good way to guarantee fork-safety.

They also have an emulation of getentropy using KERN_ARND.

myfreeweb commented Nov 8, 2016

LibreSSL just uses arc4random. The rationale was, basically, "deal with it".

But they have added locking and fork detection using pthread_atfork on FreeBSD. The comment says that atfork fails silently "if a program does not link to -lthr". That's not a problem for a Rust library — just link to thr in build.rs! Cargo is nice :) So we do have a good way to guarantee fork-safety.

They also have an emulation of getentropy using KERN_ARND.

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Nov 8, 2016

Owner

Thanks!

They also have an emulation of getentropy using KERN_ARND.

This looks the most promising to me.

Probably we should check what libsodium does too.

Owner

briansmith commented Nov 8, 2016

Thanks!

They also have an emulation of getentropy using KERN_ARND.

This looks the most promising to me.

Probably we should check what libsodium does too.

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Nov 8, 2016

They have a complicated file full of #ifdefs, but this seems like the part we're interested in:

#if defined(__OpenBSD__) || defined(__CloudABI__)
# define HAVE_SAFE_ARC4RANDOM 1
#endif

It's interesting that CloudABI's arc4random is considered safe, but not FreeBSD's. CloudABI runs on FreeBSD using, I think, the same arc4random as FreeBSD ABI programs. But on CloudABI you can't just open /dev/random, so it's not like they have a choice :D

myfreeweb commented Nov 8, 2016

They have a complicated file full of #ifdefs, but this seems like the part we're interested in:

#if defined(__OpenBSD__) || defined(__CloudABI__)
# define HAVE_SAFE_ARC4RANDOM 1
#endif

It's interesting that CloudABI's arc4random is considered safe, but not FreeBSD's. CloudABI runs on FreeBSD using, I think, the same arc4random as FreeBSD ABI programs. But on CloudABI you can't just open /dev/random, so it's not like they have a choice :D

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith Apr 20, 2017

Owner

https://svnweb.freebsd.org/base?view=revision&revision=317015

Replace the RC4 algorithm for generating in-kernel secure random
numbers with Chacha20. Keep the API, though, as that is what the
other *BSD's have done.

Use the boot-time entropy stash (if present) to bootstrap the
in-kernel entropy source.

Owner

briansmith commented Apr 20, 2017

https://svnweb.freebsd.org/base?view=revision&revision=317015

Replace the RC4 algorithm for generating in-kernel secure random
numbers with Chacha20. Keep the API, though, as that is what the
other *BSD's have done.

Use the boot-time entropy stash (if present) to bootstrap the
in-kernel entropy source.

@briansmith

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb Oct 2, 2017

Somehow I only just discovered this: the rand crate uses KERN_ARND sysctl!

myfreeweb commented Oct 2, 2017

Somehow I only just discovered this: the rand crate uses KERN_ARND sysctl!

@myfreeweb

This comment has been minimized.

Show comment
Hide comment
@myfreeweb

myfreeweb May 17, 2018

FreeBSD 12 (current dev branch) now has all the interfaces: getentropy(3), getrandom(2).

The getentropy implementation uses the getrandom syscall, but falls back to KERN_ARND if you install a new libc but keep an old kernel.

The getrandom syscall is faster than KERN_ARND but equivalent in quality (and thread/fork safety I guess??).

So I think dynamically probing for getentropy would make sense, but just using KERN_ARND like the rand crate does will still be fine.

myfreeweb commented May 17, 2018

FreeBSD 12 (current dev branch) now has all the interfaces: getentropy(3), getrandom(2).

The getentropy implementation uses the getrandom syscall, but falls back to KERN_ARND if you install a new libc but keep an old kernel.

The getrandom syscall is faster than KERN_ARND but equivalent in quality (and thread/fork safety I guess??).

So I think dynamically probing for getentropy would make sense, but just using KERN_ARND like the rand crate does will still be fine.

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith May 17, 2018

Owner

So I think dynamically probing for getentropy would make sense, but just using KERN_ARND like the rand crate does will still be fine.

I think it would be good to try to use getentropy if it is available (using weak linkage) and fallback to the /dev/urandom fallback if that default feature is enabled. That's what we'd have to do on macOS, IIUC, and I'd like to minimize the amount of BSD-specific code we have to maintain, since we have so few BSD users.

Remember:

The main drivers here are performance and the ability to work correctly and automatically in a chroot/jail.

IMO, it is OK if we only get these benefits on newer versions of BSD.

Owner

briansmith commented May 17, 2018

So I think dynamically probing for getentropy would make sense, but just using KERN_ARND like the rand crate does will still be fine.

I think it would be good to try to use getentropy if it is available (using weak linkage) and fallback to the /dev/urandom fallback if that default feature is enabled. That's what we'd have to do on macOS, IIUC, and I'd like to minimize the amount of BSD-specific code we have to maintain, since we have so few BSD users.

Remember:

The main drivers here are performance and the ability to work correctly and automatically in a chroot/jail.

IMO, it is OK if we only get these benefits on newer versions of BSD.

@briansmith

This comment has been minimized.

Show comment
Hide comment
@briansmith

briansmith May 17, 2018

Owner

That's what we'd have to do on macOS, IIUC

Oops, I forgot that we already use SecRandomCopyBytes on macOS to avoid this stuff. So, yeah, I agree that your suggestion sounds reasonable.

Owner

briansmith commented May 17, 2018

That's what we'd have to do on macOS, IIUC

Oops, I forgot that we already use SecRandomCopyBytes on macOS to avoid this stuff. So, yeah, I agree that your suggestion sounds reasonable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment