Skip to content

Commit

Permalink
random.c: use siphash in counter mode for hash initialization.
Browse files Browse the repository at this point in the history
SipHash is secure PseudoRandom Function, and could be used
in a counter mode to produce strong pseudorandom stream of bytes.
So use it to securely initialize both hashseed and sipseed.
(so no way to recover sipseed from hashseed)
  • Loading branch information
funny-falcon committed Jul 10, 2016
1 parent 9c3aa6a commit 48eecfc
Showing 1 changed file with 30 additions and 27 deletions.
57 changes: 30 additions & 27 deletions random.c
Original file line number Diff line number Diff line change
Expand Up @@ -1475,39 +1475,47 @@ random_s_rand(int argc, VALUE *argv, VALUE obj)

static st_index_t hashseed[4];
typedef uint8_t sipseed_keys_t[16];
static union {
static union sipseed {
sipseed_keys_t key;
uint32_t u32[type_roomof(sipseed_keys_t, uint32_t)];
} sipseed;

static void
init_hashseed(struct MT *mt)
init_hashseed(sipseed_keys_t key, uint32_t* cnt)
{
int i;
for (i=0; i < numberof(hashseed); i++) {
hashseed[i] = genrand_int32(mt);
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 4*8
hashseed[i] <<= 32;
hashseed[i] |= genrand_int32(mt);
int bits = SIZEOF_ST_INDEX_T*CHAR_BIT;
hashseed[i] = 0;
for (; bits > 0; bits -= 32) {
sip_uint64_t h = sip_hash24(key, (void*)cnt, sizeof(uint32_t));
(*cnt)++;
#if SIZEOF_ST_INDEX_T > 32
hashseed[i] <<= 32;
#endif
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 8*8
hashseed[i] <<= 32;
hashseed[i] |= genrand_int32(mt);
#endif
#if SIZEOF_ST_INDEX_T*CHAR_BIT > 12*8
hashseed[i] <<= 32;
hashseed[i] |= genrand_int32(mt);
#ifdef HAVE_UINT64_T
hashseed[i] ^= (st_index_t)h;
#else
hashseed[i] ^= h.u32[0] ^ h.u32[1];
#endif
}
}
}

static void
init_siphash(struct MT *mt)
init_siphash(sipseed_keys_t key, uint32_t* cnt)
{
int i;

for (i = 0; i < numberof(sipseed.u32); ++i)
sipseed.u32[i] = genrand_int32(mt);
for (i = 0; i < numberof(sipseed.u32); ++i) {
sip_uint64_t h = sip_hash24(key, (void*)cnt, sizeof(uint32_t));
(*cnt)++;
#ifdef HAVE_UINT64_T
sipseed.u32[i] = (uint32_t)h ^ (uint32_t)(h >> 32);
#else
sipseed.u32[i] = h.u32[0] ^ h.u32[1];
#endif
}
}

#define MurmurMagic_1 (st_index_t)0xc6a4a793
Expand Down Expand Up @@ -1589,20 +1597,15 @@ rb_memhash(const void *ptr, long len)
void
Init_RandomSeedCore(void)
{
/*
Don't reuse this MT for Random::DEFAULT. Random::DEFAULT::seed shouldn't
provide a hint that an attacker guess siphash's seed.
*/
struct MT mt;
uint32_t initial_seed[DEFAULT_SEED_CNT];
union sipseed seed = { {0} };
uint32_t cnt = 1;

fill_random_seed(initial_seed, DEFAULT_SEED_CNT);
init_by_array(&mt, initial_seed, DEFAULT_SEED_CNT);
fill_random_seed(seed.u32, numberof(seed.u32));

init_hashseed(&mt);
init_siphash(&mt);
init_hashseed(seed.key, &cnt);
init_siphash(seed.key, &cnt);

explicit_bzero(initial_seed, DEFAULT_SEED_LEN);
explicit_bzero(seed.key, sizeof(seed.key));
}

static VALUE
Expand Down

0 comments on commit 48eecfc

Please sign in to comment.