Merge "Require security version from the android.16 profile" into main am: be22437692
Original change: https://android-review.googlesource.com/c/platform/tools/security/+/2765488
Change-Id: Ie77b5445a179cfd2496d2a0b57f6fd7090f09bf4
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/remote_provisioning/hwtrust/src/cbor/dice/entry.rs b/remote_provisioning/hwtrust/src/cbor/dice/entry.rs
index 9d01f7c..fc4c374 100644
--- a/remote_provisioning/hwtrust/src/cbor/dice/entry.rs
+++ b/remote_provisioning/hwtrust/src/cbor/dice/entry.rs
@@ -339,13 +339,20 @@
let extensions =
extensions.into_iter().map(|(k, v)| (k.to_string(), format!("{v:?}"))).collect();
+ let security_version = if profile.security_version_optional {
+ security_version.into_optional_u64()
+ } else {
+ security_version.into_u64().map(Some)
+ }
+ .context("Security version")?;
+
Ok(ConfigDescBuilder::new()
.component_name(component_name.into_optional_string().context("Component name")?)
.component_version(
validate_version(profile, component_version).context("Component version")?,
)
.resettable(resettable.is_null().context("Resettable")?)
- .security_version(security_version.into_optional_u64().context("Security version")?)
+ .security_version(security_version)
.extensions(extensions)
.build())
}
@@ -727,7 +734,9 @@
#[test]
fn config_desc_component_version_string() {
let mut fields = valid_payload_fields();
- let config_desc = serialize(cbor!({COMPONENT_VERSION => "It's version 4"}).unwrap());
+ let config_desc = serialize(
+ cbor!({COMPONENT_VERSION => "It's version 4", SECURITY_VERSION => 99999999}).unwrap(),
+ );
let config_hash = sha512(&config_desc).to_vec();
fields.insert(CONFIG_DESC, Value::Bytes(config_desc));
fields.insert(CONFIG_HASH, Value::Bytes(config_hash));
@@ -746,7 +755,7 @@
#[test]
fn config_desc_security_version() {
let mut fields = valid_payload_fields();
- let config_desc = serialize(cbor!({SECURITY_VERSION => Value::from(0x12345678)}).unwrap());
+ let config_desc = serialize(cbor!({SECURITY_VERSION => 0x12345678}).unwrap());
let config_hash = sha512(&config_desc).to_vec();
fields.insert(CONFIG_DESC, Value::Bytes(config_desc));
fields.insert(CONFIG_HASH, Value::Bytes(config_hash));
@@ -757,6 +766,21 @@
}
#[test]
+ fn config_desc_security_version_omitted() {
+ let mut fields = valid_payload_fields();
+ let config_desc = serialize(cbor!({}).unwrap());
+ let config_hash = sha512(&config_desc).to_vec();
+ fields.insert(CONFIG_DESC, Value::Bytes(config_desc));
+ fields.insert(CONFIG_HASH, Value::Bytes(config_hash));
+ let entries = encode_fields(fields);
+ Payload::from_entries(&Profile::default(), entries.clone(), ConfigFormat::Android)
+ .unwrap_err();
+ let profile = Profile { security_version_optional: true, ..Profile::default() };
+ let payload = Payload::from_entries(&profile, entries, ConfigFormat::Android).unwrap();
+ assert_eq!(payload.config_desc().security_version(), None);
+ }
+
+ #[test]
fn config_desc_security_version_fixed_size_encoding() {
let mut fields = valid_payload_fields();
let config_desc = vec![
@@ -921,7 +945,9 @@
fn valid_payload_fields() -> HashMap<i64, Value> {
let key = PrivateKey::from_pem(ED25519_KEY_PEM[0]).public_key();
let subject_public_key = key.to_cose_key().unwrap().to_vec().unwrap();
- let config_desc = serialize(cbor!({COMPONENT_NAME => "component name"}).unwrap());
+ let config_desc = serialize(
+ cbor!({COMPONENT_NAME => "component name", SECURITY_VERSION => 1234}).unwrap(),
+ );
let config_hash = sha512(&config_desc).to_vec();
HashMap::from([
(ISS, Value::from("issuer")),
diff --git a/remote_provisioning/hwtrust/src/cbor/dice/profile.rs b/remote_provisioning/hwtrust/src/cbor/dice/profile.rs
index 308cd72..de28d3f 100644
--- a/remote_provisioning/hwtrust/src/cbor/dice/profile.rs
+++ b/remote_provisioning/hwtrust/src/cbor/dice/profile.rs
@@ -31,6 +31,9 @@
/// descriptor. This allows for compatibility with early versions of the RKP HAL which did not
/// enforce the requirements on the configuration hash as defined by the Open Profile for DICE.
pub(super) config_hash_unverified: bool,
+
+ /// Whether the security version is a required field in the configuration descriptor.
+ pub(super) security_version_optional: bool,
}
/// Type allowed for the DICE certificate mode field.
@@ -63,6 +66,7 @@
// Context: b/273552826
component_version_type: ComponentVersionType::Int,
config_hash_unverified: true,
+ security_version_optional: true,
..Self::default()
}
}
@@ -74,13 +78,14 @@
mode_type: ModeType::IntOrBytes,
allow_big_endian_key_usage: true,
config_hash_unverified: true,
+ security_version_optional: true,
..Self::default()
}
}
/// The rules for the "android.15" profile.
pub(super) fn android15() -> Self {
- Self { config_hash_unverified: true, ..Self::default() }
+ Self { config_hash_unverified: true, security_version_optional: true, ..Self::default() }
}
/// The rules for the "android.16" profile..
diff --git a/remote_provisioning/hwtrust/src/cbor/field_value.rs b/remote_provisioning/hwtrust/src/cbor/field_value.rs
index ecb2ba5..fb25f86 100644
--- a/remote_provisioning/hwtrust/src/cbor/field_value.rs
+++ b/remote_provisioning/hwtrust/src/cbor/field_value.rs
@@ -214,6 +214,10 @@
.transpose()
}
+ pub fn into_u64(self) -> Result<u64, FieldValueError> {
+ require_present(self.name, self.into_optional_u64())
+ }
+
pub fn into_optional_u64(self) -> Result<Option<u64>, FieldValueError> {
self.value
.map(|v| {