Linux Disk Encryption Using LoopAES And SmartCards

= Linux, Loop-AES and Optional Smartcard Based Disk Encryption =

The goal is to create an encrypted linux system using TuxOnIce or uswsusp on a loop-AES encrypted harddrive that is also encrypted when suspended, optionally storing the encryption keys on PKCS#11 cryptographic tokens (Smartcards).

This manual focus is to demonstrate the process and challenges, and still be productive for actual usage.

We would like to thank the following people:


 * Jari Ruusu who made loop-aes available.
 * Pavel Machek and Rafael J. Wysocki who made uswsusp available.
 * Nigel Cunningham who made TuxOnIce available.
 * Michal Januszewski for his work on fbsplash/gensplash.

The following demonstrates a working method and includes a check to see if the unencrypted /boot partition was changed (leading to a possibly compromised kernel or initrd/initramfs). And If you use frame buffer splash you also get a nice bootsplash with suspend/resume status and a set of tools to compile your kernel correctly.

We hope you will find this information useful.

Required Components

 * loop-aes from http://sourceforge.net/projects/loop-aes/ needed to encrypt a disk on-the-fly.
 * aespipe from http://sourceforge.net/projects/loop-aes/ needed to encrypt/decrypt partition.
 * uswsusp from http://suspend.sf.net optional: needed for suspending.
 * TuxOnIce from http://www.tuxonice.net optional:needed for suspending.
 * suspend2-userui from http://www.tuxonice.net optional: needed for suspend/resume status report in tuxonice configuration.
 * aescrypt from http://www.aescrypt.com/ optional: need to handle file based keys by aescrypt.
 * gpg from http://www.gnupg.org/ optional: needed to handle file based keys by gnupg.

Prerequisites
Knowledge of all of these is easy to obtain with the help of Google and the documentation for TuxOnIce and Loop-AES.


 * You know how to compile utilities in static mode.
 * You know how to create initramfs.
 * Make sure you have a working initramfs and that you control the init/linuxrc script.


 * Make sure you have a working TuxOnIce or uswsusp environment.
 * Make sure you have a working loop-aes environment, test loop on files.
 * Generate keys to be used to encrypt your disk.
 * Compile aescrypt/gpg, losetup, aespipe as static.
 * You have a backup of all data on your system. If something breaks you could easily lose the entire partition.

Partitions
In order to have a secure encrypted and suspendable environment, you will need to have at least three partitions on your hard drive.
 * boot partition
 * Unencrypted /boot partition, used to hold kernel, initramfs and keyfile.


 * swap partition
 * Encrypted swap partition, used for suspending, resuming, and safely swapping memory to disk.


 * root partition
 * Encrypted root partition, your data may be stored here.


 * /dev/sda1 - boot
 * /dev/sda2 - swap
 * /dev/sda3 - root

There are a number of ways to store the decryption keys and we try to accommodate them all. A key may be kept on a PKCS#11 cryptographic token, in a keyfile encrypted with symmetric encryption. If you do not have a smartcard, you can store a keyfile on external media such as a cd-rom or usb thumb drive. Please refer to the Loop-AES documentation for instructions on generating keys and a security analysis. Because symmetric encryption is heavily dependent on the strength of the passphrase used, http://www.diceware.com is suggested for generating strong passphrases.

Outline

 * Compile a new kernel with necessary patches and additions
 * Test new kernel
 * Create an initramfs
 * Create encryption keys
 * Set up the framework for Loop-AES encrypted root and swap
 * Actually encrypt root and swap
 * Prepare suspend framework
 * Test the final product

Compiling a New Kernel

 * Compile your kernel with TuxOnIce or uswsusp support, initramfs support and NO loop device support.
 * Compile loop-aes module.

Add:

sys-apps/loop-aes-losetup is available via overlay at http://github.com/alonbl/alon-barlev-overlay.git

Testing additions
Having done one of the two options above, you should now reboot into your new kernel to test the new features. Use the Loop-AES documentation to ensure that you can create a file-backed encrypted loop and that everything works properly. Don't forget to modprobe loop if you built Loop-AES as a module.

Create Initramfs
An initramfs is a lot like the familiar initrd only it uses a different archiving format (cpio instead of tar) and is accessed by the kernel slightly differently. Initramfs is capable of some things initrd just can't do and is the wave of the future.

Look at initramfs section in order to understand how to create the initramfs.

Initramfs Kernel Parameters
The linuxrc script accepts the following additional kernel parameters:
 * initrd_util
 * pkcs11:application:label,label,label
 * use PKCS#11 smartcards.
 * aescrypt:device:fstype:file,file,file
 * use aescrypt files located at device. wait for device to be available.
 * gpgfile:device:fstype:file,file,file
 * use gnupg files located at device. wait for device to be available.


 * initrd_devices=/dev/sdXN,/dev/sdYM,...
 * devices to loop over.


 * initrd_loopstart=N
 * The first loop index (/dev/loopN)


 * initrd_shell=N
 * Interrupts the initramfs and drops to a shell at a specified location (rescue, install, repare), see the linuxrc for more locations.

If no initrd_* parameter is specify, the initramfs will perform regular boot with no encryption support.

Example: initrd_util=aescrypt:/dev/sda1:ext2:/swap.key,/root.key initrd_devices=/dev/sda2,/dev/sda3 initrd_loopstart=4

This will load utilities from /dev/sda1 and map:
 * /dev/loop4->/dev/sda2 with key from /swap.key
 * /dev/loop5->/dev/sda3 with key from /root.key

Using a file
Run the following command:

Using PKCS#11 cryptographic token
Install pkcs11-data:

Run the following command, replacing pkcs11_provider_library with your PKCS#11 provider library:

The output will include all available tokens, select the correct token, the id='...' field is the token id to be used in next command.

Run the following command, replacing pkcs11_provider_library with your PKCS#11 provider library, and token_id with the output taken from previous command, please remember to add single quote for token_id.

Loop-AES Framework
At least the following need to be in your /etc/fstab for your system to boot properly. The suspended image will be written to /dev/loop4. Remember that loop4 maps to sda2 and loop5 maps to sda3. At this time be sure that your system is capable of mounting and unmounting Loop-AES volumes.

Modify:

Actual Encrypting Step
Boot your new kernel with your new initramfs and the following arguments: root=/dev/sda3 initrd_shell=install

You should get a shell after the initramfs has setup itself correctly but before it has mounted any partitions.

This next step goes over all of /dev/sda3 (root partition) and encrypts it. Be sure that Loop-AES is functioning in your kernel, you have created the encryption keys and the encryption keys are available on the partition passed as initrd_util. If any of the above are not true it either will not work or you will lose all your data.

Encryption using aescrypt
Run the following command:

Encryption using gpg key
Run the following command:

Encryption using PKCS#11 cryptographic token
First start PKCS#11 reader support, usually the following commands will do:

Now perform the actual encryption, don't be alarmed that the key is exported to a file, since this file resides in memory, and there is no swap.

First success boot
If you use aescrypt key, reboot using the following arguments: root=/dev/loop5 initrd_encmode=loop-aes:AES256 initrd_util=aescrypt:/dev/sda1:ext2:/root.key \ initrd_devices=/dev/sda3 initrd_loopstart=5

If you use PKCS#11 cryptographic token, reboot using the following arguments: root=/dev/loop5 initrd_encmode=loop-aes:AES256 initrd_util=pkcs11:DISK:MY \ initrd_readers=openct initrd_devices=/dev/sda3 initrd_loopstart=5

You should be prompted for the key password and boot should succeed.

Handle swap
Now we need to encrypt your swap partition.

Create a new key for the swap partition as you have done for your root.

Reboot with the following arguments: root=/dev/loop5 initrd_encmode=loop-aes:AES256 initrd_util=gpgfile:/dev/sda1:ext2:/swap.gpg,/root.gpg \ initrd_devices=/dev/sda2,/dev/sda3 initrd_loopstart=4 resume=/dev/loop4

You should be prompted for the password to the gpg key and boot should succeed.

After boot create swap file:

Congratulations
You have a working Loop-AES environment.

Software Suspend Framework
Now to get software uswsusp or TuxOnIce to work. For TuxOnIce specify a resume= parameter at kernel command-line, for uswsusp update /etc/suspend.conf of initramfs and on your root. Both should point to your swap partition (/dev/loop4).

Specify the suspend mode at kernel command-line initrd_suspend_mode=suspend2 or initrd_suspend_mode=uswsusp

If use uswsusp:

hibernate.conf
Add the following lines to hibernate.conf.

This will check the boot partition on every resume, add:

This will unmount boot partition so it can be mounted during boot by initramfs with no data loss, add:

If you are using fbsplsah, this will activate splash during suspend/resume, modify:

Boot partition integrity
sys-apps/boot-digest is available via overlay at http://github.com/alonbl/alon-barlev-overlay.git.

Use boot-digest-mark utility in order to store the digest of the boot partition, so that you will be notified if it is changed. Configure your system to run boot-digest-check during your boot process.

After you finish all your modifications, you should mark the current boot partition's digest:

During boot or resume, you will receive a warning message if someone has tampered with your unencrypted boot partition.

Trying It All Out
Now try to hibernate... Good luck!

Using PKCS#11 cryptographic tokens
You can use PKCS#11 cryptographic tokens to hold secret key. The symmetric keys are stored on the card as private data object. The advantage to this approach is that it is stronger that using RSA encryption on the symmetric keys.

Create a file /etc/pkcs11.conf with the following format, replace pkcs11_provider_library with the actual name of the PKCS#11 provider library.

You should have udev/mdev support and pcscd in the initramfs and specify initrd_util=pkcs11 as a kernel parameter.

A utility pkcs11-data for import/export of data objects is also required.

Since PKCS#11 provider is a dynamic library, some components of initramfs cannot be compiled statically.

You can import existing gpg keys to smartcard by using the following sequence.

Run the following command, replacing pkcs11_provider_library with your PKCS#11 provider library:

The output will include all available tokens, select the correct token, the id='...' field is the token id to be used in next command.

Run the following command, replacing pkcs11_provider_library with your PKCS#11 provider library, and token_id with the output taken from previous command, please remember to add single quote for token_id.

Reverting
You can revert and decrypt your filesystems. Boot your new kernel with your new initramfs and the following arguments: root=/dev/sda3 initrd_shell=install

You should get a shell after the initramfs has setup itself correctly but before it has mounted any partitions.

Decryption using gpg key
Run the following command:

Decryption using PKCS#11 cryptographic token
First start PKCS#11 reader support, usually the following commands will do:

or:

Now perform the actual decryption, don't be alarmed that the key is exported to a file, since this file resides in memory, and there is no swap.

Open issues
There is no known way to protect against sophisticated kernel attach on the unencrypted boot partition that will cause the hash check to succeed but will write your password on a location of the disk.

For now the only way to detect this is to digest the boot partition and compare it to hashes stored on the encrypted file system. This comparison is run during every boot and every resume from suspend.

In order to minimize the access of external people to this partition, consider putting the kernel and initramfs on a USB mass storage device and boot from this device. Combining with PKCS#11 cryptographic token it is the best solution.

Applets
In case smartcards are used or plug&play is needed for USB storage, additions to genkernel default configuration: CONFIG_FEATURE_DD_IBS_OBS # for initial encryption (notrunc) CONFIG_FEATURE_MDEV_CONF CONFIG_FEATURE_MDEV_EXEC

linuxrc
linuxrc

genkernel-utils
Gentoo's genkernel is a wonderful tool that ease kernel compilation process. This tool can be extended in order to provide the following features:
 * Replace the default linuxrc with the one provided here, in order to support TuxOnIce/uswsusp, disk encryption and PKCS#11. As genkernel's linuxrc script is not flexible to add additions.
 * Add required files to initramfs in order to support TuxOnIce/uswsusp, disk encryption and optionally PKCS#11.
 * Handle remerge of kernel depended modules when a new kernel is configured.
 * Support two versions of the same kernel (Debug and production), in order to not lock computer when invalid kernel is installed.
 * Don't install kernel symbol file in order to make it harder to reverse debug the bzImage.

app-misc/genkernel-utils is available via overlay at http://github.com/alonbl/alon-barlev-overlay.git.

Edit mygenkernel.conf and use mygenkernel to create your initramfs.

If you like to use genkernel and not mygenkernel, set the followings in /etc/genkernel.conf that suits your installation, so that it will create the correct module groups, add:

Maintainer
Alon Bar-Lev