ref: 9c14131a7c789bf6a9d4f38db48d04461735d948
dir: /randomfs.c/
#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);
}