• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Functions and drivers for obtaining true entropy.
16 
17 use crate::arch::rand::{platform_entropy, PlatformError, MAX_BYTES_PER_CALL};
18 use core::fmt;
19 
20 pub(crate) type Entropy = [u8; MAX_BYTES_PER_CALL];
21 
22 /// Error type for rand operations.
23 pub enum Error {
24     /// No source of entropy found.
25     NoEntropySource,
26 
27     /// Platform specific error
28     Platform(PlatformError),
29 }
30 
31 impl From<PlatformError> for Error {
from(e: PlatformError) -> Self32     fn from(e: PlatformError) -> Self {
33         Error::Platform(e)
34     }
35 }
36 
37 /// Result type for rand operations.
38 pub type Result<T> = core::result::Result<T, Error>;
39 
40 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result41     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42         match self {
43             Self::NoEntropySource => write!(f, "No source of entropy available"),
44             Self::Platform(e) => write!(f, "Platform error: {e}"),
45         }
46     }
47 }
48 
49 impl fmt::Debug for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result50     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51         write!(f, "{self}")
52     }
53 }
54 
55 /// Fills a slice of bytes with true entropy.
fill_with_entropy(s: &mut [u8]) -> Result<()>56 pub fn fill_with_entropy(s: &mut [u8]) -> Result<()> {
57     for chunk in s.chunks_mut(MAX_BYTES_PER_CALL) {
58         let entropy = platform_entropy(chunk.len())?;
59         chunk.clone_from_slice(&entropy[..chunk.len()]);
60     }
61 
62     Ok(())
63 }
64 
65 /// Generate an array of fixed-size initialized with true-random bytes.
random_array<const N: usize>() -> Result<[u8; N]>66 pub fn random_array<const N: usize>() -> Result<[u8; N]> {
67     let mut arr = [0; N];
68     fill_with_entropy(&mut arr)?;
69     Ok(arr)
70 }
71