[PATCH 3/3] dm-crypt: Add support for stream ciphers using blkcipher interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Current implementation of dm-crypt supports block ciphers of the form
"template(cipher)", e.g. "cbc(aes)". It does not support stream
ciphers of the form "cipher", e.g. "salsa20", that uses the blkcipher
interface directly.

This patch adds support for stream ciphers using the blkcipher
interface directly. It uses a special chainmode called "stream".
Example of usage:
    cryptsetup luksFormat -c salsa20-stream-plain /dev/loop0

Due to the way ESSIV uses the cipher interface directly, it is not
possible to use something like "salsa20-stream-essiv:md5". However
this is probably not an issue since ESSIV was created to prevent
watermarking attacks and for stream ciphers it is always possible,
i.e. flip the bits in the plaintext and the ciphertext will flip
accordingly. In other words, plain IV generation should be sufficient.

WARNING: Using stream ciphers with dm-crypt must be exercised with
care. If used on a read-write filesystem, it is trivial to extract the
keystream by over-writing files with 0x00s and thus recovering the
original plaintext of the overwritten files. Stream ciphers are
probably more useful for encrypting large amount of data on read-only
filesystem (e.g. media files on DVD-ROMs).

Signed-off-by: Tan Swee Heng <thesweeheng@xxxxxxxxx>
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 28c6ae0..7e07b71 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -782,10 +782,19 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 		goto bad_cipher;
 	}
 
-	if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
-		     chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
-		ti->error = "Chain mode + cipher name is too long";
-		goto bad_cipher;
+	if (strcmp(chainmode, "stream") != 0) {
+		if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s(%s)",
+			     chainmode, cipher) >= CRYPTO_MAX_ALG_NAME) {
+			ti->error = "Chain mode + cipher name is too long";
+			goto bad_cipher;
+		}
+	} else {
+		if (snprintf(cc->cipher, CRYPTO_MAX_ALG_NAME, "%s",
+			     cipher) >= CRYPTO_MAX_ALG_NAME) {
+			ti->error = "Stream cipher name is too long";
+			goto bad_cipher;
+		}
+		
 	}
 
 	tfm = crypto_alloc_blkcipher(cc->cipher, 0, CRYPTO_ALG_ASYNC);

[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux