Add support for FEC in hashtrees.
This change adds support for 'avbtool add_hashtree_footer' options
--generate_fec and --fec_num_roots. If used, this generates FEC data on
the given image. If used on the root filesystem, the kernel command-line
will be set up to use it. For more information about FEC, see
https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity
By default this feature is not turned on. It can be enabled for the root
filesystem by adding this line
BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS := --generate_fec
to the build system files.
Note that this change extends the AvbHashtreeDescriptor struct to carry
FEC-related metadata. This change would normally be a no-no (since we're
changing metadata stored on disk!) but since AVB isn't yet used in
device firmware - or even undergone a release (see Issue 32414650) -
this change is considered to be OK.
Test: New unit tests + unit tests pass.
Test: Manually tested in qemu using an UEFI-based bootloader.
Bug: 31263832
Change-Id: I271956112c0fe52f57e3a66c0d0658e6b5266239
diff --git a/test/avb_util_unittest.cc b/test/avb_util_unittest.cc
index b65e5ba..1e4bada 100644
--- a/test/avb_util_unittest.cc
+++ b/test/avb_util_unittest.cc
@@ -139,8 +139,8 @@
uint32_t n32;
uint64_t n64;
- // Specify 40 bytes of data past the end of the descriptor struct.
- nbf = 40 + sizeof(AvbHashtreeDescriptor) - sizeof(AvbDescriptor);
+ // Specify 44 bytes of data past the end of the descriptor struct.
+ nbf = 44 + sizeof(AvbHashtreeDescriptor) - sizeof(AvbDescriptor);
h.parent_descriptor.num_bytes_following = htobe64(nbf);
h.parent_descriptor.tag = htobe64(AVB_DESCRIPTOR_TAG_HASHTREE);
h.partition_name_len = htobe32(10);
@@ -162,8 +162,14 @@
n32++;
h.hash_block_size = htobe32(n32);
n32++;
+ h.fec_num_roots = htobe32(n32);
+ n32++;
+ h.fec_offset = htobe64(n64);
+ n64++;
+ h.fec_size = htobe64(n64);
+ n64++;
- EXPECT_NE(0, avb_hashtree_descriptor_validate_and_byteswap(&h, &s));
+ EXPECT_TRUE(avb_hashtree_descriptor_validate_and_byteswap(&h, &s));
n32 = 0x11223344;
n64 = 0x1122334455667788;
@@ -180,6 +186,12 @@
n32++;
EXPECT_EQ(n32, s.hash_block_size);
n32++;
+ EXPECT_EQ(n32, s.fec_num_roots);
+ n32++;
+ EXPECT_EQ(n64, s.fec_offset);
+ n64++;
+ EXPECT_EQ(n64, s.fec_size);
+ n64++;
EXPECT_EQ(AVB_DESCRIPTOR_TAG_HASHTREE, s.parent_descriptor.tag);
EXPECT_EQ(nbf, s.parent_descriptor.num_bytes_following);
@@ -190,22 +202,22 @@
// Check for bad tag.
bad = h;
bad.parent_descriptor.tag = htobe64(0xf00dd00d);
- EXPECT_EQ(0, avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
+ EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
- // Doesn't fit in 40 bytes (30 + 10 + 10 = 50).
+ // Doesn't fit in 44 bytes (30 + 10 + 10 = 50).
bad = h;
bad.partition_name_len = htobe32(30);
- EXPECT_EQ(0, avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
+ EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
- // Doesn't fit in 40 bytes (10 + 30 + 10 = 50).
+ // Doesn't fit in 44 bytes (10 + 30 + 10 = 50).
bad = h;
bad.salt_len = htobe32(30);
- EXPECT_EQ(0, avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
+ EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
- // Doesn't fit in 40 bytes (10 + 10 + 30 = 50).
+ // Doesn't fit in 44 bytes (10 + 10 + 30 = 50).
bad = h;
bad.root_digest_len = htobe32(30);
- EXPECT_EQ(0, avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
+ EXPECT_FALSE(avb_hashtree_descriptor_validate_and_byteswap(&bad, &s));
}
TEST(UtilTest, HashDescriptorByteswap) {