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 <fbl/name.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 namespace crypto {
14 
15 namespace entropy {
16 
17 class Collector {
18 public:
19     virtual ~Collector();
20 
21     // Returns a null-terminated name, in the buffer of size |len| at |buf|.
get_name(char * name,size_t len)22     void get_name(char* name, size_t len) const { name_.get(len, name); }
23 
24     // Fills |len| bytes of memory at |buf| with random data from this entropy
25     // collector's entropy source. The bytes that are returned may not be
26     // perfectly random, i.e. they may be statistically dependent or biased. Use
27     // the BytesNeeded() method to determine how may random bytes are needed to
28     // collect a certain amount of entropy.
29     virtual size_t DrawEntropy(uint8_t* buf, size_t len) = 0;
30 
31     // Returns the number of bytes of random data that should be drawn via
32     // DrawEntropy() to get approximately |bits| bits of entropy. Note: |bits|
33     // must be no larger than 2^20 (= 1048576).
34     size_t BytesNeeded(size_t bits) const;
35 
36 protected:
37     // Initialize this entropy collector. |name| is used for debugging and
38     // testing, and it may be truncated if it is too long.
39     // |entropy_per_1000_bytes| is the (approximate) amount of min-entropy in
40     // each 1000 bytes of data returned by the entropy source. The amount of
41     // entropy in a byte from the entropy source is generally not an integer.
42     // Quoting the entropy per 1000 bytes supports non-integer values, without
43     // requiring floating-point or fixed-point arithmetic. It is an error if
44     // |entropy_per_1000_bytes| is 0 or is greater than 8000.
45     //
46     // TODO(andrewkrieger): document entropy source quality tests, and reference
47     // that document here, to explain how to find a good value for
48     // entropy_per_1000_bytes.
49     Collector(const char* name, size_t entropy_per_1000_bytes);
50 
51 private:
52     DISALLOW_COPY_ASSIGN_AND_MOVE(Collector);
53 
54     fbl::Name<ZX_MAX_NAME_LEN> name_;
55 
56     size_t entropy_per_1000_bytes_;
57 };
58 
59 } // namespace entropy
60 
61 } // namespace crypto
62