LAKITU:chromiumos-overlay:verity: Add support for new dm-verity format.

Add patch to verity tool to support the dm-verity format.

BUG=b/215387349
TEST=presubmit,validation
RELEASE_NOTE=None

Change-Id: I0949a3f4a8b79b762085ed1e4867732416dc644f
Reviewed-on: https://cos-review.googlesource.com/c/third_party/overlays/chromiumos-overlay/+/37268
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com>
diff --git a/chromeos-base/verity/files/support-new-dm-verity-format.patch b/chromeos-base/verity/files/support-new-dm-verity-format.patch
new file mode 100644
index 0000000..fe899bf
--- /dev/null
+++ b/chromeos-base/verity/files/support-new-dm-verity-format.patch
@@ -0,0 +1,186 @@
+From 892e42a06f570fdb0c968f645d131ba26b5e5a22 Mon Sep 17 00:00:00 2001
+From: Meena Shanmugam <meenashanmugam@google.com>
+Date: Mon, 10 Oct 2022 00:32:50 +0000
+Subject: [PATCH] LAKITU:verity: Add support to print new and old dm-verity
+ format.
+
+Current verity tool returns old dm-verity format. COS plan to use the
+new dm verity format in the upcoming release. Added a version option to
+specify the dm verity format. If no option is given, it returns old
+format by default. Once the patch is upstreamed and SDK tool is updated
+with this option, this patch can be removed.
+
+Change-Id: If21c2d164c1cd0bede24d551e32ae71b8293eead
+---
+ verity/file_hasher.cc | 54 +++++++++++++++++++++++++++++++------------
+ verity/file_hasher.h  |  4 ++--
+ verity/verity_main.cc | 21 +++++++++++++----
+ 3 files changed, 57 insertions(+), 22 deletions(-)
+
+diff --git a/verity/file_hasher.cc b/verity/file_hasher.cc
+index fae04f817c..25ea3a3b3f 100644
+--- a/verity/file_hasher.cc
++++ b/verity/file_hasher.cc
+@@ -146,7 +146,8 @@ const char* FileHasher::RandomSalt() {
+   return random_salt_;
+ }
+ 
+-std::string FileHasher::GetTable(bool colocated) {
++std::string FileHasher::GetTable(bool colocated,
++                                 unsigned int version) {
+   // Grab the digest (up to 1kbit supported)
+   uint8_t digest[128];
+   char hexsalt[DM_BHT_SALT_SIZE * 2 + 1];
+@@ -161,24 +162,47 @@ std::string FileHasher::GetTable(bool colocated) {
+   if (colocated)
+     hash_start = root_end;
+ 
+-  std::vector<std::string> parts = {
+-      "0",
+-      base::NumberToString(root_end),
+-      "verity",
+-      "payload=ROOT_DEV",
+-      "hashtree=HASH_DEV",
+-      "hashstart=" + base::NumberToString(hash_start),
+-      "alg=" + std::string(alg_),
+-      "root_hexdigest=" + std::string(reinterpret_cast<char*>(digest)),
+-  };
+-  if (have_salt)
+-    parts.push_back("salt=" + std::string(hexsalt));
++  std::vector<std::string> parts;
++  if (version == 1) {
++    parts = {
++        "0",
++        base::NumberToString(root_end),
++        "verity",
++        "0",
++        "ROOT_DEV",
++        "HASH_DEV",
++        "4096",
++        "4096",
++        base::NumberToString(hash_start>>3),
++        base::NumberToString(hash_start>>3),
++        std::string(alg_),
++        std::string(reinterpret_cast<char*>(digest)),
++    };
++    if (have_salt) {
++      parts.push_back(std::string(hexsalt));
++    }
++  } else {
++    parts = {
++        "0",
++        base::NumberToString(root_end),
++        "verity",
++        "payload=ROOT_DEV",
++        "hashtree=HASH_DEV",
++        "hashstart=" + base::NumberToString(hash_start),
++        "alg=" + std::string(alg_),
++        "root_hexdigest=" + std::string(reinterpret_cast<char*>(digest)),
++    };
++    if (have_salt) {
++      parts.push_back("salt=" + std::string(hexsalt));
++    }
++  }
+ 
+   return base::JoinString(parts, " ");
+ }
+ 
+-void FileHasher::PrintTable(bool colocated) {
+-  printf("%s\n", GetTable(colocated).c_str());
++void FileHasher::PrintTable(bool colocated,
++                            unsigned int version) {
++  printf("%s\n", GetTable(colocated, version).c_str());
+ }
+ 
+ }  // namespace verity
+diff --git a/verity/file_hasher.h b/verity/file_hasher.h
+index 1549555f4e..d5151b6219 100644
+--- a/verity/file_hasher.h
++++ b/verity/file_hasher.h
+@@ -40,8 +40,8 @@ class BRILLO_EXPORT FileHasher {
+   virtual bool Hash();
+   virtual bool Store();
+   // Print a table to stdout which contains a dmsetup compatible format
+-  virtual void PrintTable(bool colocated);
+-  virtual std::string GetTable(bool colocated);
++  virtual void PrintTable(bool colocated, unsigned int version);
++  virtual std::string GetTable(bool colocated, unsigned int version);
+ 
+   virtual const char* RandomSalt();
+   virtual void set_salt(const char* salt);
+diff --git a/verity/verity_main.cc b/verity/verity_main.cc
+index 16d9aead65..934af23d6c 100644
+--- a/verity/verity_main.cc
++++ b/verity/verity_main.cc
+@@ -31,6 +31,7 @@ void print_usage(const char* name) {
+       "  hashtree          Path to a hash tree to create or read from\n"
+       "  root_hexdigest    Digest of the root node (in hex) for verification\n"
+       "  salt              Salt (in hex)\n"
++      "  version           one of 0 or 1\n"
+       "\n",
+       name);
+ }
+@@ -46,7 +47,8 @@ static int verity_create(const char* alg,
+                          const char* image_path,
+                          unsigned int image_blocks,
+                          const char* hash_path,
+-                         const char* salt);
++                         const char* salt,
++                         unsigned int version);
+ 
+ void splitarg(char* arg, char** key, char** val) {
+   char* sp = NULL;
+@@ -61,6 +63,7 @@ int main(int argc, char** argv) {
+   const char* hashtree = NULL;
+   const char* salt = NULL;
+   unsigned int payload_blocks = 0;
++  unsigned int version = 0;
+   int i;
+   char *key, *val;
+ 
+@@ -87,7 +90,14 @@ int main(int argc, char** argv) {
+       // Silently drop the mode for now...
+     } else if (!strcmp(key, "salt")) {
+       salt = val;
+-    } else {
++    } else if (!strcmp(key, "version")) {
++      version = (unsigned int)strtoul(val, NULL, 0);
++      if (version > 1) {
++        fprintf(stderr, "version should be either 0 or 1\n");
++        print_usage(argv[0]);
++        return -1;
++      }
++    } else {
+       fprintf(stderr, "bogus key: '%s'\n", key);
+       print_usage(argv[0]);
+       return -1;
+@@ -102,7 +112,7 @@ int main(int argc, char** argv) {
+   }
+ 
+   if (mode == VERITY_CREATE) {
+-    return verity_create(alg, payload, payload_blocks, hashtree, salt);
++    return verity_create(alg, payload, payload_blocks, hashtree, salt, version);
+   } else {
+     LOG(FATAL) << "Verification not done yet";
+   }
+@@ -113,7 +123,8 @@ static int verity_create(const char* alg,
+                          const char* image_path,
+                          unsigned int image_blocks,
+                          const char* hash_path,
+-                         const char* salt) {
++                         const char* salt,
++                         unsigned int version) {
+   auto source = std::make_unique<base::File>(
+       base::FilePath(image_path),
+       base::File::FLAG_OPEN | base::File::FLAG_READ);
+@@ -133,6 +144,6 @@ static int verity_create(const char* alg,
+     hasher.set_salt(salt);
+   LOG_IF(FATAL, !hasher.Hash()) << "Failed to hash hasher";
+   LOG_IF(FATAL, !hasher.Store()) << "Failed to store hasher";
+-  hasher.PrintTable(true);
++  hasher.PrintTable(true, version);
+   return 0;
+ }
+-- 
+2.38.0.413.g74048e4d9e-goog
+
diff --git a/chromeos-base/verity/verity-0.0.1-r248.ebuild b/chromeos-base/verity/verity-0.0.1-r249.ebuild
similarity index 68%
rename from chromeos-base/verity/verity-0.0.1-r248.ebuild
rename to chromeos-base/verity/verity-0.0.1-r249.ebuild
index 051fba3..70257aa 100644
--- a/chromeos-base/verity/verity-0.0.1-r248.ebuild
+++ b/chromeos-base/verity/verity-0.0.1-r249.ebuild
@@ -3,13 +3,18 @@
 
 EAPI=7
 
+inherit cros-constants
+
 CROS_WORKON_COMMIT="f35f2919309cf11b0ddd9deb24a6b145d40d9254"
 CROS_WORKON_TREE=("a625767bb59509159091f2ab0b71f8b9b4b2e353" "6fc4c6b35e5c71304e6fed40a7a24e6401d38df3" "e7dba8c91c1f3257c34d4a7ffff0ea2537aeb6bb")
-CROS_WORKON_INCREMENTAL_BUILD=1
+#CROS_WORKON_INCREMENTAL_BUILD=1
 CROS_WORKON_LOCALNAME="platform2"
 CROS_WORKON_PROJECT="chromiumos/platform2"
-CROS_WORKON_OUTOFTREE_BUILD=1
+CROS_WORKON_REPO="${CROS_GIT_HOST_URL}"
+#CROS_WORKON_OUTOFTREE_BUILD=1
 CROS_WORKON_SUBTREE="common-mk verity .gn"
+CROS_WORKON_DESTDIR="${S}/platform2"
+CROS_WORKON_EGIT_BRANCH="main"
 
 PLATFORM_SUBDIR="verity"
 
@@ -21,6 +26,20 @@
 LICENSE="BSD-Google GPL-2"
 KEYWORDS="*"
 
+PATCHES=(
+	"${FILESDIR}/verity-print.patch"
+)
+
+src_prepare() {
+	# The workdir is platform2/nnapi - we need to pop up one level in the stack
+	# to apply our patches.
+	pushd .. || exit
+	eapply -p1 "${FILESDIR}/support-new-dm-verity-format.patch"
+	popd || exit
+
+	eapply_user
+}
+
 src_install() {
 	dobin "${OUT}"/verity