linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: linux-mtd@lists.infradead.org
Cc: David Gstir <david@sigma-star.at>,
	Richard Weinberger <richard@nod.at>,
	kernel@pengutronix.de, linux-kernel@vger.kernel.org,
	Sascha Hauer <s.hauer@pengutronix.de>
Subject: [PATCH 18/25] ubfis: authentication: authenticate master node
Date: Wed,  4 Jul 2018 14:41:30 +0200	[thread overview]
Message-ID: <20180704124137.13396-19-s.hauer@pengutronix.de> (raw)
In-Reply-To: <20180704124137.13396-1-s.hauer@pengutronix.de>

The master node contains hashes over the root index node and the LPT.
This patch adds a HMAC to authenticate the master node itself.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/ubifs/master.c   | 61 ++++++++++++++++++++++++++++++++++++++++-----
 fs/ubifs/recovery.c |  7 +++---
 fs/ubifs/ubifs.h    |  1 +
 3 files changed, 59 insertions(+), 10 deletions(-)

diff --git a/fs/ubifs/master.c b/fs/ubifs/master.c
index f1a96b50ec68..1f633601e95b 100644
--- a/fs/ubifs/master.c
+++ b/fs/ubifs/master.c
@@ -24,6 +24,42 @@
 
 #include "ubifs.h"
 
+/**
+ * ubifs_compare_master_node - compare two UBIFS master nodes
+ * @c: UBIFS file-system description object
+ * @m1: the first node
+ * @m2: the second node
+ *
+ * This function compares two UBIFS master nodes. Returns 0 if they are equal
+ * and nonzero if not.
+ */
+int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2)
+{
+	int ret;
+	int behind;
+	int hmac_offs = offsetof(struct ubifs_mst_node, hmac);
+
+	/*
+	 * Do not compare the common node header since the sequence number and
+	 * hence the CRC are different.
+	 */
+	ret = memcmp(m1 + UBIFS_CH_SZ, m2 + UBIFS_CH_SZ,
+		     hmac_offs - UBIFS_CH_SZ);
+	if (ret)
+		return ret;
+
+	/*
+	 * Do not compare the embedded HMAC aswell which also must be different
+	 * due to the different common node header.
+	 */
+	behind = hmac_offs + UBIFS_MAX_HMAC_LEN;
+
+	if (UBIFS_MST_NODE_SZ > behind)
+		return memcmp(m1 + behind, m2 + behind, UBIFS_MST_NODE_SZ - behind);
+
+	return 0;
+}
+
 /**
  * scan_for_master - search the valid master node.
  * @c: UBIFS file-system description object
@@ -37,7 +73,7 @@ static int scan_for_master(struct ubifs_info *c)
 {
 	struct ubifs_scan_leb *sleb;
 	struct ubifs_scan_node *snod;
-	int lnum, offs = 0, nodes_cnt;
+	int lnum, offs = 0, nodes_cnt, err;
 
 	lnum = UBIFS_MST_LNUM;
 
@@ -69,12 +105,23 @@ static int scan_for_master(struct ubifs_info *c)
 		goto out_dump;
 	if (snod->offs != offs)
 		goto out;
-	if (memcmp((void *)c->mst_node + UBIFS_CH_SZ,
-		   (void *)snod->node + UBIFS_CH_SZ,
-		   UBIFS_MST_NODE_SZ - UBIFS_CH_SZ))
+	if (ubifs_compare_master_node(c, c->mst_node, snod->node))
 		goto out;
+
 	c->mst_offs = offs;
 	ubifs_scan_destroy(sleb);
+
+	if (!ubifs_authenticated(c))
+		return 0;
+
+	err = ubifs_node_verify_hmac(c, c->mst_node,
+				     sizeof(struct ubifs_mst_node),
+				     offsetof(struct ubifs_mst_node, hmac));
+	if (err) {
+		ubifs_err(c, "Failed to verify master node HMAC");
+		return -EPERM;
+	}
+
 	return 0;
 
 out:
@@ -381,7 +428,8 @@ int ubifs_write_master(struct ubifs_info *c)
 	c->mst_node->highest_inum = cpu_to_le64(c->highest_inum);
 
 	ubifs_copy_hash(c, c->zroot.hash, c->mst_node->hash_root_idx);
-	err = ubifs_write_node(c, c->mst_node, len, lnum, offs);
+	err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs,
+				    offsetof(struct ubifs_mst_node, hmac));
 	if (err)
 		return err;
 
@@ -392,7 +440,8 @@ int ubifs_write_master(struct ubifs_info *c)
 		if (err)
 			return err;
 	}
-	err = ubifs_write_node(c, c->mst_node, len, lnum, offs);
+	err = ubifs_write_node_hmac(c, c->mst_node, len, lnum, offs,
+				    offsetof(struct ubifs_mst_node, hmac));
 
 	return err;
 }
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 3af4472061cc..3fa7c2cd96b9 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -212,7 +212,8 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
 	save_flags = mst->flags;
 	mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
 
-	ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
+	ubifs_prepare_node_hmac(c, mst, UBIFS_MST_NODE_SZ,
+				offsetof(struct ubifs_mst_node, hmac), 1);
 	err = ubifs_leb_change(c, lnum, mst, sz);
 	if (err)
 		goto out;
@@ -264,9 +265,7 @@ int ubifs_recover_master_node(struct ubifs_info *c)
 			offs2 = (void *)mst2 - buf2;
 			if (offs1 == offs2) {
 				/* Same offset, so must be the same */
-				if (memcmp((void *)mst1 + UBIFS_CH_SZ,
-					   (void *)mst2 + UBIFS_CH_SZ,
-					   UBIFS_MST_NODE_SZ - UBIFS_CH_SZ))
+				if (ubifs_compare_master_node(c, mst1, mst2))
 					goto out_err;
 				mst = mst1;
 			} else if (offs2 + sz == offs1) {
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 5234a7c9380c..a2805dec8aee 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -1852,6 +1852,7 @@ int ubifs_gc_should_commit(struct ubifs_info *c);
 void ubifs_wait_for_commit(struct ubifs_info *c);
 
 /* master.c */
+int ubifs_compare_master_node(struct ubifs_info *c, void *m1, void *m2);
 int ubifs_read_master(struct ubifs_info *c);
 int ubifs_write_master(struct ubifs_info *c);
 
-- 
2.18.0


  parent reply	other threads:[~2018-07-04 12:43 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-04 12:41 [PATCH 00/25] UBIFS authentication support Sascha Hauer
2018-07-04 12:41 ` [PATCH 01/25] ubifs: refactor create_default_filesystem() Sascha Hauer
2018-07-04 12:41 ` [PATCH 02/25] ubifs: pass ubifs_zbranch to try_read_node() Sascha Hauer
2018-07-04 12:41 ` [PATCH 03/25] ubifs: pass ubifs_zbranch to read_znode() Sascha Hauer
2018-07-04 12:41 ` [PATCH 04/25] ubifs: export pnode_lookup as ubifs_pnode_lookup Sascha Hauer
2018-07-04 12:41 ` [PATCH 05/25] ubifs: implement ubifs_lpt_lookup using ubifs_pnode_lookup Sascha Hauer
2018-08-13  6:31   ` Sascha Hauer
2018-08-13  6:34     ` Richard Weinberger
2018-08-13  8:12       ` Sascha Hauer
2018-08-13 11:30         ` Richard Weinberger
2018-08-26 20:59     ` Richard Weinberger
2018-07-04 12:41 ` [PATCH 06/25] ubifs: drop write_node Sascha Hauer
2018-07-04 12:41 ` [PATCH 07/25] ubifs: Store read superblock node Sascha Hauer
2018-08-27 12:50   ` Richard Weinberger
2018-07-04 12:41 ` [PATCH 08/25] ubifs: Format changes for authentication support Sascha Hauer
2018-07-04 12:41 ` [PATCH 09/25] ubifs: add separate functions to init/crc a node Sascha Hauer
2018-07-04 12:41 ` [PATCH 10/25] ubifs: add helper functions for authentication support Sascha Hauer
2018-08-27 12:50   ` Richard Weinberger
2018-08-29  6:30     ` Sascha Hauer
2018-07-04 12:41 ` [PATCH 11/25] ubifs: Create functions to embed a HMAC in a node Sascha Hauer
2018-07-04 12:41 ` [PATCH 12/25] ubifs: Add hashes to the tree node cache Sascha Hauer
2018-08-27 19:18   ` Richard Weinberger
2018-08-29 11:16     ` Sascha Hauer
2018-07-04 12:41 ` [PATCH 13/25] ubifs: authentication: Add hashes to index nodes Sascha Hauer
2018-08-27 19:36   ` Richard Weinberger
2018-09-07 10:25     ` Sascha Hauer
2018-07-04 12:41 ` [PATCH 14/25] ubifs: Add authentication nodes to journal Sascha Hauer
2018-07-08  2:59   ` kbuild test robot
2018-08-27 20:48   ` Richard Weinberger
2018-08-29 14:38     ` Sascha Hauer
2018-08-29 14:54       ` Richard Weinberger
2018-08-30 13:41         ` Sascha Hauer
2018-09-02 19:45       ` Richard Weinberger
2018-07-04 12:41 ` [PATCH 15/25] ubifs: Add auth nodes to garbage collector journal head Sascha Hauer
2018-08-27 20:51   ` Richard Weinberger
2018-08-30 14:43     ` Sascha Hauer
2018-07-04 12:41 ` [PATCH 16/25] ubifs: authenticate replayed journal Sascha Hauer
2018-07-08  6:08   ` kbuild test robot
2018-08-27 21:16   ` Richard Weinberger
2018-07-04 12:41 ` [PATCH 17/25] ubifs: authentication: authenticate LPT Sascha Hauer
2018-07-04 12:41 ` Sascha Hauer [this message]
2018-07-04 12:41 ` [PATCH 19/25] ubifs: Create hash for default LPT Sascha Hauer
2018-07-04 12:41 ` [PATCH 20/25] ubifs: authentication: Authenticate super block node Sascha Hauer
2018-07-04 12:41 ` [PATCH 21/25] ubifs: Add hashes and HMACs to default filesystem Sascha Hauer
2018-07-04 12:41 ` [PATCH 22/25] ubifs: do not update inode size in-place in authenticated mode Sascha Hauer
2018-07-04 12:41 ` [PATCH 23/25] ubifs: Enable authentication support Sascha Hauer
2018-07-04 12:41 ` [PATCH 24/25] ubifs: support offline signed images Sascha Hauer
2018-07-04 12:41 ` [PATCH 25/25] Documentation: ubifs: Add authentication whitepaper Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180704124137.13396-19-s.hauer@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=david@sigma-star.at \
    --cc=kernel@pengutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).