aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Broz <gmazyland@gmail.com>2013-10-28 18:21:04 -0400
committerMike Snitzer <snitzer@redhat.com>2013-11-09 18:20:20 -0500
commited04d98169f1c33ebc79f510c855eed83924d97f (patch)
tree0f1ebef7bef74d467c850ef676514847d6006d0b
parentda31a0787a2ac92dd219ce0d33322160b66d6a01 (diff)
dm crypt: add TCW IV mode for old CBC TCRYPT containers
dm-crypt can already activate TCRYPT (TrueCrypt compatible) containers in LRW or XTS block encryption mode. TCRYPT containers prior to version 4.1 use CBC mode with some additional tweaks, this patch adds support for these containers. This new mode is implemented using special IV generator named TCW (TrueCrypt IV with whitening). TCW IV only supports containers that are encrypted with one cipher (Tested with AES, Twofish, Serpent, CAST5 and TripleDES). While this mode is legacy and is known to be vulnerable to some watermarking attacks (e.g. revealing of hidden disk existence) it can still be useful to activate old containers without using 3rd party software or for independent forensic analysis of such containers. (Both the userspace and kernel code is an independent implementation based on the format documentation and it completely avoids use of original source code.) The TCW IV generator uses two additional keys: Kw (whitening seed, size is always 16 bytes - TCW_WHITENING_SIZE) and Kiv (IV seed, size is always the IV size of the selected cipher). These keys are concatenated at the end of the main encryption key provided in mapping table. While whitening is completely independent from IV, it is implemented inside IV generator for simplification. The whitening value is always 16 bytes long and is calculated per sector from provided Kw as initial seed, xored with sector number and mixed with CRC32 algorithm. Resulting value is xored with ciphertext sector content. IV is calculated from the provided Kiv as initial IV seed and xored with sector number. Detailed calculation can be found in the Truecrypt documentation for version < 4.1 and will also be described on dm-crypt site, see: http://code.google.com/p/cryptsetup/wiki/DMCrypt The experimental support for activation of these containers is already present in git devel brach of cryptsetup. Signed-off-by: Milan Broz <gmazyland@gmail.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--Documentation/device-mapper/dm-crypt.txt11
-rw-r--r--drivers/md/dm-crypt.c185
2 files changed, 192 insertions, 4 deletions
diff --git a/Documentation/device-mapper/dm-crypt.txt b/Documentation/device-mapper/dm-crypt.txt
index 2c656ae43ba7..c81839b52c4d 100644
--- a/Documentation/device-mapper/dm-crypt.txt
+++ b/Documentation/device-mapper/dm-crypt.txt
@@ -4,12 +4,15 @@ dm-crypt
4Device-Mapper's "crypt" target provides transparent encryption of block devices 4Device-Mapper's "crypt" target provides transparent encryption of block devices
5using the kernel crypto API. 5using the kernel crypto API.
6 6
7For a more detailed description of supported parameters see:
8http://code.google.com/p/cryptsetup/wiki/DMCrypt
9
7Parameters: <cipher> <key> <iv_offset> <device path> \ 10Parameters: <cipher> <key> <iv_offset> <device path> \
8 <offset> [<#opt_params> <opt_params>] 11 <offset> [<#opt_params> <opt_params>]
9 12
10<cipher> 13<cipher>
11 Encryption cipher and an optional IV generation mode. 14 Encryption cipher and an optional IV generation mode.
12 (In format cipher[:keycount]-chainmode-ivopts:ivmode). 15 (In format cipher[:keycount]-chainmode-ivmode[:ivopts]).
13 Examples: 16 Examples:
14 des 17 des
15 aes-cbc-essiv:sha256 18 aes-cbc-essiv:sha256
@@ -19,7 +22,11 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
19 22
20<key> 23<key>
21 Key used for encryption. It is encoded as a hexadecimal number. 24 Key used for encryption. It is encoded as a hexadecimal number.
22 You can only use key sizes that are valid for the selected cipher. 25 You can only use key sizes that are valid for the selected cipher
26 in combination with the selected iv mode.
27 Note that for some iv modes the key string can contain additional
28 keys (for example IV seed) so the key contains more parts concatenated
29 into a single string.
23 30
24<keycount> 31<keycount>
25 Multi-key compatibility mode. You can define <keycount> keys and 32 Multi-key compatibility mode. You can define <keycount> keys and
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index e0c61a326550..50ea7ed24dce 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2,6 +2,7 @@
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-2009 Red Hat, Inc. All rights reserved. 4 * Copyright (C) 2006-2009 Red Hat, Inc. All rights reserved.
5 * Copyright (C) 2013 Milan Broz <gmazyland@gmail.com>
5 * 6 *
6 * This file is released under the GPL. 7 * This file is released under the GPL.
7 */ 8 */
@@ -98,6 +99,13 @@ struct iv_lmk_private {
98 u8 *seed; 99 u8 *seed;
99}; 100};
100 101
102#define TCW_WHITENING_SIZE 16
103struct iv_tcw_private {
104 struct crypto_shash *crc32_tfm;
105 u8 *iv_seed;
106 u8 *whitening;
107};
108
101/* 109/*
102 * Crypt: maps a linear range of a block device 110 * Crypt: maps a linear range of a block device
103 * and encrypts / decrypts at the same time. 111 * and encrypts / decrypts at the same time.
@@ -139,6 +147,7 @@ struct crypt_config {
139 struct iv_essiv_private essiv; 147 struct iv_essiv_private essiv;
140 struct iv_benbi_private benbi; 148 struct iv_benbi_private benbi;
141 struct iv_lmk_private lmk; 149 struct iv_lmk_private lmk;
150 struct iv_tcw_private tcw;
142 } iv_gen_private; 151 } iv_gen_private;
143 sector_t iv_offset; 152 sector_t iv_offset;
144 unsigned int iv_size; 153 unsigned int iv_size;
@@ -231,6 +240,16 @@ static struct crypto_ablkcipher *any_tfm(struct crypt_config *cc)
231 * version 3: the same as version 2 with additional IV seed 240 * version 3: the same as version 2 with additional IV seed
232 * (it uses 65 keys, last key is used as IV seed) 241 * (it uses 65 keys, last key is used as IV seed)
233 * 242 *
243 * tcw: Compatible implementation of the block chaining mode used
244 * by the TrueCrypt device encryption system (prior to version 4.1).
245 * For more info see: http://www.truecrypt.org
246 * It operates on full 512 byte sectors and uses CBC
247 * with an IV derived from initial key and the sector number.
248 * In addition, whitening value is applied on every sector, whitening
249 * is calculated from initial key, sector number and mixed using CRC32.
250 * Note that this encryption scheme is vulnerable to watermarking attacks
251 * and should be used for old compatible containers access only.
252 *
234 * plumb: unimplemented, see: 253 * plumb: unimplemented, see:
235 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 254 * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454
236 */ 255 */
@@ -609,6 +628,153 @@ static int crypt_iv_lmk_post(struct crypt_config *cc, u8 *iv,
609 return r; 628 return r;
610} 629}
611 630
631static void crypt_iv_tcw_dtr(struct crypt_config *cc)
632{
633 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
634
635 kzfree(tcw->iv_seed);
636 tcw->iv_seed = NULL;
637 kzfree(tcw->whitening);
638 tcw->whitening = NULL;
639
640 if (tcw->crc32_tfm && !IS_ERR(tcw->crc32_tfm))
641 crypto_free_shash(tcw->crc32_tfm);
642 tcw->crc32_tfm = NULL;
643}
644
645static int crypt_iv_tcw_ctr(struct crypt_config *cc, struct dm_target *ti,
646 const char *opts)
647{
648 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
649
650 if (cc->key_size <= (cc->iv_size + TCW_WHITENING_SIZE)) {
651 ti->error = "Wrong key size for TCW";
652 return -EINVAL;
653 }
654
655 tcw->crc32_tfm = crypto_alloc_shash("crc32", 0, 0);
656 if (IS_ERR(tcw->crc32_tfm)) {
657 ti->error = "Error initializing CRC32 in TCW";
658 return PTR_ERR(tcw->crc32_tfm);
659 }
660
661 tcw->iv_seed = kzalloc(cc->iv_size, GFP_KERNEL);
662 tcw->whitening = kzalloc(TCW_WHITENING_SIZE, GFP_KERNEL);
663 if (!tcw->iv_seed || !tcw->whitening) {
664 crypt_iv_tcw_dtr(cc);
665 ti->error = "Error allocating seed storage in TCW";
666 return -ENOMEM;
667 }
668
669 return 0;
670}
671
672static int crypt_iv_tcw_init(struct crypt_config *cc)
673{
674 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
675 int key_offset = cc->key_size - cc->iv_size - TCW_WHITENING_SIZE;
676
677 memcpy(tcw->iv_seed, &cc->key[key_offset], cc->iv_size);
678 memcpy(tcw->whitening, &cc->key[key_offset + cc->iv_size],
679 TCW_WHITENING_SIZE);
680
681 return 0;
682}
683
684static int crypt_iv_tcw_wipe(struct crypt_config *cc)
685{
686 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
687
688 memset(tcw->iv_seed, 0, cc->iv_size);
689 memset(tcw->whitening, 0, TCW_WHITENING_SIZE);
690
691 return 0;
692}
693
694static int crypt_iv_tcw_whitening(struct crypt_config *cc,
695 struct dm_crypt_request *dmreq,
696 u8 *data)
697{
698 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
699 u64 sector = cpu_to_le64((u64)dmreq->iv_sector);
700 u8 buf[TCW_WHITENING_SIZE];
701 struct {
702 struct shash_desc desc;
703 char ctx[crypto_shash_descsize(tcw->crc32_tfm)];
704 } sdesc;
705 int i, r;
706
707 /* xor whitening with sector number */
708 memcpy(buf, tcw->whitening, TCW_WHITENING_SIZE);
709 crypto_xor(buf, (u8 *)&sector, 8);
710 crypto_xor(&buf[8], (u8 *)&sector, 8);
711
712 /* calculate crc32 for every 32bit part and xor it */
713 sdesc.desc.tfm = tcw->crc32_tfm;
714 sdesc.desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
715 for (i = 0; i < 4; i++) {
716 r = crypto_shash_init(&sdesc.desc);
717 if (r)
718 goto out;
719 r = crypto_shash_update(&sdesc.desc, &buf[i * 4], 4);
720 if (r)
721 goto out;
722 r = crypto_shash_final(&sdesc.desc, &buf[i * 4]);
723 if (r)
724 goto out;
725 }
726 crypto_xor(&buf[0], &buf[12], 4);
727 crypto_xor(&buf[4], &buf[8], 4);
728
729 /* apply whitening (8 bytes) to whole sector */
730 for (i = 0; i < ((1 << SECTOR_SHIFT) / 8); i++)
731 crypto_xor(data + i * 8, buf, 8);
732out:
733 memset(buf, 0, sizeof(buf));
734 return r;
735}
736
737static int crypt_iv_tcw_gen(struct crypt_config *cc, u8 *iv,
738 struct dm_crypt_request *dmreq)
739{
740 struct iv_tcw_private *tcw = &cc->iv_gen_private.tcw;
741 u64 sector = cpu_to_le64((u64)dmreq->iv_sector);
742 u8 *src;
743 int r = 0;
744
745 /* Remove whitening from ciphertext */
746 if (bio_data_dir(dmreq->ctx->bio_in) != WRITE) {
747 src = kmap_atomic(sg_page(&dmreq->sg_in));
748 r = crypt_iv_tcw_whitening(cc, dmreq, src + dmreq->sg_in.offset);
749 kunmap_atomic(src);
750 }
751
752 /* Calculate IV */
753 memcpy(iv, tcw->iv_seed, cc->iv_size);
754 crypto_xor(iv, (u8 *)&sector, 8);
755 if (cc->iv_size > 8)
756 crypto_xor(&iv[8], (u8 *)&sector, cc->iv_size - 8);
757
758 return r;
759}
760
761static int crypt_iv_tcw_post(struct crypt_config *cc, u8 *iv,
762 struct dm_crypt_request *dmreq)
763{
764 u8 *dst;
765 int r;
766
767 if (bio_data_dir(dmreq->ctx->bio_in) != WRITE)
768 return 0;
769
770 /* Apply whitening on ciphertext */
771 dst = kmap_atomic(sg_page(&dmreq->sg_out));
772 r = crypt_iv_tcw_whitening(cc, dmreq, dst + dmreq->sg_out.offset);
773 kunmap_atomic(dst);
774
775 return r;
776}
777
612static struct crypt_iv_operations crypt_iv_plain_ops = { 778static struct crypt_iv_operations crypt_iv_plain_ops = {
613 .generator = crypt_iv_plain_gen 779 .generator = crypt_iv_plain_gen
614}; 780};
@@ -644,6 +810,15 @@ static struct crypt_iv_operations crypt_iv_lmk_ops = {
644 .post = crypt_iv_lmk_post 810 .post = crypt_iv_lmk_post
645}; 811};
646 812
813static struct crypt_iv_operations crypt_iv_tcw_ops = {
814 .ctr = crypt_iv_tcw_ctr,
815 .dtr = crypt_iv_tcw_dtr,
816 .init = crypt_iv_tcw_init,
817 .wipe = crypt_iv_tcw_wipe,
818 .generator = crypt_iv_tcw_gen,
819 .post = crypt_iv_tcw_post
820};
821
647static void crypt_convert_init(struct crypt_config *cc, 822static void crypt_convert_init(struct crypt_config *cc,
648 struct convert_context *ctx, 823 struct convert_context *ctx,
649 struct bio *bio_out, struct bio *bio_in, 824 struct bio *bio_out, struct bio *bio_in,
@@ -1491,14 +1666,20 @@ static int crypt_ctr_cipher(struct dm_target *ti,
1491 cc->iv_gen_ops = &crypt_iv_null_ops; 1666 cc->iv_gen_ops = &crypt_iv_null_ops;
1492 else if (strcmp(ivmode, "lmk") == 0) { 1667 else if (strcmp(ivmode, "lmk") == 0) {
1493 cc->iv_gen_ops = &crypt_iv_lmk_ops; 1668 cc->iv_gen_ops = &crypt_iv_lmk_ops;
1494 /* Version 2 and 3 is recognised according 1669 /*
1670 * Version 2 and 3 is recognised according
1495 * to length of provided multi-key string. 1671 * to length of provided multi-key string.
1496 * If present (version 3), last key is used as IV seed. 1672 * If present (version 3), last key is used as IV seed.
1673 * All keys (including IV seed) are always the same size.
1497 */ 1674 */
1498 if (cc->key_size % cc->key_parts) { 1675 if (cc->key_size % cc->key_parts) {
1499 cc->key_parts++; 1676 cc->key_parts++;
1500 cc->key_extra_size = cc->key_size / cc->key_parts; 1677 cc->key_extra_size = cc->key_size / cc->key_parts;
1501 } 1678 }
1679 } else if (strcmp(ivmode, "tcw") == 0) {
1680 cc->iv_gen_ops = &crypt_iv_tcw_ops;
1681 cc->key_parts += 2; /* IV + whitening */
1682 cc->key_extra_size = cc->iv_size + TCW_WHITENING_SIZE;
1502 } else { 1683 } else {
1503 ret = -EINVAL; 1684 ret = -EINVAL;
1504 ti->error = "Invalid IV mode"; 1685 ti->error = "Invalid IV mode";
@@ -1824,7 +2005,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
1824 2005
1825static struct target_type crypt_target = { 2006static struct target_type crypt_target = {
1826 .name = "crypt", 2007 .name = "crypt",
1827 .version = {1, 12, 1}, 2008 .version = {1, 13, 0},
1828 .module = THIS_MODULE, 2009 .module = THIS_MODULE,
1829 .ctr = crypt_ctr, 2010 .ctr = crypt_ctr,
1830 .dtr = crypt_dtr, 2011 .dtr = crypt_dtr,