Skip to content

Commit

Permalink
eio: periodically feed entropy
Browse files Browse the repository at this point in the history
  • Loading branch information
bikallem committed Apr 22, 2022
1 parent ca2bb5d commit 6660c44
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 6 deletions.
3 changes: 2 additions & 1 deletion rng/eio/dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
(library
(name mirage_crypto_rng_eio)
(libraries eio cstruct logs mirage-crypto-rng))
(libraries eio cstruct logs mirage-crypto-rng duration
mtime.clock.os))
37 changes: 34 additions & 3 deletions rng/eio/mirage_crypto_rng_eio.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,37 @@ let getrandom_init env i =
let data = getrandom env 128 in
Entropy.header i data

let periodic env sw f delta =
let clock = Eio.Stdenv.clock env in
let rec loop () =
f ();
Eio.Time.sleep clock (Duration.to_f delta);
loop ()
in
Eio.Fiber.fork ~sw loop

let periodically_feed_entropy env sw delta source =
let task () =
let per_pool = 8 in
let size = per_pool * pools None in
let random = getrandom env size in
let idx = ref 0 in
let f () =
incr idx;
Cstruct.sub random (per_pool * (pred !idx)) per_pool
in
Entropy.feed_pools None source f
in
periodic env sw task delta

let rdrand_task env sw delta =
match Entropy.cpu_rng with
| Error `Not_supported -> ()
| Ok cpu_rng -> periodic env sw (cpu_rng None) delta

let running = ref false

let initialize env =
let initialize ?(sleep = Duration.of_sec 1) (env: Eio.Stdenv.t) sw =
if !running then
Log.debug
(fun m -> m "Mirage_crypto_rng_eio.initialize has already been called, \
Expand All @@ -37,6 +65,9 @@ let initialize env =
Entropy.[ bootstrap ; whirlwind_bootstrap ; bootstrap ; getrandom_init env ] in
List.mapi (fun i f -> f i) init |> Cstruct.concat
in
let _ = Entropy.register_source "getrandom" in
set_default_generator (create ~seed (module Fortuna))
let rng = create ~seed ~time:Mtime_clock.elapsed_ns (module Fortuna) in
set_default_generator rng;
rdrand_task env sw sleep;
let source = Entropy.register_source "getrandom" in
periodically_feed_entropy env sw (Int64.mul sleep 10L) source
end
8 changes: 6 additions & 2 deletions rng/eio/mirage_crypto_rng_eio.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@
[Eio.Stdenv.secure_random] is used as the [getrandom()] implementation.
*)

(** [initialize env] will bring the RNG into a working state. *)
val initialize : Eio.Stdenv.t -> unit
(** [initialize ~sleep env sw] will bring the RNG into a working state. The argument
[sleep] is measured in ns (default 1s), and used to sleep between collection
of entropy from the CPU RNG, every [10 * sleep] getrandom is used to collect
entropy.
*)
val initialize : ?sleep:int64 -> Eio.Stdenv.t -> Eio.Switch.t -> unit

(** [getrandom env size] returns a buffer of [size] filled with random bytes. *)
val getrandom: Eio.Stdenv.t -> int -> Cstruct.t

0 comments on commit 6660c44

Please sign in to comment.