Skip to content

Commit

Permalink
ubifs: Format changes for authentication support
Browse files Browse the repository at this point in the history
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: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
  • Loading branch information
Sascha Hauer authored and Richard Weinberger committed Oct 23, 2018
1 parent fd61500 commit 5125cfd
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 3 deletions.
6 changes: 6 additions & 0 deletions fs/ubifs/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ const char *dbg_ntype(int type)
return "commit start node";
case UBIFS_ORPH_NODE:
return "orphan node";
case UBIFS_AUTH_NODE:
return "auth node";
default:
return "unknown node";
}
Expand Down Expand Up @@ -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]));
break;
}
case UBIFS_AUTH_NODE:
{
break;
}
default:
pr_err("node type %d was not recognized\n",
(int)ch->node_type);
Expand Down
1 change: 1 addition & 0 deletions fs/ubifs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_TRUN_NODE].len = UBIFS_TRUN_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].max_len = UBIFS_MAX_INO_NODE_SZ;
Expand Down
46 changes: 43 additions & 3 deletions fs/ubifs/ubifs-media.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,7 @@ enum {
#define UBIFS_IDX_NODE_SZ sizeof(struct ubifs_idx_node)
#define UBIFS_CS_NODE_SZ sizeof(struct ubifs_cs_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 */
#define UBIFS_XENT_NODE_SZ UBIFS_DENT_NODE_SZ
/* Only this does not have to be multiple of 8 bytes */
Expand All @@ -300,6 +301,12 @@ enum {
/* The largest UBIFS node */
#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
* nor a long name to not waste space on the flash.
Expand Down Expand Up @@ -365,6 +372,7 @@ enum {
* UBIFS_IDX_NODE: index node
* UBIFS_CS_NODE: commit start node
* UBIFS_ORPH_NODE: orphan node
* UBIFS_AUTH_NODE: authentication node
* UBIFS_NODE_TYPES_CNT: count of supported node types
*
* Note, we index arrays by these numbers, so keep them low and contiguous.
Expand All @@ -384,6 +392,7 @@ enum {
UBIFS_IDX_NODE,
UBIFS_CS_NODE,
UBIFS_ORPH_NODE,
UBIFS_AUTH_NODE,
UBIFS_NODE_TYPES_CNT,
};

Expand Down Expand Up @@ -421,15 +430,19 @@ enum {
* UBIFS_FLG_DOUBLE_HASH: store a 32bit cookie in directory entry nodes to
* support 64bit cookies for lookups by hash
* UBIFS_FLG_ENCRYPTION: this filesystem contains encrypted files
* UBIFS_FLG_AUTHENTICATION: this filesystem contains hashes for authentication
*/
enum {
UBIFS_FLG_BIGLPT = 0x02,
UBIFS_FLG_SPACE_FIXUP = 0x04,
UBIFS_FLG_DOUBLE_HASH = 0x08,
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.
Expand Down Expand Up @@ -633,6 +646,10 @@ struct ubifs_pad_node {
* @time_gran: time granularity in nanoseconds
* @uuid: UUID generated when the file system image was created
* @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_ch ch;
Expand Down Expand Up @@ -660,7 +677,10 @@ struct ubifs_sb_node {
__le32 time_gran;
__u8 uuid[16];
__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;

/**
Expand Down Expand Up @@ -695,6 +715,9 @@ struct ubifs_sb_node {
* @empty_lebs: number of empty logical eraseblocks
* @idx_lebs: number of indexing logical eraseblocks
* @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
*/
struct ubifs_mst_node {
Expand Down Expand Up @@ -727,7 +750,10 @@ struct ubifs_mst_node {
__le32 empty_lebs;
__le32 idx_lebs;
__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;

/**
Expand All @@ -746,12 +772,26 @@ struct ubifs_ref_node {
__u8 padding[28];
} __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
* @lnum: LEB number of the target node
* @offs: offset within @lnum
* @len: target node length
* @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 {
__le32 lnum;
Expand Down

0 comments on commit 5125cfd

Please sign in to comment.