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: Sascha Hauer <[email protected]>
---
 Documentation/filesystems/ubifs.txt |  7 ++++++
 fs/ubifs/Kconfig                    | 10 ++++++++
 fs/ubifs/super.c                    | 36 ++++++++++++++++++++++++++++-
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/Documentation/filesystems/ubifs.txt 
b/Documentation/filesystems/ubifs.txt
index a0a61d2f389f..acc80442a3bb 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -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
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 2a0b5f1134a4..9da1e7c21b7f 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -75,3 +75,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.
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index de7bf613addc..b2ccd2d7ce4d 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -577,7 +577,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;
@@ -932,6 +934,8 @@ static int check_volume_empty(struct ubifs_info *c)
  * Opt_chk_data_crc: 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_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 {
@@ -942,6 +946,8 @@ enum {
        Opt_chk_data_crc,
        Opt_no_chk_data_crc,
        Opt_override_compr,
+       Opt_auth_key,
+       Opt_auth_hash_name,
        Opt_ignore,
        Opt_err,
 };
@@ -954,6 +960,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_err, NULL},
@@ -1056,6 +1064,16 @@ static int ubifs_parse_options(struct ubifs_info *c, 
char *options,
                        c->default_compr = c->mount_opts.compr_type;
                        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:
@@ -1235,6 +1253,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;
@@ -1552,7 +1583,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);
-- 
2.18.0

Reply via email to