Image of the glider from the Game of Life by John Conway
Skip to content

Randomize First, Then Encrypt Your Block Device

This blog post is in continuation of the previous post, where I showed why you should not use ECB when encrypting your data. Well, when putting down an encrypted filesystem, such as LUKS, you've probably been told that you should put random data down on the partition first BEFORE encrypting the disk. Well, this post will illustrate why, and it's simple enough to do on your own GNU/Linux system.

I'll be using bitmaps in this example, as I did in the previous, except I'll use a different image. First, let's create a "random filesystem". Encrypted data should appear as nothing more than random data to the casual eye. This will be our target image for this exercise.

$ dd if=/dev/urandom of=target.bmp bs=1 count=480054
$ dd if=glider.bmp of=target.bmp bs=1 count=54 conv=notrunc

Here is what my target "encrypted filesystem" should look like (converting to GIF format for this post). Click to zoom:

Plaintext image Target filesystem

Now let's create a file full of binary zeros. This file will be the basis for our block device, and imitates an unused hard drive quite well. I have chosen ext2 over other filesystems, mostly because the size restriction with these files. Feel free to increase the file sizes, and use ext3, ext4, XFS, JFS, or whatever you want.

The file "400x400.bmp" is a white bitmap that is 400x400 pixels in size, rather than the 200x200 pixel "glider.bmp". This is to accommodate for the larger filesystems used in this post, and make the illustrations more clear. For your convenience, download the 400x400.bmp and glider.bmp for this exercise.

In these commands, "$" means running the command as an unprivileged user, "#" means running as root.

$ dd if=/dev/zero of=plain-zero-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 plain-zero-ext2.bmp
# mkfs.ext2 /dev/loop0
# mount /dev/loop0 /mnt
# cp glider.bmp /mnt
# umount /mnt
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=plain-ext2.bmp bs=1 count=54 conv=notrunc

This should give us a reference image to see what a "plaintext" filesystem would look like with our file copied to it. Now, let's setup two encrypted filesystems, one using ECB and the other using CBC, and we'll compare the three files together:

First the ECB filesystem:

$ dd if=/dev/zero of=ecb-zero-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 ecb-zero-ext2.bmp
# cryptsetup -c aes-ecb create ecb-disk /dev/loop0
# mkfs.ext2 /dev/mapper/ecb-disk
# mount /dev/mapper/ecb-disk /mnt
# cp glider.bmp /mnt
# umount /mnt
# dmsetup remove ecb-disk
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=cbc-zero-ext2.bmp bs=1 count=54 conv=notrunc

Now the CBC filesystem:

$ dd if=/dev/zero of=cbc-zero-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 cbc-zero-ext2.bmp
# cryptsetup create cbc-disk /dev/loop0
# mkfs.ext2 /dev/mapper/cbc-disk
# mount /dev/mapper/cbc-disk /mnt
# cp glider.bmp /mnt
# umount /mnt
# dmsetup remove cbc-disk
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=ecb-zero-ext2.bmp bs=1 count=54 conv=notrunc

What do we have? Here are the results of my filesystems. Click to zoom:

Plaintext filesystem ECB filesystem CBC filesystem

How do they compare to our target filesystem? Well, not close really. Even when using CBC mode with AES, we can clearly see where the encrypted data resides, and where it doesn't. Now, rather than filling our disk with zeros, let's fill it with random data, and go through the same procedure as before:

First the "plaintext" filesystem:

$ dd if=/dev/urandom of=plain-urandom-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 plain-urandom-ext2.bmp
# mkfs.ext2 /dev/loop0
# mount /dev/loop0 /mnt
# cp glider.bmp /mnt
# umount /mnt
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=plain-urandom-ext2.bmp bs=1 count=54 conv=notrunc

Now the ECB filesystem:

$ dd if=/dev/urandom of=ecb-urandom-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 ecb-urandom-ext2.bmp
# cryptsetup -c aes-ecb create ecb-disk /dev/loop0
# mkfs.ext2 /dev/mapper/ecb-disk
# mount /dev/mapper/ecb-disk /mnt
# cp glider.bmp /mnt
# umount /mnt
# dmsetup remove ecb-disk
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=cbc-urandom-ext2.bmp bs=1 count=54 conv=notrunc

Finally, the CBC filesystem:

$ dd if=/dev/urandom of=cbc-urandom-ext2.bmp bs=1 count=480054
# losetup /dev/loop0 cbc-urandom-ext2.bmp
# cryptsetup create cbc-disk /dev/loop0
# mkfs.ext2 /dev/mapper/cbc-disk
# mount /dev/mapper/cbc-disk /mnt
# cp glider.bmp /mnt
# umount /mnt
# dmsetup remove cbc-disk
# losetup -d /dev/loop0
$ dd if=400x400.bmp of=ecb-urandom-ext2.bmp bs=1 count=54 conv=notrunc

Check our results. Click to zoom:

Plaintext filesystem ECB filesystem CBC filesystem

Much better! By filling the underlying disk with (pseudo)random data first, then encrypting the filesystem with AES using CBC, we have a hard time telling the difference between it and our target filesystem, which was our main goal.

So, please, for the love of security, before putting down an encrypted filesystem on your disk, make sure you fill it with random data FIRST! The Debian installer, and many others, does this by default. Let it run to completion, even if it takes a few hours.

{ 14 } Comments

  1. Philipp Kern using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 21, 2012 at 8:49 am | Permalink

    Well, you don't really say why you need to do that. Sure, it's visible from the outside where/how much data is stored. (Especially if you use discard with SSDs.) And it's visible what kind of file system you use. But it shouldn't make access to the encrypted data any easier, given that it still resembles random data, should it?

  2. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 21, 2012 at 11:35 am | Permalink

    Absolutely! It will be clear from my next post, WHY you want to put random data underneath. There are some fairly effective attacks you can mount, to determine what sort of data is being hidden, and what it contains.

  3. Mathias Hasselmann using Google Chrome 17.0.963.56 on Ubuntu 64 bits | February 21, 2012 at 5:13 am | Permalink

    Trivial fix:

    # cp glider.bmp /mnt
    + # dd if=/dev/zero of=/mnt/fill bs=1
    # umount /mnt

    This step can be applied __after__ setting up the file system, but permits you to start working already. So no need to wait for hours. Actually wondering why Linux is not initializing free space of encrypted disking after setup. Could be considered a bug.

  4. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 21, 2012 at 7:54 am | Permalink

    Yes and no. This can be applied after setting up the filesystem, but then you'll notice "spaces" in the encrypted output. This is because the underlying block device is writing data at either 512-byte or 4-kbyte blocks. Where the data doesn't fill an entire block, there will be a space between it, and the start of the new file. These spaces will reveal file size and location, which will make watermarking and snapshot attacks a breeze.

  5. textshell using Konqueror 4.4 on GNU/Linux | February 21, 2012 at 4:24 pm | Permalink

    Comment 4 makes quite a bit of sense that files written between creating the filesystem on a encrypted volume (without randomizing before) and filling it with some kind of data (ideally random) will have worse properties. But if the data does change a bit over time it would "age" out, wouldn't it? Maybe it would be a good addition to your serien to discuss/visualize this a bit more explicit. Although it would be harder esp. with the aging.

  6. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 21, 2012 at 7:37 pm | Permalink

    textshell- Sure. You could just as easy fill your filesystem with random data after the install. Then, as your data needs expand, you will be effectively writing over where that random file existed. That works, but it shouldn't be the first thing you do. You should put the random data down first, then format and install. But, if you forget to do so, then you can make that large random file, as it is certainly better than nothing.

  7. gotfeed using Firefox 10.0.2 on Mac OS | February 21, 2012 at 8:37 pm | Permalink

    Does the Ubuntu alternative image installer do this when you enable LVM with encryption during the installation?

  8. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 22, 2012 at 5:07 am | Permalink

    gotfeed- Yes, the alternative installer does begin randomizing the disk, if you choose to do encrypted LVM.

  9. patrickdk using Safari 533.1 on Android | February 22, 2012 at 6:39 am | Permalink

    Using urandom is too slow, normally 3mb/sec. Just encrypt the block device, dd something to that device, then format it with you filesystem. This takes out not having random data in filesystem metadata areas. And so much faster than urandom, going at 50mb/s or faster even for slower cpus using aes.

  10. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 22, 2012 at 7:53 am | Permalink

    patrickdk- Your performance will depend entirely on the PRNG that is used, and the device you've booted from. The debian installer uses the same PRNG that is found in the Linux kernel, and when booted off the CD, will move at a pace of about 30 MBps on my laptop hard drive, which is the max speed my drive can realistically do.

  11. patrickdk using Safari 533.1 on Android | February 22, 2012 at 1:24 pm | Permalink

    Strange, this was tested with ubuntu 10.04 installed on a internal drive, and formatting anotherdrive. Even my servers dont get a urand more tham 4mb/sec. Maybe a kernel change recently?

  12. Aaron Toponce using Debian IceWeasel 10.0.2 on GNU/Linux 64 bits | February 22, 2012 at 7:20 pm | Permalink

    patrickdk- So, it's going to depend on your hardware, how much RAM you have, and how fast you can generate pseudorandom data, as well as the PRNG you use. If you absolutely need performance, then I would recommend booting off of a Knoppix CD, encrypting your drive, mounting it, and filling it with a file from /dev/zero. Then, reboot back into your installer and go from there. On my cheap workstation here at work, I can generate data from /dev/urandom at about 15 MBps, after RAM has been flushed.

  13. Jim using Firefox 10.0.1 on GNU/Linux | February 26, 2012 at 11:36 am | Permalink

    Regarding comments 4 and 5, I agree it is best to lay down the random data first. The data to be protected should be mingled/integrated with random data as closely as possible, so that it fills partial blocks and metadata areas as explained above. Also, if you need to ever securely wipe the disk, having random data "underneath" your secured data might give better protection against phorensic data salvage, that's only my hunch/speculation though.

  14. Jim using Firefox 10.0.1 on GNU/Linux | February 26, 2012 at 11:46 am | Permalink

    Any reason why you are using a block size of 1 byte with dd ? (bs=1)

Post a Comment

Your email is never published nor shared.

Switch to our mobile site