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 <accounts+github@chiller3.com>
This commit is contained in:
Andrew Gunnerson
2023-11-22 18:37:23 -05:00
parent a7c872be3e
commit a648df1695
+13 -3
View File
@@ -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<u8>,
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<R: Read> FromReader<R> for ChainPartitionDescriptor {
return Err(Error::FieldOutOfBounds("public_key_len"));
}
let mut reserved = [0u8; 64];
let flags = reader.read_u32::<BigEndian>()?;
let mut reserved = [0u8; 60];
reader.read_exact(&mut reserved)?;
// Not NULL-terminated.
@@ -1157,6 +1165,7 @@ impl<R: Read> FromReader<R> for ChainPartitionDescriptor {
rollback_index_location,
partition_name,
public_key,
flags,
reserved,
};
@@ -1177,6 +1186,7 @@ impl<W: Write> ToWriter<W> for ChainPartitionDescriptor {
writer.write_u32::<BigEndian>(self.rollback_index_location)?;
writer.write_u32::<BigEndian>(self.partition_name.len() as u32)?;
writer.write_u32::<BigEndian>(self.public_key.len() as u32)?;
writer.write_u32::<BigEndian>(self.flags)?;
writer.write_all(&self.reserved)?;
writer.write_all(self.partition_name.as_bytes())?;
writer.write_all(&self.public_key)?;