Hash tree is two words

Signed-off-by: Andrew Gunnerson <accounts+github@chiller3.com>
This commit is contained in:
Andrew Gunnerson
2023-09-18 15:13:04 -04:00
parent 9ca3a690df
commit acc3308d37
4 changed files with 27 additions and 25 deletions
+2 -2
View File
@@ -20,7 +20,7 @@ This subcommand shows all of the vbmeta header and footer fields. `vbmeta` parti
avbroot avb verify -i <root vbmeta image> -p <public key>
```
This subcommand verifies the vbmeta header signature and the hashes for all vbmeta descriptors (including hashtree descriptors). If the vbmeta image has a chain descriptor for another partition, that partition image will be verified as well (recursively). All partitions are expected to be in the same directory as the vbmeta image being verified.
This subcommand verifies the vbmeta header signature and the hashes for all vbmeta descriptors (including hash tree descriptors). If the vbmeta image has a chain descriptor for another partition, that partition image will be verified as well (recursively). All partitions are expected to be in the same directory as the vbmeta image being verified.
If `-p` is omitted, the signatures and hashes are checked only for validity, not that they are trusted.
@@ -65,7 +65,7 @@ This set of commands is for working with dm-verity FEC (forward error correction
The same raw FEC data can be stored in several ways:
* cryptsetup's `veritysetup` does not use any file format at all. It must be told the FEC location and parameters using the `--fec-*` options.
* AOSP's AVB 2.0 stores the FEC data inside the partition as `[Partition data][Hashtree][FEC data]`. The location and parameters are stored in the vbmeta hashtree descriptors.
* AOSP's AVB 2.0 stores the FEC data inside the partition as `[Partition data][Hash tree][FEC data]`. The location and parameters are stored in the vbmeta hash tree descriptors.
* AOSP's `fec` tool stores the FEC data in a standalone file with a header containing the FEC parameters.
The `avbroot fec` commands use AOSP's standalone FEC file format.
+7 -5
View File
@@ -34,7 +34,7 @@ fn ensure_name_is_safe(name: &str) -> Result<()> {
/// Recursively verify an image's vbmeta header and all of the chained images.
/// `seen` is used to prevent cycles. `descriptors` will contain all of the hash
/// and hashtree descriptors that need to be verified.
/// and hash tree descriptors that need to be verified.
pub fn verify_headers(
directory: &Path,
name: &str,
@@ -81,7 +81,7 @@ pub fn verify_headers(
};
match descriptor {
avb::Descriptor::Hashtree(_) | avb::Descriptor::Hash(_) => {
avb::Descriptor::HashTree(_) | avb::Descriptor::Hash(_) => {
if let Some(prev) = descriptors.get(target_name) {
if prev != descriptor {
bail!("{name} descriptor does not match previous encounter");
@@ -128,13 +128,15 @@ pub fn verify_descriptors(
};
match descriptor {
Descriptor::Hashtree(d) => {
status!("Verifying hashtree descriptor for: {name}");
Descriptor::HashTree(d) => {
status!("Verifying hash tree descriptor for: {name}");
d.verify(
|| Ok(Box::new(BufReader::new(reader.clone()))),
cancel_signal,
)
.with_context(|| format!("Failed to verify hashtree descriptor for: {name}"))?;
.with_context(|| {
format!("Failed to verify hash tree descriptor for: {name}")
})?;
}
Descriptor::Hash(d) => {
status!("Verifying hash descriptor for: {name}");
+1 -1
View File
@@ -382,7 +382,7 @@ fn update_vbmeta_descriptors(
(Descriptor::Hash(pd), Descriptor::Hash(d)) => {
*pd = d.clone();
}
(Descriptor::Hashtree(pd), Descriptor::Hashtree(d)) => {
(Descriptor::HashTree(pd), Descriptor::HashTree(d)) => {
*pd = d.clone();
}
_ => {
+17 -17
View File
@@ -77,9 +77,9 @@ pub enum Error {
#[error("Expected root digest {expected}, but have {actual}")]
InvalidRootDigest { expected: String, actual: String },
#[error("Expected hash tree {expected}, but have {actual}")]
InvalidHashtree { expected: String, actual: String },
InvalidHashTree { expected: String, actual: String },
#[error("Hash tree does not immediately follow image data")]
HashtreeGap,
HashTreeGap,
#[error("FEC data does not immediately follow hash tree")]
FecDataGap,
#[error("FEC requires data block size ({data}) and hash block size ({hash}) to match")]
@@ -293,7 +293,7 @@ impl<W: Write> ToWriter<W> for PropertyDescriptor {
}
#[derive(Clone, Eq, PartialEq)]
pub struct HashtreeDescriptor {
pub struct HashTreeDescriptor {
pub dm_verity_version: u32,
pub image_size: u64,
pub tree_offset: u64,
@@ -311,9 +311,9 @@ pub struct HashtreeDescriptor {
pub reserved: [u8; 60],
}
impl fmt::Debug for HashtreeDescriptor {
impl fmt::Debug for HashTreeDescriptor {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HashtreeDescriptor")
f.debug_struct("HashTreeDescriptor")
.field("dm_verity_version", &self.dm_verity_version)
.field("image_size", &self.image_size)
.field("tree_offset", &self.tree_offset)
@@ -333,7 +333,7 @@ impl fmt::Debug for HashtreeDescriptor {
}
}
impl HashtreeDescriptor {
impl HashTreeDescriptor {
/// Calculate the hash tree digests for a single level of the tree. If the
/// reader's position is block-aligned and `image_size` is a multiple of the
/// block size, then this function can also be used to calculate the digests
@@ -519,7 +519,7 @@ impl HashtreeDescriptor {
}
if self.tree_offset != self.image_size {
return Err(Error::HashtreeGap);
return Err(Error::HashTreeGap);
}
let mut reader = open_input()?;
@@ -533,7 +533,7 @@ impl HashtreeDescriptor {
let expected = ring::digest::digest(algorithm, &hash_tree);
let actual = ring::digest::digest(algorithm, &actual_hash_tree);
return Err(Error::InvalidHashtree {
return Err(Error::InvalidHashTree {
expected: hex::encode(expected),
actual: hex::encode(actual),
});
@@ -577,11 +577,11 @@ impl HashtreeDescriptor {
}
}
impl DescriptorTag for HashtreeDescriptor {
impl DescriptorTag for HashTreeDescriptor {
const TAG: u64 = 1;
}
impl<R: Read> FromReader<R> for HashtreeDescriptor {
impl<R: Read> FromReader<R> for HashTreeDescriptor {
type Error = Error;
fn from_reader(mut reader: R) -> Result<Self> {
@@ -643,7 +643,7 @@ impl<R: Read> FromReader<R> for HashtreeDescriptor {
}
}
impl<W: Write> ToWriter<W> for HashtreeDescriptor {
impl<W: Write> ToWriter<W> for HashTreeDescriptor {
type Error = Error;
fn to_writer(&self, mut writer: W) -> Result<()> {
@@ -984,7 +984,7 @@ impl<W: Write> ToWriter<W> for ChainPartitionDescriptor {
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Descriptor {
Property(PropertyDescriptor),
Hashtree(HashtreeDescriptor),
HashTree(HashTreeDescriptor),
Hash(HashDescriptor),
KernelCmdline(KernelCmdlineDescriptor),
ChainPartition(ChainPartitionDescriptor),
@@ -994,7 +994,7 @@ pub enum Descriptor {
impl Descriptor {
pub fn partition_name(&self) -> Option<&str> {
match self {
Self::Hashtree(d) => Some(&d.partition_name),
Self::HashTree(d) => Some(&d.partition_name),
Self::Hash(d) => Some(&d.partition_name),
Self::ChainPartition(d) => Some(&d.partition_name),
_ => None,
@@ -1016,9 +1016,9 @@ impl<R: Read> FromReader<R> for Descriptor {
let d = PropertyDescriptor::from_reader(&mut inner_reader)?;
Self::Property(d)
}
HashtreeDescriptor::TAG => {
let d = HashtreeDescriptor::from_reader(&mut inner_reader)?;
Self::Hashtree(d)
HashTreeDescriptor::TAG => {
let d = HashTreeDescriptor::from_reader(&mut inner_reader)?;
Self::HashTree(d)
}
HashDescriptor::TAG => {
let d = HashDescriptor::from_reader(&mut inner_reader)?;
@@ -1064,7 +1064,7 @@ impl<W: Write> ToWriter<W> for Descriptor {
d.to_writer(&mut inner_writer)?;
d.get_tag()
}
Self::Hashtree(d) => {
Self::HashTree(d) => {
d.to_writer(&mut inner_writer)?;
d.get_tag()
}