Use rdrand as seed for chacha prng, when available
This commit is contained in:
parent
8bbfb8bf2a
commit
e6b11f87ee
|
@ -1,3 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "randd"
|
name = "randd"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
raw-cpuid = "2.*"
|
||||||
|
|
|
@ -1,36 +1,39 @@
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
#![feature(rand)]
|
||||||
|
|
||||||
extern crate syscall;
|
extern crate syscall;
|
||||||
|
extern crate raw_cpuid;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use syscall::{Packet, Result, Scheme};
|
use rand::chacha::ChaChaRng;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
use raw_cpuid::CpuId;
|
||||||
|
|
||||||
|
use syscall::{Packet, Result, SchemeMut};
|
||||||
|
|
||||||
//TODO: Use a CSPRNG, allow write of entropy
|
//TODO: Use a CSPRNG, allow write of entropy
|
||||||
struct RandScheme;
|
struct RandScheme {
|
||||||
|
prng: ChaChaRng
|
||||||
|
}
|
||||||
|
|
||||||
impl Scheme for RandScheme {
|
impl SchemeMut for RandScheme {
|
||||||
fn open(&self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
fn open(&mut self, _path: &[u8], _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dup(&self, file: usize, _buf: &[u8]) -> Result<usize> {
|
fn dup(&mut self, file: usize, _buf: &[u8]) -> Result<usize> {
|
||||||
Ok(file)
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, _file: usize, buf: &mut [u8]) -> Result<usize> {
|
fn read(&mut self, _file: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
for chunk in buf.chunks_mut(8) {
|
for chunk in buf.chunks_mut(8) {
|
||||||
let mut rand: u64;
|
let mut rand = self.prng.next_u64();
|
||||||
unsafe {
|
|
||||||
asm!("rdrand rax"
|
|
||||||
: "={rax}"(rand)
|
|
||||||
:
|
|
||||||
:
|
|
||||||
: "intel", "volatile");
|
|
||||||
}
|
|
||||||
for b in chunk.iter_mut() {
|
for b in chunk.iter_mut() {
|
||||||
*b = rand as u8;
|
*b = rand as u8;
|
||||||
rand = rand >> 8;
|
rand = rand >> 8;
|
||||||
|
@ -40,15 +43,28 @@ impl Scheme for RandScheme {
|
||||||
Ok(i)
|
Ok(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close(&self, _file: usize) -> Result<usize> {
|
fn close(&mut self, _file: usize) -> Result<usize> {
|
||||||
Ok(0)
|
Ok(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main(){
|
fn main(){
|
||||||
|
let mut has_rdrand = CpuId::new().get_feature_info().unwrap().has_rdrand();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let mut socket = File::create(":rand").expect("rand: failed to create rand scheme");
|
let mut socket = File::create(":rand").expect("rand: failed to create rand scheme");
|
||||||
let scheme = RandScheme;
|
let mut rng = ChaChaRng::new_unseeded();
|
||||||
|
if has_rdrand {
|
||||||
|
let mut rand: u64;
|
||||||
|
unsafe {
|
||||||
|
asm!("rdrand rax"
|
||||||
|
: "={rax}"(rand)
|
||||||
|
:
|
||||||
|
:
|
||||||
|
: "intel", "volatile");
|
||||||
|
}
|
||||||
|
rng.set_counter(0, rand);
|
||||||
|
}
|
||||||
|
let mut scheme = RandScheme{prng: rng};
|
||||||
loop {
|
loop {
|
||||||
let mut packet = Packet::default();
|
let mut packet = Packet::default();
|
||||||
socket.read(&mut packet).expect("rand: failed to read events from rand scheme");
|
socket.read(&mut packet).expect("rand: failed to read events from rand scheme");
|
||||||
|
|
Loading…
Reference in a new issue