|
| 1 | +// Copyright 2018 Developers of the Rand project. |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 4 | +// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 5 | +// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your |
| 6 | +// option. This file may not be copied, modified, or distributed |
| 7 | +// except according to those terms. |
| 8 | + |
| 9 | +//! An implementation which calls out to an externally defined function. |
| 10 | +use crate::Error; |
| 11 | +use core::num::NonZeroU32; |
| 12 | + |
| 13 | +/// Register a function to be invoked by `getrandom` on custom targets. |
| 14 | +/// |
| 15 | +/// This function will only be invoked on targets not supported by `getrandom`. |
| 16 | +/// This prevents crate dependencies from either inadvertently or maliciously |
| 17 | +/// overriding the secure RNG implementations in `getrandom`. |
| 18 | +/// |
| 19 | +/// *This API requires the following crate features to be activated: `custom`* |
| 20 | +#[macro_export] |
| 21 | +macro_rules! register_custom_getrandom { |
| 22 | + ($path:path) => { |
| 23 | + // We use an extern "C" function to get the guarantees of a stable ABI. |
| 24 | + #[no_mangle] |
| 25 | + extern "C" fn __getrandom_custom(dest: *mut u8, len: usize) -> u32 { |
| 26 | + let slice = unsafe { ::std::slice::from_raw_parts_mut(dest, len) }; |
| 27 | + match $path(slice) { |
| 28 | + Ok(()) => 0, |
| 29 | + Err(e) => e.code().get(), |
| 30 | + } |
| 31 | + } |
| 32 | + }; |
| 33 | +} |
| 34 | + |
| 35 | +#[allow(dead_code)] |
| 36 | +pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> { |
| 37 | + extern "C" { |
| 38 | + fn __getrandom_custom(dest: *mut u8, len: usize) -> u32; |
| 39 | + } |
| 40 | + let ret = unsafe { __getrandom_custom(dest.as_mut_ptr(), dest.len()) }; |
| 41 | + match NonZeroU32::new(ret) { |
| 42 | + None => Ok(()), |
| 43 | + Some(code) => Err(Error::from(code)), |
| 44 | + } |
| 45 | +} |
0 commit comments