# /dev/hwrng ## Intro There is hardware that are can generate "randomness". It can be accesed trought /dev/hwrng device. Funnies part of hardware random generator it could generate anything. That why need to verify that data comming from /dev/hwrng. Good advice is to use /dev/hwrng as additional entropy source. Why we dont trust /dev/hwrng as random number souce? There is some articles about HW random generators could be backdoored and could generate predictable values that why as we cant verify HW design as its not opensourced we choose not to trust it. In general if you belive in HW random generator you can use it. ## Switching hardware rng Hardware random generator have own entry inside sysfs lets check _/sys/class/misc/hw_random/ ``` $ls /sys/class/misc/hw_random/ dev power rng_available rng_current subsystem uevent ``` Check avaliable hwrng modules ``` $cat /sys/class/misc/hw_random/rng_available zero-rng ``` Check currently running hwrng module ``` $cat /sys/class/misc/hw_random/rng_current zero-rng ``` ## Testing /dev/hwrng There couple of ways how you can test if data is "random" enought. There is standarts like FIPS 140-2 with have criterias to check if data source is pseudo-random. And there is couple of implementations of it. You can get tool like rng-tools and test data. Lets imagine that you have installed it allready in your favorite way. _Output every 5 seconds pseudo random tests results_ ```sh $cat /dev/urandom | rngtest -t 5 ``` _Program output_ ``` rngtest: starting FIPS tests... rngtest: bits received from input: 462500032 rngtest: FIPS 140-2 successes: 23108 rngtest: FIPS 140-2 failures: 17 rngtest: FIPS 140-2(2001-10-10) Monobit: 1 rngtest: FIPS 140-2(2001-10-10) Poker: 2 rngtest: FIPS 140-2(2001-10-10) Runs: 8 rngtest: FIPS 140-2(2001-10-10) Long run: 6 rngtest: FIPS 140-2(2001-10-10) Continuous run: 0 rngtest: input channel speed: (min=2.166; avg=216.912; max=19073.486)Mibits/s rngtest: FIPS tests speed: (min=56.598; avg=148.791; max=178.257)Mibits/s rngtest: Program run time: 5016745 microseconds ``` ## Example driver Create files _Makefile_ and _zero_hwrng.c_ and copy code. __Makefile__ ```Makefile obj-m += zero_hwrng.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean load: insmod zero_hwrng.ko unload: rmmod zero_hwrng ``` __zero_hwrng.c__ ```c #include #include #include #include #include #include #include #define PRINTK printk #define PRN(format, args ... ) PRINTK("DBG FUN:%s LINE:%d " format,__FUNCTION__,__LINE__, ##args); #define PNL() PRINTK("%s:%d\n",__FUNCTION__,__LINE__); static int zero_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) { int i; u8 *buf; PNL(); buf = data; for (i=0;i /sys/class/misc/hw_random/rng_current ``` check if its current module used ``` $ cat /sys/class/misc/hw_random/rng_current intel-rng ``` Well everything looks fine and test are passsed if you goint to try test it with rng-tools. ## Links 1. [Documentation/hw_random.txt](https://www.kernel.org/doc/Documentation/hw_random.txt) 2. [295_linux_really_using_hardware_random_number_generators.html](http://blog.coldtobi.de/1_coldtobis_blog/archive/295_linux_really_using_hardware_random_number_generators.html) 3. [rng-tools](https://www.archlinux.org/packages/community/x86_64/rng-tools/) 4. [include/linux/hw_random.h](https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/include/linux/hw_random.h?id=refs/tags/v4.7.4) 5. [/writeup/gcc_inline_assembly.md#toc-12](/writeup/gcc_inline_assembly.md#toc-12)