23#define ROTL(a, b) (((a) << (b)) | ((a) >> (32 - (b))))
24#define QR(a, b, c, d) ( \
25 a += b, d ^= a, d = ROTL(d, 16), \
26 c += d, b ^= c, b = ROTL(b, 12), \
27 a += b, d ^= a, d = ROTL(d, 8), \
28 c += d, b ^= c, b = ROTL(b, 7))
35 for (
int i = 0; i < 16; ++i)
38 for (
int i = 0; i < 10; ++i) {
39 QR(x[0], x[4], x[ 8], x[12]);
40 QR(x[1], x[5], x[ 9], x[13]);
41 QR(x[2], x[6], x[10], x[14]);
42 QR(x[3], x[7], x[11], x[15]);
43 QR(x[0], x[5], x[10], x[15]);
44 QR(x[1], x[6], x[11], x[12]);
45 QR(x[2], x[7], x[ 8], x[13]);
46 QR(x[3], x[4], x[ 9], x[14]);
49 for (
int i = 0; i < 16; ++i)
50 out[i] = x[i] + in[i];
56 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
79 for (
int i = 0; i < 8; ++i) {
106 size_t n =
MIN(len,
sizeof(block));
119 for (
int i = 0; i < 8; ++i)
120 state[4 + i] = block[i];
122 memset(block, 0,
sizeof(block));
129 size_t size = io->
resid, done = 0;
131 while (done < size) {
132 size_t len =
MIN(size - done,
sizeof(buf));
138 memset(buf, 0,
sizeof(buf));
139 return done ? (
ssize_t) done : r;
144 if ((
size_t) r < len)
148 memset(buf, 0,
sizeof(buf));
156 size_t size = io->
resid, done = 0;
158 while (done < size) {
162 return done ? (
ssize_t) done : len;
164 for (
ssize_t i = 0; i < len; ++i)
183 .can_read = __vfs_can_always,
184 .can_write = __vfs_can_always,
185 .eof = __vfs_eof_never,
ssize_t iobuf_out(struct iobuf *io, const void *src, size_t n)
Copies bytes from the kernel into the iobuf's buffer, and moves past them.
ssize_t iobuf_in(struct iobuf *io, void *dst, size_t n)
Copies bytes from the iobuf's buffer into the kernel, and moves past them.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int posix_file_open(struct file *file)
Finishes opening a file: with O_TRUNC, a regular file is truncated to 0 bytes.
int posix_file_close(struct file *file)
Closes an open file by dropping its reference to its vnode.
ssize_t posix_file_read(struct file *file, struct iobuf *io)
Reads from an open file at its offset, and moves the offset past what was read.
ssize_t posix_file_write(struct file *file, struct iobuf *io)
Writes to an open file at its offset, and moves the offset past what was written.
static uint32_t state[16]
static void chacha20_block(const uint32_t in[16], uint32_t out[16])
Computes one ChaCha20 block (20 rounds) of the state in, into out.
static ssize_t randomdev_read(struct devid *dd, off_t offset, struct iobuf *io)
Reads random bytes, a buffer at a time; the buffer is wiped after.
static void random_stir(void)
Mixes the pool, and the time, into the key, and empties the pool.
void random_add(uint32_t value)
Stirs a value into the pool, which goes into the next key.
static ssize_t randomdev_write(struct devid *dd, off_t offset, struct iobuf *io)
Stirs what is written into the pool.
void random_get(void *_buf, size_t len)
Fills a buffer with random bytes.
A device driver: its operations, any of which may be NULL.
Which device: its kind (S_IFCHR or S_IFBLK) and numbers.
uint64_t arch_rtime_ns(void)
Reads the monotonic clock, which starts at boot.
uint64_t arch_cycles(void)
Reads a counter that changes as fast as the CPU runs, which the kernel uses as a source of randomness...