From 093aa040ebf9f346de4e982f600f73aece2b060a Mon Sep 17 00:00:00 2001 From: Brennan Ashton Date: Mon, 4 May 2020 20:57:15 -0700 Subject: [PATCH] x86_64: Fix /dev/random rdrand implementation rdrand was checking the wrong return value for the intrinsics so it would block forever. The read function was also not returning the actual number of bytes read. This was tested by running the rand example application NuttShell (NSH) NuttX-9.0.0 nsh>rand Reading 8 random numbers Random values (0x101584f70): 0000: 019a172df7d539f2df8550362e2d3f74 9b467c51ebe30b9f6510e540e34fabcc ...-..9...P6.-?t .F|Q....e..@.O.. Signed-off-by: Brennan Ashton --- arch/x86_64/src/intel64/intel64_rng.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86_64/src/intel64/intel64_rng.c b/arch/x86_64/src/intel64/intel64_rng.c index a68d6c3016..e602f619a0 100644 --- a/arch/x86_64/src/intel64/intel64_rng.c +++ b/arch/x86_64/src/intel64/intel64_rng.c @@ -107,9 +107,10 @@ static int x86_rng_initialize(void) static ssize_t x86_rngread(struct file *filep, char *buffer, size_t buflen) { + size_t reqlen = buflen; for (; buflen > 8; buflen -= 8) { - while (_rdrand64_step((unsigned long long *)buffer)) + while (_rdrand64_step((unsigned long long *)buffer) == 0) { sched_yield(); } @@ -119,7 +120,7 @@ static ssize_t x86_rngread(struct file *filep, char *buffer, size_t buflen) for (; buflen > 4; buflen -= 4) { - while (_rdrand32_step((unsigned int *)buffer)) + while (_rdrand32_step((unsigned int *)buffer) == 0) { sched_yield(); } @@ -129,7 +130,7 @@ static ssize_t x86_rngread(struct file *filep, char *buffer, size_t buflen) for (; buflen > 2; buflen -= 2) { - while (_rdrand16_step((unsigned short *)buffer)) + while (_rdrand16_step((unsigned short *)buffer) == 0) { sched_yield(); } @@ -141,15 +142,16 @@ static ssize_t x86_rngread(struct file *filep, char *buffer, size_t buflen) { unsigned short temp = 0; - while (_rdrand16_step(&temp)) + while (_rdrand16_step(&temp) == 0) { sched_yield(); } *buffer = (temp & 0xff); + buffer++; } - return buflen; + return reqlen; } /****************************************************************************