diff --git a/README.adoc b/README.adoc index 4067293..4d34218 100644 --- a/README.adoc +++ b/README.adoc @@ -12416,6 +12416,22 @@ link:userland/arch/x86_64/loop.S[LOOP] Vs <>: https://stackoverflow.com/questions/6805692/x86-assembly-programming-loops-with-ecx-and-loop-instruction-versus-jmp-jcond Holy CISC! +=== x86 random number generator instructions + +<> 5.1.15 Random Number Generator Instructions + +Example: link:userland/arch/x86_64/rdrand.S[RDRAND] + +If you run that executable multiple times, it prints a random number every time to stdout. + +RDRAND is a true random number generator! + +This Intel engineer says its based on quantum effects: https://stackoverflow.com/questions/17616960/true-random-numbers-with-c11-and-rdrand/18004959#18004959 + +Generated some polemic when kernel devs wanted to use it as part of `/dev/random`, because it could be used as a cryptographic backdoor by Intel since it is a black box. + +RDRAND sets the carry flag when data is ready so we must loop if the carry flag isn't set. + === x86 SIMD History: diff --git a/lkmc.c b/lkmc.c index 26f8e2b..6e00437 100644 --- a/lkmc.c +++ b/lkmc.c @@ -56,6 +56,14 @@ void lkmc_assert_memcmp( } } +void lkmc_print_hex_64(uint64_t x) { + printf("0x%016" PRIx64, x); +} + +void lkmc_print_newline() { + printf("\n"); +} + #if defined(__aarch64__) #define LKMC_SYSREG_READ_WRITE(type, name) \ type LKMC_CONCAT(LKMC_CONCAT(LKMC_SYSREG_SYMBOL_PREFIX, name), _read(void)) { \ diff --git a/userland/arch/x86_64/rdrand.S b/userland/arch/x86_64/rdrand.S new file mode 100644 index 0000000..b4f068b --- /dev/null +++ b/userland/arch/x86_64/rdrand.S @@ -0,0 +1,11 @@ +/* https://github.com/cirosantilli/linux-kernel-module-cheat#x86-random-number-generator-instructions */ + +#include + +LKMC_PROLOGUE +1: + rdrand %rdi + jnc 1b + call lkmc_print_hex_64 + call lkmc_print_newline +LKMC_EPILOGUE