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) {