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