use a slightly different algorithm for arc4random_pushb interfacing:
rate-limit calls to CryptGenRandom to every 2‥4 minutes, if the last call was successful, and operate with hash() on rnd_cache[], so that it is mixed in a better way
This commit is contained in:
parent
3630e1f7dc
commit
ca8b2b534c
57
var.c
57
var.c
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include "sh.h"
|
#include "sh.h"
|
||||||
|
|
||||||
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.88 2009/09/20 13:08:12 tg Exp $");
|
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.89 2009/09/20 13:29:18 tg Exp $");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Variables
|
* Variables
|
||||||
@ -973,6 +973,47 @@ makenv(void)
|
|||||||
#if HAVE_ARC4RANDOM && !defined(MKSH_SMALL)
|
#if HAVE_ARC4RANDOM && !defined(MKSH_SMALL)
|
||||||
static uint32_t rnd_cache[2];
|
static uint32_t rnd_cache[2];
|
||||||
static unsigned char rnd_lastflag = 2;
|
static unsigned char rnd_lastflag = 2;
|
||||||
|
|
||||||
|
static void rnd_cachemix(unsigned long);
|
||||||
|
|
||||||
|
static void
|
||||||
|
rnd_cachemix(unsigned long newval)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct {
|
||||||
|
union {
|
||||||
|
int rval;
|
||||||
|
uint32_t arval;
|
||||||
|
} v0;
|
||||||
|
uint32_t v1;
|
||||||
|
uint32_t v2;
|
||||||
|
unsigned long v3;
|
||||||
|
} v;
|
||||||
|
unsigned char buf[sizeof(v) * 2 + 1], *cp, num;
|
||||||
|
|
||||||
|
v.v0.rval = rand();
|
||||||
|
v.v1 = rnd_cache[0];
|
||||||
|
v.v2 = rnd_cache[1];
|
||||||
|
v.v3 = newval;
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
loop:
|
||||||
|
cp = (void *)&v;
|
||||||
|
i = 0;
|
||||||
|
while (i < 2 * sizeof(v)) {
|
||||||
|
buf[i++] = digits_uc[*cp >> 4];
|
||||||
|
buf[i++] = digits_lc[*cp & 0x0F];
|
||||||
|
++cp;
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
|
||||||
|
rnd_cache[num] = hash(buf);
|
||||||
|
if (num == 0) {
|
||||||
|
++num;
|
||||||
|
v.v0.arval = arc4random();
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -986,14 +1027,12 @@ rnd_get(void)
|
|||||||
uint32_t rv = 0;
|
uint32_t rv = 0;
|
||||||
#endif
|
#endif
|
||||||
if (Flag(FARC4RANDOM) != rnd_lastflag) {
|
if (Flag(FARC4RANDOM) != rnd_lastflag) {
|
||||||
if (Flag(FARC4RANDOM) == 0) {
|
if (Flag(FARC4RANDOM) == 0)
|
||||||
/* transition to 0 by set: srand */
|
/* transition to 0 by set: srand */
|
||||||
srand(arc4random() & 0x7FFF);
|
srand(arc4random() & 0x7FFF);
|
||||||
} else if (rnd_lastflag == 0) {
|
else if (rnd_lastflag == 0)
|
||||||
/* transition from 0: addrandom */
|
/* transition from 0: addrandom */
|
||||||
rnd_cache[0] ^= rand();
|
rnd_cachemix(rand());
|
||||||
rnd_cache[1] ^= rand();
|
|
||||||
}
|
|
||||||
rnd_lastflag = Flag(FARC4RANDOM);
|
rnd_lastflag = Flag(FARC4RANDOM);
|
||||||
}
|
}
|
||||||
if (Flag(FARC4RANDOM)) {
|
if (Flag(FARC4RANDOM)) {
|
||||||
@ -1027,8 +1066,7 @@ rnd_set(unsigned long newval)
|
|||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if HAVE_ARC4RANDOM
|
#if HAVE_ARC4RANDOM
|
||||||
rnd_cache[0] ^= (newval << 15) | rand();
|
rnd_cachemix(newval);
|
||||||
rnd_cache[1] ^= newval >> 17;
|
|
||||||
if (Flag(FARC4RANDOM) == 1)
|
if (Flag(FARC4RANDOM) == 1)
|
||||||
return;
|
return;
|
||||||
if (Flag(FARC4RANDOM) == 2)
|
if (Flag(FARC4RANDOM) == 2)
|
||||||
@ -1053,8 +1091,7 @@ change_random(unsigned long newval)
|
|||||||
|
|
||||||
#if HAVE_ARC4RANDOM
|
#if HAVE_ARC4RANDOM
|
||||||
if (Flag(FARC4RANDOM)) {
|
if (Flag(FARC4RANDOM)) {
|
||||||
rnd_cache[0] ^= (newval << 15) | rand();
|
rnd_cachemix(newval);
|
||||||
rnd_cache[1] ^= newval >> 17;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user