1//! RDRAND and RDSEED instructions for returning random numbers from an Intel
2//! on-chip hardware random number generator which has been seeded by an
3//! on-chip entropy source.
4#![allow(clippy::module_name_repetitions)]
5
6#[allow(improper_ctypes)]
7extern "unadjusted" {
8 #[link_name = "llvm.x86.rdrand.16"]
9 fn x86_rdrand16_step() -> (u16, i32);
10 #[link_name = "llvm.x86.rdrand.32"]
11 fn x86_rdrand32_step() -> (u32, i32);
12 #[link_name = "llvm.x86.rdseed.16"]
13 fn x86_rdseed16_step() -> (u16, i32);
14 #[link_name = "llvm.x86.rdseed.32"]
15 fn x86_rdseed32_step() -> (u32, i32);
16}
17
18#[cfg(test)]
19use stdarch_test::assert_instr;
20
21/// Read a hardware generated 16-bit random value and store the result in val.
22/// Returns 1 if a random value was generated, and 0 otherwise.
23///
24/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdrand16_step)
25#[inline]
26#[target_feature(enable = "rdrand")]
27#[cfg_attr(test, assert_instr(rdrand))]
28#[stable(feature = "simd_x86", since = "1.27.0")]
29pub unsafe fn _rdrand16_step(val: &mut u16) -> i32 {
30 let (v: u16, flag: i32) = x86_rdrand16_step();
31 *val = v;
32 flag
33}
34
35/// Read a hardware generated 32-bit random value and store the result in val.
36/// Returns 1 if a random value was generated, and 0 otherwise.
37///
38/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdrand32_step)
39#[inline]
40#[target_feature(enable = "rdrand")]
41#[cfg_attr(test, assert_instr(rdrand))]
42#[stable(feature = "simd_x86", since = "1.27.0")]
43pub unsafe fn _rdrand32_step(val: &mut u32) -> i32 {
44 let (v: u32, flag: i32) = x86_rdrand32_step();
45 *val = v;
46 flag
47}
48
49/// Read a 16-bit NIST SP800-90B and SP800-90C compliant random value and store
50/// in val. Return 1 if a random value was generated, and 0 otherwise.
51///
52/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdseed16_step)
53#[inline]
54#[target_feature(enable = "rdseed")]
55#[cfg_attr(test, assert_instr(rdseed))]
56#[stable(feature = "simd_x86", since = "1.27.0")]
57pub unsafe fn _rdseed16_step(val: &mut u16) -> i32 {
58 let (v: u16, flag: i32) = x86_rdseed16_step();
59 *val = v;
60 flag
61}
62
63/// Read a 32-bit NIST SP800-90B and SP800-90C compliant random value and store
64/// in val. Return 1 if a random value was generated, and 0 otherwise.
65///
66/// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_rdseed32_step)
67#[inline]
68#[target_feature(enable = "rdseed")]
69#[cfg_attr(test, assert_instr(rdseed))]
70#[stable(feature = "simd_x86", since = "1.27.0")]
71pub unsafe fn _rdseed32_step(val: &mut u32) -> i32 {
72 let (v: u32, flag: i32) = x86_rdseed32_step();
73 *val = v;
74 flag
75}
76