#define SILC_RNG_STATE_NUM 4
/* Byte size of the random data pool. */
-#define SILC_RNG_POOLSIZE 1024
+#define SILC_RNG_POOLSIZE (20 * 48)
static SilcUInt32 silc_rng_get_position(SilcRng rng);
static void silc_rng_stir_pool(SilcRng rng);
/* Get data as much as we can get into the buffer */
for (i = 0; i < sizeof(buf); i++) {
c = fgetc(fd);
- if (c == EOF) {
- if (!i)
- return;
+ if (c == EOF)
break;
- }
buf[i] = c;
}
pclose(fd);
- /* Add the buffer into random pool */
- silc_rng_add_noise(rng, buf, i);
- memset(buf, 0, sizeof(buf));
+ if (i != 0) {
+ /* Add the buffer into random pool */
+ silc_rng_add_noise(rng, buf, i);
+ memset(buf, 0, sizeof(buf));
+ }
#endif
}
static void silc_rng_xor(SilcRng rng, SilcUInt32 val, unsigned int pos)
{
- assert(rng != NULL);
- rng->pool[pos] ^= val + val;
+ SilcUInt32 tmp;
+
+ SILC_GET32_MSB(tmp, &rng->pool[pos]);
+ val ^= tmp + val;
+ SILC_PUT32_MSB(val, &rng->pool[pos]);
}
/* This function stirs the random pool by encrypting buffer in CFB
static void silc_rng_stir_pool(SilcRng rng)
{
int i;
- SilcUInt32 iv[5];
+ SilcUInt32 iv[5], tmp;
/* Get the IV */
- memcpy(iv, &rng->pool[16], sizeof(iv));
+ SILC_GET32_MSB(iv[0], &rng->pool[16 ]);
+ SILC_GET32_MSB(iv[1], &rng->pool[16 + 4]);
+ SILC_GET32_MSB(iv[2], &rng->pool[16 + 8]);
+ SILC_GET32_MSB(iv[3], &rng->pool[16 + 12]);
+ SILC_GET32_MSB(iv[4], &rng->pool[16 + 16]);
/* First CFB pass */
- for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) {
+ for (i = 0; i < SILC_RNG_POOLSIZE; i += 20) {
silc_hash_transform(rng->sha1, iv, rng->key);
- iv[0] = rng->pool[i] ^= iv[0];
- iv[1] = rng->pool[i + 1] ^= iv[1];
- iv[2] = rng->pool[i + 2] ^= iv[2];
- iv[3] = rng->pool[i + 3] ^= iv[3];
- iv[4] = rng->pool[i + 4] ^= iv[4];
+
+ SILC_GET32_MSB(tmp, &rng->pool[i]);
+ iv[0] ^= tmp;
+ SILC_PUT32_MSB(iv[0], &rng->pool[i]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 4]);
+ iv[1] ^= tmp;
+ SILC_PUT32_MSB(iv[1], &rng->pool[i + 4]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 8]);
+ iv[2] ^= tmp;
+ SILC_PUT32_MSB(iv[2], &rng->pool[i + 8]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 12]);
+ iv[3] ^= tmp;
+ SILC_PUT32_MSB(iv[3], &rng->pool[i + 12]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 16]);
+ iv[4] ^= tmp;
+ SILC_PUT32_MSB(iv[4], &rng->pool[i + 16]);
}
/* Get new key */
memcpy(rng->key, &rng->pool[silc_rng_get_position(rng)], sizeof(rng->key));
/* Second CFB pass */
- for (i = 0; i < SILC_RNG_POOLSIZE; i += 5) {
+ for (i = 0; i < SILC_RNG_POOLSIZE; i += 20) {
silc_hash_transform(rng->sha1, iv, rng->key);
- iv[0] = rng->pool[i] ^= iv[0];
- iv[1] = rng->pool[i + 1] ^= iv[1];
- iv[2] = rng->pool[i + 2] ^= iv[2];
- iv[3] = rng->pool[i + 3] ^= iv[3];
- iv[4] = rng->pool[i + 4] ^= iv[4];
+
+ SILC_GET32_MSB(tmp, &rng->pool[i]);
+ iv[0] ^= tmp;
+ SILC_PUT32_MSB(iv[0], &rng->pool[i]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 4]);
+ iv[1] ^= tmp;
+ SILC_PUT32_MSB(iv[1], &rng->pool[i + 4]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 8]);
+ iv[2] ^= tmp;
+ SILC_PUT32_MSB(iv[2], &rng->pool[i + 8]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 12]);
+ iv[3] ^= tmp;
+ SILC_PUT32_MSB(iv[3], &rng->pool[i + 12]);
+
+ SILC_GET32_MSB(tmp, &rng->pool[i + 16]);
+ iv[4] ^= tmp;
+ SILC_PUT32_MSB(iv[4], &rng->pool[i + 16]);
}
memset(iv, 0, sizeof(iv));
if (rng->fd_devurandom == -1) {
rng->fd_devurandom = open("/dev/urandom", O_RDONLY);
- if (rng < 0)
+ if (rng->fd_devurandom < 0)
return silc_rng_get_byte(rng);
fcntl(rng->fd_devurandom, F_SETFL, O_NONBLOCK);
}
SilcUInt32 silc_rng_get_rn32(SilcRng rng)
{
unsigned char rn[4];
- SilcUInt16 num;
+ SilcUInt32 num;
rn[0] = silc_rng_get_byte(rng);
rn[1] = silc_rng_get_byte(rng);