Merge "vmbase: Trivial changes to prepare for smccc::trng" into main
diff --git a/vmbase/src/hvc.rs b/vmbase/src/hvc.rs
index 4d489d5..ebd1625 100644
--- a/vmbase/src/hvc.rs
+++ b/vmbase/src/hvc.rs
@@ -30,11 +30,11 @@
pub const ARM_SMCCC_TRNG_RND64: u32 = 0xc400_0053;
/// Returns the (major, minor) version tuple, as defined by the SMCCC TRNG.
-pub fn trng_version() -> trng::Result<(u16, u16)> {
+pub fn trng_version() -> trng::Result<trng::Version> {
let args = [0u64; 17];
let version = positive_or_error_64::<Error>(hvc64(ARM_SMCCC_TRNG_VERSION, args)[0])?;
- Ok(((version >> 16) as u16, version as u16))
+ (version as u32 as i32).try_into()
}
pub type TrngRng64Entropy = (u64, u64, u64);
diff --git a/vmbase/src/hvc/trng.rs b/vmbase/src/hvc/trng.rs
index 1a27d64..efb86f6 100644
--- a/vmbase/src/hvc/trng.rs
+++ b/vmbase/src/hvc/trng.rs
@@ -55,3 +55,40 @@
}
pub type Result<T> = result::Result<T, Error>;
+
+/// A version of the SMCCC TRNG interface.
+#[derive(Copy, Clone, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Version {
+ pub major: u16,
+ pub minor: u16,
+}
+
+impl fmt::Display for Version {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "{}.{}", self.major, self.minor)
+ }
+}
+
+impl fmt::Debug for Version {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Display::fmt(self, f)
+ }
+}
+
+impl TryFrom<i32> for Version {
+ type Error = Error;
+
+ fn try_from(value: i32) -> core::result::Result<Self, Error> {
+ if value < 0 {
+ Err((value as i64).into())
+ } else {
+ Ok(Self { major: (value >> 16) as u16, minor: value as u16 })
+ }
+ }
+}
+
+impl From<Version> for u32 {
+ fn from(version: Version) -> Self {
+ (u32::from(version.major) << 16) | u32::from(version.minor)
+ }
+}
diff --git a/vmbase/src/rand.rs b/vmbase/src/rand.rs
index a5a5f5f..6b8d7e0 100644
--- a/vmbase/src/rand.rs
+++ b/vmbase/src/rand.rs
@@ -14,7 +14,7 @@
//! Functions and drivers for obtaining true entropy.
-use crate::hvc;
+use crate::hvc::{self, TrngRng64Entropy};
use core::fmt;
use core::mem::size_of;
use smccc::{self, Hvc};
@@ -30,7 +30,7 @@
/// Unsupported SMCCC version.
UnsupportedSmcccVersion(smccc::arch::Version),
/// Unsupported SMCCC TRNG version.
- UnsupportedVersion((u16, u16)),
+ UnsupportedTrngVersion(hvc::trng::Version),
}
impl From<smccc::arch::Error> for Error {
@@ -55,9 +55,7 @@
Self::Smccc(e) => write!(f, "Architectural SMCCC error: {e}"),
Self::Trng(e) => write!(f, "SMCCC TRNG error: {e}"),
Self::UnsupportedSmcccVersion(v) => write!(f, "Unsupported SMCCC version {v}"),
- Self::UnsupportedVersion((x, y)) => {
- write!(f, "Unsupported SMCCC TRNG version v{x}.{y}")
- }
+ Self::UnsupportedTrngVersion(v) => write!(f, "Unsupported SMCCC TRNG version {v}"),
}
}
}
@@ -78,8 +76,8 @@
// TRNG_RND requires SMCCC TRNG v1.0.
match hvc::trng_version()? {
- (1, _) => (),
- version => return Err(Error::UnsupportedVersion(version)),
+ hvc::trng::Version { major: 1, minor: _ } => (),
+ version => return Err(Error::UnsupportedTrngVersion(version)),
}
// TRNG_RND64 doesn't define any special capabilities so ignore the successful result.
@@ -97,7 +95,7 @@
/// Fills a slice of bytes with true entropy.
pub fn fill_with_entropy(s: &mut [u8]) -> Result<()> {
- const MAX_BYTES_PER_CALL: usize = size_of::<hvc::TrngRng64Entropy>();
+ const MAX_BYTES_PER_CALL: usize = size_of::<TrngRng64Entropy>();
let (aligned, remainder) = s.split_at_mut(s.len() - s.len() % MAX_BYTES_PER_CALL);
@@ -125,13 +123,14 @@
Ok(())
}
-fn repeat_trng_rnd(n_bytes: usize) -> hvc::trng::Result<hvc::TrngRng64Entropy> {
+fn repeat_trng_rnd(n_bytes: usize) -> Result<TrngRng64Entropy> {
let bits = usize::try_from(u8::BITS).unwrap();
let n_bits = (n_bytes * bits).try_into().unwrap();
loop {
match hvc::trng_rnd64(n_bits) {
- Err(hvc::trng::Error::NoEntropy) => continue,
- res => return res,
+ Ok(entropy) => return Ok(entropy),
+ Err(hvc::trng::Error::NoEntropy) => (),
+ Err(e) => return Err(e.into()),
}
}
}