Commit 542da317668c35036e8471822a564b609d05af66
Committed by
Alasdair G Kergon
1 parent
b95bf2d3d5
Exists in
master
and in
7 other branches
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>
Showing 1 changed file with 30 additions and 4 deletions Side-by-side Diff
drivers/md/dm-crypt.c
1 | 1 | /* |
2 | 2 | * Copyright (C) 2003 Christophe Saout <christophe@saout.de> |
3 | 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 | 6 | * This file is released under the GPL. |
7 | 7 | */ |
... | ... | @@ -72,6 +72,7 @@ |
72 | 72 | const char *opts); |
73 | 73 | void (*dtr)(struct crypt_config *cc); |
74 | 74 | int (*init)(struct crypt_config *cc); |
75 | + int (*wipe)(struct crypt_config *cc); | |
75 | 76 | int (*generator)(struct crypt_config *cc, u8 *iv, sector_t sector); |
76 | 77 | }; |
77 | 78 | |
... | ... | @@ -199,6 +200,17 @@ |
199 | 200 | crypto_hash_digestsize(essiv->hash_tfm)); |
200 | 201 | } |
201 | 202 | |
203 | +/* Wipe salt and reset key derived from volume key */ | |
204 | +static 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 | + | |
202 | 214 | static void crypt_iv_essiv_dtr(struct crypt_config *cc) |
203 | 215 | { |
204 | 216 | struct iv_essiv_private *essiv = &cc->iv_gen_private.essiv; |
... | ... | @@ -334,6 +346,7 @@ |
334 | 346 | .ctr = crypt_iv_essiv_ctr, |
335 | 347 | .dtr = crypt_iv_essiv_dtr, |
336 | 348 | .init = crypt_iv_essiv_init, |
349 | + .wipe = crypt_iv_essiv_wipe, | |
337 | 350 | .generator = crypt_iv_essiv_gen |
338 | 351 | }; |
339 | 352 | |
... | ... | @@ -1305,6 +1318,7 @@ |
1305 | 1318 | static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) |
1306 | 1319 | { |
1307 | 1320 | struct crypt_config *cc = ti->private; |
1321 | + int ret = -EINVAL; | |
1308 | 1322 | |
1309 | 1323 | if (argc < 2) |
1310 | 1324 | goto error; |
1311 | 1325 | |
... | ... | @@ -1314,10 +1328,22 @@ |
1314 | 1328 | DMWARN("not suspended during key manipulation."); |
1315 | 1329 | return -EINVAL; |
1316 | 1330 | } |
1317 | - if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) | |
1318 | - return crypt_set_key(cc, argv[2]); | |
1319 | - if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) | |
1331 | + if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { | |
1332 | + ret = crypt_set_key(cc, argv[2]); | |
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 | 1345 | return crypt_wipe_key(cc); |
1346 | + } | |
1321 | 1347 | } |
1322 | 1348 | |
1323 | 1349 | error: |