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