title: Kernel /dev/hwrng # /dev/hwrng ## Intro There is hardware that are can generate "randomness". It can be accessed trough /dev/hwrng device. Funnies part of hardware random generator it could generate anything. That why need to verify that data coming from /dev/hwrng. Good advice is to use /dev/hwrng as additional entropy source. Why we dont trust /dev/hwrng as random number source? 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 open sourced we choose not to trust it. In general if you trust in HW random generators you can use them, but for security you better not trust them as there is no way to verify on your side if there is no backdoors, so use default secure linux implementation. First code example is introducing crypto subsystem of linux and how to use it, by creating "random" generator that generates zeros. Second example is utilise Intel builtin random generator and instruction __rdrand__. ## 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 available 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" enough. There is standards like FIPS 140-2 with have criteria 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 already 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 passed if you going 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)