Commit 5125cfdf authored by Sascha Hauer's avatar Sascha Hauer Committed by Richard Weinberger

ubifs: Format changes for authentication support

This patch adds the changes to the on disk format needed for
authentication support. We'll add:

* a HMAC covering super block node
* a HMAC covering the master node
* a hash over the root index node to the master node
* a hash over the LPT to the master node
* a flag to the filesystem flag indicating the filesystem is
  authenticated
* an authentication node necessary to authenticate the nodes written
  to the journal heads while they are written.
* a HMAC of a well known message to the super block node to be able
  to check if the correct key is provided

And finally, not visible in this patch, nevertheless explained here:

* hashes over the referenced child nodes in each branch of a index node
Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent fd615005
...@@ -165,6 +165,8 @@ const char *dbg_ntype(int type) ...@@ -165,6 +165,8 @@ const char *dbg_ntype(int type)
return "commit start node"; return "commit start node";
case UBIFS_ORPH_NODE: case UBIFS_ORPH_NODE:
return "orphan node"; return "orphan node";
case UBIFS_AUTH_NODE:
return "auth node";
default: default:
return "unknown node"; return "unknown node";
} }
...@@ -542,6 +544,10 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node) ...@@ -542,6 +544,10 @@ void ubifs_dump_node(const struct ubifs_info *c, const void *node)
(unsigned long long)le64_to_cpu(orph->inos[i])); (unsigned long long)le64_to_cpu(orph->inos[i]));
break; break;
} }
case UBIFS_AUTH_NODE:
{
break;
}
default: default:
pr_err("node type %d was not recognized\n", pr_err("node type %d was not recognized\n",
(int)ch->node_type); (int)ch->node_type);
......
...@@ -579,6 +579,7 @@ static int init_constants_early(struct ubifs_info *c) ...@@ -579,6 +579,7 @@ static int init_constants_early(struct ubifs_info *c)
c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ; c->ranges[UBIFS_REF_NODE].len = UBIFS_REF_NODE_SZ;
c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ; c->ranges[UBIFS_TRUN_NODE].len = UBIFS_TRUN_NODE_SZ;
c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ; c->ranges[UBIFS_CS_NODE].len = UBIFS_CS_NODE_SZ;
c->ranges[UBIFS_AUTH_NODE].len = UBIFS_AUTH_NODE_SZ;
c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ; c->ranges[UBIFS_INO_NODE].min_len = UBIFS_INO_NODE_SZ;
c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ; c->ranges[UBIFS_INO_NODE].max_len = UBIFS_MAX_INO_NODE_SZ;
......
...@@ -286,6 +286,7 @@ enum { ...@@ -286,6 +286,7 @@ enum {
#define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node) #define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node)
#define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_node) #define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_node)
#define UBIFS_ORPH_NODE_SZ sizeof(struct ubifs_orph_node) #define UBIFS_ORPH_NODE_SZ sizeof(struct ubifs_orph_node)
#define UBIFS_AUTH_NODE_SZ sizeof(struct ubifs_auth_node)
/* Extended attribute entry nodes are identical to directory entry nodes */ /* Extended attribute entry nodes are identical to directory entry nodes */
#define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ #define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ
/* Only this does not have to be multiple of 8 bytes */ /* Only this does not have to be multiple of 8 bytes */
...@@ -300,6 +301,12 @@ enum { ...@@ -300,6 +301,12 @@ enum {
/* The largest UBIFS node */ /* The largest UBIFS node */
#define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ #define UBIFS_MAX_NODE_SZ UBIFS_MAX_INO_NODE_SZ
/* The maxmimum size of a hash, enough for sha512 */
#define UBIFS_MAX_HASH_LEN 64
/* The maxmimum size of a hmac, enough for hmac(sha512) */
#define UBIFS_MAX_HMAC_LEN 64
/* /*
* xattr name of UBIFS encryption context, we don't use a prefix * xattr name of UBIFS encryption context, we don't use a prefix
* nor a long name to not waste space on the flash. * nor a long name to not waste space on the flash.
...@@ -365,6 +372,7 @@ enum { ...@@ -365,6 +372,7 @@ enum {
* UBIFS_IDX_NODE: index node * UBIFS_IDX_NODE: index node
* UBIFS_CS_NODE: commit start node * UBIFS_CS_NODE: commit start node
* UBIFS_ORPH_NODE: orphan node * UBIFS_ORPH_NODE: orphan node
* UBIFS_AUTH_NODE: authentication node
* UBIFS_NODE_TYPES_CNT: count of supported node types * UBIFS_NODE_TYPES_CNT: count of supported node types
* *
* Note, we index arrays by these numbers, so keep them low and contiguous. * Note, we index arrays by these numbers, so keep them low and contiguous.
...@@ -384,6 +392,7 @@ enum { ...@@ -384,6 +392,7 @@ enum {
UBIFS_IDX_NODE, UBIFS_IDX_NODE,
UBIFS_CS_NODE, UBIFS_CS_NODE,
UBIFS_ORPH_NODE, UBIFS_ORPH_NODE,
UBIFS_AUTH_NODE,
UBIFS_NODE_TYPES_CNT, UBIFS_NODE_TYPES_CNT,
}; };
...@@ -421,15 +430,19 @@ enum { ...@@ -421,15 +430,19 @@ enum {
* UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to * UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to
* support 64bit cookies for lookups by hash * support 64bit cookies for lookups by hash
* UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files * UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files
* UBIFS_FLG_AUTHENTICATION: this filesystem contains hashes for authentication
*/ */
enum { enum {
UBIFS_FLG_BIGLPT = 0x02, UBIFS_FLG_BIGLPT = 0x02,
UBIFS_FLG_SPACE_FIXUP = 0x04, UBIFS_FLG_SPACE_FIXUP = 0x04,
UBIFS_FLG_DOUBLE_HASH = 0x08, UBIFS_FLG_DOUBLE_HASH = 0x08,
UBIFS_FLG_ENCRYPTION = 0x10, UBIFS_FLG_ENCRYPTION = 0x10,
UBIFS_FLG_AUTHENTICATION = 0x20,
}; };
#define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT|UBIFS_FLG_SPACE_FIXUP|UBIFS_FLG_DOUBLE_HASH|UBIFS_FLG_ENCRYPTION) #define UBIFS_FLG_MASK (UBIFS_FLG_BIGLPT | UBIFS_FLG_SPACE_FIXUP | \
UBIFS_FLG_DOUBLE_HASH | UBIFS_FLG_ENCRYPTION | \
UBIFS_FLG_AUTHENTICATION)
/** /**
* struct ubifs_ch - common header node. * struct ubifs_ch - common header node.
...@@ -633,6 +646,10 @@ struct ubifs_pad_node { ...@@ -633,6 +646,10 @@ struct ubifs_pad_node {
* @time_gran: time granularity in nanoseconds * @time_gran: time granularity in nanoseconds
* @uuid: UUID generated when the file system image was created * @uuid: UUID generated when the file system image was created
* @ro_compat_version: UBIFS R/O compatibility version * @ro_compat_version: UBIFS R/O compatibility version
* @hmac: HMAC to authenticate the superblock node
* @hmac_wkm: HMAC of a well known message (the string "UBIFS") as a convenience
* to the user to check if the correct key is passed.
* @hash_algo: The hash algo used for this filesystem (one of enum hash_algo)
*/ */
struct ubifs_sb_node { struct ubifs_sb_node {
struct ubifs_ch ch; struct ubifs_ch ch;
...@@ -660,7 +677,10 @@ struct ubifs_sb_node { ...@@ -660,7 +677,10 @@ struct ubifs_sb_node {
__le32 time_gran; __le32 time_gran;
__u8 uuid[16]; __u8 uuid[16];
__le32 ro_compat_version; __le32 ro_compat_version;
__u8 padding2[3968]; __u8 hmac[UBIFS_MAX_HMAC_LEN];
__u8 hmac_wkm[UBIFS_MAX_HMAC_LEN];
__le16 hash_algo;
__u8 padding2[3838];
} __packed; } __packed;
/** /**
...@@ -695,6 +715,9 @@ struct ubifs_sb_node { ...@@ -695,6 +715,9 @@ struct ubifs_sb_node {
* @empty_lebs: number of empty logical eraseblocks * @empty_lebs: number of empty logical eraseblocks
* @idx_lebs: number of indexing logical eraseblocks * @idx_lebs: number of indexing logical eraseblocks
* @leb_cnt: count of LEBs used by file-system * @leb_cnt: count of LEBs used by file-system
* @hash_root_idx: the hash of the root index node
* @hash_lpt: the hash of the LPT
* @hmac: HMAC to authenticate the master node
* @padding: reserved for future, zeroes * @padding: reserved for future, zeroes
*/ */
struct ubifs_mst_node { struct ubifs_mst_node {
...@@ -727,7 +750,10 @@ struct ubifs_mst_node { ...@@ -727,7 +750,10 @@ struct ubifs_mst_node {
__le32 empty_lebs; __le32 empty_lebs;
__le32 idx_lebs; __le32 idx_lebs;
__le32 leb_cnt; __le32 leb_cnt;
__u8 padding[344]; __u8 hash_root_idx[UBIFS_MAX_HASH_LEN];
__u8 hash_lpt[UBIFS_MAX_HASH_LEN];
__u8 hmac[UBIFS_MAX_HMAC_LEN];
__u8 padding[152];
} __packed; } __packed;
/** /**
...@@ -746,12 +772,26 @@ struct ubifs_ref_node { ...@@ -746,12 +772,26 @@ struct ubifs_ref_node {
__u8 padding[28]; __u8 padding[28];
} __packed; } __packed;
/**
* struct ubifs_auth_node - node for authenticating other nodes
* @ch: common header
* @hmac: The HMAC
*/
struct ubifs_auth_node {
struct ubifs_ch ch;
__u8 hmac[];
} __packed;
/** /**
* struct ubifs_branch - key/reference/length branch * struct ubifs_branch - key/reference/length branch
* @lnum: LEB number of the target node * @lnum: LEB number of the target node
* @offs: offset within @lnum * @offs: offset within @lnum
* @len: target node length * @len: target node length
* @key: key * @key: key
*
* In an authenticated UBIFS we have the hash of the referenced node after @key.
* This can't be added to the struct type definition because @key is a
* dynamically sized element already.
*/ */
struct ubifs_branch { struct ubifs_branch {
__le32 lnum; __le32 lnum;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment