aboutsummarylogtreecommitdiffstats
path: root/README.md
blob: f7da3e9c17baffcc4e865e5643f51c77057c2f91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# HAVEGE Kernel Driver

This is a Linux kernel driver that implements the [HAVEGE](https://www.irisa.fr/caps/projects/hipsor/)
 algorithm to gather entropy from system and cache timings.

The driver implements a character device at `/dev/havege` that outputs raw binary data.

This data can then be used for reseeding the internal kernel entropy pool or for other
 purposes where random numbers are needed.

This project is licensed under the GPL. Please see the [LICENSE](LICENSE) for more information.

# Installation

There are two ways to install this driver. The first involves compiling it normally against
 the current running kernel and loading it manually.

```sh
# make all -j`nproc`
# insmod havege.ko
```

The second method involves the use of [DKMS](https://en.wikipedia.org/wiki/Dynamic_Kernel_Module_Support)
 to automatically build the driver every time the kernel is updated.

For this purpose, a [dkms.conf](dkms.conf) file was added allowing you to install this
 driver as a DKMS package. Please refer to your distribution's guide to install DKMS packages.

*N.B.* For Arch Linux users, you can simply clone this repository and run `makepkg -s` to
 build the DKMS module.

# UDEV Rule

By default, the character device implemented ( `/dev/havege` ) can only be read by the root user.

To allow the file to be read by all users, a udev rule was added. Simply copy the file to your
 rules folder before loading the kernel module to allow users to read it.

```sh
# cp 99-havege-udev.rules /etc/rules.d/99-havege-udev.rules
# modprobe havege
```

# Enhancing The Kernel Entropy Pool

For those wishing to use this driver to refill the kernel entropy pool, you must install `rng-tools`
 for your specific distribution.

After wish, direct `rngd` to use the character device provided to refill the kernel's entropy pool.

If using the service `rngd.service`, you must edit your default `rngd` configuration file.

```sh
# rngd -f -r /dev/havege
```
# Modifying Behavior

The driver comes with two parameters that may be modified to change how many times the system is
 polled for entropy during each reseeding or initial reseeding.

The initial specification uses 32 steps for both initial seeding and reseeding.

This driver uses 64 steps instead which produces throughput at roughly 30 MB/s on an
 `i7-4790` processor clocked at 3.60 GHz. Increasing these parameters will increase or decrease 
 the throughput accordingly.

You can view these parameters using `modinfo` and apply them by creating a `modprobe` rule in
 `/etc/modprobe.d/`.

# Tests

To ensure the driver works as intended, various tests were performed using well known tools.

These being the `rngtest` program, provided by `rng-tools`, `ent` and `dieharder`.

For `rngtest` and `ent`, a 25 MiB sample generated as follows:

```sh
 $ ➜  dd if=/dev/havege of=sample.bin bs=1k count=25k iflag=fullblock
```

This sample file was used for the tests as follows:

```sh
$ ent sample.bin

Entropy = 7.999993 bits per byte.

Optimum compression would reduce the size
of this 25000960 byte file by 0 percent.

Chi square distribution for 25000960 samples is 254.62, and randomly
would exceed this value 49.49 percent of the times.

Arithmetic mean value of data bytes is 127.4976 (127.5 = random).
Monte Carlo value for Pi is 3.142048168 (error 0.01 percent).
Serial correlation coefficient is -0.000219 (totally uncorrelated = 0.0).
```

```sh
 $ ➜  rngtest < sample.bin

rngtest 6.6
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: entropy source drained
rngtest: bits received from input: 200007680
rngtest: FIPS 140-2 successes: 9993
rngtest: FIPS 140-2 failures: 7
rngtest: FIPS 140-2(2001-10-10) Monobit: 1
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 5
rngtest: FIPS 140-2(2001-10-10) Long run: 1
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=1.693; avg=25.960; max=18.626)Gibits/s
rngtest: FIPS tests speed: (min=103.100; avg=218.266; max=224.394)Mibits/s
rngtest: Program run time: 881882 microseconds
```

Then `dieharder` was run with the following flags:

- `-k 2` - Run the tests using maximum precision at the cost of throughput.
- `-Y 1` - 'resolve ambiguity' (RA) mode.  If a test returns 'weak', this reruns it using a
	larger number of psamples in increments of 100 till it either fails fully or passes.
- `-a` - Runs all the tests with standard/default options

This was run directly from the character device yielding the following results:

```sh
 $ ➜ dd if=/dev/havege bs=10M iflag=fullblock | dieharder -Y 1 -k 2 -a

#=============================================================================#
#            dieharder version 3.31.1 Copyright 2003 Robert G. Brown          #
#=============================================================================#
   rng_name    |rands/second|   Seed   |
        mt19937|  1.54e+08  |4189723306|
#=============================================================================#
        test_name   |ntup| tsamples |psamples|  p-value |Assessment
#=============================================================================#
   diehard_birthdays|   0|       100|     100|0.07828562|  PASSED  
      diehard_operm5|   0|   1000000|     100|0.24618768|  PASSED  
  diehard_rank_32x32|   0|     40000|     100|0.80501063|  PASSED  
    diehard_rank_6x8|   0|    100000|     100|0.83317286|  PASSED  
   diehard_bitstream|   0|   2097152|     100|0.56375314|  PASSED  
        diehard_opso|   0|   2097152|     100|0.69228339|  PASSED  
        diehard_oqso|   0|   2097152|     100|0.72100905|  PASSED  
         diehard_dna|   0|   2097152|     100|0.79020740|  PASSED  
diehard_count_1s_str|   0|    256000|     100|0.62718998|  PASSED  
diehard_count_1s_byt|   0|    256000|     100|0.81067746|  PASSED  
 diehard_parking_lot|   0|     12000|     100|0.62905479|  PASSED  
    diehard_2dsphere|   2|      8000|     100|0.11269347|  PASSED  
    diehard_3dsphere|   3|      4000|     100|0.58435569|  PASSED  
     diehard_squeeze|   0|    100000|     100|0.69140466|  PASSED  
        diehard_sums|   0|       100|     100|0.03990886|  PASSED  
        diehard_runs|   0|    100000|     100|0.51357242|  PASSED  
        diehard_runs|   0|    100000|     100|0.52397010|  PASSED  
       diehard_craps|   0|    200000|     100|0.81900152|  PASSED  
       diehard_craps|   0|    200000|     100|0.76929002|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.15679060|  PASSED  
 marsaglia_tsang_gcd|   0|  10000000|     100|0.40846035|  PASSED  
         sts_monobit|   1|    100000|     100|0.92019722|  PASSED  
            sts_runs|   2|    100000|     100|0.89305950|  PASSED  
          sts_serial|   1|    100000|     100|0.71650275|  PASSED  
          sts_serial|   2|    100000|     100|0.43694160|  PASSED  
          sts_serial|   3|    100000|     100|0.97264959|  PASSED  
          sts_serial|   3|    100000|     100|0.89108668|  PASSED  
          sts_serial|   4|    100000|     100|0.54264432|  PASSED  
          sts_serial|   4|    100000|     100|0.37555075|  PASSED  
          sts_serial|   5|    100000|     100|0.78949709|  PASSED  
          sts_serial|   5|    100000|     100|0.40606125|  PASSED  
          sts_serial|   6|    100000|     100|0.97969978|  PASSED  
          sts_serial|   6|    100000|     100|0.79414091|  PASSED  
          sts_serial|   7|    100000|     100|0.80494445|  PASSED  
          sts_serial|   7|    100000|     100|0.99538345|   WEAK   
          sts_serial|   8|    100000|     100|0.68028996|  PASSED  
          sts_serial|   8|    100000|     100|0.33495704|  PASSED  
          sts_serial|   9|    100000|     100|0.57681976|  PASSED  
          sts_serial|   9|    100000|     100|0.45092761|  PASSED  
          sts_serial|  10|    100000|     100|0.64251408|  PASSED  
          sts_serial|  10|    100000|     100|0.25023464|  PASSED  
          sts_serial|  11|    100000|     100|0.53638706|  PASSED  
          sts_serial|  11|    100000|     100|0.91582355|  PASSED  
          sts_serial|  12|    100000|     100|0.18660413|  PASSED  
          sts_serial|  12|    100000|     100|0.93968726|  PASSED  
          sts_serial|  13|    100000|     100|0.47663887|  PASSED  
          sts_serial|  13|    100000|     100|0.22058456|  PASSED  
          sts_serial|  14|    100000|     100|0.69650537|  PASSED  
          sts_serial|  14|    100000|     100|0.67749838|  PASSED  
          sts_serial|  15|    100000|     100|0.99327337|  PASSED  
          sts_serial|  15|    100000|     100|0.69469078|  PASSED  
          sts_serial|  16|    100000|     100|0.59125350|  PASSED  
          sts_serial|  16|    100000|     100|0.98966700|  PASSED  
          sts_serial|   1|    100000|     200|0.19601400|  PASSED  
          sts_serial|   2|    100000|     200|0.33826281|  PASSED  
          sts_serial|   3|    100000|     200|0.22209718|  PASSED  
          sts_serial|   3|    100000|     200|0.83091121|  PASSED  
          sts_serial|   4|    100000|     200|0.12860004|  PASSED  
          sts_serial|   4|    100000|     200|0.97207073|  PASSED  
          sts_serial|   5|    100000|     200|0.11692114|  PASSED  
          sts_serial|   5|    100000|     200|0.26192745|  PASSED  
          sts_serial|   6|    100000|     200|0.47520472|  PASSED  
          sts_serial|   6|    100000|     200|0.97632585|  PASSED  
          sts_serial|   7|    100000|     200|0.86177050|  PASSED  
          sts_serial|   7|    100000|     200|0.73921982|  PASSED  
          sts_serial|   8|    100000|     200|0.66482804|  PASSED  
          sts_serial|   8|    100000|     200|0.75521757|  PASSED  
          sts_serial|   9|    100000|     200|0.86263171|  PASSED  
          sts_serial|   9|    100000|     200|0.34619180|  PASSED  
          sts_serial|  10|    100000|     200|0.98828662|  PASSED  
          sts_serial|  10|    100000|     200|0.63457556|  PASSED  
          sts_serial|  11|    100000|     200|0.56678030|  PASSED  
          sts_serial|  11|    100000|     200|0.69667576|  PASSED  
          sts_serial|  12|    100000|     200|0.73423841|  PASSED  
          sts_serial|  12|    100000|     200|0.67862680|  PASSED  
          sts_serial|  13|    100000|     200|0.70115984|  PASSED  
          sts_serial|  13|    100000|     200|0.23922799|  PASSED  
          sts_serial|  14|    100000|     200|0.98543778|  PASSED  
          sts_serial|  14|    100000|     200|0.50529911|  PASSED  
          sts_serial|  15|    100000|     200|0.36004982|  PASSED  
          sts_serial|  15|    100000|     200|0.17283932|  PASSED  
          sts_serial|  16|    100000|     200|0.53274108|  PASSED  
          sts_serial|  16|    100000|     200|0.56658655|  PASSED  
         rgb_bitdist|   1|    100000|     100|0.80659811|  PASSED  
         rgb_bitdist|   2|    100000|     100|0.77944380|  PASSED  
         rgb_bitdist|   3|    100000|     100|0.66530230|  PASSED  
         rgb_bitdist|   4|    100000|     100|0.13074912|  PASSED  
         rgb_bitdist|   5|    100000|     100|0.10877526|  PASSED  
         rgb_bitdist|   6|    100000|     100|0.86446353|  PASSED  
         rgb_bitdist|   7|    100000|     100|0.98502972|  PASSED  
         rgb_bitdist|   8|    100000|     100|0.71678227|  PASSED  
         rgb_bitdist|   9|    100000|     100|0.63339078|  PASSED  
         rgb_bitdist|  10|    100000|     100|0.83608462|  PASSED  
         rgb_bitdist|  11|    100000|     100|0.15566276|  PASSED  
         rgb_bitdist|  12|    100000|     100|0.52103141|  PASSED  
rgb_minimum_distance|   2|     10000|    1000|0.87156380|  PASSED  
rgb_minimum_distance|   3|     10000|    1000|0.79089173|  PASSED  
rgb_minimum_distance|   4|     10000|    1000|0.22133014|  PASSED  
rgb_minimum_distance|   5|     10000|    1000|0.30816676|  PASSED  
    rgb_permutations|   2|    100000|     100|0.70997391|  PASSED  
    rgb_permutations|   3|    100000|     100|0.16735842|  PASSED  
    rgb_permutations|   4|    100000|     100|0.74315136|  PASSED  
    rgb_permutations|   5|    100000|     100|0.99564663|   WEAK   
    rgb_permutations|   5|    100000|     200|0.73122983|  PASSED  
      rgb_lagged_sum|   0|   1000000|     100|0.14206609|  PASSED  
      rgb_lagged_sum|   1|   1000000|     100|0.76954863|  PASSED  
      rgb_lagged_sum|   2|   1000000|     100|0.80043208|  PASSED  
      rgb_lagged_sum|   3|   1000000|     100|0.45648849|  PASSED  
      rgb_lagged_sum|   4|   1000000|     100|0.90035262|  PASSED  
      rgb_lagged_sum|   5|   1000000|     100|0.46099924|  PASSED  
      rgb_lagged_sum|   6|   1000000|     100|0.17885043|  PASSED  
      rgb_lagged_sum|   7|   1000000|     100|0.93997311|  PASSED  
      rgb_lagged_sum|   8|   1000000|     100|0.26356022|  PASSED  
      rgb_lagged_sum|   9|   1000000|     100|0.25486242|  PASSED  
      rgb_lagged_sum|  10|   1000000|     100|0.95460356|  PASSED  
      rgb_lagged_sum|  11|   1000000|     100|0.24742445|  PASSED  
      rgb_lagged_sum|  12|   1000000|     100|0.47326246|  PASSED  
      rgb_lagged_sum|  13|   1000000|     100|0.18139624|  PASSED  
      rgb_lagged_sum|  14|   1000000|     100|0.24961440|  PASSED  
      rgb_lagged_sum|  15|   1000000|     100|0.60006813|  PASSED  
      rgb_lagged_sum|  16|   1000000|     100|0.95799649|  PASSED  
      rgb_lagged_sum|  17|   1000000|     100|0.25125998|  PASSED  
      rgb_lagged_sum|  18|   1000000|     100|0.27818535|  PASSED  
      rgb_lagged_sum|  19|   1000000|     100|0.76062551|  PASSED  
      rgb_lagged_sum|  20|   1000000|     100|0.09752780|  PASSED  
      rgb_lagged_sum|  21|   1000000|     100|0.62887918|  PASSED  
      rgb_lagged_sum|  22|   1000000|     100|0.89325033|  PASSED  
      rgb_lagged_sum|  23|   1000000|     100|0.52161424|  PASSED  
      rgb_lagged_sum|  24|   1000000|     100|0.82893665|  PASSED  
      rgb_lagged_sum|  25|   1000000|     100|0.62524900|  PASSED  
      rgb_lagged_sum|  26|   1000000|     100|0.12340213|  PASSED  
      rgb_lagged_sum|  27|   1000000|     100|0.18904618|  PASSED  
      rgb_lagged_sum|  28|   1000000|     100|0.91897446|  PASSED  
      rgb_lagged_sum|  29|   1000000|     100|0.08619284|  PASSED  
      rgb_lagged_sum|  30|   1000000|     100|0.34386569|  PASSED  
      rgb_lagged_sum|  31|   1000000|     100|0.78404592|  PASSED  
      rgb_lagged_sum|  32|   1000000|     100|0.83746391|  PASSED  
     rgb_kstest_test|   0|     10000|    1000|0.21168760|  PASSED  
     dab_bytedistrib|   0|  51200000|       1|0.41140405|  PASSED  
             dab_dct| 256|     50000|       1|0.30160704|  PASSED  
        dab_filltree|  32|  15000000|       1|0.58112590|  PASSED  
        dab_filltree|  32|  15000000|       1|0.32213300|  PASSED  
       dab_filltree2|   0|   5000000|       1|0.77375471|  PASSED  
       dab_filltree2|   1|   5000000|       1|0.24311552|  PASSED  
        dab_monobit2|  12|  65000000|       1|0.75745817|  PASSED 
```