/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <vfs.h>
#include <kfs.h>
#include <slab.h>
#include <kmalloc.h>
#include <kref.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <error.h>
#include <cpio.h>
#include <pmap.h>
#include <smp.h>
#include <ip.h>
#include <random/fortuna.h>

static qlock_t rl;

/*
 * Add entropy. This is not currently used but we might want to hook it into a
 * hardware entropy source.
 */
void random_add(void *xp)
{
	ERRSTACK(1);

	qlock(&rl);
	if (waserror()) {
		qunlock(&rl);
		nexterror();
	}

	fortuna_add_entropy(xp, sizeof(xp));
	qunlock(&rl);

	poperror();
}

/*
 *  consume random bytes
 */
uint32_t random_read(void *xp, uint32_t n)
{
	ERRSTACK(1);

	qlock(&rl);

	if (waserror()) {
		qunlock(&rl);
		nexterror();
	}

	fortuna_get_bytes(n, xp);
	qunlock(&rl);

	poperror();

	return n;
}

/**
 * Fast random generator
 **/
uint32_t urandom_read(void *xp, uint32_t n)
{
	uint64_t seed[16];
	uint8_t *e, *p;
	uint32_t x = 0;
	uint64_t s0;
	uint64_t s1;

	if (n <= sizeof(seed))
		return random_read(xp, n);
	// The initial seed is from a good random pool.
	random_read(seed, sizeof(seed));
	p = xp;
	for (e = p + n; p < e;) {
		s0 = seed[x];
		s1 = seed[x = (x + 1) & 15];
		s1 ^= s1 << 31;
		s1 ^= s1 >> 11;
		s0 ^= s0 >> 30;
		*p++ = (seed[x] = s0 ^ s1) * 1181783497276652981LL;
	}

	return n;
}

struct dev randomdevtab;

static char *devname(void)
{
	return randomdevtab.name;
}

enum {
	Qdir,
	Qrandom,
	Qurandom
};

static
struct dirtab randomdir[] = {
	{".", {Qdir, 0, QTDIR}, 0, DMDIR | 0500},
	{"random", {Qrandom}, 0, 0444},
	{"urandom", {Qurandom}, 0, 0444},
};

static void randominit(void)
{
	qlock_init(&rl);
}

/*
 *  create a random, no streams are created until an open
 */
static struct chan *randomattach(char *spec)
{
	return devattach(devname(), spec);
}

static struct walkqid *randomwalk(struct chan *c, struct chan *nc, char **name,
								int nname)
{
	return devwalk(c, nc, name, nname, randomdir,
		       ARRAY_SIZE(randomdir), devgen);
}

static int randomstat(struct chan *c, uint8_t *dp, int n)
{
	struct dir dir;
	struct dirtab *tab;
	int perm;

	switch (c->qid.path) {
	case Qrandom:
		tab = &randomdir[Qrandom];
		perm = tab->perm | DMREADABLE;
		devdir(c, tab->qid, tab->name, 0, eve.name, perm, &dir);
		return dev_make_stat(c, &dir, dp, n);
	case Qurandom:
		tab = &randomdir[Qurandom];
		perm = tab->perm | DMREADABLE;
		devdir(c, tab->qid, tab->name, 0, eve.name, perm, &dir);
		return dev_make_stat(c, &dir, dp, n);
	default:
		return devstat(c, dp, n, randomdir, ARRAY_SIZE(randomdir), devgen);
	}
}

/*
 *  if the stream doesn't exist, create it
 */
static struct chan *randomopen(struct chan *c, int omode)
{
	return devopen(c, omode, randomdir, ARRAY_SIZE(randomdir), devgen);
}

static void randomclose(struct chan *c)
{
}

static long randomread(struct chan *c, void *va, long n, int64_t ignored)
{
	switch (c->qid.path) {
		case Qdir:
			return devdirread(c, va, n, randomdir,
					  ARRAY_SIZE(randomdir), devgen);
		case Qrandom:
			return random_read(va, n);
		case Qurandom:
			return urandom_read(va, n);
		default:
			panic("randomread: qid %d is impossible", c->qid.path);
	}
	return -1;	/* not reached */
}

/*
 *  A write to a closed random causes an ERANDOM error to be thrown.
 */
static long randomwrite(struct chan *c, void *va, long n, int64_t ignored)
{
	error(EPERM, "No use for writing random just yet");
	return -1;
}

static long randombwrite(struct chan *c, struct block *bp, uint32_t junk)
{
	error(EPERM, "No use for writing random just yet");
	return -1;
}

static int randomwstat(struct chan *c, uint8_t *dp, int n)
{
	error(EPERM, "No use for wstat random just yet");
	return -1;
}

static int random_tapfd(struct chan *c, struct fd_tap *tap, int cmd)
{
	/* We don't actually support HANGUP, but epoll implies it. */
	#define RANDOM_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_HANGUP)

	if (tap->filter & ~RANDOM_TAPS) {
		set_error(ENOSYS, "Unsupported #%s tap, must be %p", devname(),
		          RANDOM_TAPS);
		return -1;
	}
	switch (c->qid.path) {
	case Qrandom:
	case Qurandom:
		/* Faking any legit command on (u)random, which never blocks. */
		return 0;
	default:
		set_error(ENOSYS, "Can't tap #%s file type %d", devname(),
		          c->qid.path);
		return -1;
	}
}

struct dev randomdevtab __devtab = {
	.name = "random",

	.reset = devreset,
	.init = randominit,
	.shutdown = devshutdown,
	.attach = randomattach,
	.walk = randomwalk,
	.stat = randomstat,
	.open = randomopen,
	.create = devcreate,
	.close = randomclose,
	.read = randomread,
	.write = randomwrite,
	.remove = devremove,
	.wstat = randomwstat,
	.power = devpower,
	.chaninfo = devchaninfo,
	.tapfd = random_tapfd,
};
