1. dmsetup, losetup and mount
    1. Author
    2. Commands
    3. Summary
    4. Discussion
    5. Security Considerations

dmsetup, losetup and mount

Author

Commands

#!/bin/bash

ldev=/dev/loop/0
mdev=mdev
pass="my_sekkrit_password"

# create empty filesystem image
dd if=/dev/zero of=image bs=1M count=10

# make a block device out of it using the loopback driver 
losetup $ldev image

# get the exact size of the loopback block device
blksize=$(blockdev --getsize $ldev)
echo "blksize= $blksize"

# create a hexadecimal key 128 bits long out of the passphrase
key=$(echo "$pass" | md5sum | cut -d" " -f1)
echo "key= $key"

# create an encrypted block device representation of the image file
# using the aes cipher with the 128 bit key we generated above
echo "0 $blksize crypt aes-plain $key 0 $ldev 0" | dmsetup create $mdev

# create an ext filesystem through the encrypted block device
mkfs -t ext2 /dev/mapper/${mdev}

# mount the filesystem
mkdir mnt
mount /dev/mapper/${mdev} ./mnt

# spawn a subshell so the user can create some files whose contents
# will then be encrypted in the image file.
echo "write some files to mnt, then exit from this subshell"
bash

# undo mount, device mapping, and loopback.
umount mnt
rmdir mnt
dmsetup remove $mdev
losetup -d $ldev

Summary

We extend the previous article (../dmsetup_and_losetup) by creating a filesystem inside the encrypted image file.

Discussion

This script is only a little more complicated than that of the previous article: It creates an ext2 filesystem inside the image file and mounts it. It is somewhat better parameterized (using ldev, mdev, and pass).

This line:

key=$(echo "$pass" | md5sum | cut -d" " -f1)

derives a 128 bit hexadecimal key, suitable for use in the dmsetup command with the aes cipher, from an arbitrary passphrase by calculaing the md5 checksum of the passphrase. The md5sum command can be run on standard in or on named files. For example, running it on a file named tmp.txt:

$ md5sum tmp.txt 

generates the following output:

8448af516bf24b00065a60018992a91a *tmp.txt

In other words, md5sum's output has the form:

<128 bit hexadecimal checksum> <filename>

We discard everything after the checksum using the "cut" command. Our particular "cut" command is saying: assume the input is divided into columns by space characters, and only write out the first column.

Finally, by wrapping the whole command pipe in the bash command quoting construct, "$()", we capture the output in the variable "key".

This line:

mkfs -t ext2 /dev/mapper/${mdev}

creates the filesystem on the mapper device, causing the corresponding cipher text of the filesystem image to be written to the underlying file image_file.

The script then mounts the mapper device at ./mnt and spawns a subshell (the line "bash") to allow the user to create files under mnt. Once finished creating files, the user types "exit", and the script continues executing after the "bash" line. This, by the way, is a useful trick to use when debugging bash scripts with complicated setup sequences: invoke bash in the script right after the complicated setup sequence so the user can determine if the sequence worked.

The final four lines undo mount, loopback, crypto mappings leaving the encrypted filesystem image, image_file, inscrutable to enemey eyes.

To verify that the crypto mapping wasn't a *complete and utter fraud*, you can try mounting image_file without the crypto mapping like this:

mount -o loop image_file ./mnt

To mount the image_file properly, and to view the same files created inside the filesystem during the first run, simply comment out the "dd" command in the above script and run it again. From inside the subshell, you should be able to see the previously created files.

Security Considerations

When building scripts that are serious about protecting data from prying eyes, you need to consider at least two additional factors.

hopeless_linux: encrypted filesystems/dmsetup losetup and mount (last modified 2007-07-01 16:01:00)