Skip to content

Commit

Permalink
Merge pull request #12 from hannesm/entropy
Browse files Browse the repository at this point in the history
integrate mirage-entropy as mirage-crypto-entropy
  • Loading branch information
hannesm authored Feb 26, 2020
2 parents e760aa8 + c5741c5 commit b390b50
Show file tree
Hide file tree
Showing 23 changed files with 509 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ script: bash -ex .travis-opam.sh
sudo: required
env:
global:
- PINS="mirage-crypto:. mirage-crypto-rng:. mirage-crypto-pk:."
- PINS="mirage-crypto:. mirage-crypto-rng:. mirage-crypto-pk:. mirage-crypto-entropy:."
- PACKAGE="mirage-crypto-pk"
- TESTS=true
matrix:
Expand Down
66 changes: 66 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,72 @@
`List.iter`.
* `Rsa.well_formed` can test if a triplet `(e, p, q)` looks enough like a key to
be safe to use.
* Imported mirage-entropy v0.5.1 with the following changelog

### v0.5.1 (2020-02-24)

* use dune for building this package (#47 @hannesm)

### v0.5.0 (2019-11-01)

* Use mirage-runtime provided hooks (since 3.7.0), see mirage/mirage#1010 (#45 @samoht)
* Drop mirage-os-shim dependency (#45 @samoht)
* Raise minimum OCaml version to 4.06.0 (#46 @hannesm)

### 0.4.1 (2018-08-15)

* Aarch64 support (#39 by @reynir)

### 0.4.0 (2017-01-20)

* Compatibility with MirageOS 3 module types.
* Add a benchmark.
* Obsolete `mirage-entropy-<BACKEND>`; the repository now contains only `mirage-entropy`.
* Support Unix, Xen, and Solo5 backends.
* Prune `oasis`.
* Move `noalloc` to 4.03-style annotations

### 0.3.0 (2015-05-02)

* Remove `mirage-entropy-unix` from the repository; it now only contains `mirage-entropy-xen`.
* Add internal entropy harvesting via timing and CPU RNG if available.
* Temporarily disable `xentropyd`.
* The API is no longer `V1.ENTROPY` compatible.

### 0.2.0 (09-Mar-2015)

* Do not wrap `Entropy_unix` in a functor as it is meant to be used directly.
* Xen: read entropy from a Xen PV device. This is implemented by the `xentropyd` daemon.

### 0.1.6 (06-July-2014)

* Rework the module to be event-driven, more in line with entropy gathering.

### 0.1.5 (06-July-2014)

* Guarantee that all of the required entropy is read on Unix.
* Add a `Entropy_xen_weak` that uses the builtin `Random.self_init` as a measure of last-resort.

### 0.1.4 (04-July-2014)

* provide Mirage 1.2.0 interfaces (`V1_LWT.ENTROPY`).
* name modules `Entropy_xen` and `Entropy_unix` to not clash.

### 0.1.3 (03-July-2014)

* Unbreak build: ocamlfind wasn't able to locate the package previously.

### 0.1.2 (03-July-2014)

* Use `/dev/urandom` instead of `/dev/random` (for non-blocking behaviour).

### 0.1.1 (03-July-2014)

* Use Makefile instead of oasis as build system.

### 0.1.0 (03-July-2014)

* Initial release: on Unix, use `/dev/random`; on XEN, error out.

## v0.5.4 2017-01-31:
* Relicense from BSD2 to ISC.
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ Kaloper. It was forked with the permission of the original author in order to
facilitate changes (e.g. build system) required by Mirage that the upstream
didn't have time to keep up with.

Mirage-crypto-entropy embeds the former mirage-entropy opam package, which
implements various entropy sources for MirageOS unikernels:
- timer based ones (see [whirlwind RNG paper](https://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf))
- rdseed and rdrand (x86/x86-64 only)

# Status

This is a work in progress repository that is not yet released. Please see
Expand Down
11 changes: 9 additions & 2 deletions config/cfg.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let evar = "MIRAGE_CRYPTO_ACCELERATE"
let needs = [`SSSE3; `AES; `PCLMULQDQ]
let flags = ["-DACCELERATE"; "-mssse3"; "-maes"; "-mpclmul"]
let std_flags = ["--std=c99"; "-Wall"; "-Wextra"; "-O3"]
let std_flags = ["--std=c99"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3"]

let _ =
let auto = match Cpuid.supports needs with Ok true -> flags | _ -> [] in
Expand All @@ -11,5 +11,12 @@ let _ =
| _ -> auto
| exception Not_found -> auto
in
let fs = std_flags @ accelerate_flags in
let ent_flags =
let c = Configurator.V1.create "mirage-crypto" in
let arch = Configurator.V1.Process.run c "uname" ["-m"] in
match String.trim arch.Configurator.V1.Process.stdout with
| "x86_64" | "amd64" | "x86" -> [ "-mrdrnd" ; "-mrdseed" ]
| _ -> []
in
let fs = std_flags @ ent_flags @ accelerate_flags in
Format.(printf "(@[%a@])@.%!" (fun ppf -> List.iter (fprintf ppf "%s@ ")) fs)
2 changes: 1 addition & 1 deletion config/dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
(executables
(names cfg)
(libraries dune-configurator result cpuid))
(libraries dune-configurator cpuid))
23 changes: 23 additions & 0 deletions entropy/LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Copyright (c) 2014-2016, Hannes Mehnert, Anil Madhavapeddy, David Kaloper Meršinjak
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4 changes: 4 additions & 0 deletions entropy/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(library
(name mirage_crypto_entropy)
(public_name mirage-crypto-entropy)
(libraries cstruct lwt mirage-runtime mirage-crypto mirage-crypto-rng))
133 changes: 133 additions & 0 deletions entropy/mirage_crypto_entropy.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
(*
* Copyright (c) 2014 Hannes Mehnert
* Copyright (c) 2014 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2014-2016 David Kaloper Meršinjak
* Copyright (c) 2015 Citrix Systems Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)

module Cpu_native = struct

external cycles : unit -> int = "caml_cycle_counter" [@@noalloc]
external random : unit -> int = "caml_cpu_random" [@@noalloc]
external rng_type : unit -> int = "caml_cpu_rng_type" [@@noalloc]
external detect : unit -> unit = "caml_entropy_detect"

let () = detect ()

let cpu_rng =
match rng_type () with
| 0 -> None
| 1 -> Some `Rdrand
| 2 -> Some `Rdseed
| _ -> assert false
end

open Lwt.Infix

type t = unit

type source = [
| `Timer
| `Rdseed
| `Rdrand
]

let pp_source ppf s =
let str = match s with
| `Timer -> "timer"
| `Rdseed -> "rdseed"
| `Rdrand -> "rdrand"
in
Format.pp_print_string ppf str

let sources () =
`Timer ::
match Cpu_native.cpu_rng with
| Some x -> [x]
| None -> []

(* Note:
* `bootstrap` is not a simple feedback loop. It attempts to exploit CPU-level
* data races that lead to execution-time variability of identical instructions.
* See Whirlwind RNG:
* http://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf
*)
let bootstrap f =
let outer = 100
and inner_max = 1024
and a = ref 0
and cs = Cstruct.create 2 in
for i = 0 to outer - 1 do
let tsc = Cpu_native.cycles () in
let () = Cstruct.LE.set_uint16 cs 0 tsc ; f cs in
for j = 1 to tsc mod inner_max do
a := tsc / j - !a * i + 1
done
done ;
Lwt.return_unit

let interrupt_hook () =
match Cpu_native.cpu_rng with
| None ->
let buf = Cstruct.create 4 in fun () ->
let a = Cpu_native.cycles () in
Cstruct.LE.set_uint32 buf 0 (Int32.of_int a) ;
buf
| Some _ ->
let buf = Cstruct.create 12 in fun () ->
let a = Cpu_native.cycles ()
and b = Cpu_native.random () in
Cstruct.LE.set_uint32 buf 0 (Int32.of_int a) ;
Cstruct.LE.set_uint64 buf 4 (Int64.of_int b) ;
buf

(* XXX TODO
*
* Xentropyd. Detect its presence here, make it feed into `t.handlers` as
* `~source:1` and add a function providing initial entropy burst to
* `t.inits`.
*
* Compile-time entropy. A function returning it could go into `t.inits`.
*)
let bootstrap_functions = [ bootstrap ]

let running = ref false

let initialize (type a) ?g (rng : a Mirage_crypto_rng.generator) =
if !running then
Lwt.fail_with "entropy harvesting already running"
else begin
running := true;
let rng = Mirage_crypto_rng.(create ?g rng) in
Mirage_crypto_rng.generator := rng;
let `Acc handler = Mirage_crypto_rng.accumulate (Some rng) in
Lwt_list.iteri_p
(fun i boot -> boot (handler ~source:i))
bootstrap_functions >|= fun () ->
let hook = interrupt_hook () in
Mirage_runtime.at_enter_iter (fun () ->
let e = hook () in
handler ~source:0 e)
end
49 changes: 49 additions & 0 deletions entropy/mirage_crypto_entropy.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
(*
* Copyright (c) 2014 Hannes Mehnert
* Copyright (c) 2014 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2014-2016 David Kaloper Meršinjak
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*)

type t
(** The type of the entropy device. *)

type source = [
| `Timer
| `Rdseed
| `Rdrand
]
(** A polymorphic variant of entropy sources. *)

val pp_source : Format.formatter -> source -> unit
(** [pp_source ppf source] pretty-prints [source] on [ppf]. *)

val sources : unit -> source list
(** [sources ()] is a list of supported entropy sources on your platform. *)

val initialize :
?g:'a -> (module Mirage_crypto_rng.Generator with type g = 'a) -> t Lwt.t
(** [initialize ~g rng_module] sets the default generator to the [rng_module]
and sets up periodic entropy feeding for that rng. This function raises if
called a second time. *)
2 changes: 1 addition & 1 deletion freestanding/dune
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
(libraries ocaml-freestanding)
(c_flags (:include ../src/cflags.sexp) (:include cflags-freestanding.sexp))
(c_names misc hash_stubs md5 sha1 sha256 sha512 aes_generic
aes_aesni des_generic ghash_pclmul ghash_generic)
aes_aesni des_generic ghash_pclmul ghash_generic entropy_cpu_stubs)
)

(rule (with-stdout-to cflags-freestanding.sexp (run ./cflags.sh)))
34 changes: 34 additions & 0 deletions mirage-crypto-entropy.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
opam-version: "2.0"
homepage: "https://github.com/mirage/mirage-crypto"
dev-repo: "git+https://github.com/mirage/mirage-crypto.git"
bug-reports: "https://github.com/mirage/mirage-crypto/issues"
doc: "https://mirage.github.io/mirage-crypto/"
author: ["Hannes Mehnert" "David Kaloper" "Anil Madhavapeddy" "Dave Scott"]
maintainer: "Hannes Mehnert <hannes@mehnert.org>"
license: "BSD2"

build: [
["dune" "subst"] {pinned}
["dune" "build" "-p" name "-j" jobs]
["dune" "runtest" "-p" name "-j" jobs] {with-test}
]
depends: [
"dune" {>= "1.7.0"}
"ocaml" {>= "4.07.0"}
"cstruct" {>= "4.0.0"}
"mirage-runtime" {>= "3.7.0"}
"lwt" {>= "4.0.0"}
"mirage-crypto" {=version}
"mirage-crypto-rng" {=version}
"mirage-unix" {with-test & >= "3.0.0"}
]
tags: [ "org:mirage"]
available: [
arch = "arm" | arch = "x86_32" | arch = "x86_64" | arch = "arm64"
]
synopsis: "Entropy source for MirageOS unikernels"
description: """
mirage-crypto-entropy implements various entropy sources for MirageOS unikernels:
- timer based ones (see [whirlwind RNG paper](https://www.ieee-security.org/TC/SP2014/papers/Not-So-RandomNumbersinVirtualizedLinuxandtheWhirlwindRNG.pdf))
- rdseed and rdrand (x86/x86-64 only)
"""
4 changes: 0 additions & 4 deletions mirage-crypto-rng.opam
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,4 @@ depends: [
"ounit" {with-test}
"cstruct" {>="3.2.0"}
"mirage-crypto" {=version}

#needed for the mirage subpackage - may move to a separate package
"lwt"
"mirage-entropy"
]
6 changes: 0 additions & 6 deletions rng/mirage/dune

This file was deleted.

Loading

0 comments on commit b390b50

Please sign in to comment.