Add util methods to get payload vbmeta image hash
The methods will be used later to build avmdtool.
Test: libapexutil_rust.test
Change-Id: I28bde2f57cb2c4e05f4cd4be5abf52cb6f788003
diff --git a/libs/apexutil/src/lib.rs b/libs/apexutil/src/lib.rs
index 63b09de..1183aea 100644
--- a/libs/apexutil/src/lib.rs
+++ b/libs/apexutil/src/lib.rs
@@ -93,6 +93,19 @@
Err(ApexParseError::DescriptorNotHashtree)
}
+/// Gets the hash of the payload's verified VBMeta image data.
+pub fn get_payload_vbmeta_image_hash(path: &str) -> Result<Vec<u8>, ApexVerificationError> {
+ let apex_file = File::open(path).map_err(ApexParseError::Io)?;
+ let (_, offset, size) = get_public_key_and_image_info(&apex_file)?;
+ let vbmeta = VbMetaImage::verify_reader_region(apex_file, offset, size)?;
+ Ok(vbmeta.hash().ok_or(ApexVerificationError::ApexPubkeyMistmatch)?.to_vec())
+}
+
+/// Converts the buffer to a Hex String
+pub fn to_hex_string(buf: &[u8]) -> String {
+ buf.iter().map(|b| format!("{:02x}", b)).collect()
+}
+
fn get_public_key_and_image_info(apex_file: &File) -> Result<(Vec<u8>, u64, u64), ApexParseError> {
let mut z = ZipArchive::new(apex_file).map_err(|err| match err {
ZipError::Io(err) => ApexParseError::Io(err),
@@ -130,9 +143,7 @@
#[cfg(test)]
mod tests {
use super::*;
- fn to_hex_string(buf: &[u8]) -> String {
- buf.iter().map(|b| format!("{:02x}", b)).collect()
- }
+
#[test]
fn test_open_apex() {
let res = verify("tests/data/test.apex").unwrap();
@@ -141,4 +152,13 @@
"fe11ab17da0a3a738b54bdc3a13f6139cbdf91ec32f001f8d4bbbf8938e04e39"
);
}
+
+ #[test]
+ fn test_payload_vbmeta_image_hash() {
+ let result = get_payload_vbmeta_image_hash("tests/data/test.apex").unwrap();
+ assert_eq!(
+ to_hex_string(&result),
+ "296e32a76544de9da01713e471403ab4667705ad527bb4f1fac0cf61e7ce122d"
+ );
+ }
}
diff --git a/libs/vbmeta/src/lib.rs b/libs/vbmeta/src/lib.rs
index 2d3463c..887844c 100644
--- a/libs/vbmeta/src/lib.rs
+++ b/libs/vbmeta/src/lib.rs
@@ -138,6 +138,18 @@
Some(&self.data[begin..end])
}
+ /// Get the hash of the verified data in the VBMeta image from the authentication block. If the
+ /// image was not signed, there might not be a hash and, if there is, it's not known to be
+ /// correct.
+ pub fn hash(&self) -> Option<&[u8]> {
+ if self.header.algorithm_type == AvbAlgorithmType_AVB_ALGORITHM_TYPE_NONE {
+ return None;
+ }
+ let begin = size_of::<AvbVBMetaImageHeader>() + self.header.hash_offset as usize;
+ let end = begin + self.header.hash_size as usize;
+ Some(&self.data[begin..end])
+ }
+
/// Get the descriptors of the VBMeta image.
pub fn descriptors(&self) -> Result<Descriptors<'_>, VbMetaImageParseError> {
Descriptors::from_image(&self.data)