In this section I will show how to configure the kernel and some of its utilities to use the loop device mechanism to encrypt block devices (i.e. partitions or regular files containing whole filesystems). This is the preferred method, as it is fast, simple and reliable.
There are, however, some restrictions still not resolved that avoid its use in all and every situation (e.g. swap partitions and root filesystems cannot yet be encrypted reliably), so I will briefly discuss other approaches that may fix some of these issues in section Other Disk Encryption Approaches.
After successfully applying the patch to the kernel source tree, we are in the position to configure the kernel to actually use the encryption routines. As usual, this includes re-compilation of the kernel. If this should be the first time you compile a custom kernel yourself, get yourself the help of a friend or read the Kernel HOWTO.
make oldconfig
will prompt you for only the new kernel
options, while make xconfig
or make menuconfig
will
somewhat hide the new features as they are spread over all the menus,
as we will see in a minute.
After configuring the options you want (see below), you re-compile and install the kernel as usual and then reboot it. Your kernel has now all it needs to support encryption of disks.
This is a short summary of disk encryption related kernel config options. See section Encrypting Network Traffic for options related to network traffic encryption. As of 2.2.11.2, the help texts of most of these options do not contain much information.
This enables the use of a
wide variety of crypto ciphers (= routines that de/encrypt data) for
the Crypto API. The Crypto API can be employed to disk encryption via
the generic crypto driver for the loop device
(CONFIG_BLK_DEV_LOOP_GEN
). That obsoletes the concept that
the ``direct'' drivers CONFIG_BLK_DEV_LOOP_CAST
and
CONFIG_BLK_DEV_LOOP_FISH2
are using. Use of the generic
driver is strongly recommended.
This set of options enables specific ciphers (= routines that de/encrypt data) to be used in CBC mode by the Crypto API (see above).
This options has nothing to do with encryption per se. However, as the current disk encryption implementation uses the loop device, you must say ``Y'' here.
This options allows you to copy around the file containing your encrypted file system without affecting it's usability. Without this option enabled, you have to make sure it stays at the exact same place on the disk in order to use it, because the (absolute, as opposed to relative) block numbers the file occupies on disk affect the crypto cipher, see the question on copying files in the FAQ section.
This
option provides an additional layer of abstraction for crypto
ciphers. With this option enabled, you can use any of the ciphers
(CONFIG_CIPHER_*
) the Crypto API supports.
This option
provides 128-bit key CAST encryption in ECB mode for use with the loop
device. This option does not depend on the general encryption support
(CONFIG_BLK_DEV_LOOP_GEN
) or the Crypto API above. Use of
this option is deprecated.
This option
provides Twofish encryption in CBC mode for use with the loop
device. This options does not depend on the general encryption support
(CONFIG_BLK_DEV_LOOP_GEN
) or the Crypto API above. Use of
this option is deprecated.
This is easy. First, you choose which cipher you want to use. Make sure that you know what using a particular cipher implies (licensing fees and/or even break of law). The help texts as well as the glossary at the end of this document will help you with that, although these sources are not to be considered authorative.
Next, if you want to use CAST-128 or Twofish, then say ``yes'' to
CONFIG_BLK_DEV_LOOP
and CONFIG_BLK_DEV_LOOP_CAST
or
CONFIG_BLK_DEV_LOOP_FISH2
. Note that the implementation of
these ciphers will likely change in future releases, as they will
become accessible through the Crypto API. I'm not sure the future
implementation will be compatible with existing encryption, so use
these only if you have no choice or want to experiment. Also, they
conflict with the loop_gen
driver, so you can only have one
of them in the kernel at any given time.
If you want to use one of the ciphers in the Crypto API, then you need
to say ``yes'' to CONFIG_CIPHERS
,
CONFIG_BLK_DEV_LOOP
, CONFIG_BLK_DEV_LOOP_GEN
and the
cipher you wish to use under ``Crypto options''. I recommend to also
enable CONFIG_BLK_DEV_LOOP_USE_REL_BLOCKS
(available in
patch-int-2.2.10.4
and later), as this solves problems with
physically moving around the encrypted file on disk.
NOTE: Using relative block numbers will probably not help you
if you plan to move the file containing the encrypted filesystem
between underlying filesystems with different block sizes. I nearly
lost my gigabyte of encrypted data while trying to do so. A solution
is in the work. It will allow you to choose the encryption block size
(currently equal to the block size of the underlying filesystem - this
where the trouble stems from) on setup via losetup
.
If you want to compile crypto ciphers as modules, see the FAQ section for how.
util-linux
source
After re-compiling the kernel and rebooting it, you need to patch some
of its helper programs, namely losetup
and/or mount
. The patch
used resides in the Documentation/crypto
hierarchy of the
kernel source tree.
losetup
and mount
need to be patched if you want to use any of the
following ciphers:
patch-int-2.2.17.6
. As it is one short-term
goal to unify the conceptional design of the crypto modules (i.e. all
will use the loop_gen abstraction someday), the size of this list is
likely to monotonically increase as new releases come out.
In order to patch the mount utilities to support encrypted filesystems over the loop device, you need to fetch a recent source tree of the util-linux package, e.g. from ftp.kernel.org/pub/linux/utils/util-linux/ or oneof it's mirrors.
As usual, you issue the following commands to apply the patch:
user$ tar xfzv util-linux*.tar.gz user$ cd util-linux* user$ patch -p1 < /usr/src/linux/Documentation/crypto/util-linux*.patchIt should apply cleanly if you use the patch only on util-linux trees that have a higher version number than the patch file shows.
Next you have to make sure that only the mount utilities are
built. You can get in all sorts of troubles if you mess around with
init
or the password authentication programs. You can render
your computer unusable if you do not make sure that you only compile
mount
and losetup
!.
In order to avoid this mess, you need to install the executable files yourself, so you can gain control over what is being installed. But that is not hard to do:
After paching the util-linux source tree as described above, issue the
following commands in the util-linux*
directory. Make sure
you have not currently mounted any filesystems using the loop device.
user$ ./configure user$ make -C lib setproctitle.o # mount depends on this user$ cd mount user$ make losetup mount umount root# for i in losetup mount umount; do root> j=$(locate bin/$i) root> cp $j{,.old} && chattr +i $j.old root> cp $i $j root> doneIf the make step fails, check that
/usr/include/linux
and
/usr/include/asm
resp. are symlinks to include/linux
and include/asm-arch
resp. Some distributions (e.g. Debian)
only have a copy of the kernel include there. If you change
the kernel, they become outdated.
Change the permissons and ownership of the new binaries according to your distribution's policy (check the old binaries for the right settings).
Create a file that will hold the encrypted data. We will call it
.crypto
for now and assume it is placed in the home diretory
of user ``user''. You can use any other name, though. Note that this
file will not grow dynamically as you feed more and more data into
it. On the other hand, it will permanently block the amount of disk
space you allocate to it, even if there is no data stored in the
encrypted folder. However, you can always grow or shrink the
filesystem manually, see FAQ section for how. Choose a reasonable
size, e.g. 10M in the following command (calculated as bs *
count):
user$ dd if=/dev/urandom of=~/.crypto bs=1024k count=10This will take some time, as the urandom device emits random numbers that need to be created first. The above command takes about one minute to complete on my 300 MHz AMD K6-2. You might want to use
/dev/zero
instead, if you have a slow machine or want a huge
crypto filesystem, but then your filesystem is said to be vulnerable
to known-plaintext attacks. I cannot follow that argument, as we do
not encrypt the zeros, but instead pretend they were the ciphertext.
However, using zeros to create the file in the first place makes it
possible for the attacker to know which blocks have not been written
to. This may give him one or another hint as to how to attack
your ciphertext.
You may also choose to encrypt a whole partition. Just make sure it
contains no data and replace the filename ~/.config
in the
following discussion with the name of the block device that you wish
to use (e.g. /dev/sda3
).
Now set up this file as the target of a loop device. You must do this
as superuser, unless the loop device files can be written to by
everyone (not recommended). Choose a loop device that is not currently
in use. Try mount|grep loop
to see which loop devices are
currently used by mounted filesystems.
root# losetup -e ciphername /dev/loop0 ~user/.crypto Password :Note that you should take your time as you enter the password, as you are not prompted to enter it again for typo checking! One way around this, if you have a recent bash (tested to work with bash-2.04, tested to not work with bash-2.01) and util-linux-2.10p or higher (which will hopefully include the
-p
option to losetup
and mount
), is
to use the following
little script:
#!/bin/bash # the cipher is the first command line argument CIPHER=$1 # the loop device to use is the second LOOPDEV=$2 # the underlying file is third UNDERLYING=$3 # until the two passphrases match and are not empty... until [ "$PASS1" = "$PASS2" -a -n "$PASS1" ]; do # the bash read buitlin has to support the -s option. # Don't use read without -s!! read -s -p "Enter Passphrase: " PASS1; echo read -s -p "Re-enter Passphrase: " PASS2; echo done # setup the loop device using the passphrase given on STDIN. echo "$PASS1" | losetup -e $CIPHER -p 0 $LOOPDEV $UNDERLYING
What you have done so far is to set up a so-called encrypted block
device /dev/loop0
. It is functionally equivalent to a
partition device (e.g. /dev/hda1
), so you next need to do
what you (or your installation tool) did with naked partitions: Make a
filesystem on it. Ext2 should be your choice, as it is Linux' native
filesystem: (FIXME: what about journalling?)
root# mke2fs /dev/loop0Next, you mount it. We take the mount point to be
~/crypto
(notice the omission of the leading dot!):
user$ mkdir ~/crypto root# mount -t ext2 /dev/loop0 ~user/cryptoThe last step needs to be done as root, as only the superuser is allowed to (un)mount filesystems, unless otherwise stated in
/etc/fstab
.
If all worked well, you now have a filesystem that encryptedly resides
in the file ~/.crypto
and is mounted on
~/crypto
. You can enter it and look at the files in it
(not many now as it is just newly created, only the
lost+found
folder should be visible).
Now, all this is nice but really clumsy to do everytime you want to access the encrypted data. But before you learn how to make mounting the encrypted file/folder more user-friendly, you first need to unmount and destroy the loop device. I'd like to make it very clear at this point that encryption does not buy you anything if you leave the filesystem mounted all the time and/or set the permissions not restrictive enough. You should be familiar with what the following commands do, so I will let them speak for themselves:
root# grep -q "lost+found" /dev/loop0 && echo 'found!' root# chmod go= ~user/.crypto root# chown user -R ~user/crypto root# chmod go= -R ~user/cryptoNow unmount the filesytem:
root# umount /dev/loop0and detach the loop device from the file:
root# losetup -d /dev/loop0
You next edit your /etc/fstab
to include the following
line:
/home/user/.crypto /home/user/crypto ext2 \ defaults,noauto,loop,encryption=ciphername,user 0 0where
ciphername
is the same as the one you used with the
losetup
command.
This approach has some advantages over the one previously used to initially create the filesystem:
user
; this is not meant to be the example username
``user'' we used throughout this section!)losetup
yourself, as mount
will do that for you (options loop
, encryption
)mount
will do this for you, choosing free loop devices by itself
as needed.Warning: mount
currently has a bug that leads to the
assignment of additional loop devices, e.g. when remounting. The
symtoms are that the sequence
root# mount /my/crypto/fs.file root# mount -o remount,ro /my/crypto/fs.file root# umount /my/crypto/fs.filewill leave
/dev/loop0
assigned to
/my/crypto/fs.file
. Temporary fix: issue losetup -d
/dev/loop0
after the umount
command. Util-linux version
2.10p should fix this problem.
I cannot yet discuss this (additional) patch to the util-linux tree, as I have not yet successfully installed it on my system.
You may do your own experiments, though: The patch (written by Id Est) and some documentation can be obtained from http://members.home.net/id-est/.
Do not expect too much comfort from this patch, however. It does not
work with rsh
, which is OK, because rsh
is
inherently insecure, but also not with ssh
(although you can
instruct ssh
to use login
for access control) and
su
, which is not acceptable in a networked environment. Also,
I have not seen how it should work for X sessions.
All these restrictions stem from the inherent need to enter the passphrase for decryption. Maybe PAM (pluggable authentication) modules are a better place to implement this functionality, but I have yet to see such an approach being taken. However, there is a quite concrete idea of how to do this floating around in my head. If you are interested, give my a call.
The loop device approach has several drawbacks. Some will be resolved sometime soon, some are deeply buried in the design of the loop device mechanism. Some can be overcome with scripts and tricks, some are not that easy.
Major drawbacks---and a good reason for other approaches to exist---include (in order of increasing chance to overcome them):
This is what Doobee writes about it in his document (see below for an URL):
You can read more about the design of PPDD in the specification or in the PPDD man page (available at the homepage, see below). One of the very nice features of PPDD is that you can decrypt devices without kernel support, if needed. And the author has thought extensively about ways to backup encrypted media and shows several solutions to solve this problem. He even made it possible to have an encrypted root partition.One of the drawbacks of ppdd is that it doesn't use the now evolving Linux Crypto API. But you can use it together with the International Kernel Patch without big hassle. Perhaps you get a few rejects while patching the two together, but these are easy to resolve by hand.
You can find PPDD at http://linux01.gwdg.de/~alatham and ftp://ftp.gwdg.de/pub/ linux/misc/ppdd. If you want to know how to install PPDD, check out the file ppddhow.txt.
I have done some performance testing on a dual PII/266 MHz/256 MB using
bonnie
. Writing on an encrypted volume takes about twice the time as writing to a plain volume. But reading from an encrypted volume takes 4 times as long as reading from an unencrypted one:-------Sequential Output-------- ---Sequential Input-- -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU plain 100 4022 95.0 13628 28.7 4036 17.8 3782 84.7 11663 20.4 encrypted 100 2609 75.5 5719 17.2 808 23.8 968 44.9 1165 28.1 --Random-- -----Time------ --Seeks--- -user- -system- Machine MB /sec %CPU sec sec plain 100 286.3 7.0 42.98 13.82 encrypted 100 18.2 5.1 43.40 103.28While doing these tests my PS/2 mouse reacted like I was using Windows :-( but this should be tweakable by skewing with the buffer cache.
The rest of this section is copied with kind permission of the author from Doobee R. Tzeck's (drt@ailis.de) document "Encrypting your Disks with Linux" at http://drt.ailis.de/crypto/linux-disk.html.
CFS is the first free UNIX disk encryption program hacked by well-known Matt Blaze. It hooks into NFS so one feature of CFS is the fact that you don't have to fiddle with the kernel to get it running and CFS is more portable among UNIXes than the other solutions. Another nice thing is that you can use CFS over NFS so that your files won't be transmitted in clear text over the wire. You can find more about the working of CFS by reading the Cryptographic File System under Linux HOWTO or "A Cryptographic File System for Unix" by Matt Blaze at ftp://research.att.com/dist/mab/.
CFS supports DES, which is insecure because the key is too short, 3DES, which can be considered secure but painfully slow, MacGuffin, which is broken, and SAFER-SK128, which has an unusual design and is designed by some NSA buddys at Cylink---enough reason to not fully trust this algorithm. But darkstar@frop.org was kind enough to hack Blowfish into CFS and Matt Blaze integrated it into CFS 1.3.4.
The main problem of CFS even with Blowfish is the lack of speed. This results from CFS being an user space daemon forcing the data to be copied several times between kernel and user space. If you want to encrypt large amounts of data expect a significant performance penalty when using CFS.
A nice feature of TCFS is that it will allow you to securely share files among the members of a group. One big misfeature of TCFS is the fact that it needs kernel patches and that the patches are still made for the now obsolete 2.0 kernels. Nevertheless TCFS is under active development. Another problem with TCFS is that it only supports minimal (read: no) key management. There is some placebo-key management delivered with TCFS, but that is next to nothing, using only the login password to decrypt the key.
To learn more about TCFS, read the TCFS-FAQ at http://tcfs.dia.unisa.it/tcfs-faq.html. Since it is from Italy, which is part of the free world, you can download it without any problems, from the TCFS Homepage at http://tcfs.dia.unisa.it/.
The theoretical background of SFS was laid by Ross Anderson, Roger Needham and Adi Shamir in their paper "The Steganographic File System". You can grab it at http://drt.ailis.de/crypto/sfs3.ps.gz.
The first implementation was done by Carl van Schaik and Paul Smeddle in a Project called vs3fs. They describe the code they have hacked this way:
Ok, firstly we would like to note that this project evolved from a computer science project that had specific goals and deadlines and thus the code may not be complete in specific areas and still has many bugs to be stomped out.Briefly, a steganographic filesystem aims to be more than just your every day encrypted file system. It tries to hide the information in such a way as to discredit its very existence. This has been a very difficult task to perform given such a short development time, but we have succeeded in attaining this goal despite a few alternative methods of doing things (read: kludges :).
We present this filesystem as is. We take no responsibility for any damage to disks or data while using this program. I repeat: This is still very experimental and you will probably lose data stored on steganographic partitions. We also hope that some of you will be able to work out some of our problems and perhaps try to modify the structure to be more flexible and to provide better security. After all... thats the beauty of open source :)
We must also note that we use encryption methods that may be stronger than those allowed in your country. We will accept no responsibility for your actions involving your country's regulations.
They had a homepage at http://leg.uct.ac.za/~carl/vs3fs/ with patches for Linux 2.0 and 2.1, but this page is now defunct. Seems they have left university and also left SFS alone.
Peter Schneider-Kamp (peter@schneider-kamp.de) updated the stuff to 2.2. This stuff can be found at http://www.linux-security.org/sfs/. But since his pages seem to be down, too, you can also get it at http://drt.ailis.de/crypto/sfspatch-2.2.10.tar.gz.
SFS still has a lot of rough edges and Peter doesn't seem to maintain it actively.
Andrew McDonald and Markus Kuhn did another implementation of the ideas outlaid in the paper of Anderson, Needham and Shamir. They claim that SFS is flawed and this claim seems reasonable.
StegFS seems to be really elaborate and looks much more usable to me than SFS. Since McDonald and Kuhn come from the same University as Anderson, it seems obvious that they tried hard to meet the criteria of the Steganographic Filesystem paper.
StegFS has a homepage at http://ban.joh.cam.ac.uk/~adm36/StegFS/.
There is another good-looking crypto file system called CryptFS. It is described in "CryptFS: A Stackable Vnode Level Encryption File System" and can be downloaded from http://www.cs.columbia.edu/~ezk/research/software/cryptfs/.
But since this site is in the USA, which is a country keeping its scientists from publishing research worldwide, CryptFS is unusable for people from the free world until some dark figure smuggles it over here.
As they are commercial products, I (Marc Mutz) will not include a discussion of them here.