summaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
authorOndrej Kozina <okozina@redhat.com>2018-01-12 10:30:32 -0500
committerMike Snitzer <snitzer@redhat.com>2018-01-17 09:10:48 -0500
commitdc94902bde1e158cd19c4deab208e5d6eb382a44 (patch)
tree921d063aaf2197a2bd437f5c9dd0969dc5f68e20 /drivers/md/dm-crypt.c
parent717f4b1c52135f279112df82583e0c77e80f90de (diff)
dm crypt: wipe kernel key copy after IV initialization
Loading key via kernel keyring service erases the internal key copy immediately after we pass it in crypto layer. This is wrong because IV is initialized later and we use wrong key for the initialization (instead of real key there's just zeroed block). The bug may cause data corruption if key is loaded via kernel keyring service first and later same crypt device is reactivated using exactly same key in hexbyte representation, or vice versa. The bug (and fix) affects only ciphers using following IVs: essiv, lmk and tcw. Fixes: c538f6ec9f56 ("dm crypt: add ability to use keys from the kernel key retention service") Cc: stable@vger.kernel.org # 4.10+ Signed-off-by: Ondrej Kozina <okozina@redhat.com> Reviewed-by: Milan Broz <gmazyland@gmail.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 4cc3809b2a3a..971241409c30 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2058,9 +2058,6 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string
2058 2058
2059 ret = crypt_setkey(cc); 2059 ret = crypt_setkey(cc);
2060 2060
2061 /* wipe the kernel key payload copy in each case */
2062 memset(cc->key, 0, cc->key_size * sizeof(u8));
2063
2064 if (!ret) { 2061 if (!ret) {
2065 set_bit(DM_CRYPT_KEY_VALID, &cc->flags); 2062 set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
2066 kzfree(cc->key_string); 2063 kzfree(cc->key_string);
@@ -2528,6 +2525,10 @@ static int crypt_ctr_cipher(struct dm_target *ti, char *cipher_in, char *key)
2528 } 2525 }
2529 } 2526 }
2530 2527
2528 /* wipe the kernel key payload copy */
2529 if (cc->key_string)
2530 memset(cc->key, 0, cc->key_size * sizeof(u8));
2531
2531 return ret; 2532 return ret;
2532} 2533}
2533 2534
@@ -2966,6 +2967,9 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
2966 return ret; 2967 return ret;
2967 if (cc->iv_gen_ops && cc->iv_gen_ops->init) 2968 if (cc->iv_gen_ops && cc->iv_gen_ops->init)
2968 ret = cc->iv_gen_ops->init(cc); 2969 ret = cc->iv_gen_ops->init(cc);
2970 /* wipe the kernel key payload copy */
2971 if (cc->key_string)
2972 memset(cc->key, 0, cc->key_size * sizeof(u8));
2969 return ret; 2973 return ret;
2970 } 2974 }
2971 if (argc == 2 && !strcasecmp(argv[1], "wipe")) { 2975 if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
@@ -3012,7 +3016,7 @@ static void crypt_io_hints(struct dm_target *ti, struct queue_limits *limits)
3012 3016
3013static struct target_type crypt_target = { 3017static struct target_type crypt_target = {
3014 .name = "crypt", 3018 .name = "crypt",
3015 .version = {1, 18, 0}, 3019 .version = {1, 18, 1},
3016 .module = THIS_MODULE, 3020 .module = THIS_MODULE,
3017 .ctr = crypt_ctr, 3021 .ctr = crypt_ctr,
3018 .dtr = crypt_dtr, 3022 .dtr = crypt_dtr,