From 7288179d1218f8e0308455d4d58346aec268eb2e Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 23 Feb 2018 09:09:35 +0000 Subject: win32: make /dev/urandom more random --- include/mingw.h | 2 + win32/Kbuild | 1 + win32/isaac.c | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ win32/mingw.c | 3 +- 4 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 win32/isaac.c diff --git a/include/mingw.h b/include/mingw.h index 46be4dc23..8f7e529ba 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -481,3 +481,5 @@ int err_win_to_posix(DWORD winerr); ULONGLONG CompatGetTickCount64(void); #define GetTickCount64 CompatGetTickCount64 + +ssize_t get_random_bytes(void *buf, ssize_t count); diff --git a/win32/Kbuild b/win32/Kbuild index 8248c994f..00950e0f7 100644 --- a/win32/Kbuild +++ b/win32/Kbuild @@ -8,6 +8,7 @@ lib-$(CONFIG_PLATFORM_MINGW32) += env.o lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o lib-$(CONFIG_PLATFORM_MINGW32) += fsync.o lib-$(CONFIG_PLATFORM_MINGW32) += ioctl.o +lib-$(CONFIG_PLATFORM_MINGW32) += isaac.o lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o lib-$(CONFIG_PLATFORM_MINGW32) += process.o lib-$(CONFIG_PLATFORM_MINGW32) += regex.o diff --git a/win32/isaac.c b/win32/isaac.c new file mode 100644 index 000000000..8e9da9baf --- /dev/null +++ b/win32/isaac.c @@ -0,0 +1,240 @@ +/* +------------------------------------------------------------------------------ +readable.c: My random number generator, ISAAC. +(c) Bob Jenkins, March 1996, Public Domain +You may use this code in any way you wish, and it is free. No warrantee. +* May 2008 -- made it not depend on standard.h +------------------------------------------------------------------------------ + + The original version of this file was downloaded from Bob Jenkins website: + + http://burtleburtle.net/bob/rand/isaacafa.html + + The isaac and randinit functions have been slightly modified to silence + warnings in modern compilers; the get_entropy and get_random_bytes have + been added. + + These changes were made by R M Yorston and are also dedicated to the + public domain. +*/ +#include "libbb.h" + +/* external results */ +static uint32_t randrsl[256]; + +/* internal state */ +static uint32_t mm[256]; +static uint32_t aa=0, bb=0, cc=0; + + +static void isaac(void) +{ + register uint32_t i,x,y; + + cc = cc + 1; /* cc just gets incremented once per 256 results */ + bb = bb + cc; /* then combined with bb */ + + for (i=0; i<256; ++i) + { + x = mm[i]; + switch (i%4) + { + case 0: aa = aa^(aa<<13); break; + case 1: aa = aa^(aa>>6); break; + case 2: aa = aa^(aa<<2); break; + case 3: aa = aa^(aa>>16); break; + } + aa = mm[(i+128)%256] + aa; + mm[i] = y = mm[(x>>2)%256] + aa + bb; + randrsl[i] = bb = mm[(y>>10)%256] + x; + + /* Note that bits 2..9 are chosen from x but 10..17 are chosen + from y. The only important thing here is that 2..9 and 10..17 + don't overlap. 2..9 and 10..17 were then chosen for speed in + the optimized version (rand.c) */ + /* See http://burtleburtle.net/bob/rand/isaac.html + for further explanations and analysis. */ + } +} + + +/* if (flag!=0), then use the contents of randrsl[] to initialize mm[]. */ +#define mix(a,b,c,d,e,f,g,h) \ +{ \ + a^=b<<11; d+=a; b+=c; \ + b^=c>>2; e+=b; c+=d; \ + c^=d<<8; f+=c; d+=e; \ + d^=e>>16; g+=d; e+=f; \ + e^=f<<10; h+=e; f+=g; \ + f^=g>>4; a+=f; g+=h; \ + g^=h<<8; b+=g; h+=a; \ + h^=a>>9; c+=h; a+=b; \ +} + +static void randinit(int flag) +{ + int i; + uint32_t a,b,c,d,e,f,g,h; + aa=bb=cc=0; + a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */ + + for (i=0; i<4; ++i) /* scramble it */ + { + mix(a,b,c,d,e,f,g,h); + } + + for (i=0; i<256; i+=8) /* fill in mm[] with messy stuff */ + { + if (flag) /* use all the information in the seed */ + { + a+=randrsl[i ]; b+=randrsl[i+1]; c+=randrsl[i+2]; d+=randrsl[i+3]; + e+=randrsl[i+4]; f+=randrsl[i+5]; g+=randrsl[i+6]; h+=randrsl[i+7]; + } + mix(a,b,c,d,e,f,g,h); + mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; + mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; + } + + if (flag) + { /* do a second pass to make all of the seed affect all of mm */ + for (i=0; i<256; i+=8) + { + a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; + e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; + mix(a,b,c,d,e,f,g,h); + mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; + mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; + } + } + + isaac(); /* fill in the first set of results */ +} + +/* call 'fn' to put data in 'dt' then copy it to generator state */ +#define GET_DATA(fn, dt) \ + fn(&dt); \ + u = (uint32_t *)&dt; \ + for (j=0; j 0) { + int bytes_left = RAND_BYTES - rand_index; + + if (bytes_left >= count) { + /* we have enough random bytes */ + memcpy(buf, ptr+rand_index, count); + rand_index += count; + count = 0; + } + else { + /* insufficient bytes, use what we have */ + memcpy(buf, ptr+rand_index, bytes_left); + buf += bytes_left; + count -= bytes_left; + rand_index += bytes_left; + } + + if (rand_index >= RAND_BYTES) { + /* generate more */ + isaac(); + rand_index = 0; + } + } + + return save_count; +} diff --git a/win32/mingw.c b/win32/mingw.c index 595042d85..86f649674 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -210,8 +210,7 @@ ssize_t mingw_read(int fd, void *buf, size_t count) return count; } else if (fd == rand_fd) { - memset(buf, 0x5A, count); - return count; + return get_random_bytes(buf, count); } return read(fd, buf, count); } -- cgit v1.2.3-55-g6feb