Skip to content

Commit 83ff1a4

Browse files
author
lhw
committed
feat: add rng device and virtio rng
1 parent e740d8d commit 83ff1a4

File tree

35 files changed

+620
-154
lines changed

35 files changed

+620
-154
lines changed

Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ V9P ?= n
5959
BUS ?= mmio
6060
RISCV_BIOS ?= default
6161
GICV3 ?= n
62+
RNG ?= n
6263

6364
DISK_IMG ?= disk.img
6465
FS ?= fat32

api/ruxfeat/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ display = [
7676
"ruxruntime/display",
7777
]
7878

79+
#virtio random number generator
80+
virtio-rng = ["ruxdriver/virtio-rng","ruxruntime/rng"]
81+
7982
# 9P
8083
virtio-9p = [
8184
"9pfs",

api/ruxos_posix_api/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ poll = ["fd"]
3232
tls = ["ruxfeat/tls"]
3333
irq = ["ruxfeat/irq"]
3434
random-hw = []
35+
rng = ["ruxrand"]
36+
virtio-rng = ["driver_virtio/rng","rng"]
3537

3638
musl = ["ruxhal/musl", "ruxruntime/musl", "axalloc/slab", "ruxtask/musl"]
3739

@@ -52,6 +54,7 @@ ruxtask = { path = "../../modules/ruxtask", features = [
5254
ruxfs = { path = "../../modules/ruxfs", optional = true }
5355
ruxfuse = { path = "../../modules/ruxfuse", optional = true }
5456
ruxnet = { path = "../../modules/ruxnet", optional = true }
57+
ruxrand = { path = "../../modules/ruxrand", optional = true }
5558

5659
# Other crates
5760
tty = { path = "../../crates/tty" }
@@ -69,6 +72,8 @@ flatten_objects = { path = "../../crates/flatten_objects" }
6972
page_table = { path = "../../crates/page_table" }
7073
crate_interface = "0.1.1"
7174
capability = { path = "../../crates/capability" }
75+
driver_virtio = { path = "../../crates/driver_virtio" }
76+
7277

7378
cfg-if = "1.0"
7479
elf = { version = "0.7", default-features = false }

api/ruxos_posix_api/src/imp/getrandom.rs

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::ctypes::{size_t, ssize_t};
2222

2323
use axerrno::LinuxError;
2424

25-
#[cfg(all(target_arch = "x86_64", feature = "random-hw"))]
25+
#[cfg(all(target_arch = "x86_64", feature = "random-hw", not(feature = "rng")))]
2626
use core::arch::x86_64::__cpuid;
2727

2828
static SEED: AtomicU64 = AtomicU64::new(0xae_f3);
@@ -53,7 +53,7 @@ fn srand_lcg(seed: u64) {
5353
}
5454

5555
/// Checking if the CPU core is compatible with hardware random number instructions.
56-
#[cfg(feature = "random-hw")]
56+
#[cfg(all(feature = "random-hw", not(feature = "rng")))]
5757
fn has_rdrand() -> bool {
5858
#[cfg(target_arch = "x86_64")]
5959
{
@@ -77,7 +77,7 @@ fn has_rdrand() -> bool {
7777
}
7878

7979
/// Return 64-bit unsigned random interger using cpu instruction
80-
#[cfg(feature = "random-hw")]
80+
#[cfg(all(feature = "random-hw", not(feature = "rng")))]
8181
fn random_hw() -> u64 {
8282
let mut _random: u64;
8383

@@ -118,33 +118,38 @@ pub unsafe extern "C" fn sys_srand(_seed: c_uint) {
118118
/// Returns a 32-bit unsigned random integer
119119
#[no_mangle]
120120
pub unsafe extern "C" fn sys_rand() -> c_int {
121-
#[cfg(feature = "random-hw")]
121+
#[cfg(all(feature = "rng", not(feature = "random-hw")))]
122122
{
123-
match has_rdrand() {
124-
true => (random_hw() >> 33) as c_int,
125-
false => rand_lcg32() as c_int,
126-
}
123+
use ruxrand::random;
124+
return random::<c_int>();
127125
}
128-
#[cfg(not(feature = "random-hw"))]
126+
#[cfg(all(feature = "random-hw", not(feature = "rng")))]
129127
{
130-
rand_lcg32() as c_int
128+
match has_rdrand() {
129+
true => return (random_hw() >> 33) as c_int,
130+
false => return rand_lcg32() as c_int,
131+
}
131132
}
133+
rand_lcg32() as c_int
132134
}
133135

134136
/// Returns a 64-bit unsigned random integer
135137
#[no_mangle]
136138
pub unsafe extern "C" fn sys_random() -> c_long {
137-
#[cfg(feature = "random-hw")]
139+
#[cfg(all(feature = "rng", not(feature = "random-hw")))]
138140
{
139-
match has_rdrand() {
140-
true => (random_hw() >> 1) as c_long,
141-
false => random_lcg64() as c_long,
142-
}
141+
use ruxrand::random;
142+
return random::<c_long>();
143143
}
144-
#[cfg(not(feature = "random-hw"))]
144+
#[cfg(all(feature = "random-hw", not(feature = "rng")))]
145145
{
146-
random_lcg64() as c_long
146+
match has_rdrand() {
147+
true => return (random_hw() >> 1) as c_long,
148+
false => return random_lcg64() as c_long,
149+
}
147150
}
151+
152+
random_lcg64() as c_long
148153
}
149154

150155
/// Fills the buffer pointed to by buf with up to buflen random bytes.
@@ -159,15 +164,29 @@ pub unsafe extern "C" fn sys_getrandom(buf: *mut c_void, buflen: size_t, flags:
159164
if flags != 0 {
160165
warn!("flags are not implemented yet, flags: {flags}, ignored");
161166
}
162-
// fill the buffer 8 bytes at a time first, then fill the remaining bytes
163-
let buflen_mod = buflen % (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
164-
let buflen_div = buflen / (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
165-
for i in 0..buflen_div {
166-
*((buf as *mut u8 as *mut i64).add(i)) = sys_random() as i64;
167+
#[cfg(feature = "rng")]
168+
{
169+
use ruxrand::request_entropy;
170+
let slice: &mut [u8] =
171+
unsafe { core::slice::from_raw_parts_mut(buf as *mut u8, buflen) };
172+
request_entropy(slice).map_err(|e| {
173+
warn!("Failed to get random bytes: {e:?}");
174+
LinuxError::EIO
175+
})?;
176+
Ok(buflen as ssize_t)
167177
}
168-
for i in 0..buflen_mod {
169-
*((buf as *mut u8).add(buflen - buflen_mod + i)) = sys_rand() as u8;
178+
#[cfg(not(feature = "rng"))]
179+
{
180+
// fill the buffer 8 bytes at a time first, then fill the remaining bytes
181+
let buflen_mod = buflen % (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
182+
let buflen_div = buflen / (core::mem::size_of::<i64>() / core::mem::size_of::<u8>());
183+
for i in 0..buflen_div {
184+
*((buf as *mut u8 as *mut i64).add(i)) = sys_random() as i64;
185+
}
186+
for i in 0..buflen_mod {
187+
*((buf as *mut u8).add(buflen - buflen_mod + i)) = sys_rand() as u8;
188+
}
189+
Ok(buflen as ssize_t)
170190
}
171-
Ok(buflen as ssize_t)
172191
})
173192
}

apps/c/libc-bench/Readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
- Run with following command
66
```
7-
make A=apps/c/libc-bench/ MUSL=y BLK=y ARCH=aarch64 LOG=error SMP=4 run
7+
make A=apps/c/libc-bench/ MUSL=y BLK=y RNG=y ARCH=aarch64 LOG=error SMP=4 run
88
```
99

1010
- This benchmark includes (all codes are really simple to read):

apps/c/random/features.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
virtio-rng

apps/c/random/main.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/* Copyright (c) [2023] [Syswonder Community]
2+
* [Ruxos] is licensed under Mulan PSL v2.
3+
* You can use this software according to the terms and conditions of the Mulan PSL v2.
4+
* You may obtain a copy of Mulan PSL v2 at:
5+
* http://license.coscl.org.cn/MulanPSL2
6+
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
7+
* See the Mulan PSL v2 for more details.
8+
*/
9+
10+
#define _GNU_SOURCE
11+
#include <sys/random.h>
12+
#include <stdio.h>
13+
14+
int main() {
15+
printf("Using getrandom to fetch random bytes...\n");
16+
unsigned char buf[16];
17+
ssize_t n = getrandom(buf, sizeof(buf), 0);
18+
if (n < 0) {
19+
perror("getrandom");
20+
return 1;
21+
}
22+
23+
printf("Random bytes:\n");
24+
for (int i = 0; i < n; ++i) {
25+
printf("%02x ", buf[i]);
26+
}
27+
printf("\n");
28+
29+
return 0;
30+
}

crates/driver_common/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub enum DeviceType {
3838
Display,
3939
/// Plan-9 device (e.g. 9pfs)
4040
_9P,
41+
/// Random number generator device.
42+
Rng,
4143
}
4244

4345
/// The error type for device operation failures.

crates/driver_rng/Cargo.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[package]
2+
name = "driver_rng"
3+
version = "0.1.0"
4+
edition = "2021"
5+
authors = ["Haowen Liu <2401213328@stu.pku.edu.com>"]
6+
description = "Common traits and types for random number generator device drivers"
7+
license = "Mulan PSL v2"
8+
homepage = "https://github.com/syswonder/ruxos"
9+
repository = "https://github.com/syswonder/ruxos/tree/main/crates/driver_rng"
10+
11+
[features]
12+
default = []
13+
xoshiro= ["dep:rand_xoshiro"]
14+
15+
easy-spin = []
16+
17+
[dependencies]
18+
driver_common = { path = "../driver_common" }
19+
crate_interface = "0.1.1"
20+
rand = { version = "0.8.5", default-features = false }
21+
rand_xoshiro = { version = "0.6.0", default-features = false, optional = true }
22+
23+
spinlock = { version = "0.1.0", path = "../../crates/spinlock" }
24+
percpu = "0.2"
25+
lazy_init = { version = "0.1.0", path = "../../crates/lazy_init", default-features = false }
26+
27+
[dev-dependencies]
28+
rand = { version = "0.8.5" }

0 commit comments

Comments
 (0)