From a648df1695cdb7d5869ed0242bdf488554ccb61a Mon Sep 17 00:00:00 2001 From: Andrew Gunnerson Date: Wed, 22 Nov 2023 18:37:23 -0500 Subject: [PATCH] avb: Add support for AVB 2.0 format 1.3.0 Format version 1.3.0 adds a new 32-bit big endian `flags` field to chain descriptors, carved out from the `reserved` array. There is only one possible flag, which indicates that the target partition is not A/B and so the bootloader should not append the `_a` or `_b` suffix. There are no known AVB images in the wild where the first four bytes of the `reserved` field are not zero. Thus, to keep the logic simple, the AVB parser will unconditionally parse those bytes as if they were the `flags` field, regardless of the file format version. AOSP changes: * https://android.googlesource.com/platform/external/avb/+/a1fe228b86543a21739c51352f5ce72f134fccfa%5E%21/ * https://android.googlesource.com/platform/external/avb/+/d00d02c390e267ef43d93562864dd6e45966c435%5E%21/ Signed-off-by: Andrew Gunnerson --- avbroot/src/format/avb.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/avbroot/src/format/avb.rs b/avbroot/src/format/avb.rs index d98f9f4..390e76e 100644 --- a/avbroot/src/format/avb.rs +++ b/avbroot/src/format/avb.rs @@ -35,7 +35,7 @@ use crate::{ }; pub const VERSION_MAJOR: u32 = 1; -pub const VERSION_MINOR: u32 = 2; +pub const VERSION_MINOR: u32 = 3; pub const VERSION_SUB: u32 = 0; pub const FOOTER_VERSION_MAJOR: u32 = 1; @@ -1109,8 +1109,13 @@ pub struct ChainPartitionDescriptor { pub partition_name: String, #[serde(with = "hex")] pub public_key: Vec, + pub flags: u32, #[serde(with = "hex")] - pub reserved: [u8; 64], + pub reserved: [u8; 60], +} + +impl ChainPartitionDescriptor { + pub const FLAG_DO_NOT_USE_AB: u32 = 1 << 0; } impl fmt::Debug for ChainPartitionDescriptor { @@ -1119,6 +1124,7 @@ impl fmt::Debug for ChainPartitionDescriptor { .field("rollback_index_location", &self.rollback_index_location) .field("partition_name", &self.partition_name) .field("public_key", &hex::encode(&self.public_key)) + .field("flags", &self.flags) .field("reserved", &hex::encode(self.reserved)) .finish() } @@ -1142,7 +1148,9 @@ impl FromReader for ChainPartitionDescriptor { return Err(Error::FieldOutOfBounds("public_key_len")); } - let mut reserved = [0u8; 64]; + let flags = reader.read_u32::()?; + + let mut reserved = [0u8; 60]; reader.read_exact(&mut reserved)?; // Not NULL-terminated. @@ -1157,6 +1165,7 @@ impl FromReader for ChainPartitionDescriptor { rollback_index_location, partition_name, public_key, + flags, reserved, }; @@ -1177,6 +1186,7 @@ impl ToWriter for ChainPartitionDescriptor { writer.write_u32::(self.rollback_index_location)?; writer.write_u32::(self.partition_name.len() as u32)?; writer.write_u32::(self.public_key.len() as u32)?; + writer.write_u32::(self.flags)?; writer.write_all(&self.reserved)?; writer.write_all(self.partition_name.as_bytes())?; writer.write_all(&self.public_key)?;