1 // Copyright 2017 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 #pragma once
8 
9 #include <lib/crypto/entropy/collector.h>
10 #include <lib/jitterentropy/jitterentropy.h>
11 #include <zircon/types.h>
12 #include <fbl/mutex.h>
13 
14 namespace crypto {
15 
16 namespace entropy {
17 
18 // An implementation of crypto::entropy::Collector that uses jitterentropy as
19 // its entropy source. Ultimately, the entropy is derived from variations in
20 // CPU timing, when various code blocks are exercised.
21 //
22 // TODO(andrewkrieger): Document jitterentropy better for Zircon, then link to
23 // that documentation here.
24 class JitterentropyCollector : public Collector {
25 public:
26     // Gets the global JitterentropyCollector instance. Returns
27     // ZX_ERR_NOT_SUPPORTED if jitterentropy is not supported (usually because
28     // the system clock is not available or not suitable).
29     //
30     // This function must be called once in a single-threaded context to
31     // initialize the JitterentropyCollector instance. After one successful call
32     // (typically during boot), it's safe to call this function from multiple
33     // threads, and to access the JitterentropyCollector instance from multiple
34     // threads. The JitterentropyCollector::DrawEntropy method is internally
35     // guarded by a mutex, so it's safe to call from multiple threads but it may
36     // block.
37     static zx_status_t GetInstance(Collector** ptr);
38 
39     // Inherited from Collector; see comments there.
40     //
41     // Note that this method internally uses a mutex to prevent multiple
42     // accesses. It is safe to call this method from multiple threads, but it
43     // may block.
44     //
45     // TODO(andrewkrieger): Determine what level of thread safety is needed for
46     // RNG reseeding, and support it more uniformly (e.g. have a thread safety
47     // contract for Collector::DrawEntropy, obeyed by all implementations).
48     size_t DrawEntropy(uint8_t* buf, size_t len) override;
49 private:
50     JitterentropyCollector(uint8_t* mem, size_t len);
51 
52     DISALLOW_COPY_ASSIGN_AND_MOVE(JitterentropyCollector);
53 
54     struct rand_data ec_;
55     fbl::Mutex lock_;
56     uint32_t mem_loops_, lfsr_loops_;
57     bool use_raw_samples_;
58 };
59 
60 } // namespace entropy
61 
62 } // namespace crypto
63