1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
// SPDX-License-Identifier: GPL-2.0
//! Rust random device.
//!
//! Adapted from Alex Gaynor's original available at
//! <https://github.com/alex/just-use/blob/master/src/lib.rs>.
use kernel::{
file::{self, File},
io_buffer::{IoBufferReader, IoBufferWriter},
prelude::*,
};
module_misc_device! {
type: RandomFile,
name: "rust_random",
author: "Rust for Linux Contributors",
description: "Just use /dev/urandom: Now with early-boot safety",
license: "GPL",
}
struct RandomFile;
#[vtable]
impl file::Operations for RandomFile {
fn open(_data: &(), _file: &File) -> Result {
Ok(())
}
fn read(_this: (), file: &File, buf: &mut impl IoBufferWriter, _: u64) -> Result<usize> {
let total_len = buf.len();
let mut chunkbuf = [0; 256];
while !buf.is_empty() {
let len = chunkbuf.len().min(buf.len());
let chunk = &mut chunkbuf[0..len];
let blocking = (file.flags() & file::flags::O_NONBLOCK) == 0;
if blocking {
kernel::random::getrandom(chunk)?;
} else {
kernel::random::getrandom_nonblock(chunk)?;
}
buf.write_slice(chunk)?;
}
Ok(total_len)
}
fn write(_this: (), _file: &File, buf: &mut impl IoBufferReader, _: u64) -> Result<usize> {
let total_len = buf.len();
let mut chunkbuf = [0; 256];
while !buf.is_empty() {
let len = chunkbuf.len().min(buf.len());
let chunk = &mut chunkbuf[0..len];
buf.read_slice(chunk)?;
kernel::random::add_randomness(chunk);
}
Ok(total_len)
}
}
|