Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* 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);
}