Merge branch 'for-4.16/block' of git://git.kernel.dk/linux-block
[linux-2.6-microblaze.git] / drivers / md / dm-crypt.c
index 4833266..2ad4291 100644 (file)
@@ -1953,10 +1953,15 @@ static int crypt_setkey(struct crypt_config *cc)
        /* Ignore extra keys (which are used for IV etc) */
        subkey_size = crypt_subkey_size(cc);
 
-       if (crypt_integrity_hmac(cc))
+       if (crypt_integrity_hmac(cc)) {
+               if (subkey_size < cc->key_mac_size)
+                       return -EINVAL;
+
                crypt_copy_authenckey(cc->authenc_key, cc->key,
                                      subkey_size - cc->key_mac_size,
                                      cc->key_mac_size);
+       }
+
        for (i = 0; i < cc->tfms_count; i++) {
                if (crypt_integrity_hmac(cc))
                        r = crypto_aead_setkey(cc->cipher_tfm.tfms_aead[i],
@@ -2052,9 +2057,6 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string
 
        ret = crypt_setkey(cc);
 
-       /* wipe the kernel key payload copy in each case */
-       memset(cc->key, 0, cc->key_size * sizeof(u8));
-
        if (!ret) {
                set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
                kzfree(cc->key_string);
@@ -2522,6 +2524,10 @@ static int crypt_ctr_cipher(struct dm_target *ti, char *cipher_in, char *key)
                }
        }
 
+       /* wipe the kernel key payload copy */
+       if (cc->key_string)
+               memset(cc->key, 0, cc->key_size * sizeof(u8));
+
        return ret;
 }
 
@@ -2739,6 +2745,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                        cc->tag_pool_max_sectors * cc->on_disk_tag_size);
                if (!cc->tag_pool) {
                        ti->error = "Cannot allocate integrity tags mempool";
+                       ret = -ENOMEM;
                        goto bad;
                }
 
@@ -2960,6 +2967,9 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
                                return ret;
                        if (cc->iv_gen_ops && cc->iv_gen_ops->init)
                                ret = cc->iv_gen_ops->init(cc);
+                       /* wipe the kernel key payload copy */
+                       if (cc->key_string)
+                               memset(cc->key, 0, cc->key_size * sizeof(u8));
                        return ret;
                }
                if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
@@ -3006,7 +3016,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
 
 static struct target_type crypt_target = {
        .name   = "crypt",
-       .version = {1, 18, 0},
+       .version = {1, 18, 1},
        .module = THIS_MODULE,
        .ctr    = crypt_ctr,
        .dtr    = crypt_dtr,