summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com>2024-05-14 19:28:48 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-05-14 19:28:48 +0000
commita6552305233a2c32dfafea4715b01388e7af074d (patch)
tree408fed810fde5a0f009fa868314e2c47dc42be4f
parent3ff0458db68b2ddd1d6e309088eb1dac19666ebd (diff)
parent957d597fad6f7aecb8ddd108b027da9814296e35 (diff)
downloadsecurity-main.tar.gz
Merge changes from topic "b/338601050" into mainHEADmastermain
* changes: [hwtrust] Add avf field to CSR device info enums Revert "[hwtrust] Add avf field placeholder in CSR device info parser"
-rw-r--r--remote_provisioning/hwtrust/src/cbor/rkp/csr.rs4
-rw-r--r--remote_provisioning/hwtrust/src/cbor/rkp/device_info.rs137
-rw-r--r--remote_provisioning/hwtrust/src/rkp/device_info.rs20
3 files changed, 131 insertions, 30 deletions
diff --git a/remote_provisioning/hwtrust/src/cbor/rkp/csr.rs b/remote_provisioning/hwtrust/src/cbor/rkp/csr.rs
index a93b200..e621756 100644
--- a/remote_provisioning/hwtrust/src/cbor/rkp/csr.rs
+++ b/remote_provisioning/hwtrust/src/cbor/rkp/csr.rs
@@ -226,8 +226,8 @@ pub(crate) mod testutil {
product: "pixel".to_string(),
model: "model".to_string(),
device: "device".to_string(),
- vb_state: Some(DeviceInfoVbState::Green),
- bootloader_state: Some(DeviceInfoBootloaderState::Locked),
+ vb_state: DeviceInfoVbState::Green,
+ bootloader_state: DeviceInfoBootloaderState::Locked,
vbmeta_digest: b"\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff".to_vec(),
os_version: Some("12".to_string()),
system_patch_level: 20221025,
diff --git a/remote_provisioning/hwtrust/src/cbor/rkp/device_info.rs b/remote_provisioning/hwtrust/src/cbor/rkp/device_info.rs
index 4b26a48..09b2eca 100644
--- a/remote_provisioning/hwtrust/src/cbor/rkp/device_info.rs
+++ b/remote_provisioning/hwtrust/src/cbor/rkp/device_info.rs
@@ -1,6 +1,8 @@
use crate::cbor::field_value::FieldValue;
-use crate::rkp::DeviceInfo;
-use anyhow::{bail, Context, Result};
+use crate::rkp::{
+ DeviceInfo, DeviceInfoBootloaderState, DeviceInfoSecurityLevel, DeviceInfoVbState,
+};
+use anyhow::{bail, ensure, Context, Result};
use ciborium::value::Value;
impl DeviceInfo {
@@ -61,23 +63,15 @@ impl DeviceInfo {
Some(s) => Some(s.as_str().try_into()?),
None => None,
};
- let bootloader_state = match bootloader_state.into_optional_string()? {
- Some(s) => Some(s.as_str().try_into()?),
- None => None,
- };
- let vb_state = match vb_state.into_optional_string()? {
- Some(s) => Some(s.as_str().try_into()?),
- None => None,
- };
- Ok(DeviceInfo {
+ let info = DeviceInfo {
brand: brand.into_string()?,
manufacturer: manufacturer.into_string()?,
product: product.into_string()?,
model: model.into_string()?,
device: device.into_string()?,
- vb_state,
- bootloader_state,
+ vb_state: vb_state.into_string()?.as_str().try_into()?,
+ bootloader_state: bootloader_state.into_string()?.as_str().try_into()?,
vbmeta_digest: vbmeta_digest.into_bytes()?,
os_version: os_version.into_optional_string()?,
system_patch_level: system_patch_level.into_u32()?,
@@ -86,16 +80,45 @@ impl DeviceInfo {
security_level,
fused: fused.into_bool()?,
version: version.try_into()?,
- })
+ };
+ info.validate_avf_fields()?;
+ Ok(info)
+ }
+
+ fn validate_avf_fields(&self) -> Result<()> {
+ if Some(DeviceInfoSecurityLevel::Avf) == self.security_level {
+ ensure!(
+ self.bootloader_state == DeviceInfoBootloaderState::Avf
+ && self.vb_state == DeviceInfoVbState::Avf
+ && self.brand == "aosp-avf"
+ && self.device == "avf"
+ && self.model == "avf"
+ && self.manufacturer == "aosp-avf"
+ && self.product == "avf",
+ "AVF security level requires AVF fields. Got: {:?}",
+ self
+ );
+ } else {
+ ensure!(
+ self.bootloader_state != DeviceInfoBootloaderState::Avf
+ && self.vb_state != DeviceInfoVbState::Avf
+ && self.brand != "aosp-avf"
+ && self.device != "avf"
+ && self.model != "avf"
+ && self.manufacturer != "aosp-avf"
+ && self.product != "avf",
+ "Non-AVF security level requires non-AVF fields. Got: {:?}",
+ self
+ );
+ }
+ Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
- use crate::rkp::{
- DeviceInfoBootloaderState, DeviceInfoSecurityLevel, DeviceInfoVbState, DeviceInfoVersion,
- };
+ use crate::rkp::DeviceInfoVersion;
#[test]
fn device_info_from_cbor_values_optional_os_version() {
@@ -121,8 +144,8 @@ mod tests {
product: "phone".to_string(),
model: "the best one".to_string(),
device: "really the best".to_string(),
- vb_state: Some(DeviceInfoVbState::Green),
- bootloader_state: Some(DeviceInfoBootloaderState::Locked),
+ vb_state: DeviceInfoVbState::Green,
+ bootloader_state: DeviceInfoBootloaderState::Locked,
vbmeta_digest: b"abcdefg".to_vec(),
os_version: Some("dessert".to_string()),
system_patch_level: 303010,
@@ -145,8 +168,8 @@ mod tests {
product: "phone".to_string(),
model: "the best one".to_string(),
device: "really the best".to_string(),
- vb_state: Some(DeviceInfoVbState::Green),
- bootloader_state: Some(DeviceInfoBootloaderState::Locked),
+ vb_state: DeviceInfoVbState::Green,
+ bootloader_state: DeviceInfoBootloaderState::Locked,
vbmeta_digest: b"abcdefg".to_vec(),
os_version: Some("dessert".to_string()),
system_patch_level: 303010,
@@ -201,6 +224,59 @@ mod tests {
assert!(err.to_string().contains("may be set only once"));
}
+ #[test]
+ fn device_info_from_cbor_values_non_avf_security_level_has_avf_vb_state() {
+ let mut values = get_valid_values_filtered(|x| x != "vb_state");
+ values.push(("vb_state".into(), "avf".into()));
+
+ let err = DeviceInfo::from_cbor_values(values, None).unwrap_err();
+ assert!(err.to_string().contains("Non-AVF security level"), "{err:?}");
+ }
+
+ #[test]
+ fn device_info_from_cbor_values_non_avf_security_level_has_avf_bootloader_state() {
+ let mut values = get_valid_values_filtered(|x| x != "bootloader_state");
+ values.push(("bootloader_state".into(), "avf".into()));
+
+ let err = DeviceInfo::from_cbor_values(values, None).unwrap_err();
+ assert!(err.to_string().contains("Non-AVF security level"), "{err:?}");
+ }
+
+ #[test]
+ fn device_info_from_cbor_values_avf_security_level_has_non_avf_vb_state() {
+ let values: Vec<(Value, Value)> = get_valid_avf_values()
+ .into_iter()
+ .filter(|(k, _v)| k.as_text().unwrap() != "vb_state")
+ .chain(vec![("vb_state".into(), "green".into())])
+ .collect();
+ let err = DeviceInfo::from_cbor_values(values, Some(3)).unwrap_err();
+ assert!(err.to_string().contains("AVF security level requires AVF fields"), "{err:?}");
+ }
+
+ #[test]
+ fn device_info_from_cbor_values_avf_security_level_has_avf_fields() {
+ let values = get_valid_avf_values();
+ let actual = DeviceInfo::from_cbor_values(values, Some(3)).unwrap();
+ let expected = DeviceInfo {
+ brand: "aosp-avf".to_string(),
+ manufacturer: "aosp-avf".to_string(),
+ product: "avf".to_string(),
+ model: "avf".to_string(),
+ device: "avf".to_string(),
+ vb_state: DeviceInfoVbState::Avf,
+ bootloader_state: DeviceInfoBootloaderState::Avf,
+ vbmeta_digest: b"abcdefg".to_vec(),
+ os_version: Some("dessert".to_string()),
+ system_patch_level: 303010,
+ boot_patch_level: 30300102,
+ vendor_patch_level: 30300304,
+ security_level: Some(DeviceInfoSecurityLevel::Avf),
+ fused: true,
+ version: DeviceInfoVersion::V3,
+ };
+ assert_eq!(expected, actual);
+ }
+
fn get_valid_values() -> Vec<(Value, Value)> {
vec![
("brand".into(), "generic".into()),
@@ -221,6 +297,25 @@ mod tests {
]
}
+ fn get_valid_avf_values() -> Vec<(Value, Value)> {
+ vec![
+ ("brand".into(), "aosp-avf".into()),
+ ("manufacturer".into(), "aosp-avf".into()),
+ ("product".into(), "avf".into()),
+ ("model".into(), "avf".into()),
+ ("device".into(), "avf".into()),
+ ("vb_state".into(), "avf".into()),
+ ("bootloader_state".into(), "avf".into()),
+ ("vbmeta_digest".into(), b"abcdefg".as_ref().into()),
+ ("os_version".into(), "dessert".into()),
+ ("system_patch_level".into(), 303010.into()),
+ ("boot_patch_level".into(), 30300102.into()),
+ ("vendor_patch_level".into(), 30300304.into()),
+ ("security_level".into(), "avf".into()),
+ ("fused".into(), 1.into()),
+ ]
+ }
+
fn get_valid_values_filtered<F: Fn(&str) -> bool>(filter: F) -> Vec<(Value, Value)> {
get_valid_values().into_iter().filter(|x| filter(x.0.as_text().unwrap())).collect()
}
diff --git a/remote_provisioning/hwtrust/src/rkp/device_info.rs b/remote_provisioning/hwtrust/src/rkp/device_info.rs
index a6fce2b..c99f74d 100644
--- a/remote_provisioning/hwtrust/src/rkp/device_info.rs
+++ b/remote_provisioning/hwtrust/src/rkp/device_info.rs
@@ -22,9 +22,9 @@ pub struct DeviceInfo {
/// the same underlying device.
pub device: String,
/// Verified boot state.
- pub vb_state: Option<DeviceInfoVbState>,
+ pub vb_state: DeviceInfoVbState,
/// Whether the bootloader is locked or not.
- pub bootloader_state: Option<DeviceInfoBootloaderState>,
+ pub bootloader_state: DeviceInfoBootloaderState,
/// Digest of the verified boot metadata structures.
pub vbmeta_digest: Vec<u8>,
/// Partner-defined operating system version.
@@ -45,9 +45,6 @@ impl fmt::Debug for DeviceInfo {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let security_level: &dyn fmt::Debug = self.security_level.as_ref().map_or(&"<none>", |s| s);
let os_version: &dyn fmt::Debug = self.os_version.as_ref().map_or(&"<none>", |v| v);
- let bootloader_state: &dyn fmt::Debug =
- self.bootloader_state.as_ref().map_or(&"<none>", |v| v);
- let vb_state: &dyn fmt::Debug = self.vb_state.as_ref().map_or(&"<none>", |v| v);
fmt.debug_struct("DeviceInfo")
.field("version", &self.version)
@@ -56,8 +53,8 @@ impl fmt::Debug for DeviceInfo {
.field("product", &self.product)
.field("model", &self.model)
.field("device", &self.device)
- .field("vb_state", vb_state)
- .field("bootloader_state", bootloader_state)
+ .field("vb_state", &self.vb_state)
+ .field("bootloader_state", &self.bootloader_state)
.field("vbmeta_digest", &hex::encode(&self.vbmeta_digest))
.field("os_version", os_version)
.field("system_patch_level", &self.system_patch_level)
@@ -76,6 +73,8 @@ pub enum DeviceInfoBootloaderState {
Locked,
/// The bootloader will load arbitrary images.
Unlocked,
+ /// This field is a placeholder for the AVF backend.
+ Avf,
}
impl TryFrom<&str> for DeviceInfoBootloaderState {
@@ -85,6 +84,7 @@ impl TryFrom<&str> for DeviceInfoBootloaderState {
match s.to_ascii_lowercase().as_str() {
"locked" => Ok(Self::Locked),
"unlocked" => Ok(Self::Unlocked),
+ "avf" => Ok(Self::Avf),
_ => Err(anyhow!("Invalid bootloader state: `{s}`")),
}
}
@@ -99,6 +99,8 @@ pub enum DeviceInfoVbState {
Yellow,
/// The bootloader is unlocked, and no guarantees of image integrity are available.
Orange,
+ /// This field is a placeholder for the AVF backend.
+ Avf,
}
impl TryFrom<&str> for DeviceInfoVbState {
@@ -109,6 +111,7 @@ impl TryFrom<&str> for DeviceInfoVbState {
"green" => Ok(Self::Green),
"yellow" => Ok(Self::Yellow),
"orange" => Ok(Self::Orange),
+ "avf" => Ok(Self::Avf),
_ => Err(anyhow!("Invalid VB state: `{s}`")),
}
}
@@ -142,6 +145,8 @@ pub enum DeviceInfoSecurityLevel {
Tee,
/// KeyMint's backend runs in a Secure Element.
StrongBox,
+ /// AVF's backend.
+ Avf,
}
impl TryFrom<&str> for DeviceInfoSecurityLevel {
@@ -151,6 +156,7 @@ impl TryFrom<&str> for DeviceInfoSecurityLevel {
match s.to_ascii_lowercase().as_str() {
"strongbox" => Ok(Self::StrongBox),
"tee" => Ok(Self::Tee),
+ "avf" => Ok(Self::Avf),
_ => Err(anyhow!("Invalid security level: `{s}`")),
}
}