Coverage Report

Created: 2025-07-14 07:05

/src/MigTD/deps/td-shim/library/ring/src/rand.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2015-2016 Brian Smith.
2
//
3
// Permission to use, copy, modify, and/or distribute this software for any
4
// purpose with or without fee is hereby granted, provided that the above
5
// copyright notice and this permission notice appear in all copies.
6
//
7
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
15
//! Cryptographic pseudo-random number generation.
16
//!
17
//! *ring* functions that generate random bytes take a `&dyn SecureRandom`
18
//! parameter to make it clear which functions are non-deterministic.
19
20
use crate::error;
21
22
/// A secure random number generator.
23
pub trait SecureRandom: sealed::SecureRandom {
24
    /// Fills `dest` with random bytes.
25
    fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified>;
26
}
27
28
impl<T> SecureRandom for T
29
where
30
    T: sealed::SecureRandom,
31
{
32
    #[inline(always)]
33
0
    fn fill(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> {
34
0
        self.fill_impl(dest)
35
0
    }
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::SecureRandom>::fill
Unexecuted instantiation: <ring::ec::suite_b::ecdsa::signing::NonceRandom as ring::rand::SecureRandom>::fill
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::SecureRandom>::fill
Unexecuted instantiation: <ring::ec::suite_b::ecdsa::signing::NonceRandom as ring::rand::SecureRandom>::fill
36
}
37
38
/// A random value constructed from a `SecureRandom` that hasn't been exposed
39
/// through any safe Rust interface.
40
///
41
/// Intentionally does not implement any traits other than `Sized`.
42
pub struct Random<T: RandomlyConstructable>(T);
43
44
impl<T: RandomlyConstructable> Random<T> {
45
    /// Expose the random value.
46
    #[inline]
47
0
    pub fn expose(self) -> T {
48
0
        self.0
49
0
    }
Unexecuted instantiation: <ring::rand::Random<[u8; 32]>>::expose
Unexecuted instantiation: <ring::rand::Random<[u8; 32]>>::expose
50
}
51
52
/// Generate the new random value using `rng`.
53
#[inline]
54
0
pub fn generate<T: RandomlyConstructable>(
55
0
    rng: &dyn SecureRandom,
56
0
) -> Result<Random<T>, error::Unspecified> {
57
0
    let mut r = T::zero();
58
0
    rng.fill(r.as_mut_bytes())?;
59
0
    Ok(Random(r))
60
0
}
Unexecuted instantiation: ring::rand::generate::<[u8; 32]>
Unexecuted instantiation: ring::rand::generate::<[u8; 32]>
61
62
pub(crate) mod sealed {
63
    use crate::error;
64
65
    pub trait SecureRandom: core::fmt::Debug {
66
        /// Fills `dest` with random bytes.
67
        fn fill_impl(&self, dest: &mut [u8]) -> Result<(), error::Unspecified>;
68
    }
69
70
    pub trait RandomlyConstructable: Sized {
71
        fn zero() -> Self; // `Default::default()`
72
        fn as_mut_bytes(&mut self) -> &mut [u8]; // `AsMut<[u8]>::as_mut`
73
    }
74
75
    impl<const N: usize> RandomlyConstructable for [u8; N] {
76
        #[inline]
77
0
        fn zero() -> Self {
78
0
            [0; N]
79
0
        }
Unexecuted instantiation: <[u8; 32] as ring::rand::sealed::RandomlyConstructable>::zero
Unexecuted instantiation: <[u8; 32] as ring::rand::sealed::RandomlyConstructable>::zero
80
81
        #[inline]
82
0
        fn as_mut_bytes(&mut self) -> &mut [u8] {
83
0
            &mut self[..]
84
0
        }
Unexecuted instantiation: <[u8; 32] as ring::rand::sealed::RandomlyConstructable>::as_mut_bytes
Unexecuted instantiation: <[u8; 32] as ring::rand::sealed::RandomlyConstructable>::as_mut_bytes
85
    }
86
}
87
88
/// A type that can be returned by `ring::rand::generate()`.
89
pub trait RandomlyConstructable: sealed::RandomlyConstructable {}
90
impl<T> RandomlyConstructable for T where T: sealed::RandomlyConstructable {}
91
92
/// A secure random number generator where the random values come directly
93
/// from the operating system.
94
///
95
/// "Directly from the operating system" here presently means "whatever the
96
/// `getrandom` crate does" but that may change in the future. That roughly
97
/// means calling libc's `getrandom` function or whatever is analogous to that;
98
/// see the `getrandom` crate's documentation for more info.
99
///
100
/// A single `SystemRandom` may be shared across multiple threads safely.
101
///
102
/// `new()` is guaranteed to always succeed and to have low latency; it won't
103
/// try to open or read from a file or do similar things. The first call to
104
/// `fill()` may block a substantial amount of time since any and all
105
/// initialization is deferred to it. Therefore, it may be a good idea to call
106
/// `fill()` once at a non-latency-sensitive time to minimize latency for
107
/// future calls.
108
#[derive(Clone, Debug)]
109
pub struct SystemRandom(());
110
111
impl SystemRandom {
112
    /// Constructs a new `SystemRandom`.
113
    #[inline(always)]
114
0
    pub fn new() -> Self {
115
0
        Self(())
116
0
    }
Unexecuted instantiation: <ring::rand::SystemRandom>::new
Unexecuted instantiation: <ring::rand::SystemRandom>::new
117
}
118
119
impl crate::sealed::Sealed for SystemRandom {}
120
121
// Use the `getrandom` crate whenever it is using the environment's (operating
122
// system's) CSPRNG. Avoid using it on targets where it uses the `rdrand`
123
// implementation.
124
#[cfg(any(
125
    all(feature = "less-safe-getrandom-custom-or-rdrand", target_os = "none"),
126
    all(feature = "less-safe-getrandom-espidf", target_os = "espidf"),
127
    target_os = "aix",
128
    target_os = "android",
129
    target_os = "dragonfly",
130
    target_os = "freebsd",
131
    target_os = "fuchsia",
132
    target_os = "haiku",
133
    target_os = "hermit",
134
    target_os = "hurd",
135
    target_os = "horizon",
136
    target_os = "illumos",
137
    target_os = "linux",
138
    target_os = "netbsd",
139
    target_os = "openbsd",
140
    target_os = "redox",
141
    target_os = "solaris",
142
    target_os = "vita",
143
    target_os = "windows",
144
    all(
145
        target_vendor = "apple",
146
        any(
147
            target_os = "ios",
148
            target_os = "macos",
149
            target_os = "tvos",
150
            target_os = "visionos",
151
            target_os = "watchos",
152
        )
153
    ),
154
    all(
155
        target_arch = "wasm32",
156
        any(
157
            target_os = "wasi",
158
            all(target_os = "unknown", feature = "wasm32_unknown_unknown_js")
159
        )
160
    ),
161
))]
162
impl sealed::SecureRandom for SystemRandom {
163
    #[inline(always)]
164
0
    fn fill_impl(&self, dest: &mut [u8]) -> Result<(), error::Unspecified> {
165
0
        getrandom::getrandom(dest).map_err(|_| error::Unspecified)
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl::{closure#0}
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl::{closure#0}
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl::{closure#0}
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl::{closure#0}
166
0
    }
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl
Unexecuted instantiation: <ring::rand::SystemRandom as ring::rand::sealed::SecureRandom>::fill_impl
167
}