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

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
...@@ -91,6 +91,13 @@ chk_data_crc do not skip checking CRCs on data nodes ...@@ -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=none override default compressor and set it to "none"
compr=lzo override default compressor and set it to "lzo" compr=lzo override default compressor and set it to "lzo"
compr=zlib override default compressor and set it to "zlib" 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 Quick usage instructions
......
...@@ -86,3 +86,13 @@ config UBIFS_FS_SECURITY ...@@ -86,3 +86,13 @@ config UBIFS_FS_SECURITY
the extended attribute support in advance. the extended attribute support in advance.
If you are not using a security module, say N. 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.
...@@ -579,7 +579,9 @@ static int init_constants_early(struct ubifs_info *c) ...@@ -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_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_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].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;
...@@ -935,6 +937,8 @@ static int check_volume_empty(struct ubifs_info *c) ...@@ -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_no_chk_data_crc: do not check CRCs when reading data nodes
* Opt_override_compr: override default compressor * Opt_override_compr: override default compressor
* Opt_assert: set ubifs_assert() action * 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 * Opt_err: just end of array marker
*/ */
enum { enum {
...@@ -946,6 +950,8 @@ enum { ...@@ -946,6 +950,8 @@ enum {
Opt_no_chk_data_crc, Opt_no_chk_data_crc,
Opt_override_compr, Opt_override_compr,
Opt_assert, Opt_assert,
Opt_auth_key,
Opt_auth_hash_name,
Opt_ignore, Opt_ignore,
Opt_err, Opt_err,
}; };
...@@ -958,6 +964,8 @@ static const match_table_t tokens = { ...@@ -958,6 +964,8 @@ static const match_table_t tokens = {
{Opt_chk_data_crc, "chk_data_crc"}, {Opt_chk_data_crc, "chk_data_crc"},
{Opt_no_chk_data_crc, "no_chk_data_crc"}, {Opt_no_chk_data_crc, "no_chk_data_crc"},
{Opt_override_compr, "compr=%s"}, {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, "ubi=%s"},
{Opt_ignore, "vol=%s"}, {Opt_ignore, "vol=%s"},
{Opt_assert, "assert=%s"}, {Opt_assert, "assert=%s"},
...@@ -1081,6 +1089,16 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, ...@@ -1081,6 +1089,16 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options,
kfree(act); kfree(act);
break; 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: case Opt_ignore:
break; break;
default: default:
...@@ -1260,6 +1278,19 @@ static int mount_ubifs(struct ubifs_info *c) ...@@ -1260,6 +1278,19 @@ static int mount_ubifs(struct ubifs_info *c)
c->mounting = 1; 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); err = ubifs_read_superblock(c);
if (err) if (err)
goto out_free; goto out_free;
...@@ -1577,7 +1608,10 @@ static void ubifs_umount(struct ubifs_info *c) ...@@ -1577,7 +1608,10 @@ static void ubifs_umount(struct ubifs_info *c)
free_wbufs(c); free_wbufs(c);
free_orphans(c); free_orphans(c);
ubifs_lpt_free(c, 0); ubifs_lpt_free(c, 0);
ubifs_exit_authentication(c);
kfree(c->auth_key_name);
kfree(c->auth_hash_name);
kfree(c->cbuf); kfree(c->cbuf);
kfree(c->rcvrd_mst_node); kfree(c->rcvrd_mst_node);
kfree(c->mst_node); kfree(c->mst_node);
......
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