|
|
@ -1,4 +1,4 @@ |
|
|
|
/* $OpenBSD: arc4random.c,v 1.27 2014/05/04 20:40:08 deraadt Exp $ */ |
|
|
|
/* $OpenBSD: arc4random.c,v 1.28 2014/05/06 02:31:45 tedu Exp $ */ |
|
|
|
|
|
|
|
/* |
|
|
|
* Copyright (c) 1996, David Mazieres <dm@uun.org> |
|
|
@ -31,6 +31,8 @@ |
|
|
|
#include <sys/param.h> |
|
|
|
#include <sys/time.h> |
|
|
|
#include <sys/sysctl.h> |
|
|
|
#include <sys/mman.h> |
|
|
|
|
|
|
|
#include "thread_private.h" |
|
|
|
|
|
|
|
#define KEYSTREAM_ONLY |
|
|
@ -48,8 +50,8 @@ |
|
|
|
#define RSBUFSZ (16*BLOCKSZ) |
|
|
|
static int rs_initialized; |
|
|
|
static pid_t rs_stir_pid; |
|
|
|
static chacha_ctx rs; /* chacha context for random keystream */ |
|
|
|
static u_char rs_buf[RSBUFSZ]; /* keystream blocks */ |
|
|
|
static chacha_ctx *rs; /* chacha context for random keystream */ |
|
|
|
static u_char *rs_buf; /* keystream blocks */ |
|
|
|
static size_t rs_have; /* valid bytes at end of rs_buf */ |
|
|
|
static size_t rs_count; /* bytes till reseed */ |
|
|
|
|
|
|
@ -60,8 +62,16 @@ _rs_init(u_char *buf, size_t n) |
|
|
|
{ |
|
|
|
if (n < KEYSZ + IVSZ) |
|
|
|
return; |
|
|
|
chacha_keysetup(&rs, buf, KEYSZ * 8, 0); |
|
|
|
chacha_ivsetup(&rs, buf + KEYSZ); |
|
|
|
|
|
|
|
if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE, |
|
|
|
MAP_ANON, -1, 0)) == MAP_FAILED) |
|
|
|
abort(); |
|
|
|
if ((rs_buf = mmap(NULL, RSBUFSZ, PROT_READ|PROT_WRITE, |
|
|
|
MAP_ANON, -1, 0)) == MAP_FAILED) |
|
|
|
abort(); |
|
|
|
|
|
|
|
chacha_keysetup(rs, buf, KEYSZ * 8, 0); |
|
|
|
chacha_ivsetup(rs, buf + KEYSZ); |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
@ -110,7 +120,7 @@ _rs_rekey(u_char *dat, size_t datlen) |
|
|
|
memset(rs_buf, 0,RSBUFSZ); |
|
|
|
#endif |
|
|
|
/* fill rs_buf with the keystream */ |
|
|
|
chacha_encrypt_bytes(&rs, rs_buf, rs_buf, RSBUFSZ); |
|
|
|
chacha_encrypt_bytes(rs, rs_buf, rs_buf, RSBUFSZ); |
|
|
|
/* mix in optional user provided data */ |
|
|
|
if (dat) { |
|
|
|
size_t i, m; |
|
|
|