Skip to content

Commit 9ce4061

Browse files
committed
random.c: use siphash in counter mode for hash initialization.
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)
1 parent 3b9a382 commit 9ce4061

File tree

1 file changed

+29
-19
lines changed

1 file changed

+29
-19
lines changed

random.c

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,33 +1474,48 @@ random_s_rand(int argc, VALUE *argv, VALUE obj)
14741474
#include "siphash.c"
14751475

14761476
typedef uint8_t sipseed_keys_t[16];
1477-
static union {
1477+
static union sipseed {
14781478
sipseed_keys_t key;
14791479
uint32_t u32[type_roomof(sipseed_keys_t, uint32_t)];
14801480
} sipseed;
14811481

14821482
static void
1483-
init_hashseed(struct MT *mt)
1483+
init_hashseed(sipseed_keys_t key, uint32_t* cnt)
14841484
{
14851485
st_index_t hashseed[2];
14861486
int i,b;
14871487
for (i = 0; i < 2; i++) {
1488-
hashseed[i] = genrand_int32(mt);
1489-
for (b = ST_INDEX_BITS - 32; b > 0; b -= 32) {
1488+
hashseed[i] = 0;
1489+
for (b = ST_INDEX_BITS; b > 0; b -= 32) {
1490+
sip_uint64_t h = sip_hash24(key, (void*)cnt, sizeof(uint32_t));
1491+
(*cnt)++;
1492+
#if ST_INDEX_BITS > 32
14901493
hashseed[i] <<= 32;
1491-
hashseed[i] |= genrand_int32(mt);
1494+
#endif
1495+
#ifdef HAVE_UINT64_T
1496+
hashseed[i] ^= (st_index_t)h;
1497+
#else
1498+
hashseed[i] ^= h.u32[0] ^ h.u32[1];
1499+
#endif
14921500
}
14931501
}
14941502
st_hash_seed(hashseed);
14951503
}
14961504

14971505
static void
1498-
init_siphash(struct MT *mt)
1506+
init_siphash(sipseed_keys_t key, uint32_t* cnt)
14991507
{
15001508
int i;
15011509

1502-
for (i = 0; i < numberof(sipseed.u32); ++i)
1503-
sipseed.u32[i] = genrand_int32(mt);
1510+
for (i = 0; i < numberof(sipseed.u32); ++i) {
1511+
sip_uint64_t h = sip_hash24(key, (void*)cnt, sizeof(uint32_t));
1512+
(*cnt)++;
1513+
#ifdef HAVE_UINT64_T
1514+
sipseed.u32[i] = (uint32_t)h ^ (uint32_t)(h >> 32);
1515+
#else
1516+
sipseed.u32[i] = h.u32[0] ^ h.u32[1];
1517+
#endif
1518+
}
15041519
}
15051520

15061521
st_index_t
@@ -1519,20 +1534,15 @@ rb_memhash(const void *ptr, long len)
15191534
void
15201535
Init_RandomSeedCore(void)
15211536
{
1522-
/*
1523-
Don't reuse this MT for Random::DEFAULT. Random::DEFAULT::seed shouldn't
1524-
provide a hint that an attacker guess siphash's seed.
1525-
*/
1526-
struct MT mt;
1527-
uint32_t initial_seed[DEFAULT_SEED_CNT];
1537+
union sipseed seed = { {0} };
1538+
uint32_t cnt = 1;
15281539

1529-
fill_random_seed(initial_seed, DEFAULT_SEED_CNT);
1530-
init_by_array(&mt, initial_seed, DEFAULT_SEED_CNT);
1540+
fill_random_seed(seed.u32, numberof(seed.u32));
15311541

1532-
init_hashseed(&mt);
1533-
init_siphash(&mt);
1542+
init_hashseed(seed.key, &cnt);
1543+
init_siphash(seed.key, &cnt);
15341544

1535-
explicit_bzero(initial_seed, DEFAULT_SEED_LEN);
1545+
explicit_bzero(seed.key, sizeof(seed.key));
15361546
}
15371547

15381548
static VALUE

0 commit comments

Comments
 (0)