aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-crypt.c
diff options
context:
space:
mode:
authorMilan Broz <mbroz@redhat.com>2009-12-10 18:51:57 -0500
committerAlasdair G Kergon <agk@redhat.com>2009-12-10 18:51:57 -0500
commit542da317668c35036e8471822a564b609d05af66 (patch)
tree3c553eda1e52cde6b7270fb0b7aa3b5db80d58d9 /drivers/md/dm-crypt.c
parentb95bf2d3d5a48b095bffe2a0cd8c40453cf59557 (diff)
dm crypt: make wipe message also wipe essiv key
The "wipe key" message is used to wipe the volume key from memory temporarily, for example when suspending to RAM. But the initialisation vector in ESSIV mode is calculated from the hashed volume key, so the wipe message should wipe this IV key too and reinitialise it when the volume key is reinstated. This patch adds an IV wipe method called from a wipe message callback. ESSIV is then reinitialised using the init function added by the last patch. Cc: stable@kernel.org Signed-off-by: Milan Broz <mbroz@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md/dm-crypt.c')
-rw-r--r--drivers/md/dm-crypt.c34
1 files changed, 30 insertions, 4 deletions
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 446153a071d6..91e1bf91769f 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> 2 * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
3 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> 3 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
4 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. 4 * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
5 * 5 *
6 * This file is released under the GPL. 6 * This file is released under the GPL.
7 */ 7 */
@@ -72,6 +72,7 @@ struct crypt_iv_operations {
72 const char *opts); 72 const char *opts);
73 void (*dtr)(struct crypt_config *cc); 73 void (*dtr)(struct crypt_config *cc);
74 int (*init)(struct crypt_config *cc); 74 int (*init)(struct crypt_config *cc);
75 int (*wipe)(struct crypt_config *cc);
75 int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); 76 int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector);
76}; 77};
77 78
@@ -199,6 +200,17 @@ static int crypt_iv_essiv_init(struct crypt_config *cc)
199 crypto_hash_digestsize(essiv->hash_tfm)); 200 crypto_hash_digestsize(essiv->hash_tfm));
200} 201}
201 202
203/* Wipe salt and reset key derived from volume key */
204static int crypt_iv_essiv_wipe(struct crypt_config *cc)
205{
206 struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
207 unsigned salt_size = crypto_hash_digestsize(essiv->hash_tfm);
208
209 memset(essiv->salt, 0, salt_size);
210
211 return crypto_cipher_setkey(essiv->tfm, essiv->salt, salt_size);
212}
213
202static void crypt_iv_essiv_dtr(struct crypt_config *cc) 214static void crypt_iv_essiv_dtr(struct crypt_config *cc)
203{ 215{
204 struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; 216 struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv;
@@ -334,6 +346,7 @@ static struct crypt_iv_operations crypt_iv_essiv_ops = {
334 .ctr = crypt_iv_essiv_ctr, 346 .ctr = crypt_iv_essiv_ctr,
335 .dtr = crypt_iv_essiv_dtr, 347 .dtr = crypt_iv_essiv_dtr,
336 .init = crypt_iv_essiv_init, 348 .init = crypt_iv_essiv_init,
349 .wipe = crypt_iv_essiv_wipe,
337 .generator = crypt_iv_essiv_gen 350 .generator = crypt_iv_essiv_gen
338}; 351};
339 352
@@ -1305,6 +1318,7 @@ static void crypt_resume(struct dm_target *ti)
1305static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) 1318static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
1306{ 1319{
1307 struct crypt_config *cc = ti->private; 1320 struct crypt_config *cc = ti->private;
1321 int ret = -EINVAL;
1308 1322
1309 if (argc < 2) 1323 if (argc < 2)
1310 goto error; 1324 goto error;
@@ -1314,10 +1328,22 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
1314 DMWARN("not suspended during key manipulation."); 1328 DMWARN("not suspended during key manipulation.");
1315 return -EINVAL; 1329 return -EINVAL;
1316 } 1330 }
1317 if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) 1331 if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) {
1318 return crypt_set_key(cc, argv[2]); 1332 ret = crypt_set_key(cc, argv[2]);
1319 if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) 1333 if (ret)
1334 return ret;
1335 if (cc->iv_gen_ops && cc->iv_gen_ops->init)
1336 ret = cc->iv_gen_ops->init(cc);
1337 return ret;
1338 }
1339 if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) {
1340 if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
1341 ret = cc->iv_gen_ops->wipe(cc);
1342 if (ret)
1343 return ret;
1344 }
1320 return crypt_wipe_key(cc); 1345 return crypt_wipe_key(cc);
1346 }
1321 } 1347 }
1322 1348
1323error: 1349error: