Skip to main content

bssl_crypto/
rand.rs

1/* Copyright 2023 The BoringSSL Authors
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
16//! Getting random bytes.
17
18use crate::{with_output_array, FfiMutSlice};
19
20/// Fills `buf` with random bytes.
21pub fn rand_bytes(buf: &mut [u8]) {
22    // Safety: `RAND_bytes` writes exactly `buf.len()` bytes.
23    let ret = unsafe { bssl_sys::RAND_bytes(buf.as_mut_ffi_ptr(), buf.len()) };
24
25    // BoringSSL's `RAND_bytes` always succeeds returning 1, or crashes the
26    // address space if the PRNG can not provide random data.
27    debug_assert!(ret == 1);
28}
29
30/// Returns an array of random bytes.
31pub fn rand_array<const N: usize>() -> [u8; N] {
32    unsafe {
33        with_output_array(|out, out_len| {
34            // Safety: `RAND_bytes` writes exactly `out_len` bytes, as required.
35            let ret = bssl_sys::RAND_bytes(out, out_len);
36            // BoringSSL RAND_bytes always succeeds returning 1, or crashes the
37            // address space if the PRNG can not provide random data.
38            debug_assert!(ret == 1);
39        })
40    }
41}
42
43#[cfg(test)]
44mod tests {
45    use super::*;
46
47    #[test]
48    fn fill() {
49        let mut buf = [0; 32];
50        rand_bytes(&mut buf);
51    }
52
53    #[test]
54    fn fill_empty() {
55        let mut buf = [];
56        rand_bytes(&mut buf);
57    }
58
59    #[test]
60    fn array() {
61        let _rand: [u8; 32] = rand_array();
62    }
63
64    #[test]
65    fn empty_array() {
66        let _rand: [u8; 0] = rand_array();
67    }
68}