Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d8a22773 authored by Sascha Hauer's avatar Sascha Hauer Committed by Richard Weinberger
Browse files

ubifs: Enable authentication support



With the preparations all being done this patch now enables authentication
support for UBIFS. Authentication is enabled when the newly introduced
auth_key and auth_hash_name mount options are passed. auth_key provides
the key which is used for authentication whereas auth_hash_name provides
the hashing algorithm used for this FS. Passing these options make
authentication mandatory and only UBIFS images that can be authenticated
with the given key are allowed.

Signed-off-by: default avatarSascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: default avatarRichard Weinberger <richard@nod.at>
parent 1e76592f
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -91,6 +91,13 @@ chk_data_crc do not skip checking CRCs on data nodes
compr=none              override default compressor and set it to "none"
compr=lzo               override default compressor and set it to "lzo"
compr=zlib              override default compressor and set it to "zlib"
auth_key=		specify the key used for authenticating the filesystem.
			Passing this option makes authentication mandatory.
			The passed key must be present in the kernel keyring
			and must be of type 'logon'
auth_hash_name=		The hash algorithm used for authentication. Used for
			both hashing and for creating HMACs. Typical values
			include "sha256" or "sha512"


Quick usage instructions
+10 −0
Original line number Diff line number Diff line
@@ -86,3 +86,13 @@ config UBIFS_FS_SECURITY
	  the extended attribute support in advance.

	  If you are not using a security module, say N.

config UBIFS_FS_AUTHENTICATION
	bool "UBIFS authentication support"
	select CRYPTO_HMAC
	help
	  Enable authentication support for UBIFS. This feature offers protection
	  against offline changes for both data and metadata of the filesystem.
	  If you say yes here you should also select a hashing algorithm such as
	  sha256, these are not selected automatically since there are many
	  different options.
+35 −1
Original line number Diff line number Diff line
@@ -579,7 +579,9 @@ 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_AUTH_NODE].min_len = UBIFS_AUTH_NODE_SZ;
	c->ranges[UBIFS_AUTH_NODE].max_len = UBIFS_AUTH_NODE_SZ +
				UBIFS_MAX_HMAC_LEN;

	c->ranges[UBIFS_INO_NODE].min_len  = UBIFS_INO_NODE_SZ;
	c->ranges[UBIFS_INO_NODE].max_len  = UBIFS_MAX_INO_NODE_SZ;
@@ -935,6 +937,8 @@ static int check_volume_empty(struct ubifs_info *c)
 * Opt_no_chk_data_crc: do not check CRCs when reading data nodes
 * Opt_override_compr: override default compressor
 * Opt_assert: set ubifs_assert() action
 * Opt_auth_key: The key name used for authentication
 * Opt_auth_hash_name: The hash type used for authentication
 * Opt_err: just end of array marker
 */
enum {
@@ -946,6 +950,8 @@ enum {
	Opt_no_chk_data_crc,
	Opt_override_compr,
	Opt_assert,
	Opt_auth_key,
	Opt_auth_hash_name,
	Opt_ignore,
	Opt_err,
};
@@ -958,6 +964,8 @@ static const match_table_t tokens = {
	{Opt_chk_data_crc, "chk_data_crc"},
	{Opt_no_chk_data_crc, "no_chk_data_crc"},
	{Opt_override_compr, "compr=%s"},
	{Opt_auth_key, "auth_key=%s"},
	{Opt_auth_hash_name, "auth_hash_name=%s"},
	{Opt_ignore, "ubi=%s"},
	{Opt_ignore, "vol=%s"},
	{Opt_assert, "assert=%s"},
@@ -1081,6 +1089,16 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
			kfree(act);
			break;
		}
		case Opt_auth_key:
			c->auth_key_name = kstrdup(args[0].from, GFP_KERNEL);
			if (!c->auth_key_name)
				return -ENOMEM;
			break;
		case Opt_auth_hash_name:
			c->auth_hash_name = kstrdup(args[0].from, GFP_KERNEL);
			if (!c->auth_hash_name)
				return -ENOMEM;
			break;
		case Opt_ignore:
			break;
		default:
@@ -1260,6 +1278,19 @@ static int mount_ubifs(struct ubifs_info *c)

	c->mounting = 1;

	if (c->auth_key_name) {
		if (IS_ENABLED(CONFIG_UBIFS_FS_AUTHENTICATION)) {
			err = ubifs_init_authentication(c);
			if (err)
				goto out_free;
		} else {
			ubifs_err(c, "auth_key_name, but UBIFS is built without"
				  " authentication support");
			err = -EINVAL;
			goto out_free;
		}
	}

	err = ubifs_read_superblock(c);
	if (err)
		goto out_free;
@@ -1577,7 +1608,10 @@ static void ubifs_umount(struct ubifs_info *c)
	free_wbufs(c);
	free_orphans(c);
	ubifs_lpt_free(c, 0);
	ubifs_exit_authentication(c);

	kfree(c->auth_key_name);
	kfree(c->auth_hash_name);
	kfree(c->cbuf);
	kfree(c->rcvrd_mst_node);
	kfree(c->mst_node);