Skip to content

Commit

Permalink
Issue briansmith#316 - Replace /dev/urandom usage on *BSD
Browse files Browse the repository at this point in the history
Now OpenBSD and FreeBSD utilizes `arc4rand_buf()` function in their
C stdlib.

- Implement GFp_sysrand_chunk() in sysrand.c for OpenBSD and FreeBSD.
- On OpenBSD and FreeBSD, mk/ring.mk now uses `-D_BSD_SOURCE` in
  `CPPFLAGS` instead of `-D_XOPEN_SOURCE=700`.

TODOs:
- Update docs.
- Remove debug print.
- Ensure FreeBSD's arc4rand_buf() is as safe as OpenBSD's.

I agree to license my contributions to each file under the terms given
at the top of each file I changed.
  • Loading branch information
tatsuya6502 committed Oct 23, 2016
1 parent 4102ae7 commit 321d710
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 13 deletions.
20 changes: 20 additions & 0 deletions crypto/rand/sysrand.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,24 @@ int GFp_sysrand_chunk(void *out, size_t requested) {
return 1;
}

#elif defined(__OpenBSD__) || defined(__FreeBSD__)

#include <limits.h>
#include <stdlib.h>

// DEBUG:
#include <stdio.h>

const size_t GFp_sysrand_chunk_max_len = ULONG_MAX;

int GFp_sysrand_chunk(void *out, size_t requested) {
// DEBUG:
printf("calling arc4rand_buf()\n");

assert(requested <= GFp_sysrand_chunk_max_len);
// This function never fails so let's always return 1.
arc4random_buf(out, requested);
return 1;
}

#endif
7 changes: 6 additions & 1 deletion mk/ring.mk
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@

RING_PREFIX ?= ring/

RING_CPPFLAGS = -I$(RING_PREFIX)include -D_XOPEN_SOURCE=700
RING_CPPFLAGS = -I$(RING_PREFIX)include
ifneq (, $(filter openbsd freebsd, $(TARGET_SYS)))
RING_CPPFLAGS += -D_BSD_SOURCE
else
RING_CPPFLAGS += -D_XOPEN_SOURCE=700
endif

RING_SRCS = $(addprefix $(RING_PREFIX), \
crypto/aes/aes.c \
Expand Down
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@
#[cfg(feature = "internal_benches")]
extern crate test as bench;

#[cfg(any(all(unix,
any(not(target_os = "linux"),
feature = "dev_urandom_fallback"))))]
#[cfg(all(unix,
any(not(target_os = "linux"), feature = "dev_urandom_fallback"),
not(any(target_os = "openbsd",
target_os = "freebsd"))))]
#[macro_use]
extern crate lazy_static;

Expand Down
40 changes: 31 additions & 9 deletions src/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
//! (seccomp filters on Linux in particular). See `SystemRandom`'s
//! documentation for more details.

#[cfg(any(target_os = "linux", windows, test))]
#[cfg(any(target_os = "linux",
target_os = "openbsd",
target_os = "freebsd",
windows,
test))]
use c;

#[cfg(test)]
Expand Down Expand Up @@ -107,17 +110,25 @@ impl SecureRandom for SystemRandom {
}
}

#[cfg(not(any(target_os = "linux", windows)))]
#[cfg(not(any(target_os = "linux",
target_os = "openbsd",
target_os = "freebsd",
windows)))]
use self::urandom::fill as fill_impl;

#[cfg(any(all(target_os = "linux", not(feature = "dev_urandom_fallback")),
target_os = "openbsd",
target_os = "freebsd",
windows))]
use self::sysrand::fill as fill_impl;

#[cfg(all(target_os = "linux", feature = "dev_urandom_fallback"))]
use self::sysrand_or_urandom::fill as fill_impl;

#[cfg(any(target_os = "linux", windows))]
#[cfg(any(target_os = "linux",
target_os = "openbsd",
target_os = "freebsd",
windows))]
mod sysrand {
use {bssl, error};

Expand All @@ -134,8 +145,10 @@ mod sysrand {

// Keep the `cfg` conditions in sync with the conditions in lib.rs.
#[cfg(all(unix,
not(all(target_os = "linux",
not(feature = "dev_urandom_fallback")))))]
not(any(all(target_os = "linux",
not(feature = "dev_urandom_fallback")),
target_os = "openbsd",
target_os = "freebsd"))))]
mod urandom {
extern crate std;
use error;
Expand Down Expand Up @@ -215,7 +228,10 @@ pub unsafe extern fn RAND_bytes(rng: *mut RAND, dest: *mut u8,
}


#[cfg(any(target_os = "linux", windows))]
#[cfg(any(windows,
target_os = "linux",
target_os = "openbsd",
target_os = "freebsd"))]
extern {
static GFp_sysrand_chunk_max_len: c::size_t;
fn GFp_sysrand_chunk(buf: *mut u8, len: c::size_t) -> c::int;
Expand Down Expand Up @@ -333,10 +349,16 @@ mod tests {
}
}

#[cfg(any(target_os = "linux", windows))]
#[cfg(any(target_os = "linux",
target_os = "openbsd",
target_os = "freebsd",
windows))]
fn max_chunk_len() -> usize { unsafe { super::GFp_sysrand_chunk_max_len } }

#[cfg(not(any(target_os = "linux", windows)))]
#[cfg(not(any(target_os = "linux",
target_os = "openbsd",
target_os = "freebsd",
windows)))]
fn max_chunk_len() -> usize {
use core;
core::usize::MAX
Expand Down

0 comments on commit 321d710

Please sign in to comment.