summaryrefslogtreecommitdiff
path: root/md/writeup
diff options
context:
space:
mode:
Diffstat (limited to 'md/writeup')
-rw-r--r--md/writeup/kernel_dev_hwrng.md287
1 files changed, 287 insertions, 0 deletions
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)