[avb] Keep Digest reference in avb hash descriptor to avoid copy
Test: atest libpvmfw_avb.integration_test
Bug: 279557218
Change-Id: I82fe78c4389d1b58a6a7ebcd50f1988c91c33d10
diff --git a/pvmfw/avb/src/descriptor/descriptors.rs b/pvmfw/avb/src/descriptor/descriptors.rs
index b577adf..6eaf643 100644
--- a/pvmfw/avb/src/descriptor/descriptors.rs
+++ b/pvmfw/avb/src/descriptor/descriptors.rs
@@ -28,11 +28,11 @@
slice,
};
-pub(super) enum Descriptor {
- Hash(HashDescriptor),
+pub(super) enum Descriptor<'a> {
+ Hash(HashDescriptor<'a>),
}
-impl Descriptor {
+impl<'a> Descriptor<'a> {
/// # Safety
///
/// Behavior is undefined if any of the following conditions are violated:
@@ -119,22 +119,30 @@
Ok(descriptor)
}
-#[derive(Default)]
-pub(crate) struct HashDescriptor {
+pub(crate) struct HashDescriptor<'a> {
pub(crate) partition_name: PartitionName,
- pub(crate) digest: Digest,
+ pub(crate) digest: &'a Digest,
}
-impl HashDescriptor {
- fn new(desc: &HashDescriptorHeader, data: &[u8]) -> utils::Result<Self> {
+impl<'a> Default for HashDescriptor<'a> {
+ fn default() -> Self {
+ Self { partition_name: Default::default(), digest: &Self::EMPTY_DIGEST }
+ }
+}
+
+impl<'a> HashDescriptor<'a> {
+ const EMPTY_DIGEST: Digest = [0u8; 32];
+
+ fn new(desc: &HashDescriptorHeader, data: &'a [u8]) -> utils::Result<Self> {
let partition_name = data
.get(desc.partition_name_range()?)
.ok_or(AvbIOError::RangeOutsidePartition)?
.try_into()?;
- let partition_digest =
- data.get(desc.digest_range()?).ok_or(AvbIOError::RangeOutsidePartition)?;
- let mut digest = [0u8; size_of::<Digest>()];
- digest.copy_from_slice(partition_digest);
+ let digest = data
+ .get(desc.digest_range()?)
+ .ok_or(AvbIOError::RangeOutsidePartition)?
+ .try_into()
+ .map_err(|_| AvbIOError::InvalidValueSize)?;
Ok(Self { partition_name, digest })
}
}
diff --git a/pvmfw/avb/src/descriptor/mod.rs b/pvmfw/avb/src/descriptor/mod.rs
index 67f85d9..3c169bf 100644
--- a/pvmfw/avb/src/descriptor/mod.rs
+++ b/pvmfw/avb/src/descriptor/mod.rs
@@ -32,11 +32,11 @@
/// `Descriptors` can have at most one `HashDescriptor` per known partition and at most one
/// `PropertyDescriptor`.
#[derive(Default)]
-pub(crate) struct Descriptors {
- hash_descriptors: ArrayVec<[HashDescriptor; PartitionName::NUM_OF_KNOWN_PARTITIONS]>,
+pub(crate) struct Descriptors<'a> {
+ hash_descriptors: ArrayVec<[HashDescriptor<'a>; PartitionName::NUM_OF_KNOWN_PARTITIONS]>,
}
-impl Descriptors {
+impl<'a> Descriptors<'a> {
/// Builds `Descriptors` from `AvbVBMetaData`.
/// Returns an error if the given `AvbVBMetaData` contains non-hash descriptor, hash
/// descriptor of unknown `PartitionName` or duplicated hash descriptors.
@@ -80,13 +80,13 @@
.ok_or(AvbSlotVerifyError::InvalidMetadata)
}
- fn push(&mut self, descriptor: Descriptor) -> utils::Result<()> {
+ fn push(&mut self, descriptor: Descriptor<'a>) -> utils::Result<()> {
match descriptor {
Descriptor::Hash(d) => self.push_hash_descriptor(d),
}
}
- fn push_hash_descriptor(&mut self, descriptor: HashDescriptor) -> utils::Result<()> {
+ fn push_hash_descriptor(&mut self, descriptor: HashDescriptor<'a>) -> utils::Result<()> {
if self.hash_descriptors.iter().any(|d| d.partition_name == descriptor.partition_name) {
return Err(AvbIOError::Io);
}
diff --git a/pvmfw/avb/src/verify.rs b/pvmfw/avb/src/verify.rs
index 05a6492..ded0766 100644
--- a/pvmfw/avb/src/verify.rs
+++ b/pvmfw/avb/src/verify.rs
@@ -119,7 +119,7 @@
verify_vbmeta_has_only_one_hash_descriptor(&descriptors)?;
return Ok(VerifiedBootData {
debug_level: DebugLevel::None,
- kernel_digest: kernel_descriptor.digest,
+ kernel_digest: *kernel_descriptor.digest,
initrd_digest: None,
public_key: trusted_public_key,
});
@@ -143,8 +143,8 @@
let initrd_descriptor = descriptors.find_hash_descriptor(initrd_partition_name)?;
Ok(VerifiedBootData {
debug_level,
- kernel_digest: kernel_descriptor.digest,
- initrd_digest: Some(initrd_descriptor.digest),
+ kernel_digest: *kernel_descriptor.digest,
+ initrd_digest: Some(*initrd_descriptor.digest),
public_key: trusted_public_key,
})
}