From 3e156b96a15d153cb4c6378cb25911b3cfa035ea Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 8 Jan 2025 14:07:35 +0100 Subject: [PATCH] Mark the initialize functions as deprecated. Instead, advertise the use of the default Unix generator based on getrandom/getentropy. This is thread-safe and allows to remove the mirage-crypto-rng-{lwt,miou-unix,eio,async} packages in the future. --- bench/speed.ml | 10 +++++---- rng/async/mirage_crypto_rng_async.mli | 1 + rng/eio/mirage_crypto_rng_eio.mli | 1 + rng/lwt/mirage_crypto_rng_lwt.mli | 1 + rng/miou/mirage_crypto_rng_miou_unix.mli | 1 + rng/mirage_crypto_rng.mli | 27 ++++------------------- rng/rng.ml | 15 +------------ rng/unix/mirage_crypto_rng_unix.mli | 1 + tests/test_eio_entropy_collection.ml | 28 +++++++++++++----------- tests/test_eio_rng.ml | 16 ++++++++------ tests/test_entropy_collection_async.ml | 4 +++- tests/test_miou_entropy_collection.ml | 6 ++++- tests/test_miou_rng.ml | 6 ++++- 13 files changed, 53 insertions(+), 64 deletions(-) diff --git a/bench/speed.ml b/bench/speed.ml index dcb25267..2447d6d6 100644 --- a/bench/speed.ml +++ b/bench/speed.ml @@ -480,10 +480,12 @@ let benchmarks = [ throughput_into name (fun dst cs -> DES.ECB.unsafe_encrypt_into ~key cs ~src_off:0 dst ~dst_off:0 (String.length cs))) ; bm "fortuna" (fun name -> - Mirage_crypto_rng_unix.initialize (module Mirage_crypto_rng.Fortuna); - throughput name (fun buf -> - let buf = Bytes.unsafe_of_string buf in - Mirage_crypto_rng.generate_into buf ~off:0 (Bytes.length buf))) ; + begin[@alert "-deprecated"] + Mirage_crypto_rng_unix.initialize (module Mirage_crypto_rng.Fortuna); + throughput name (fun buf -> + let buf = Bytes.unsafe_of_string buf in + Mirage_crypto_rng.generate_into buf ~off:0 (Bytes.length buf)) + end); bm "getentropy" (fun name -> Mirage_crypto_rng_unix.use_getentropy (); diff --git a/rng/async/mirage_crypto_rng_async.mli b/rng/async/mirage_crypto_rng_async.mli index 67982af8..78d35266 100644 --- a/rng/async/mirage_crypto_rng_async.mli +++ b/rng/async/mirage_crypto_rng_async.mli @@ -16,3 +16,4 @@ val initialize -> ?sleep:Time_ns.Span.t -> 'a Mirage_crypto_rng.generator -> unit +[@@deprecated "Use 'Mirage_crypto_rng_unix.use_default ()' instead."] diff --git a/rng/eio/mirage_crypto_rng_eio.mli b/rng/eio/mirage_crypto_rng_eio.mli index e20d179a..e14c0f3d 100644 --- a/rng/eio/mirage_crypto_rng_eio.mli +++ b/rng/eio/mirage_crypto_rng_eio.mli @@ -39,3 +39,4 @@ val run -> 'a Mirage_crypto_rng.generator -> _ env -> (unit -> 'b) -> 'b +[@@deprecated "Use 'Mirage_crypto_rng_unix.use_default ()' instead."] diff --git a/rng/lwt/mirage_crypto_rng_lwt.mli b/rng/lwt/mirage_crypto_rng_lwt.mli index fb9db2e6..af251d3c 100644 --- a/rng/lwt/mirage_crypto_rng_lwt.mli +++ b/rng/lwt/mirage_crypto_rng_lwt.mli @@ -9,3 +9,4 @@ is used to collect entropy. *) val initialize : ?g:'a -> ?sleep:int64 -> 'a Mirage_crypto_rng.generator -> unit +[@@deprecated "Use 'Mirage_crypto_rng_unix.use_default ()' instead."] diff --git a/rng/miou/mirage_crypto_rng_miou_unix.mli b/rng/miou/mirage_crypto_rng_miou_unix.mli index 057afbc8..2a025d5c 100644 --- a/rng/miou/mirage_crypto_rng_miou_unix.mli +++ b/rng/miou/mirage_crypto_rng_miou_unix.mli @@ -14,6 +14,7 @@ type rng (** Type of tasks seeding the RNG. *) val initialize : ?g:'a -> ?sleep:int64 -> 'a Mirage_crypto_rng.generator -> rng +[@@deprecated "Use 'Mirage_crypto_rng_unix.use_default ()' instead."] (** [initialize ?g ?sleep (module Generator)] will allow the RNG to operate in a returned task. This task periodically launches sub-tasks that seed the engine (using [getrandom()], [getentropy()] or [BCryptGenRandom()] depending diff --git a/rng/mirage_crypto_rng.mli b/rng/mirage_crypto_rng.mli index a483331d..ad7e9299 100644 --- a/rng/mirage_crypto_rng.mli +++ b/rng/mirage_crypto_rng.mli @@ -23,36 +23,17 @@ Please ensure to call [Mirage_crypto_rng_unix.use_default], or [Mirage_crypto_rng_unix.use_dev_urandom] (if you only want to use /dev/urandom), or [Mirage_crypto_rng_unix.use_getentropy] (if you only want - to use getentropy). + to use getrandom/getentropy/BCryptGenRandom). For fine-grained control (doing entropy harvesting, etc.), please continue - reading the documentation below. {b Please be aware that the feeding of Fortuna - and producing random numbers is not thread-safe} (it is on Miou_unix via Pfortuna). + reading the documentation below. {b Please be aware that the feeding of + Fortuna and producing random numbers is not thread-safe} (it is on Miou_unix + via Pfortuna). The RNGs here are merely the deterministic part of a full random number generation suite. For proper operation, they need to be seeded with a high-quality entropy source. - Suitable entropy feeding of generators are provided by other libraries - {{!Mirage_crypto_rng_lwt}mirage-crypto-rng-lwt} (for Lwt), - {{!Mirage_crypto_rng_async}mirage-crypto-rng-async} (for Async), - {{!Mirage_crypto_rng_mirage}mirage-crypto-rng-mirage} (for MirageOS), - {{!Mirage_crypto_rng_unix}mirage-crypto-rng.unix}, - {{!Mirage_crypto_rng_eio}mirage-crypto-rng-eio} (for Eio), - and {{!Mirage_crypto_rng_miou_unix}mirage-crypto-miou-unix} (for Miou_unix). - - The intention is that "initialize" in the respective sub-library is called - once, which sets the default generator and registers entropy - harvesting asynchronous tasks. The semantics is that the entropy is always - fed to the {{!default_generator}default generator}, which is not necessarily - the one set by "initialize". The reasoning behind this is that the default - generator should be used in most setting, and that should be fed a constant - stream of entropy. - - [mirage-crypto-rng-eio] package differs slightly from other rng packages. - Instead of the [initialize] function a [run] function is provided with - similar behaviour, i.e. RNG setup, entropy collection and periodic reseeding. - Although this module exposes a more fine-grained interface, e.g. allowing manual seeding of generators, this is intended either for implementing entropy-harvesting modules, or very specialized purposes. Users of this diff --git a/rng/rng.ml b/rng/rng.ml index 0be9e75d..c410d415 100644 --- a/rng/rng.ml +++ b/rng/rng.ml @@ -15,20 +15,7 @@ let setup_rng = following:\ \n If you are using MirageOS, use the random device in config.ml: \ `let main = Mirage.main \"Unikernel.Main\" (random @-> job)`, \ - and `let () = register \"my_unikernel\" [main $ default_random]`. \ - \n If you are using Lwt, execute \ - `Mirage_crypto_rng_lwt.initialize (module Mirage_crypto_rng.Fortuna)` \ - at startup. \ - \n If you are using Async, execute \ - `Mirage_crypto_rng_async.initialize (module Mirage_crypto_rng.Fortuna)` \ - at startup. \ - \n If you are using Eio, execute in one of the fibers \ - `Mirage_crypto_rng_eio.run (module Fortuna) env` (`env` from `Eio_main.run`). - \n Otherwise, there is no periodic reseeding. For an initial seed from \ - getrandom(), execute \ - `Mirage_crypto_rng_unix.initialize (module Mirage_crypto_rng.Fortuna)`. \ - You can use `Mirage_crypto_rng.accumulate` and `Mirage_crypto_rng.reseed` \ - to reseed the RNG manually." + and `let () = register \"my_unikernel\" [main $ default_random]`." let () = Printexc.register_printer (function | Unseeded_generator -> diff --git a/rng/unix/mirage_crypto_rng_unix.mli b/rng/unix/mirage_crypto_rng_unix.mli index 46cb64c7..2df769b3 100644 --- a/rng/unix/mirage_crypto_rng_unix.mli +++ b/rng/unix/mirage_crypto_rng_unix.mli @@ -8,6 +8,7 @@ (** [initialize ~g rng] will bring the RNG into a working state. *) val initialize : ?g:'a -> 'a Mirage_crypto_rng.generator -> unit +[@@deprecated "Use 'Mirage_crypto_rng_unix.use_default ()' instead."] (** [getrandom size] returns a buffer of [size] filled with random bytes. *) val getrandom : int -> string diff --git a/tests/test_eio_entropy_collection.ml b/tests/test_eio_entropy_collection.ml index b2764517..09a4cade 100644 --- a/tests/test_eio_entropy_collection.ml +++ b/tests/test_eio_entropy_collection.ml @@ -20,17 +20,19 @@ end let () = Eio_main.run @@ fun env -> - Mirage_crypto_rng_eio.run (module Printing_rng) env @@ fun () -> - Eio.Fiber.both - begin fun () -> - let sleep = Duration.(of_sec 2 |> to_f) in - Eio.Time.sleep env#clock sleep - end - begin fun () -> - Format.printf "entropy sources: %a@,%!" - (fun ppf -> List.iter (fun x -> - Mirage_crypto_rng.Entropy.pp_source ppf x; - Format.pp_print_space ppf ())) - (Mirage_crypto_rng.Entropy.sources ()) - end + begin[@alert "-deprecated"] + Mirage_crypto_rng_eio.run (module Printing_rng) env @@ fun () -> + Eio.Fiber.both + begin fun () -> + let sleep = Duration.(of_sec 2 |> to_f) in + Eio.Time.sleep env#clock sleep + end + begin fun () -> + Format.printf "entropy sources: %a@,%!" + (fun ppf -> List.iter (fun x -> + Mirage_crypto_rng.Entropy.pp_source ppf x; + Format.pp_print_space ppf ())) + (Mirage_crypto_rng.Entropy.sources ()) + end + end diff --git a/tests/test_eio_rng.ml b/tests/test_eio_rng.ml index 713e8c46..5e5ce5a7 100644 --- a/tests/test_eio_rng.ml +++ b/tests/test_eio_rng.ml @@ -2,10 +2,12 @@ open Mirage_crypto_rng let () = Eio_main.run @@ fun env -> - Mirage_crypto_rng_eio.run (module Fortuna) env @@ fun () -> - let random_num = Mirage_crypto_rng.generate 32 in - assert (String.length random_num = 32); - Printf.printf "32 bit random number: %S\n%!" random_num; - let random_num = Mirage_crypto_rng.generate 16 in - assert (String.length random_num = 16); - Printf.printf "16 bit random number: %S\n%!" random_num; + begin[@alert "-deprecated"] + Mirage_crypto_rng_eio.run (module Fortuna) env @@ fun () -> + let random_num = Mirage_crypto_rng.generate 32 in + assert (String.length random_num = 32); + Printf.printf "32 bit random number: %S\n%!" random_num; + let random_num = Mirage_crypto_rng.generate 16 in + assert (String.length random_num = 16); + Printf.printf "16 bit random number: %S\n%!" random_num; + end diff --git a/tests/test_entropy_collection_async.ml b/tests/test_entropy_collection_async.ml index d2331249..2b4b54d1 100644 --- a/tests/test_entropy_collection_async.ml +++ b/tests/test_entropy_collection_async.ml @@ -28,7 +28,9 @@ module E = Mirage_crypto_rng_async let main () = - E.initialize (module Printing_rng); + begin[@alert "-deprecated"] + E.initialize (module Printing_rng); + end; Format.printf "entropy sources: %a@,%!" (fun ppf -> List.iter ~f:(fun x -> Mirage_crypto_rng.Entropy.pp_source ppf x; diff --git a/tests/test_miou_entropy_collection.ml b/tests/test_miou_entropy_collection.ml index 57ad3eab..45a7f20f 100644 --- a/tests/test_miou_entropy_collection.ml +++ b/tests/test_miou_entropy_collection.ml @@ -20,7 +20,11 @@ end let () = Miou_unix.run @@ fun () -> - let rng = Mirage_crypto_rng_miou_unix.initialize (module Printing_rng) in + let rng = + begin[@alert "-deprecated"] + Mirage_crypto_rng_miou_unix.initialize (module Printing_rng) + end + in Format.printf "entropy sources: %a@,%!" (fun ppf -> List.iter (fun x -> Mirage_crypto_rng.Entropy.pp_source ppf x; diff --git a/tests/test_miou_rng.ml b/tests/test_miou_rng.ml index 1cd5dcb8..852a3251 100644 --- a/tests/test_miou_rng.ml +++ b/tests/test_miou_rng.ml @@ -1,5 +1,9 @@ let () = Miou_unix.run @@ fun () -> - let rng = Mirage_crypto_rng_miou_unix.(initialize (module Pfortuna)) in + let rng = + begin[@alert "-deprecated"] + Mirage_crypto_rng_miou_unix.(initialize (module Pfortuna)) + end + in let random_num = Mirage_crypto_rng.generate 32 in assert (String.length random_num = 32); Printf.printf "32 bit random number: %s\n%!" (Ohex.encode random_num);