Encrypt Your Root Filesystem
In the Linux Journal article “Implementing Encrypted Home Directories” (August 2003), I described how to encrypt home directories transparently. This article describes how to implement another technique, an encrypted root filesystem. I discuss the GNU/Linux boot process and software requirements, present some instructions, introduce Open Firmware and discuss other relevant considerations. The system I use to teach these concepts is a New World PowerPC-based Apple iBook running a pre-release of Fedora Core 3. Despite these specifics, the concepts and procedures in this article can be applied to any device, architecture or operating system. My instructions assume you have a spare USB Flash disk and your system's firmware has the ability to boot off of it.
I also assume the reader is comfortable applying source patches and compiling programs. As of Fedora Core 3 Test 3, the mkinitrd and initscripts packages require patching to support an encrypted root filesystem. A basic understanding of how to manage partitions and create filesystems also is required. Performing a basic install of a Linux distribution is beyond the scope of this article.
Before presenting the technical steps involved, a higher-level concept must be discussed, trust. Trust is intertwined with cryptography and authentication. An implicit assumption of trustworthiness is given to any device that has an electronic key. For example, when I share my bank account PIN with an automatic teller machine, I trust that the ATM will not share my PIN with an inappropriate third party. In the same way, when I provide an encryption key to my computer, I assume the key will not be shared with anyone else. I trust the computer to keep the secret between us.
So, can you trust your computer? Unless you carry it with you everywhere, you really can't. This is true even if the disks have been encrypted. Consider this scenario: someone steals your computer as you sleep. The thief makes a copy of the encrypted contents of the computer, even though they are useless to him without their encryption key. He then replaces the encrypted laptop contents with something a little more diabolical and puts the computer back. When you wake up the next day, the computer prompts for an encryption password as it does every morning. But this time when you provide the key it electronically transmits the key to the thief. Because he now has a copy of your data and key, he can read your files.
This scenario may be a bit far-fetched, but it does illustrate a point. You can't trust your laptop. It's too big to keep your eyes on all the time. Therefore, no matter how well implemented your encryption system is, it is built without the prerequisite foundation of trust.
To ensure that we can trust the computer's boot process, we need to separate it from the computer. Consider this: you carry the keys to your car with you instead of carrying your car. Your encryption key is a natural conceptual leap from your car key. You can protect your encryption key more easily, so you don't have to carry your computer everywhere. To take things a little further and to address the above scenario, we also will place the software required to boot the computer on this key. The Flash disk will serve as this key. By protecting the software that boots the system initially, in addition to the encryption key, we can mitigate the risk of the boot process being hijacked.
An understanding of how your computer boots is required, because unlocking an encrypted root filesystem is integral to the bootstrap process. The current, stable kernel series, 2.6, optionally uses initramfs to help boot, as documented in LWN.net's “Initramfs Arrives”. Initramfs is a cpio archive that the kernel now knows how to unpack into a RAM-based disk. This unpacked filesystem contains a script that traditionally loads kernel modules needed to mount the root filesystem. In our case, this script also unlocks the encrypted root filesystem. More information on this subject can be found in the files buffer-format.txt and initrd.txt that are distributed with the Linux kernel sources.
Several filesystem encryption interfaces are available for Linux. Jari Ruusu's Loop-AES is one such project. Several cryptoloop variations that provide an encrypted loopback device also exist. This article focuses on the dm-crypt interface provided by recent 2.6 Linux kernels. This interface currently is preferred by the Fedora Project, and dm-crypt modules are provided by Fedora's kernel packages. Also required is a statically linked cryptsetup. This utility simplifies the management of dm-crypt devices. Finally, parted and hfsutils are used to manage the boot filesystem.
Unfortunately, Fedora Core's anaconda installer does not yet support installing to an encrypted filesystem out of the box. To bypass this limitation, you must leave a partition free, install Fedora, format the free partition as an encrypted filesystem and copy the originally installed data onto the new encrypted filesystem. For the purpose of simplicity, I assume Fedora is to be installed onto two partitions: /dev/hda4, mounted at /home, and /dev/hda5, mounted at /. Because /home is not populated until after Fedora is installed, we can use /dev/hda4 as our spare partition and /dev/hda3 as the swap partition.
Install Fedora Core 3, mounting /dev/hda4 at /home and /dev/hda5 at /. Do not add any nonroot users yet, as /home will be wiped clean later. At this point, you should have a fully functioning Linux system.
Before an encrypted filesystem is set up, you should randomize the partition it will occupy. This eliminates a potential leak of information about the disk's contents. Figure 1 demonstrates an abstract disk that is half-full and not randomized properly. Figure 2 demonstrates a disk that was randomized properly before being formatted to contain an encrypted filesystem. Notice that, given Figure 1, one can gain some knowledge about its contents (such as that they span one-half of the disk). Figure 2 affords an adversary no such luxury. In this case, the disk could as easily be empty as full. A partition is randomized by overwriting its contents with random data: dd if=/dev/urandom of=/dev/hda4. This process can take a long time, because creating random data is somewhat difficult.
To create an encrypted ext3 filesystem on /dev/hda4, use the following steps:
1) Ensure that the aes, dm-mod and dm-crypt modules have been loaded into the kernel.
2) Unmount the partition that will host the encrypted root filesystem, /dev/hda4, from /home:
# umount /dev/hda4
3) Create a random 256-bit encryption key and store it at /etc/root-key:
# dd if=/dev/urandom of=/etc/root-key bs=1c count=32