dm-crypt: Creating Encrypted Filesystem using Devive Mapper This goes from basic FS encryptions through to LUKS FS encryptions. ------------------------------------------------------------------------------- Basic Info Main home page dm-crypt for 2.6 kernels http://www.saout.de/misc/dm-crypt/ It works by creating a new block device in the "/dev/mapper" sub-directory which is software linked to the raw encrypted device. The raw control of this device mapping is via the "dmsetup" program (device-mapper package). Redhat FC2 provides all the above, including the initial device files. A better method "cryptsetup" was later develops first as a shell script and later as a binary that also provides a pass-phrase to encryption key algorithm. The kernel requires either loadable or builtin modules for "dm-mod" and "dm-crypt". The former will load the latter using "modprobe dm-mod". pass-phrase A simple user typed string which is used to either create or decode a longer encryption key. encryption key A long key for the encrypting of the data, usally generated from the pass-phrase using a well known algorithm, such as "ripemd160" (see below). Generally the pass-phrase to key algorithm hashing function is done repeatally (thousands of times) so that even on a fast computer it could take a second or so to generate the key from the pass-phrase. This makes it harder to 'crack' even simple pass-phases using brute force dictionary attacks. A technique known as 'hardening'. Alturnativally, I have seen it encrupted by the pass-phase and stored in a block (offset protected) with-in the disk partition itself. This is not standard however, and if known, may not be as secure. On the other hand such partitions may not be recognizable as being some form of standard encryption by a security agency. Especially if the first few blocks of the partition looks like something else entirely. See other non-cryptsetup methods below. ------------------------------------------------------------------------------- Raw "dmsetup" encryption setup The "dmsetup" command is given a table of lines to create the device mapping. echo "{start_sector} {sector_count} {target_type} {arguments}" | dmsetup create {name} Where {name} name of the new /dev/mapper device to create and mount {start_sector} start of 512 byte sectors (usally 0) {sector_count} size of the device ... what sort of mapping is needed. This is expanded for encryption to... echo "{start_sector} {sector_count} crypt {format} {key} {IV offset} {real_device} {sector_offset}" | dmsetup create {name} Where {format} symmetric encryption cipher and an optional IV generation Typically: aes-ecb Equivelent to the old crypto-loop FS encryption aes-plain A better more secure for of AES encription twofish-ecb {key} 8bit encryption key in Hexadecimal for mapping {IV_offset} Offset to sector count before creating 'IV' (usally 0) {real_device} Block device to contain the encrypted data {sector_offset} Offset where encrypted data begins (usally 0) ------ Raw dmsetup example... File System Partition, encrypted USB drive rm -f /dev/mapper/crypted_fs echo 0 `blockdev --getsize /dev/sda1` crypt aes-plain \ 0123456789abcdef0123456789abcdef 0 /dev/sda1 0 |\ dmsetup create crypted_fs mkfs -t ext3 /dev/mapper/crypted_fs mount /dev/mapper/crypted_fs /mnt/crypted_fs ... umount /dev/mapper/crypted_fs dmsetup remove crypted_fs After creating, and unmounting, just skip the "mkfs" file command. EG: set mapping, and mount. That is all... Note the encryption key above is just a test hexadecimal value 256 bits or 32 bytes long (needed for AES encryption). It should be something more sutiable, like a 'ripemd160' one-way hash of a user pass-phrase, as the cryptsetup tool does. For example ask user for a password and return a256 bit hexadecimal hash hashalot -x -n32 ripemd160 You can recover the key information from a existing mapping using the comand: dmsetup table As such this technique is not safe for suid/sudo access to the "dmsetup" access, particularly on a multi-user system. On the other hand "cryptsetup" does not provide such a option so should be safe for user control, with user specific fstab mount of the mapped partition. You do not have to use a ext3 filesystem, you can use anyfile system type linux can generate, including vfat. You may even be able to use the Windows software "CrossCrypt" to mount encrypted vfat file systems. You don't even have to create a filesystem, just using the raw disk device directly. For example "dd" a compressed tar file onto device, rather than use a filesystem) though that my not be very usable. ASIDE: There are other target other than 'crypt', including making mirrors, and stripes. Type this to see... dmsetup targets The arguments for the other targets is not known. ------------------------------------------------------------------------------- Using cryptsetup Fedora Core Package: cryptsetup The advantage and disadvantage is that the the method use for mounting a encrypting file system is well known and other tools can be developed to make use of that proceedure. For example various File Managers, like "konquer" could be made to ask the user of the pass phrase and mount the file system simply and easilly. Defaults to using "aes-plain" for the files system encryption. Older cryptoloop's defaulted to "aes-ecb", but "aes-plain" is more secure. The pass-phrase is hashed to a 256 bit key (32 bytes) using ripemd160 This is equivelent to the "hashalot" command used above. Example: Encrypted disk partition cryptsetup create x /dev/hda8 # mkfs -t ext3 /dev/mapper/x mount /dev/mapper/x /extra/x ... umount /dev/mapper/x cryptsetup remove x Example: loopback filesystem (also for cdroms) # dd if=/dev/zero of=encrypted.img bs=1M count=100 losetup /dev/loop0 encrypted.img cryptsetup create unencrypted /dev/loop0 # mkfs -t ext3 /dev/mapper/unencrypted mount /dev/mapper/unencrypted /mnt/unencrypted ... umount /dev/mapper/unencrypted cryptsetup remove unencrypted losetup -d /dev/loop0 Example: Encrypted swap, using a completely random key cryptsetup --key-file=/dev/urandom create swap /dev/hda5 mkswap /dev/mapper/swap mkswap swapon /dev/mapper/swap Example: Encrypt an existing disk partition (not guranteed) WARNING: DO NOT interupt it. It can take a long time. fsck -fC /dev/hda3 cryptsetup -y create hda3-aes /dev/hda3 dd if=/dev/hda3 of=/dev/mapper/hda3-aes bs=4k fsck /dev/mapper/hda3-aes mount /dev/mapper/hda3-aes {appropriate_location} VFAT USB key WARNING: for some reason you can not create a vfat filesystem on a mapped device. You need to create the vfat file system, then re-map the FS mkfs -t vfat /dev/sda1 cryptsetup create xusb /dev/sda1 dd if=/dev/sda1 of=/dev/mapper/xusb bs=4k mount /dev/mapper/xusb /extra/xusb ------------------------------------------------------------------------------- Other (non-cryptsetup) Ways of storing keys. Well if you use the third party cryptsetup, the key is generated directly from the pass phrase, so no key needs to be storied. ----- Encrypted Key on Device itself... One way is to use SSL to save a copy of the pass phrase encrypted key in the first block of the raw filesystem, and set up the device mapping so as to ignore that one block. This was incorperated into a perl script, but this has a security flaw, involving the users password on a multi-user machine. For example... Settings device='/dev/sda1' mapper='sda1' magic='fixed identifier string of 32 characters' Generate a random key for the encryption key=`dd if=/dev/random bs=32 count=1 | openssl dgst -md5 -hex` Store the key onto the first partition on the disk, encrypted passwd=`read password from user (no newline)` ( echo $magic; echo $key; ) | \ openssl enc -e -pass pass:"$passwd" -aes256 | \ dd of=$device bs=512 count=1 Read the key from disk passwd=`read password from user (no newline)` dd if=$device bs=512 count=1 | \ openssl enc -d -pass pass:"$passwd" -aes256 | ( read magic -- compare against $magic and abort if different read key ) Set up mapping (skipping the first block) sectors=`blockdev --getsize $device` sectors-- echo "0 $sectors crypt aes-plain $key 0 $device 1" | \ dmsetup create $mapping Mount it mount /dev/mapper/$mapper /data ----- Store key in a GPG (or other) password protected file Create a secure key head -c 2880 /dev/urandom | uuencode -m - |\ head -n 65 | tail -n 64 |\ gpg --armour --symmetric > keyfile.gpg Use a secure key, pipe into cryptsetup gpg --decrypt keyfile.gpg | cryptsetup create ... Or direct to dm_crypt (needs 32 bytes as hexadecimal) head -c 32 /dev/urandom | perl -0777 -e 'print unpack("H*",<>), "\n"' |\ gpg --armour --symmetric > keyfile.gpg gpg --decrypt keyfile.gpg |\ sed 's%.*%0 35021637 crypt aes-plain & 0 /dev/sda1 0% |\ dmsetup create crypted_fs #mkfs -t ext3 /dev/mapper/crypted_fs mount /dev/mapper/crypted_fs /mnt/crypted_fs ------------------------------------------------------------------------------- En-crypting, De-crypting, Re-crypting an existing filesystem I have tested this with LVM2 devices containing nothing important, it worked for me but you are advised to have current working backups if the data matters to you... you have been warned In the following example we convert /dev/hda3 to use dm-crypt as the device /dev/mapper/hda3-aes WARNING: do not use this when a mapping offset is also used. * Unmount the device to be converted: umount /dev/hda3 * Optional: fsck the device (to be sure there are no errors to start with): fsck /dev/hda3 * Setup the new dm-crypt device: cryptsetup -y -c aes -s 256 create hda3-aes /dev/hda3 (enter the passphrase twice) * Start up the convertion process: dd if=/dev/hda3 of=/dev/mapper/hda3-aes bs=4k * Check the command twice as this will overwrite the contents of devices involved * Wait, this could take some time. My test convertions (2Gb) took about 10 minutes on a dual P3 1Ghz) * Once the conversion has finished fsck the new device again: fsck /dev/mapper/hda3-aes * Mount /dev/mapper/hda3-aes where /dev/hda3 would normally have been mounted: mount /dev/mapper/hda3-aes /mnt/hda3 This can be used in reverse to move a device from being encrypted to be plain. In addition you can use this with 2 different mappings to re-encrypt the device with either a new passphrase or with different options including crypher and key size ---- Before copying or burning a encrypted filesystem you should stop the device mapping temporarilly with dmsetup suspend then when finished restart it with dmsetup resume ------------------------------------------------------------------------------- LUKS cryptsetup This is the next advancement in cryptsetup. The passwords are encrypted into a table, which then decodes the filesystem crypt key. This allows you to change encryption passowrd without re-encrypting the whole disk, and even multiple password. However under FC5 it appears to be slow, causing all other applications to lockup for a second or two while the LUKS encrypted filesystem passowrd is checked and the dm-crypt setup. FC10 works very well with LUKS, and even reconizes them on USB disks! You can even encrypt the whole disk or just the home, so that passwords are requested on boot, as specified by a /etc/crypttab file. PreConfiguration Look for badblocks and fill it with random data (long time) /sbin/badblocks -c 10240 -s -w -t random -v /dev/sdb Just fill with random data dd if=/dev/urandom of=/dev/sdb Re-Partition the disk /sbin/fdisk /dev/sdb Create LUKS encrypted cryptsetup luksFormat /dev/sdb1 cryptsetup isLuks /dev/sdb1; echo $? cryptsetup luksOpen /dev/sdb1 sdb1 mkfs -t ext3 /dev/mapper/sdb1 e2label /dev/mapper/sdb1 MyLabel tune2fs -c 0 -i 0 -m 0 /dev/mapper/sdb1 cryptsetup luksClose sdb1 Mount cryptsetup luksOpen /dev/sdb1 sdb1 mount /dev/mapper/sdb1 Unmount umount /dev/mapper/sdb1 cryptsetup luksClose sdb1 Note that the arguments are swapped for 'create' and 'luksOpen' in cryptsetup! This is a real pain for scripts that want to use both. Remember cryptsetup, LUKS or otherwise, can be SUID'd or added to sudo so it can be run as root. Of course a fstab entry is still needed for user mount of the mapped device. -------------------------------------------------------------------------------