/*
 * 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 <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 <net/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,
                                  unsigned int nname)
{
	return devwalk(c, nc, name, nname, randomdir,
		       ARRAY_SIZE(randomdir), devgen);
}

static size_t randomstat(struct chan *c, uint8_t *dp, size_t 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 size_t randomread(struct chan *c, void *va, size_t n, off64_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 size_t randomwrite(struct chan *c, void *va, size_t n, off64_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 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 = devwstat,
	.power = devpower,
	.chaninfo = devchaninfo,
	.tapfd = random_tapfd,
};
