OSDN Git Service

ubifs: Enable authentication support
authorSascha Hauer <s.hauer@pengutronix.de>
Fri, 7 Sep 2018 12:36:45 +0000 (14:36 +0200)
committerRichard Weinberger <richard@nod.at>
Tue, 23 Oct 2018 11:49:01 +0000 (13:49 +0200)
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 <s.hauer@pengutronix.de>
Signed-off-by: Richard Weinberger <richard@nod.at>
Documentation/filesystems/ubifs.txt
fs/ubifs/Kconfig
fs/ubifs/super.c

index a0a61d2..acc8044 100644 (file)
@@ -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
index 853c775..529856f 100644 (file)
@@ -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.
index e2964ce..1fac113 100644 (file)
@@ -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);