/*
 * fortuna.c
 *		Fortuna-like PRNG.
 *
 * Copyright (c) 2005 Marko Kreen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * contrib/pgcrypto/fortuna.c
 */

#include <arch/arch.h>
#include <time.h>

#include <random/fortuna.h>
#include <random/rijndael.h>
#include <random/sha2.h>


/*
 * Why Fortuna-like: There does not seem to be any definitive reference
 * on Fortuna in the net.  Instead this implementation is based on
 * following references:
 *
 * http://en.wikipedia.org/wiki/Fortuna_(PRNG)
 *	 - Wikipedia article
 * http://jlcooke.ca/random/
 *	 - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
 */

/*
 * There is some confusion about whether and how to carry forward
 * the state of the pools.	Seems like original Fortuna does not
 * do it, resetting hash after each request.  I guess expecting
 * feeding to happen more often that requesting.   This is absolutely
 * unsuitable for pgcrypto, as nothing asynchronous happens here.
 *
 * J.L. Cooke fixed this by feeding previous hash to new re-initialized
 * hash context.
 *
 * Fortuna predecessor Yarrow requires ability to query intermediate
 * 'final result' from hash, without affecting it.
 *
 * This implementation uses the Yarrow method - asking intermediate
 * results, but continuing with old state.
 */

/*
 * Algorithm parameters
 */

/*
 * How many pools.
 *
 * Original Fortuna uses 32 pools, that means 32'th pool is
 * used not earlier than in 13th year.	This is a waste in
 * pgcrypto, as we have very low-frequancy seeding.  Here
 * is preferable to have all entropy usable in reasonable time.
 *
 * With 23 pools, 23th pool is used after 9 days which seems
 * more sane.
 *
 * In our case the minimal cycle time would be bit longer
 * than the system-randomness feeding frequency.
 */
enum {
	numPools = 23,

	/* in microseconds */
	reseedInterval = 100000, /* 0.1 sec */

	/* for one big request, reseed after this many bytes */
	reseedBytes = (1024 * 1024),

	/*
	* Skip reseed if pool 0 has less than this many
	* bytes added since last reseed.
	*/
	pool0Fill = (256 / 8),

	/*
	* Algorithm constants
	*/

	/* Both cipher key size and hash result size */
	block = 32,

	/* cipher block size */
	ciphBlock = 16
};

/* for internal wrappers */
typedef SHA256Ctx mdCtx;
typedef rijndaelCtx ciphCtx;

struct FState {
	uint8_t counter[ciphBlock];
	uint8_t result[ciphBlock];
	uint8_t key[block];
	mdCtx pool[numPools];
	ciphCtx ciph;
	unsigned reseedCount;
	int32_t lastReseedTime;
	unsigned pool0Bytes;
	unsigned rndPos;
	int tricksDone;
};
typedef struct FState FState;

/*
 * Use our own wrappers here.
 * - Need to get intermediate result from digest, without affecting it.
 * - Need re-set key on a cipher context.
 * - Algorithms are guaranteed to exist.
 * - No memory allocations.
 */

static void ciph_init(ciphCtx *ctx, const uint8_t *key, int klen)
{
	rijndael_set_key(ctx, (const uint32_t *)key, klen, 1);
}

static void ciph_encrypt(ciphCtx *ctx, const uint8_t *in, uint8_t *out)
{
	rijndael_encrypt(ctx, (const uint32_t *)in, (uint32_t *)out);
}

static void md_init(mdCtx *ctx) { SHA256_Init(ctx); }

static void md_update(mdCtx *ctx, const uint8_t *data, int len)
{
	SHA256_Update(ctx, data, len);
}

static void md_result(mdCtx *ctx, uint8_t *dst)
{
	SHA256Ctx tmp;

	memmove(&tmp, ctx, sizeof(*ctx));
	SHA256_Final(dst, &tmp);
	memset(&tmp, 0, sizeof(tmp));
}

/*
 * initialize state
 */
static void init_state(FState *st)
{
	int i;

	memset(st, 0, sizeof(*st));
	for (i = 0; i < numPools; i++)
		md_init(&st->pool[i]);
}

/*
 * Endianess does not matter.
 * It just needs to change without repeating.
 */
static void inc_counter(FState *st)
{
	uint32_t *val = (uint32_t *)st->counter;

	if (++val[0])
		return;
	if (++val[1])
		return;
	if (++val[2])
		return;
	++val[3];
}

/*
 * This is called 'cipher in counter mode'.
 */
static void encrypt_counter(FState *st, uint8_t *dst)
{
	ciph_encrypt(&st->ciph, st->counter, dst);
	inc_counter(st);
}

/*
 * The time between reseed must be at least reseedInterval
 * microseconds.
 */
static int enough_time_passed(FState *st)
{
	int ok;
	int32_t now;
	int32_t last = st->lastReseedTime;

	now = tsc2sec(read_tsc());

	/* check how much time has passed */
	ok = 0;
	if (now - last >= reseedInterval)
		ok = 1;

	/* reseed will happen, update lastReseedTime */
	if (ok)
		st->lastReseedTime = now;

	return ok;
}

/*
 * generate new key from all the pools
 */
static void reseed(FState *st)
{
	unsigned k;
	unsigned n;
	mdCtx key_md;
	uint8_t buf[block];

	/* set pool as empty */
	st->pool0Bytes = 0;

	/*
	 * Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
	 */
	n = ++st->reseedCount;

	/*
	 * The goal: use k-th pool only 1/(2^k) of the time.
	 */
	md_init(&key_md);
	for (k = 0; k < numPools; k++) {
		md_result(&st->pool[k], buf);
		md_update(&key_md, buf, block);

		if (n & 1 || !n)
			break;
		n >>= 1;
	}

	/* add old key into mix too */
	md_update(&key_md, st->key, block);

	/* now we have new key */
	md_result(&key_md, st->key);

	/* use new key */
	ciph_init(&st->ciph, st->key, block);

	memset(&key_md, 0, sizeof(key_md));
	memset(buf, 0, block);
}

/*
 * Pick a random pool.	This uses key bytes as random source.
 */
static unsigned get_rand_pool(FState *st)
{
	unsigned rnd;

	/*
	 * This slightly prefers lower pools - thats OK.
	 */
	rnd = st->key[st->rndPos] % numPools;

	st->rndPos++;
	if (st->rndPos >= block)
		st->rndPos = 0;

	return rnd;
}

/*
 * update pools
 */
static void add_entropy(FState *st, const uint8_t *data, unsigned len)
{
	unsigned pos;
	uint8_t hash[block];
	mdCtx md;

	/* hash given data */
	md_init(&md);
	md_update(&md, data, len);
	md_result(&md, hash);

	/*
	 * Make sure the pool 0 is initialized, then update randomly.
	 */
	if (st->reseedCount == 0)
		pos = 0;
	else
		pos = get_rand_pool(st);
	md_update(&st->pool[pos], hash, block);

	if (pos == 0)
		st->pool0Bytes += len;

	memset(hash, 0, block);
	memset(&md, 0, sizeof(md));
}

/*
 * Just take 2 next blocks as new key
 */
static void rekey(FState *st)
{
	encrypt_counter(st, st->key);
	encrypt_counter(st, st->key + ciphBlock);
	ciph_init(&st->ciph, st->key, block);
}

/*
 * Hide public constants. (counter, pools > 0)
 *
 * This can also be viewed as spreading the startup
 * entropy over all of the components.
 */
static void startup_tricks(FState *st)
{
	int i;
	uint8_t buf[block];

	/* Use next block as counter. */
	encrypt_counter(st, st->counter);

	/* Now shuffle pools, excluding #0 */
	for (i = 1; i < numPools; i++) {
		encrypt_counter(st, buf);
		encrypt_counter(st, buf + ciphBlock);
		md_update(&st->pool[i], buf, block);
	}
	memset(buf, 0, block);

	/* Hide the key. */
	rekey(st);

	/* This can be done only once. */
	st->tricksDone = 1;
}

static void extract_data(FState *st, unsigned count, uint8_t *dst)
{
	unsigned n;
	unsigned block_nr = 0;

	/* Should we reseed? */
	if (st->pool0Bytes >= pool0Fill || st->reseedCount == 0)
		if (enough_time_passed(st))
			reseed(st);

	/* Do some randomization on first call */
	if (!st->tricksDone)
		startup_tricks(st);

	while (count > 0) {
		/* produce bytes */
		encrypt_counter(st, st->result);

		/* copy result */
		if (count > ciphBlock)
			n = ciphBlock;
		else
			n = count;
		memmove(dst, st->result, n);
		dst += n;
		count -= n;

		/* must not give out too many bytes with one key */
		block_nr++;
		if (block_nr > (reseedBytes / ciphBlock)) {
			rekey(st);
			block_nr = 0;
		}
	}
	/* Set new key for next request. */
	rekey(st);
}

static FState mainState;
static int initDone;

static void init()
{
	init_state(&mainState);
	initDone = 1;
}

/*
 * public interface
 */

void fortuna_add_entropy(const uint8_t *data, unsigned len)
{
	if (!initDone)
		init();

	if (!data || !len)
		return;
	add_entropy(&mainState, data, len);
}

void fortuna_get_bytes(unsigned len, uint8_t *dst)
{
	if (!initDone)
		init();

	if (!dst || !len)
		return;
	extract_data(&mainState, len, dst);
}
