shithub: util

ref: 9c14131a7c789bf6a9d4f38db48d04461735d948
dir: /randomfs.c/

View raw version
#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>

#define ADC "/dev/adc%d"

uint seed[16];

int
readadc(int n)
{
	char *fname;
	int fd;
	char buf[32];
	int ret;

	if (n < 0 || n > 7)
		sysfatal("adc %d?", n);

	fname = smprint(ADC, n);
	if (fname == nil)
		sysfatal("smprint: %r");

	fd = open(fname, OREAD);
	if (fd < 0)
		sysfatal("open: %r");

	free(fname);

	if ((ret = read(fd, buf, 32)) <= 0)
		sysfatal("read: %r");

	close(fd);

	buf[ret] = '\0';

	ret = atoi(buf);

	return ret;
}

#define ROTATE(v,c) ((unsigned long)((v) << (c)) | ((v) >> (32 - (c))))

#define QUARTERROUND(ia,ib,ic,id) { \
	uint a, b, c, d, t; \
	a = x[ia]; b = x[ib]; c = x[ic]; d = x[id]; \
	a += b; t = d^a; d = ROTATE(t,16); \
	c += d; t = b^c; b = ROTATE(t,12); \
	a += b; t = d^a; d = ROTATE(t, 8); \
	c += d; t = b^c; b = ROTATE(t, 7); \
	x[ia] = a; x[ib] = b; x[ic] = c; x[id] = d; \
}

void
_chachablock(uint x[16], int rounds)
{
	for(; rounds > 0; rounds -= 2) {
		QUARTERROUND(0, 4, 8,12)
		QUARTERROUND(1, 5, 9,13)
		QUARTERROUND(2, 6,10,14)
		QUARTERROUND(3, 7,11,15)

		QUARTERROUND(0, 5,10,15)
		QUARTERROUND(1, 6,11,12)
		QUARTERROUND(2, 7, 8,13)
		QUARTERROUND(3, 4, 9,14)
	}
}

void
fsread(Req *r)
{
	int i, j, k;

	if ((intptr)(r->fid->file->aux) == 1) {
		for (i = 0; i < 16; i++) {
			for (j = 0; j < 8; j++) {
				seed[i] <<= 1;
				seed[i] ^= readadc(j) ^ nsec();
			}
		}

		for (k = 0; k < r->ifcall.count; k++) {
			i = k & 15;
			if (i == 0)
				_chachablock(seed, 20);
			r->ofcall.data[k] = seed[i] & 0xFF;
		}

		r->ofcall.count = k;
		respond(r, nil);
	} else {
		respond(r, "file not found");
	}
}

void
fswrite(Req *r)
{
	int i, k;
	if ((intptr)(r->fid->file->aux) == 1) {
		for (k = 0; k < r->ifcall.count; k++) {
			i = k & 15;
			seed[i] <<= 1;
			seed[i] ^= r->ifcall.data[k];
		}

		r->ofcall.count = k;
		respond(r, nil);
	} else {
		respond(r, "file not found");
	}
}

Srv fs = {
.read	= fsread,
.write	= fswrite,
};

void
main()
{
	readadc(0);

	fs.tree = alloctree("randomfs", "randomfs", DMDIR|0555, nil);
	createfile(fs.tree->root, "random", "randomfs", 0666, (void*)1);
	postmountsrv(&fs, "randomfs", "/dev", MBEFORE);
}