/* Internal function to return processed entropy from the PRNG */ int read_random_real(void *buf, int count) { static int cur = 0; static int gate = 1; static u_char genval[KEYSIZE]; size_t tomove; int i; int retval; /* The reseed task must not be jumped on */ mtx_lock(&random_reseed_mtx); if (gate) { generator_gate(); random_state.outputblocks = 0; gate = 0; } if (count > 0 && (size_t)count >= sizeof(random_state.counter)) { retval = 0; for (i = 0; i < count; i += (int)sizeof(random_state.counter)) { random_state.counter[0]++; yarrow_encrypt(&random_state.key, random_state.counter, genval); tomove = min(count - i, sizeof(random_state.counter)); memcpy((char *)buf + i, genval, tomove); if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } retval += (int)tomove; } } else { if (!cur) { random_state.counter[0]++; yarrow_encrypt(&random_state.key, random_state.counter, genval); memcpy(buf, genval, (size_t)count); cur = (int)sizeof(random_state.counter) - count; if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } retval = count; } else { retval = cur < count ? cur : count; memcpy(buf, &genval[(int)sizeof(random_state.counter) - cur], (size_t)retval); cur -= retval; } } mtx_unlock(&random_reseed_mtx); return retval; }
/* Internal function to return processed entropy from the PRNG */ int random_yarrow_read(void *buf, int count) { static int cur = 0; static int gate = 1; static uint8_t genval[KEYSIZE]; size_t tomove; int i; int retval; /* Check for final read request */ if (buf == NULL && count == 0) return (0); /* The reseed task must not be jumped on */ mtx_lock(&random_reseed_mtx); if (gate) { generator_gate(); random_state.outputblocks = 0; gate = 0; } if (count > 0 && (size_t)count >= BLOCKSIZE) { retval = 0; for (i = 0; i < count; i += BLOCKSIZE) { increment_counter(); randomdev_encrypt(&random_state.key, random_state.counter.byte, genval, BLOCKSIZE); tomove = MIN(count - i, BLOCKSIZE); memcpy((char *)buf + i, genval, tomove); if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } retval += (int)tomove; cur = 0; } } else { if (!cur) { increment_counter(); randomdev_encrypt(&random_state.key, random_state.counter.byte, genval, BLOCKSIZE); memcpy(buf, genval, (size_t)count); cur = BLOCKSIZE - count; if (++random_state.outputblocks >= random_state.gengateinterval) { generator_gate(); random_state.outputblocks = 0; } retval = count; } else { retval = MIN(cur, count); memcpy(buf, &genval[BLOCKSIZE - cur], (size_t)retval); cur -= retval; } } mtx_unlock(&random_reseed_mtx); return (retval); }