aboutsummarylogtreecommitdiffstats
# 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 ```