diff options
author | FreeArtMan <dos21h@gmail.com> | 2016-09-23 00:09:35 +0100 |
---|---|---|
committer | FreeArtMan <dos21h@gmail.com> | 2016-09-23 00:09:35 +0100 |
commit | 7711f25852c8372ade16accfca50115af64e1951 (patch) | |
tree | 8204127c9398a074de204d9629562370c1b2df8b | |
parent | b5d250a50ec0ae873fea50cc574d056620032ec5 (diff) | |
download | md-content-7711f25852c8372ade16accfca50115af64e1951.tar.gz md-content-7711f25852c8372ade16accfca50115af64e1951.zip |
Kernel /dev/hwrng driver: added new note
-rw-r--r-- | md/writeup.md | 1 | ||||
-rw-r--r-- | md/writeup/kernel_dev_hwrng.md | 287 |
2 files changed, 288 insertions, 0 deletions
diff --git a/md/writeup.md b/md/writeup.md index 038d2f4..3c7ad39 100644 --- a/md/writeup.md +++ b/md/writeup.md @@ -14,6 +14,7 @@ [Compile Linux Kernel](writeup/compile_linux_kernel.md) [Kernel:Hello World](writeup/kernel_hello_world.md) [Kernel:Debug messages](writeup/kernel_debug_messages.md) +[Kernel:/dev/hwrng](writeup/kernel_dev_hwrng.md) ## Projects diff --git a/md/writeup/kernel_dev_hwrng.md b/md/writeup/kernel_dev_hwrng.md new file mode 100644 index 0000000..9812d0f --- /dev/null +++ b/md/writeup/kernel_dev_hwrng.md @@ -0,0 +1,287 @@ +# /dev/hwrng + +## Intro + +/* Could be not random at all */ + +## 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 + +/* Say basic usage of rng-tools */ +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 <linux/module.h> +#include <linux/kernel.h> +#include <linux/hw_random.h> +#include <linux/completion.h> +#include <linux/atomic.h> +#include <linux/slab.h> +#include <linux/device.h> + +#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<max;i++) + { + buf[i] = 0; + } + + return max; +} + +static void zero_rng_cleanup(struct hwrng *rng) +{ + PNL(); +} + +static struct hwrng zero_rng = { + .name = "zero-rng", + .cleanup = zero_rng_cleanup, + .read = zero_rng_read, +}; + +static void zero_rng_exit(void) +{ + PNL(); + + hwrng_unregister(&zero_rng); +} + +static int zero_rng_init(void) +{ + PNL(); + + PRN("register device"); + + return hwrng_register(&zero_rng); +} + +module_init(zero_rng_init); +module_exit(zero_rng_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Zero /dev/hwrng"); +MODULE_AUTHOR("Internet User"); +``` + +### Loading module + +Rng module depends on rng-core module + +``` +modprobe rng-core +``` + +then load our module + +``` +insmode zero_rng.ko +``` + +check if everything is properly loaded + +``` +$lsmod | grep rng +zero_hwrng 16384 0 +rng_core 16384 1 zero_hwrng +``` + +### Verify randomness + +Lets test how our stuff works + +``` +$ dd if=/dev/hwrng of=/tmp/random bs=1024 count=32 +32+0 records in +32+0 records out +32768 bytes (33 kB, 32 KiB) copied, 0.00111024 s, 29.5 MB/s +$ hexdump /tmp/random +0000000 0000 0000 0000 0000 0000 0000 0000 0000 +* +0008000 +``` + +As we can see all data that we get is just zeros lets check it with rng-tools +``` +$ cat /tmp/random | rngtest -t 5 +rngtest 5 +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: 262144 +rngtest: FIPS 140-2 successes: 0 +rngtest: FIPS 140-2 failures: 13 +rngtest: FIPS 140-2(2001-10-10) Monobit: 13 +rngtest: FIPS 140-2(2001-10-10) Poker: 13 +rngtest: FIPS 140-2(2001-10-10) Runs: 13 +rngtest: FIPS 140-2(2001-10-10) Long run: 13 +rngtest: FIPS 140-2(2001-10-10) Continuous run: 13 +rngtest: input channel speed: (min=6.209; avg=13.452; max=18.626)Gibits/s +rngtest: FIPS tests speed: (min=168.792; avg=201.099; max=207.321)Mibits/s +rngtest: Program run time: 1369 microseconds +``` + +Well all tests fails thats good + +### Practical example + +Lets asume that we are running this code on Intel arch and it supports +_rdrand_ instruction for random genertion. + + +``` +void get_hw_rand2(uint8_t *mem) +{ + int i=0; + asm("rdrand %%rax\n\t" + "mov %%rax, %0\n\t" + :"=m"(*mem)::"0"); + +} +``` + +Lets replace intel_rng_read function with our naive implementation of _rdrand_ + +``` +static int intel_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) +{ + int i; + u8 *buf; + u64 rnd; + u8 rnd8[8]; + u8 val; + + PNL(); + + buf = data; + for (i=0;i<max;i++) + { + if ((i%8)==0) + { + get_hw_rand2(rnd8); + } + buf[i] = rnd8[i%8]; + } + + return max; +} +``` + +Verify that our module loaded + +``` +$ cat /sys/class/misc/hw_random/rng_available +zero-rng intel-rng +``` + +Check with module are currently used + +``` +$ cat /sys/class/misc/hw_random/rng_current +zero-rng +``` + +if not our module set lets set it + +``` +$ echo "intel-rng" > /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) |