1232 lines
53 KiB
Plaintext
1232 lines
53 KiB
Plaintext
|
Written by Jari Ruusu <jariruusu@users.sourceforge.net>, October 26 2004
|
|||
|
|
|||
|
Copyright 2001,2002,2003,2004 by Jari Ruusu.
|
|||
|
Redistribution of this file is permitted under the GNU Public License.
|
|||
|
|
|||
|
|
|||
|
Table of Contents
|
|||
|
~~~~~~~~~~~~~~~~~
|
|||
|
1. Loop device primer
|
|||
|
2. General information
|
|||
|
2.1. Key setup and IV modes
|
|||
|
2.2. Use of journaling file systems on loop device
|
|||
|
2.3. Use of offsets and sizelimits
|
|||
|
2.4. Use of software suspend
|
|||
|
2.5. File system soft block sizes
|
|||
|
2.6. Compatibility with earlier versions
|
|||
|
3. Instructions for building loop.o driver
|
|||
|
4. Instructions for building new mount, umount, losetup, swapon and swapoff
|
|||
|
5. Instructions for building new gpg
|
|||
|
6. Testing the loop.o driver and losetup program
|
|||
|
7. Examples
|
|||
|
7.1 Example 1 - Encrypting swap on 2.4 and newer kernels
|
|||
|
7.2. Example 2 - Partition backed loop with gpg encrypted key file
|
|||
|
7.3. Example 3 - Encrypted partition that multiple users can mount
|
|||
|
7.4. Example 4 - Encrypting /tmp partition with random keys
|
|||
|
7.5. Example 5 - Encrypting root partition
|
|||
|
7.6. Example 6 - Boot from CD-ROM + encrypted root partition
|
|||
|
8. Security levels
|
|||
|
9. Performance tuning for 2.4 and newer kernels
|
|||
|
10. Files
|
|||
|
11. Credits
|
|||
|
|
|||
|
|
|||
|
1. Loop device primer
|
|||
|
~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Loop devices are block devices that do not store any data directly but loop
|
|||
|
all reads and writes to underlying block device or file, possibly encrypting
|
|||
|
and decrypting data in the process. Normally you don't write to a loop
|
|||
|
device directly, but set up a file system on it. The file system will then
|
|||
|
read from and write to loop device.
|
|||
|
|
|||
|
By default, 8 loop devices are available: /dev/loop0, /dev/loop1 ...
|
|||
|
/dev/loop7 (on devfs /dev/loop/0 ... /dev/loop/7). All devices are
|
|||
|
identical, and each can be tied to one real block device or one file on some
|
|||
|
file system. You have to decide and allocate which loop to use for which
|
|||
|
purpose.
|
|||
|
|
|||
|
losetup(8) program is used to make and tear down the connection between a
|
|||
|
loop device and underlying device or file. You don't have to specify type of
|
|||
|
underlying device as loop driver detects that automatically. mount(8),
|
|||
|
umount(8), swapon(8) and swapoff(8) programs can also set up and tear down
|
|||
|
loop devices.
|
|||
|
|
|||
|
File backed loops may deadlock under some kernel + file system combinations.
|
|||
|
So, if you can choose between device backed and file backed, choose device
|
|||
|
backed even if it means that you have to re-partition your disks.
|
|||
|
|
|||
|
|
|||
|
2. General information
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
This package provides loadable Linux kernel module (loop.o or loop.ko on 2.6
|
|||
|
kernels) that has AES cipher built-in. The AES cipher can be used to encrypt
|
|||
|
local file systems and disk partitions.
|
|||
|
|
|||
|
Loop device encrypts data but does not authenticate ciphertext. In other
|
|||
|
words, it delivers data privacy, but does not guarantee that data has not
|
|||
|
been tampered with. Admins setting up encrypted file systems should ensure
|
|||
|
that neither ciphertext, nor tools used to access ciphertext (kernel +
|
|||
|
kernel modules, mount, losetup, and other utilities) can be trojaned or
|
|||
|
tampered.
|
|||
|
|
|||
|
This package does *not* modify your kernel in any way, so you are free to
|
|||
|
use kernels of your choice, with or without cool patches. This package works
|
|||
|
with 2.0.x, 2.2.x, 2.4.x (2.4.7 or later) and 2.6.x kernels.
|
|||
|
|
|||
|
Latest version of this package can be found at:
|
|||
|
|
|||
|
http://loop-aes.sourceforge.net/
|
|||
|
http://members.tiscali.fi/ce6c8edf/ (limited downloads)
|
|||
|
|
|||
|
New versions are announced to linux-crypto mailing list:
|
|||
|
|
|||
|
http://mail.nl.linux.org/linux-crypto/
|
|||
|
http://www.spinics.net/lists/crypto/
|
|||
|
|
|||
|
List-subscribe: <mailto:linux-crypto-request@nl.linux.org?Subject=subscribe>
|
|||
|
|
|||
|
|
|||
|
2.1. Key setup and IV modes
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
The AES cipher is used in CBC (cipher block chaining) mode. Data is
|
|||
|
encrypted and decrypted in 512 byte chains. Two key setup modes are
|
|||
|
supported; single-key mode and multi-key mode. Single-key mode uses simple
|
|||
|
sector IV and one AES key to encrypt and decrypt all sectors in the loop
|
|||
|
device. Multi-key mode uses cryptographically more secure MD5 IV and 64
|
|||
|
different AES keys to encrypt and decrypt sectors in the loop device. In
|
|||
|
multi-key mode first key is used for first sector, second key for second
|
|||
|
sector, and so on.
|
|||
|
|
|||
|
Password string has a minimum length of 20 characters. Optional password
|
|||
|
seed (salt) and key iteration count can be used to slow down dictionary
|
|||
|
attacks. Password seed is appended to user supplied password before password
|
|||
|
is hashed using one way hash. If password iteration count is specified,
|
|||
|
password hash output is encrypted N thousand times using AES-256. Unique
|
|||
|
seed prevents an adversary from precomputing hashes of passwords in his
|
|||
|
dictionary in advance, and thus making an optimized attack slower. Large
|
|||
|
password iteration count makes dictionary attack painfully slow.
|
|||
|
|
|||
|
If encryption type is specified as AES128 or AES, password string is hashed
|
|||
|
with SHA-256, and 128 bit AES encryption is used. If encryption type is
|
|||
|
specified as AES192, password string is hashed with SHA-384, and 192 bit AES
|
|||
|
encryption is used. If encryption type is specified as AES256, password
|
|||
|
string is hashed with SHA-512, and 256 bit AES encryption is used.
|
|||
|
|
|||
|
|
|||
|
2.2. Use of journaling file systems on loop device
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Don't use a journaling file system on top of file backed loop device. Device
|
|||
|
backed loop device can be used with journaling file systems as device backed
|
|||
|
loops guarantee that writes reach disk platters in order required by
|
|||
|
journaling file system (write caching must be disabled on the disk drive, of
|
|||
|
course). With file backed loop devices, correct write ordering may extend
|
|||
|
only to page cache (which resides in RAM) of underlying file system. VM can
|
|||
|
write such pages to disk in any order it wishes, and thus break write order
|
|||
|
expectation of journaling file system.
|
|||
|
|
|||
|
|
|||
|
2.3. Use of offsets and sizelimits
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
losetup and mount programs support using offset to underlying device or
|
|||
|
file. 2.4.x and later kernels also support use of sizelimit that limit size
|
|||
|
of device to some subset of full underlying device or file size. Both offset
|
|||
|
and sizelimit are specified in bytes. If no offset is specified, zero offset
|
|||
|
is used. If no sizelimit is specified, full device/file size is used. If you
|
|||
|
do use nonzero offsets, make sure offset is integer multiple of 512 bytes.
|
|||
|
Nonzero offsets that are not integer multiple of 512 bytes are NOT supported
|
|||
|
as they may be nonportable and/or nonworking.
|
|||
|
|
|||
|
|
|||
|
2.4. Use of software suspend
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Encryption keys are kept in kernel RAM while loop is active. Key is
|
|||
|
immediately erased when loop is deactivated. Use of suspend-to-disk while
|
|||
|
there are active encrypted loops should be used with caution: it would be
|
|||
|
really bad security wise because encryption keys are written to disk when
|
|||
|
kernel RAM is saved to disk. Once key is written to disk it may be
|
|||
|
recoverable from that disk pretty much forever. Security of data encrypted
|
|||
|
with such recoverable key is void.
|
|||
|
|
|||
|
|
|||
|
2.5. File system soft block sizes
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
If you intend to move encrypted file system to some other device (CD-ROM for
|
|||
|
example), be sure to create file system with soft block size that is integer
|
|||
|
multiple of device hard sector size. CD-ROMs have 2048 byte sectors. File
|
|||
|
system with 1024 byte soft block size is not going to work with all CD-ROM
|
|||
|
drives and/or drivers.
|
|||
|
|
|||
|
|
|||
|
2.6. Compatibility with earlier versions
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
This version is compatible with on-disk formats of all previous relased
|
|||
|
versions. This version is compatible with recommended mount, losetup and
|
|||
|
swapon command line syntax and /etc/fstab option syntax since
|
|||
|
loop-AES-v1.1b.
|
|||
|
|
|||
|
Unhashed encryption type as created using ancient loop-AES-v1.0c, now needs
|
|||
|
'mount -o phash=unhashed1' or 'losetup -H unhashed1' options.
|
|||
|
|
|||
|
Mount and losetup programs from loop-AES-v2.0g and older accepted unlimited
|
|||
|
long passphrase when passphrase was read from a file descriptor using '-p 0'
|
|||
|
option. To prevent abuse of mlock()ed RAM by non-root users, mount and
|
|||
|
losetup programs from loop-AES-v2.1a and newer limit max passphrase length
|
|||
|
to 4094 bytes.
|
|||
|
|
|||
|
|
|||
|
3. Instructions for building loop.o driver
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Before you attempt to build loop.o driver (loop.ko on 2.6 kernels), you
|
|||
|
*must* configure, compile and install new kernel so that CONFIG_MODULES=y
|
|||
|
and CONFIG_BLK_DEV_LOOP=n. Also, CONFIG_KMOD=y is recommended but not
|
|||
|
required (kernel 2.0 doesn't have CONFIG_KMOD, set CONFIG_KERNELD=y
|
|||
|
instead). Configuring your kernel so that loop driver is built-in
|
|||
|
(CONFIG_BLK_DEV_LOOP=y) or module (CONFIG_BLK_DEV_LOOP=m) will *not* work.
|
|||
|
After building and installing your new kernel, do not attempt to clean
|
|||
|
kernel tree, or rename path to kernel sources.
|
|||
|
|
|||
|
(Re)configuring and (re)compiling your kernel are required for following
|
|||
|
reasons: (1) to disable loop driver in your kernel, (2) to get your kernel
|
|||
|
sources to match your running kernel, (3) to get your kernel .config to
|
|||
|
match your running kernel, (4) to set up configure time generated links
|
|||
|
properly, (5) to generate compile time created header files properly to
|
|||
|
match your kernel configuration. Failure to fulfill *all* above requirements
|
|||
|
may cause loop.o driver compilation to fail or generate incorrectly
|
|||
|
operating code. If you are just upgrading existing loop-AES with newer
|
|||
|
version, there is no need to recompile kernel or reboot. Just unmount all
|
|||
|
file systems using old loop driver, and remove loop driver from kernel with
|
|||
|
rmmod command before compiling new loop driver.
|
|||
|
|
|||
|
This is how loop.o is compiled and installed:
|
|||
|
|
|||
|
2.2 and older kernels: Makefile copies your kernel's loop.c to this
|
|||
|
directory. Then, Makefile patches that copy with a
|
|||
|
kernel version specific patch. If patching a copy of
|
|||
|
your kernel's loop.c fails, then a local copy of
|
|||
|
known-to-work and patch-able loop.c-2.X.original is
|
|||
|
used instead.
|
|||
|
|
|||
|
2.4 and newer kernels: Makefile copies pre-patched loop.c-2.X.patched to
|
|||
|
file called patched-loop.c.
|
|||
|
|
|||
|
Resulting patched-loop.c along with other source files is then compiled and
|
|||
|
linked to form a new loop.o driver that is (usually) installed in
|
|||
|
/lib/modules/`uname -r`/block directory. AES cipher is permanently glued to
|
|||
|
loop.o driver so that when loop.o is loaded it automagically has AES support
|
|||
|
built in. There is no need to define any aliases in /etc/modules.conf file.
|
|||
|
|
|||
|
To compile and install loop.o driver, as root, use commands:
|
|||
|
|
|||
|
make clean
|
|||
|
make
|
|||
|
|
|||
|
Makefile tries to locate running kernel source directory, steal definitions
|
|||
|
from kernel Makefile, and build a version that matches your running kernel.
|
|||
|
Following directories are tried, in this order:
|
|||
|
|
|||
|
/lib/modules/`uname -r`/source
|
|||
|
/lib/modules/`uname -r`/build
|
|||
|
/usr/src/linux
|
|||
|
/usr/src/linux-`uname -r`
|
|||
|
/usr/src/kernel-source-`uname -r`
|
|||
|
|
|||
|
You can override automatic kernel source directory detection by specifying
|
|||
|
LINUX_SOURCE like this: make LINUX_SOURCE=/usr/src/linux-2.4.22aa1
|
|||
|
|
|||
|
Both LINUX_SOURCE and KBUILD_OUTPUT must be specified when compiling for
|
|||
|
2.6.x kernel with separate object directory.
|
|||
|
|
|||
|
You can disable automatic module installation and creation of module
|
|||
|
dependencies by specifying MODINST=n RUNDM=n on make command line.
|
|||
|
|
|||
|
Automatic kernel source directory detection is not foolproof. For best
|
|||
|
results, always specify LINUX_SOURCE, especially if loop.o module appears to
|
|||
|
compile for wrong kernel. Observe last five lines of make output for clues.
|
|||
|
|
|||
|
If you are upgrading your kernel and you need loop.o module during boot, you
|
|||
|
probably need to build new version of loop.o module that matches your new
|
|||
|
kernel *before* you boot the new kernel. To build loop.o module for other
|
|||
|
kernel than running kernel, you *must* specify LINUX_SOURCE parameter to
|
|||
|
make.
|
|||
|
|
|||
|
You can override default installation root directory by specifying
|
|||
|
INSTALL_MOD_PATH like this: make INSTALL_MOD_PATH=/path/to/destination/root
|
|||
|
|
|||
|
Makefile detects processor type from kernel configuration. If selected
|
|||
|
processor type is x86 processor or AMD64 processor, optimized assembler
|
|||
|
implementations of AES and MD5 are used instead of C implementations. If you
|
|||
|
want to unconditionally disable x86 assembler AES and MD5 implementations,
|
|||
|
specify X86_ASM=n on make command line. If you want to unconditionally
|
|||
|
disable AMD64 assembler AES and MD5 implementations, specify AMD64_ASM=n on
|
|||
|
make command line.
|
|||
|
|
|||
|
If you want to enable encryption key scrubbing, specify KEYSCRUB=y on make
|
|||
|
command line. Loop encryption key scrubbing moves and inverts key bits in
|
|||
|
kernel RAM so that the thin oxide which forms the storage capacitor
|
|||
|
dielectric of DRAM cells is not permitted to develop detectable property.
|
|||
|
For more info, see Peter Gutmann's paper:
|
|||
|
http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
|
|||
|
|
|||
|
Note: If your patch program is very old, it may not understand the --dry-run
|
|||
|
option, and may puke lengthy error messages. Even if that happens, the build
|
|||
|
process should still produce a working loop driver.
|
|||
|
|
|||
|
|
|||
|
4. Instructions for building new mount, umount, losetup, swapon and swapoff
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
In order to support AES and other ciphers, mount, umount, losetup, swapon
|
|||
|
and swapoff need to be patched and recompiled. A patch is included. Mount,
|
|||
|
umount, losetup, swapon and swapoff sources are in util-linux package which
|
|||
|
you can get from:
|
|||
|
|
|||
|
ftp://ftp.win.tue.nl/pub/linux-local/utils/util-linux/
|
|||
|
or
|
|||
|
ftp://ftp.kernel.org/pub/linux/utils/util-linux/
|
|||
|
|
|||
|
Just in case if the tarball is not properly signed, the md5 sum of
|
|||
|
util-linux-2.12h.tar.gz is f8f1b2096abbf52fadf86d470c5035dd
|
|||
|
|
|||
|
Do *not* install all the utilities in the util-linux package without
|
|||
|
thinking. You may ruin your system if you do that. Read the INSTALL file
|
|||
|
provided with util-linux tarball.
|
|||
|
|
|||
|
These commands, as root user, will recompile and install mount, umount,
|
|||
|
losetup, swapon, swapoff and their man pages:
|
|||
|
|
|||
|
zcat util-linux-2.12h.tar.gz | tar xvf -
|
|||
|
cd util-linux-2.12h
|
|||
|
patch -p1 <../util-linux-2.12h.diff
|
|||
|
CFLAGS=-O2 ./configure
|
|||
|
make SUBDIRS="lib mount"
|
|||
|
cd mount
|
|||
|
install -m 4755 -o root mount umount /bin
|
|||
|
install -m 755 losetup swapon /sbin
|
|||
|
rm -f /sbin/swapoff && ( cd /sbin && ln -s swapon swapoff )
|
|||
|
rm -f /usr/share/man/man8/{mount,umount,losetup,swapon,swapoff}.8.gz
|
|||
|
install -m 644 mount.8 umount.8 losetup.8 /usr/share/man/man8
|
|||
|
install -m 644 swapon.8 swapoff.8 /usr/share/man/man8
|
|||
|
rm -f /usr/share/man/man5/fstab.5.gz
|
|||
|
install -m 644 fstab.5 /usr/share/man/man5
|
|||
|
mandb
|
|||
|
cd ../..
|
|||
|
|
|||
|
Debian users may want to put mount package on hold like this:
|
|||
|
|
|||
|
echo mount hold | dpkg --set-selections
|
|||
|
|
|||
|
|
|||
|
5. Instructions for building new gpg
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
When gpg encrypts data with symmetric cipher only or when gpg encrypts
|
|||
|
secret keyring keys with secret passphrase, gpg uses seeded (salted) and
|
|||
|
iterated key setup. However, default amount of iteration is tuned for slow
|
|||
|
processors and can be increased for better resistance against dictionary
|
|||
|
attacks. Larger key iteration makes key setup much slower, but also makes
|
|||
|
dictionary attacks much slower too.
|
|||
|
|
|||
|
Included optional gpg patch makes gpg password iteration 128 times slower.
|
|||
|
gpg stores new iteration value along with seed bytes into symmetric cipher
|
|||
|
encrypted output file or secret keyring, so unpatched gpg versions will read
|
|||
|
and decrypt the data just fine.
|
|||
|
|
|||
|
gpg sources are available from:
|
|||
|
|
|||
|
ftp://ftp.gnupg.org/gcrypt/gnupg/
|
|||
|
|
|||
|
These commands, as root user, will recompile and install gpg and gpgv and
|
|||
|
their man pages:
|
|||
|
|
|||
|
zcat gnupg-1.2.6.tar.gz | tar xvf -
|
|||
|
cd gnupg-1.2.6
|
|||
|
patch -p1 <../gnupg-1.2.6.diff
|
|||
|
CFLAGS="-O2" LDFLAGS="-static -s" ./configure --prefix=/usr --enable-static-rnd=linux
|
|||
|
make
|
|||
|
rm -f /usr/share/man/man1/{gpg,gpgv}.1.gz
|
|||
|
make install
|
|||
|
chown root.root /usr/bin/gpg
|
|||
|
chmod 4755 /usr/bin/gpg
|
|||
|
|
|||
|
Note: Above instructions create statically linked version of gpg. Static
|
|||
|
linking is necessary if you ever decide to encrypt your root partition.
|
|||
|
|
|||
|
If /usr/bin directory is not on your root partition, then it is necessary to
|
|||
|
move gpg to /bin directory on your root partition:
|
|||
|
|
|||
|
cd /usr/bin
|
|||
|
mv gpg ../../bin
|
|||
|
ln -s ../../bin/gpg gpg
|
|||
|
|
|||
|
Debian users may want to put gnupg package on hold like this:
|
|||
|
|
|||
|
echo gnupg hold | dpkg --set-selections
|
|||
|
|
|||
|
|
|||
|
6. Testing the loop.o driver and losetup program
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Run this command, as root, and Makefile will run series of tests.
|
|||
|
|
|||
|
make tests
|
|||
|
|
|||
|
Makefile will display "*** Test results ok ***" message if tests are
|
|||
|
completed successfully. If tests fail, do not use the driver as it is
|
|||
|
broken.
|
|||
|
|
|||
|
If gpg isn't available, then tests that involve decrypting gpg encrypted key
|
|||
|
files will fail. You can skip gpg key file tests by specifying
|
|||
|
TEST_GPG_TYPES=n on make command line.
|
|||
|
|
|||
|
|
|||
|
7. Examples
|
|||
|
~~~~~~~~~~~
|
|||
|
Many of following examples depend on gpg encrypted key file. gpg appears to
|
|||
|
prevent its own keys from being leaked to swap, but does not appear to
|
|||
|
prevent data handled by it from being leaked to swap. In gpg encrypted key
|
|||
|
file cases, the data handled by gpg are loop encryption keys, and they may
|
|||
|
leak to swap. Therefore, use of gpg encrypted key file depends on encrypted
|
|||
|
swap.
|
|||
|
|
|||
|
When using gpg encrypted key file, the password that is used to encrypt the
|
|||
|
key file is the password that losetup and mount programs want. losetup and
|
|||
|
mount programs run gpg to decrypt the key file, and pipe the password to
|
|||
|
gpg. gpg then decrypts the file and pipes the real loop keys back to losetup
|
|||
|
or mount program.
|
|||
|
|
|||
|
Many of following examples need uuencode program. Not all boxes have it
|
|||
|
installed by default. If you need to install uuencode program, it is usually
|
|||
|
part of sharutils package.
|
|||
|
|
|||
|
Many of following examples attempt to use loop in multi-key mode and thus
|
|||
|
*require* losetup/mount programs from loop-AES-v2.0b or later. Setting up
|
|||
|
multi-key gpg key-file and using that key-file with old single-key only
|
|||
|
aware losetup/mount programs is *dangerous*. In multi-key loop cases
|
|||
|
"losetup -a" command run by root user should output "multi-key" indicating
|
|||
|
that loop is really in multi-key mode. If no "multi-key" string shows up,
|
|||
|
your loop setup is a time bomb. If you later upgrade your losetup/mount
|
|||
|
programs to version that can understand multi-key mode, those new
|
|||
|
losetup/mount programs will correctly setup loop in multi-key mode instead
|
|||
|
of single-key mode, and you may not be able to access your data any more.
|
|||
|
New losetup/mount programs are compatible with both single-key and multi-key
|
|||
|
key-files. New losetup/mount programs will recognize single-key key-files
|
|||
|
and set up loop in single-key mode in those cases. Old single-key only aware
|
|||
|
losetup/mount programs need single-key examples. None of the following gpg
|
|||
|
key-file examples are such.
|
|||
|
|
|||
|
|
|||
|
7.1. Example 1 - Encrypting swap on 2.4 and newer kernels
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Device backed (partition backed) loop is capable of encrypting swap on 2.4
|
|||
|
and newer kernels. File backed loops can't be used for swap.
|
|||
|
|
|||
|
First, run "swapoff -a" to turn off swap devices in your /etc/fstab file.
|
|||
|
Second, add "loop=/dev/loop?" and "encryption=AES128" options to swap lines
|
|||
|
in your /etc/fstab file. Example:
|
|||
|
|
|||
|
/dev/hda666 none swap sw,loop=/dev/loop6,encryption=AES128 0 0
|
|||
|
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
|
|||
|
Third, there may be old unencrypted data on your swap devices, in which case
|
|||
|
you can try to overwrite that data with command like this:
|
|||
|
|
|||
|
dd if=/dev/zero of=/dev/hda666 bs=64k conv=notrunc
|
|||
|
mkswap /dev/hda666
|
|||
|
|
|||
|
Fourth, run "swapon -a" and "rm -rf /var/log/ksymoops" and you are done.
|
|||
|
|
|||
|
Running "swapon -a" will set up loop devices using random keys, run mkswap
|
|||
|
on them, and enable encrypted swap on specified loop devices. Usually your
|
|||
|
distro's startup scripts will run the "swapon -a" command so you don't need
|
|||
|
to change your startup scripts at all. As expected, "swapoff -a" will tear
|
|||
|
down such loop devices.
|
|||
|
|
|||
|
Removing /var/log/ksymoops directory is often required because some versions
|
|||
|
of modprobe (part of modutils package) try to log loaded modules to
|
|||
|
/var/log/ksymoops/*.log files. This is bad because swap is often enabled
|
|||
|
(and loop.o modprobe'd to kernel) before any partitions are mounted
|
|||
|
writable. Without /var/log/ksymoops directory on root partition, modprobe
|
|||
|
will not try to log loaded modules, and you won't see annoying error
|
|||
|
messages.
|
|||
|
|
|||
|
Note: If you are using encrypted swap and you are upgrading your kernel, you
|
|||
|
probably need to build new version of loop.o module that matches your new
|
|||
|
kernel *before* you boot the new kernel. See "Instructions for building
|
|||
|
loop.o driver" section for more details.
|
|||
|
|
|||
|
|
|||
|
7.2. Example 2 - Partition backed loop with gpg encrypted key file
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
This example, originally from Michael H. Warfield, shows how to create an
|
|||
|
ext2 file system on encrypted hard disk partition, and creates 64 random
|
|||
|
encryption keys that are encrypted using gpg. Store the key file where ever
|
|||
|
you like, on separate removable media, USB dongle, or on a smart card if you
|
|||
|
like. You have to have both your passphrase and that key file in order to
|
|||
|
mount that file system.
|
|||
|
|
|||
|
This example uses a fictitious partition /dev/hda666 for storage and
|
|||
|
fictitious directory /mnt666 as mount point. A removable USB dongle is
|
|||
|
assumed to be (auto-)mounted at /a/usbdongle directory.
|
|||
|
|
|||
|
Create 64 random encryption keys and encrypt those keys using gpg. Reading
|
|||
|
from /dev/random may take indefinitely long if kernel's random entropy pool
|
|||
|
is empty. If that happens, do some other work on some other console (use
|
|||
|
keyboard, mouse and disks). Use of gpg encrypted key file depends on
|
|||
|
encrypted swap.
|
|||
|
|
|||
|
head -c 2880 /dev/random | uuencode -m - | head -n 65 | tail -n 64 \
|
|||
|
| gpg --symmetric -a >/a/usbdongle/keyfile.gpg
|
|||
|
|
|||
|
Fill the partition with random looking data. "dd" command may take a while
|
|||
|
to execute if partition is large.
|
|||
|
|
|||
|
head -c 15 /dev/urandom | uuencode -m - | head -n 2 | tail -n 1 \
|
|||
|
| losetup -p 0 -e AES128 /dev/loop3 /dev/hda666
|
|||
|
dd if=/dev/zero of=/dev/loop3 bs=4k conv=notrunc 2>/dev/null
|
|||
|
losetup -d /dev/loop3
|
|||
|
|
|||
|
Add this to your /etc/fstab file:
|
|||
|
|
|||
|
/dev/hda666 /mnt666 ext2 defaults,noauto,loop=/dev/loop3,encryption=AES128,gpgkey=/a/usbdongle/keyfile.gpg 0 0
|
|||
|
|
|||
|
The "losetup -F" command asks for passphrase to unlock your key file.
|
|||
|
Losetup -F option reads loop related options from /etc/fstab. Partition name
|
|||
|
/dev/hda666, encryption=AES128 and gpgkey=/a/usbdongle/keyfile.gpg come from
|
|||
|
/etc/fstab.
|
|||
|
|
|||
|
losetup -F /dev/loop3
|
|||
|
mkfs -t ext2 /dev/loop3
|
|||
|
losetup -d /dev/loop3
|
|||
|
mkdir /mnt666
|
|||
|
|
|||
|
Now you should be able to mount the file system like this. The "mount"
|
|||
|
command asks for passphrase to unlock your key file.
|
|||
|
|
|||
|
mount /mnt666
|
|||
|
|
|||
|
Check that loop is really in multi-key mode. Losetup -a output should
|
|||
|
include string "multi-key" indicating that loop is really in multi-key mode.
|
|||
|
If no "multi-key" string shows up, you somehow managed to mess up gpg key
|
|||
|
file generation part or you are trying to use old losetup/mount programs
|
|||
|
that only understand single-key mode.
|
|||
|
|
|||
|
losetup -a
|
|||
|
|
|||
|
You can unmount partition like this:
|
|||
|
|
|||
|
umount /mnt666
|
|||
|
|
|||
|
Unmounted filesystem can be fsck'ed like this. -F option reads loop related
|
|||
|
options from /etc/fstab. Partition name /dev/hda666, encryption=AES128 and
|
|||
|
gpgkey=/a/usbdongle/keyfile.gpg come from /etc/fstab.
|
|||
|
|
|||
|
losetup -F /dev/loop3
|
|||
|
fsck -t ext2 -f -y /dev/loop3
|
|||
|
losetup -d /dev/loop3
|
|||
|
|
|||
|
|
|||
|
7.3. Example 3 - Encrypted partition that multiple users can mount
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
This example shows how to create encrypted partition that multiple non-root
|
|||
|
users can mount, each with their own gpg key. Non-root users don't have
|
|||
|
access to file system key that is actually used to encrypt data. Root can
|
|||
|
add or remove user's permission to mount encrypted partition at any time.
|
|||
|
This example uses a fictitious partition /dev/hda666 for storage and
|
|||
|
fictitious directory /secret1 as mount point.
|
|||
|
|
|||
|
Create 64 random file system keys and encrypt those keys using root's gpg
|
|||
|
public key. Reading from /dev/random may take indefinitely long if kernel's
|
|||
|
random entropy pool is empty. If that happens, do some other work on some
|
|||
|
other console (use keyboard, mouse and disks). Use of gpg encrypted key file
|
|||
|
depends on encrypted swap.
|
|||
|
|
|||
|
umask 077
|
|||
|
head -c 2880 /dev/random | uuencode -m - | head -n 65 | tail -n 64 \
|
|||
|
| gpg -e -a -r "Superuser" > /root/masterkey-secret1.gpg
|
|||
|
|
|||
|
Fill the partition with random looking data. "dd" command may take a while
|
|||
|
to execute if partition is large.
|
|||
|
|
|||
|
head -c 15 /dev/urandom | uuencode -m - | head -n 2 | tail -n 1 \
|
|||
|
| losetup -p 0 -e AES128 /dev/loop0 /dev/hda666
|
|||
|
dd if=/dev/zero of=/dev/loop0 bs=4k conv=notrunc 2>/dev/null
|
|||
|
losetup -d /dev/loop0
|
|||
|
|
|||
|
Use file system keys to setup /dev/loop0 to partition /dev/hda666 and create
|
|||
|
encrypted ext2 file system. The "losetup -e" command asks for root's gpg
|
|||
|
passphrase to unlock root's secret gpg key.
|
|||
|
|
|||
|
losetup -e AES128 -K /root/masterkey-secret1.gpg /dev/loop0 /dev/hda666
|
|||
|
mkfs -t ext2 /dev/loop0
|
|||
|
losetup -d /dev/loop0
|
|||
|
mkdir /secret1
|
|||
|
|
|||
|
Add mount information to /etc/fstab file. Something like this:
|
|||
|
|
|||
|
/dev/hda666 /secret1 ext2 defaults,user,noauto,encryption=AES128,loop=/dev/loop0,gpgkey=/etc/userkey-secret1.gpg 0 0
|
|||
|
^^^^
|
|||
|
You may want to check non-obvious side effects of above "user" mount option.
|
|||
|
It's all explained in mount man page.
|
|||
|
|
|||
|
Create root-only-readable /etc/userkey-secret1.gpg file which contains file
|
|||
|
system key encrypted with each user's public key. List all users as
|
|||
|
recipient who should be able to mount /secret1 encrypted partition. Repeat
|
|||
|
this every time you want to add or remove users.
|
|||
|
|
|||
|
umask 077
|
|||
|
gpg --decrypt < /root/masterkey-secret1.gpg | gpg -e -a --always-trust \
|
|||
|
-r "Superuser" -r "John Doe" -r "Tea Lipton" > /etc/userkey-secret1.gpg
|
|||
|
|
|||
|
Users can mount encrypted partition like this. mount asks for gpg passphrase
|
|||
|
to unlock user's secret gpg key. Each user can use their own gpg key.
|
|||
|
|
|||
|
mount /secret1
|
|||
|
|
|||
|
Root user can check that loop is really in multi-key mode. Losetup -a output
|
|||
|
should include string "multi-key" indicating that loop is really in
|
|||
|
multi-key mode. If no "multi-key" string shows up, you somehow managed to
|
|||
|
mess up gpg key file generation part or you are trying to use old
|
|||
|
losetup/mount programs that only understand single-key mode.
|
|||
|
|
|||
|
losetup -a
|
|||
|
|
|||
|
You can unmount partition like this:
|
|||
|
|
|||
|
umount /secret1
|
|||
|
|
|||
|
Root user can fsck unmounted filesystem like this. -F option reads loop
|
|||
|
related options from /etc/fstab. Partition name /dev/hda666,
|
|||
|
encryption=AES128 and gpgkey=/etc/userkey-secret1.gpg come from /etc/fstab.
|
|||
|
|
|||
|
losetup -F /dev/loop0
|
|||
|
fsck -t ext2 -f -y /dev/loop0
|
|||
|
losetup -d /dev/loop0
|
|||
|
|
|||
|
|
|||
|
7.4. Example 4 - Encrypting /tmp partition with random keys
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
When mount passphrase hash function is specified as random, mount does not
|
|||
|
ask for password but sets up 64 random keys and attempts to put loop to
|
|||
|
multi-key mode and creates new file system on that encrypted loop device
|
|||
|
before that file system is mounted.
|
|||
|
|
|||
|
First, unmount your existing /tmp partition by running "umount /tmp". There
|
|||
|
may be open files in there, so you may have to do this from single user
|
|||
|
mode.
|
|||
|
|
|||
|
Second, add loop= encryption= and phash=random mount options to /etc/fstab
|
|||
|
file. The sixth /etc/fstab field (fs_passno) must be zero so that fcsk will
|
|||
|
not attempt to check this partition.
|
|||
|
|
|||
|
/dev/hda555 /tmp ext2 defaults,loop=/dev/loop2,encryption=AES128,phash=random/1777 0 0
|
|||
|
^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^
|
|||
|
Third, run "mount /tmp" command and you are done.
|
|||
|
|
|||
|
Octal digits after phash=random/ mount option specify initial permissions of
|
|||
|
file system root directory that gets created on the loop device. 1777 means
|
|||
|
read+write+search permissions for all and sticky bit set. Type "man 2 stat"
|
|||
|
for more info about what each bit stands for.
|
|||
|
|
|||
|
Encryption keys and plaintext data on above type mount vanish on unmount or
|
|||
|
power off. Using journaled file system in such case does not make much
|
|||
|
sense, because file system is re-created with different encryption keys on
|
|||
|
each mount, and file system jounal is never used.
|
|||
|
|
|||
|
This example requires that mount program is derived from util-linux patch
|
|||
|
found in loop-AES-v2.2d or later version.
|
|||
|
|
|||
|
|
|||
|
7.5. Example 5 - Encrypting root partition
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Encrypting root partition requires a small unencrypted /boot partition.
|
|||
|
Everything else (root, swap and other partitions) can be encrypted. Kernels
|
|||
|
and tools required to boot kernels reside in the /boot partition. Included
|
|||
|
build-initrd.sh script builds a small "initrd" ram-disk that works with 2.2
|
|||
|
2.4, and 2.6 kernels. build-initrd.sh script depends on having minix file
|
|||
|
system support in the kernel and working mkfs.minix program binary.
|
|||
|
Util-linux includes source for mkfs.minix if you don't have it and need to
|
|||
|
build it yourself. You need to temporarily boot from rescue floppy/CD-ROM or
|
|||
|
other partition to do the actual encrypting work. The rescue floppy/CD-ROM
|
|||
|
or other partition kernel doesn't need to support loop crypto, so just about
|
|||
|
anything that boots will work.
|
|||
|
|
|||
|
1) build-initrd.sh script needs dietlibc. Dietlibc source is available
|
|||
|
from:
|
|||
|
|
|||
|
http://www.fefe.de/dietlibc/
|
|||
|
ftp://ftp.kernel.org/pub/linux/libs/dietlibc/
|
|||
|
|
|||
|
To compile and install dietlibc, follow instructions in the dietlibc
|
|||
|
README file. For example, on a x86 box, do this:
|
|||
|
|
|||
|
make
|
|||
|
install bin-i386/diet /usr/local/bin
|
|||
|
|
|||
|
2) You need to use aespipe program (v2.2a or later) with your rescue
|
|||
|
floppy/CD-ROM or other partition. aespipe source is available from:
|
|||
|
|
|||
|
http://loop-aes.sourceforge.net/
|
|||
|
http://members.tiscali.fi/ce6c8edf/ (limited downloads)
|
|||
|
|
|||
|
Download latest version of aespipe-*.tar.bz2
|
|||
|
|
|||
|
Dynamically linked aespipe program may have library dependency problems
|
|||
|
with rescue floppy/CD-ROM or other partition C library. To avoid such
|
|||
|
trouble, aespipe program needs to be linked statically. Static linking
|
|||
|
with glibc makes aespipe much bigger (hundreds of kilobytes), and may
|
|||
|
also create link warning about 'getpwuid'. Big program size and link
|
|||
|
warning can be ignored here.
|
|||
|
|
|||
|
Compile aespipe program like this:
|
|||
|
|
|||
|
CFLAGS="-O2" LDFLAGS="-static -s" ./configure
|
|||
|
make
|
|||
|
make tests
|
|||
|
|
|||
|
Copy statically linked aespipe program to /boot partition.
|
|||
|
|
|||
|
cp -p aespipe /boot
|
|||
|
|
|||
|
3) If you followed advise about recompiling and statically linking gpg
|
|||
|
program, you don't need to do that again. However, if you don't have
|
|||
|
statically linked gpg, you need to do that now because later steps in
|
|||
|
root partition encryption depend on it.
|
|||
|
|
|||
|
4) Backup all important data before proceeding with root partition
|
|||
|
encryption.
|
|||
|
|
|||
|
5) Recompile your kernel. These are required: CONFIG_BLK_DEV_RAM=y
|
|||
|
CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y CONFIG_MINIX_FS=y
|
|||
|
CONFIG_PROC_FS=y CONFIG_CRAMFS=n (or CONFIG_CRAMFS=m)
|
|||
|
|
|||
|
CONFIG_BLK_DEV_{RAM,INITRD}=y are needed because kernel needs to support
|
|||
|
initial ramdisk. CONFIG_MINIX_FS=y is needed because file system on
|
|||
|
initrd is minix. CONFIG_CRAMFS=n is needed because cramfs code may
|
|||
|
incorrectly detect initrd's compressed minix file system as cramfs file
|
|||
|
system. If cramfs must be built-in, then build-initrd.sh must be
|
|||
|
configured with USEPIVOT=1, and kernel parameter "rootfstype=minix" must
|
|||
|
be added to bootloader configuration file. 2.2.x and older kernels have
|
|||
|
neither CONFIG_CRAMFS nor cramfs, so that kernel configuration setting
|
|||
|
can be ignored on those kernels.
|
|||
|
|
|||
|
All kernel subsystems needed by root and /boot file systems must be
|
|||
|
compiled directly into kernel (and not be modules).
|
|||
|
|
|||
|
cd /usr/src/linux-2.4.22aa1
|
|||
|
cp .config ../somewhere/somename.config
|
|||
|
make distclean
|
|||
|
cp ../somewhere/somename.config .config
|
|||
|
make config
|
|||
|
make dep && make clean && make bzImage
|
|||
|
make modules && make modules_install
|
|||
|
cat arch/i386/boot/bzImage >/boot/vmlinuz
|
|||
|
cp System.map /boot/System.map-2.4.22aa1
|
|||
|
|
|||
|
6) Compile loop-AES loop.o module for your kernel.
|
|||
|
|
|||
|
cd ../loop-AES-*
|
|||
|
make LINUX_SOURCE=/usr/src/linux-2.4.22aa1
|
|||
|
|
|||
|
7) Copy kernel version specific loop.o (2.4 and older kernels) or loop.ko
|
|||
|
(2.6 kernels) to /boot/modules-KERNELRELEASE/
|
|||
|
|
|||
|
mkdir /boot/modules-2.4.22aa1
|
|||
|
^^^^^^^^^
|
|||
|
cp -p /lib/modules/2.4.22aa1/block/loop.*o /boot/modules-2.4.22aa1/
|
|||
|
^^^^^^^^^ ^^^^^^^^^
|
|||
|
Note: You need to have a kernel version specific loop.o or loop.ko
|
|||
|
module in /boot/modules-KERNELRELEASE/ directory for every kernel you
|
|||
|
intend to use.
|
|||
|
|
|||
|
8) If your boot scripts automatically run "umount /initrd" and "blockdev
|
|||
|
--flushbufs /dev/ram0" commands, you may want to disable those commands.
|
|||
|
If you don't disable them, you may see annoying error messages when
|
|||
|
booting to encrypted root partition.
|
|||
|
|
|||
|
Root partition loop device node is inside initrd, and that device node
|
|||
|
will remain busy forever. This means that encrypted root initrd can't be
|
|||
|
unmounted and RAM used by initrd file system can't be freed. This
|
|||
|
unable-to-unmount side effect is the reason why initrd is intentionally
|
|||
|
made as small as possible.
|
|||
|
|
|||
|
9) Create 64 random encryption keys and encrypt those keys using gpg.
|
|||
|
Reading from /dev/random may take indefinitely long if kernel's random
|
|||
|
entropy pool is empty. If that happens, do some other work on some other
|
|||
|
console (use keyboard, mouse and disks). Use of gpg encrypted key file
|
|||
|
depends on encrypted swap.
|
|||
|
|
|||
|
umask 077
|
|||
|
head -c 2880 /dev/random | uuencode -m - | head -n 65 | tail -n 64 \
|
|||
|
| gpg --symmetric -a >/boot/rootkey.gpg
|
|||
|
|
|||
|
10) Edit build-initrd.sh to match your setup. Set BOOTDEV, BOOTTYPE,
|
|||
|
CRYPTROOT and ROOTTYPE variables to correct values. If you are using 2.2
|
|||
|
or older kernels, set USEPIVOT=0 because 2.2 and older kernels do not
|
|||
|
have pivot_root functionality. You may also want to set
|
|||
|
LOADNATIONALKEYB=1 and manually copy your uncompressed national keyboard
|
|||
|
layout file (in "loadkeys" format) to /boot/default.kmap
|
|||
|
|
|||
|
loadkeys configuration files for some popular distros:
|
|||
|
|
|||
|
Debian: /etc/console/boottime.kmap.gz
|
|||
|
Mandrake: /usr/lib/kbd/keymaps/i386/qwert[yz]/*.kmap.gz
|
|||
|
Red Hat: /lib/kbd/keymaps/i386/qwert[yz]/*.kmap.gz
|
|||
|
SuSE: /usr/lib/kbd/keymaps/i386/qwert[yz]/*.map.gz
|
|||
|
Slackware: /usr/share/kbd/keymaps/i386/qwert[yz]/*.map.gz
|
|||
|
|
|||
|
Or alternatively, you can create keyboard map using your current
|
|||
|
keyboard layout. Like this:
|
|||
|
|
|||
|
dumpkeys >/boot/default.kmap
|
|||
|
|
|||
|
devfs enabled kernel users (CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y
|
|||
|
in kernel configuration) need to pay special attention to comments above
|
|||
|
these build-initrd.sh options: USEDEVFS, BOOTDEV, CRYPTROOT and
|
|||
|
EXTERNALGPGDEV.
|
|||
|
|
|||
|
11) Edit /etc/lilo.conf (or whatever) and set root= initrd= and append= as
|
|||
|
explained in comments at beginning of build-initrd.sh script.
|
|||
|
|
|||
|
12) Build a new /boot/initrd.gz
|
|||
|
|
|||
|
./build-initrd.sh
|
|||
|
|
|||
|
Note: /boot/initrd.gz is supposed to be small (2 KB to 3 KB). All other
|
|||
|
utilities (loop.o module, insmod, losetup, loadkeys and possibly
|
|||
|
libraries) are copied to /boot directory. Libraries are not copied if
|
|||
|
programs are statically linked.
|
|||
|
|
|||
|
13) Run lilo (or whatever)
|
|||
|
|
|||
|
lilo
|
|||
|
|
|||
|
14) Reboot your computer from rescue floppy/CD-ROM or other partition, so
|
|||
|
that the partition you are about to encrypt is *not* mounted.
|
|||
|
|
|||
|
15) Now you should be running a shell from rescue floppy/CD-ROM or other
|
|||
|
partition. This example assumes that /dev/hda1 is your /boot partition
|
|||
|
and /dev/hda2 is your root partition. Temporarily mount your root
|
|||
|
partition under /mnt
|
|||
|
|
|||
|
mount -t ext2 /dev/hda2 /mnt
|
|||
|
|
|||
|
16) Edit root partition entry in /mnt/etc/fstab file. Replace old /dev/hda2
|
|||
|
with /dev/loop5 or whatever loop you are using for root partition. Loop
|
|||
|
device number must match ROOTLOOPINDEX= in build-initrd.sh
|
|||
|
configuration. The default in build-initrd.sh is 5, meaning /dev/loop5.
|
|||
|
|
|||
|
Old /etc/fstab line:
|
|||
|
/dev/hda2 / ext2 defaults 0 1
|
|||
|
New /etc/fstab line:
|
|||
|
/dev/loop5 / ext2 defaults 0 1
|
|||
|
|
|||
|
devfs enabled kernel users (CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y
|
|||
|
in kernel configuration) need to substitute /dev/loop5 with /dev/loop/5
|
|||
|
|
|||
|
17) Unmount your root partition (and sync for extra safety).
|
|||
|
|
|||
|
umount /mnt
|
|||
|
sync
|
|||
|
|
|||
|
18) Mount your normal /boot partition under /mnt so that you can use
|
|||
|
previously built statically linked aespipe and gpg programs and read gpg
|
|||
|
encrypted key file 'rootkey.gpg'. Statically linked gpg program was
|
|||
|
copied there by build-initrd.sh script.
|
|||
|
|
|||
|
mount -r -t ext2 /dev/hda1 /mnt
|
|||
|
|
|||
|
19) Use dd program to read your root partition contents, pipe that data
|
|||
|
through aespipe program, and finally write encrypted data back to same
|
|||
|
partition with another dd program. This is going to take a while if
|
|||
|
partition is large.
|
|||
|
|
|||
|
dd if=/dev/hda2 bs=64k \
|
|||
|
| /mnt/aespipe -e AES128 -K /mnt/rootkey.gpg -G / \
|
|||
|
| dd of=/dev/hda2 bs=64k conv=notrunc
|
|||
|
|
|||
|
aespipe program tries to run gpg from obvious locations on your rescue
|
|||
|
floppy/CD-ROM file system, but if it can't find gpg from those obvious
|
|||
|
locations, aespipe finally tries to run gpg from same directory that
|
|||
|
aespipe was run from (/mnt/) and should find statically linked gpg
|
|||
|
program there.
|
|||
|
|
|||
|
20) Clean up and reboot your computer.
|
|||
|
|
|||
|
umount /mnt
|
|||
|
sync
|
|||
|
reboot
|
|||
|
|
|||
|
If you are upgrading kernel of a system where root partition is already
|
|||
|
encrypted, only steps 5 to 7 and 13 are needed. /boot/initrd.gz is kernel
|
|||
|
independent and there is no need to re-create it for each kernel. However,
|
|||
|
if you are upgrading from 2.4 kernel to 2.6 kernel, new insmod may need to
|
|||
|
be copied to /boot directory by running step 12 before running step 13.
|
|||
|
|
|||
|
If you want to fsck and mount partitions automatically and are indeed
|
|||
|
encrypting root partition, it may be easier to just losetup required
|
|||
|
partitions early in init scripts (before partitions are fsck'ed and
|
|||
|
mounted). Don't losetup root partition again, as root partition has already
|
|||
|
been losetup'ed by /linuxrc program in the "initrd" ram-disk.
|
|||
|
|
|||
|
Init scripts reside on root partition and encryption keys within such init
|
|||
|
scripts are protected by root partition encryption. Of course, init scripts
|
|||
|
containing sensitive keys must be readable only by root user:
|
|||
|
|
|||
|
-rwx------ 1 root root 162 Nov 24 19:23 /etc/rcS.d/S07losetup.sh
|
|||
|
|
|||
|
Here is an example of /etc/rcS.d/S07losetup.sh Debian init script. Other
|
|||
|
distros may store such init scripts in different directory under different
|
|||
|
name. On SuSE, /etc/init.d/boot.d/S01losetup.sh may be more appropriate.
|
|||
|
|
|||
|
#!/bin/sh
|
|||
|
echo "Pd1eXapMJk0XAJnNSIzE" | losetup -p 0 -e AES128 -K /etc/swapkey.gpg /dev/loop6 /dev/hda666
|
|||
|
echo "D0aZNSNnu6FdAph+zrHt" | losetup -p 0 -e AES128 -K /etc/homekey.gpg /dev/loop4 /dev/hdd666
|
|||
|
|
|||
|
Above partitions use gpg encrypted key files. Having encrypted files on
|
|||
|
encrypted partition may seem little bit silly, but currently -K option is
|
|||
|
the easiest way to activate multi-key mode with more secure MD5 IV
|
|||
|
computation.
|
|||
|
|
|||
|
Here are example lines of /etc/fstab file. It's not necessary to give
|
|||
|
"loop=/dev/loop4,encryption=AES128" mount options as loop devices are
|
|||
|
already losetup'ed and there is no need for mount program to do that again.
|
|||
|
|
|||
|
/dev/loop5 / ext2 defaults 0 1
|
|||
|
/dev/loop6 none swap sw 0 0
|
|||
|
/dev/loop4 /home ext2 defaults 0 2
|
|||
|
|
|||
|
In above example, device /dev/hda666 is used as encrypted swap with fixed
|
|||
|
key. If you set up swap with fixed key like in above example, don't forget
|
|||
|
to initialize swap space by running "mkswap /dev/loop6" once. /dev/hdd666 is
|
|||
|
used as encrypted /home partition. /dev/loop5 is encrypted root partition,
|
|||
|
and it set up by /linuxrc program in "initrd" ram-disk.
|
|||
|
|
|||
|
|
|||
|
7.6. Example 6 - Boot from CD-ROM + encrypted root partition
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Here is slight variation of above 'encrypting root partition' instructions.
|
|||
|
Computer gets booted from read-only CD-ROM and there is no need for any
|
|||
|
unencrypted partitions on the hard disk.
|
|||
|
|
|||
|
1-6) Same as above 'encrypting root partition' steps 1-6.
|
|||
|
|
|||
|
7) Copy kernel version specific loop.o or loop.ko module to CD-ROM source
|
|||
|
directory
|
|||
|
|
|||
|
rm -r -f /boot/iso/modules-*
|
|||
|
mkdir -p /boot/iso/modules-2.4.22aa1
|
|||
|
^^^^^^^^^
|
|||
|
cp -p /lib/modules/2.4.22aa1/block/loop.*o /boot/iso/modules-2.4.22aa1/
|
|||
|
^^^^^^^^^ ^^^^^^^^^
|
|||
|
8-9) Same as above 'encrypting root partition' steps 8-9, with exception
|
|||
|
that in step 9 you must write rootkey.gpg to /boot/iso directory instead
|
|||
|
of /boot directory.
|
|||
|
|
|||
|
10a) Contents of /boot/initrd.conf configuration file are below.
|
|||
|
|
|||
|
BOOTDEV=/dev/hdc # CD-ROM device
|
|||
|
BOOTTYPE=iso9660
|
|||
|
CRYPTROOT=/dev/hda2
|
|||
|
ROOTTYPE=ext2
|
|||
|
CIPHERTYPE=AES128
|
|||
|
DESTINATIONPREFIX=/boot/iso
|
|||
|
INITRDGZNAME=../initrd.gz
|
|||
|
LOADNATIONALKEYB=1
|
|||
|
|
|||
|
devfs enabled kernel users (CONFIG_DEVFS_FS=y and CONFIG_DEVFS_MOUNT=y
|
|||
|
in kernel configuration) need to pay special attention to comments above
|
|||
|
these build-initrd.sh options: USEDEVFS, BOOTDEV, CRYPTROOT and
|
|||
|
EXTERNALGPGDEV.
|
|||
|
|
|||
|
10b) Copy your national keyboard layout to CD-ROM source directory in
|
|||
|
uncompressed form.
|
|||
|
|
|||
|
dumpkeys >/boot/iso/default.kmap
|
|||
|
|
|||
|
11) Contents of /etc/lilo.conf configuration file are below. Two copies of
|
|||
|
'/dev/loop7' on first two lines refer to temporary file backed loop
|
|||
|
mount that is mounted on /mnt later in step 13a.
|
|||
|
|
|||
|
boot=/dev/loop7
|
|||
|
disk=/dev/loop7
|
|||
|
bios=0x00
|
|||
|
sectors=36
|
|||
|
heads=2
|
|||
|
cylinders=80
|
|||
|
geometric
|
|||
|
compact
|
|||
|
read-only
|
|||
|
prompt
|
|||
|
timeout=30
|
|||
|
vga=normal
|
|||
|
backup=/dev/null
|
|||
|
install=text
|
|||
|
map=/mnt/map
|
|||
|
image=/mnt/vmlinuz
|
|||
|
label=Linux
|
|||
|
append="init=/linuxrc rootfstype=minix"
|
|||
|
initrd=/mnt/initrd.gz
|
|||
|
root=/dev/ram0
|
|||
|
|
|||
|
12) Build new /boot/initrd.gz
|
|||
|
|
|||
|
./build-initrd.sh /boot/initrd.conf
|
|||
|
|
|||
|
13a) Build and mount minix file system on floppy image
|
|||
|
|
|||
|
dd if=/dev/zero of=/boot/iso/fdimage.bin bs=1024 count=2880
|
|||
|
mkfs -t minix -i 32 /boot/iso/fdimage.bin 2880
|
|||
|
mount -t minix /boot/iso/fdimage.bin /mnt -o loop=/dev/loop7
|
|||
|
|
|||
|
13b) Copy kernel and initrd.gz to floppy image
|
|||
|
|
|||
|
cp -p /boot/vmlinuz /mnt/vmlinuz
|
|||
|
cp -p /boot/initrd.gz /mnt/initrd.gz
|
|||
|
|
|||
|
13c) Run lilo and unmount floppy image
|
|||
|
|
|||
|
lilo
|
|||
|
umount /mnt
|
|||
|
sync
|
|||
|
|
|||
|
13d) Create boot CD-ROM image
|
|||
|
|
|||
|
mkisofs -r -b fdimage.bin /boot/iso >/boot/bootcdimage.iso
|
|||
|
|
|||
|
13e) Burn /boot/bootcdimage.iso to CD-R. Resulting CD-ROM is your boot
|
|||
|
CD-ROM that you use to boot to encrypted root, not the rescue CD-ROM
|
|||
|
referred to in above 'encrypting root partition' step 14.
|
|||
|
|
|||
|
You may want to burn two copies or at least archive bootcdimage.iso to
|
|||
|
some unencrypted partition so that you can burn new copy if original
|
|||
|
CD-ROM gets damaged.
|
|||
|
|
|||
|
13f) Temporarily disable swap partitions and put a "temporary file system on
|
|||
|
swap" into one of swap partitions. This example assumes that /dev/hda3
|
|||
|
is such swap partition. The 'dd' command clears first 64KB of that
|
|||
|
partition so that dangerously buggy rescue floppies/CD-ROMs don't enable
|
|||
|
swap on it.
|
|||
|
|
|||
|
swapoff -a
|
|||
|
dd if=/dev/zero of=/dev/hda3 bs=64k count=1 conv=notrunc
|
|||
|
mkfs -t ext2 /dev/hda3
|
|||
|
mount -t ext2 /dev/hda3 /mnt
|
|||
|
|
|||
|
13g) Copy statically linked aespipe and gpg programs and rootkey.gpg file to
|
|||
|
"temporary file system on swap" partition.
|
|||
|
|
|||
|
cp -p /boot/aespipe /boot/iso/rootkey.gpg /usr/bin/gpg /mnt
|
|||
|
umount /mnt
|
|||
|
|
|||
|
14-19) Same as above 'encrypting root partition' steps 14-19, with exception
|
|||
|
that in step 18 you must rw mount (no -r option to mount) "temporary
|
|||
|
file system on swap" /dev/hda3 instead of /boot partition.
|
|||
|
|
|||
|
20) Clean up and reboot your computer. The 'dd' command attempts to
|
|||
|
overwrite gpg encrypted root partition key file and 'mkswap' command
|
|||
|
restores "temporary file system on swap" /dev/hda3 back to swap usage.
|
|||
|
|
|||
|
dd if=/dev/zero of=/mnt/rootkey.gpg bs=64k count=1 conv=notrunc
|
|||
|
umount /mnt
|
|||
|
sync
|
|||
|
mkswap /dev/hda3
|
|||
|
sync
|
|||
|
reboot
|
|||
|
|
|||
|
If you are upgrading kernel of a system where root partition is already
|
|||
|
encrypted, only steps 5 to 7 and 13a to 13e are needed. However, if you are
|
|||
|
upgrading from 2.4 kernel to 2.6 kernel, new insmod may need to be copied to
|
|||
|
/boot/iso directory by running step 12 before running step 13a.
|
|||
|
|
|||
|
|
|||
|
8. Security levels
|
|||
|
~~~~~~~~~~~~~~~~~~
|
|||
|
Loop encryption key can be set up in different ways. Just in case it isn't
|
|||
|
obvious how these different ways rank security wise, here is a list of
|
|||
|
security levels from 1 (highest security) to 4 (lowest security).
|
|||
|
|
|||
|
1) gpg encrypted 'multi-key' key file and/or gpg public+private keys are
|
|||
|
stored on separate removable USB dongle that is not available to
|
|||
|
attacker. If USB dongle and its key files are available to attacker,
|
|||
|
security level is equivalent to level 2. (Example 2)
|
|||
|
|
|||
|
2) gpg encrypted 'multi-key' key file and gpg public+private keys are
|
|||
|
stored on disk that is available to attacker. This assumes that included
|
|||
|
gpg patch is applied to gpg and symmetric cipher encrypted key file or
|
|||
|
private keyring password was created/changed with patched version.
|
|||
|
(Example 3)
|
|||
|
|
|||
|
3) Loop is used in single-key mode. Random password seed and iteration
|
|||
|
count are used to slow down optimized dictionary attacks. This level is
|
|||
|
vulnerable to watermark attacks. Watermarked files contain special bit
|
|||
|
patterns that can be detected without decryption.
|
|||
|
|
|||
|
4) Loop is used in single-key mode. Neither password seed nor gpg encrypted
|
|||
|
key file are used. This level is vulnerable to optimized dictionary
|
|||
|
attacks as well as watermark attacks. (mainline linux cryptoloop is
|
|||
|
example of this type of backdoored crypto)
|
|||
|
|
|||
|
|
|||
|
9. Performance tuning for 2.4 and newer kernels
|
|||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|||
|
Loop-AES driver for 2.4 and newer kernels understand two additional options:
|
|||
|
lo_prealloc and lo_nice. First number of 'lo_prealloc' is the default number
|
|||
|
of RAM pages to pre-allocate for each device backed (partition backed) loop.
|
|||
|
Every configured device backed loop pre-allocates this amount of RAM pages
|
|||
|
unless later 'lo_prealloc' numbers provide an override. 'lo_prealloc'
|
|||
|
overrides are defined in pairs: loop_index,number_of_pages. If 'lo_prealloc'
|
|||
|
is undefined, all pre-allocations default to 125 pages. A maximum of four
|
|||
|
overrides (four number pairs) can be used.
|
|||
|
|
|||
|
This example line added to your /etc/modules.conf file means that each
|
|||
|
device backed loop device pre-allocates 100 pages of RAM at losetup/mount
|
|||
|
time, except that /dev/loop6 allocates 200 pages, and /dev/loop5 allocates
|
|||
|
250 pages.
|
|||
|
|
|||
|
options loop lo_prealloc=100,6,200,5,250
|
|||
|
|
|||
|
On x86 systems page size is 4 Kbytes, some other architectures have 8 Kbyte
|
|||
|
page size.
|
|||
|
|
|||
|
lo_nice option sets scheduler nice for loop helper threads. Values between 0
|
|||
|
(low priority) to -20 (high priority) can be used. If loop transfers are
|
|||
|
disk transfer rate limited, lowering loop thread priority may improve
|
|||
|
performance. If loop transfers are CPU processing power limited, increasing
|
|||
|
loop thread priority may improve performance. renice(8) command can be used
|
|||
|
to alter nice values of loop helper threads while loop is being used.
|
|||
|
Example /etc/modules.conf line:
|
|||
|
|
|||
|
options loop lo_nice=-4
|
|||
|
|
|||
|
If lo_nice is not set, default nice value for kernels with old scheduler is
|
|||
|
-20. For kernels with O(1) scheduler, default nice value is -1.
|
|||
|
|
|||
|
2.6 kernels include anticipatory (the default) and deadline I/O schedulers.
|
|||
|
Deadline I/O scheduler may improve performance of device backed loop
|
|||
|
devices.<2E>Please read kernel's Documentation/as-iosched.txt file for more
|
|||
|
information.
|
|||
|
|
|||
|
|
|||
|
10. Files
|
|||
|
~~~~~~~~~
|
|||
|
ChangeLog History of changes and public releases.
|
|||
|
|
|||
|
Makefile Makefile to build and install loop.o module.
|
|||
|
|
|||
|
README This README file.
|
|||
|
|
|||
|
aes-GPL.diff A patch for aes-amd64.S and aes-x86.S files that
|
|||
|
updates licenses to be fully GPL compatible.
|
|||
|
aes-amd64.S and aes-x86.S files are derived from
|
|||
|
Brian Gladman's December 2001 published version
|
|||
|
that had no mention of GPL, but both Brian
|
|||
|
Gladman and Jari Ruusu permit this license
|
|||
|
change.
|
|||
|
|
|||
|
aes-amd64.S Optimized assembler implementation of AES cipher
|
|||
|
for AMD64 and compatible processors.
|
|||
|
|
|||
|
aes-x86.S Optimized assembler implementation of AES cipher
|
|||
|
for x86 processors.
|
|||
|
|
|||
|
aes.[ch] AES encryption functions, portable and usable in
|
|||
|
kernel and in user space, as well as in other
|
|||
|
operating systems.
|
|||
|
|
|||
|
build-initrd.sh Bash shell script to build a small initrd
|
|||
|
ram-disk that can be used when root partition is
|
|||
|
encrypted.
|
|||
|
|
|||
|
dkms.conf Configuration file for Dynamic Kernel Module
|
|||
|
Support. http://linux.dell.com/dkms/dkms.html
|
|||
|
for more info. This dkms.conf can't be used to
|
|||
|
compile loop module with partial kernel sources
|
|||
|
that some distros provide. Build procedure
|
|||
|
depends on presence of full kernel sources, and
|
|||
|
using partial kernel source to build loop module
|
|||
|
will guarantee miscompiled loop module.
|
|||
|
|
|||
|
glue.c Glue logic between loop driver and encryption
|
|||
|
functions in aes.c / aes-*.S and md5.c / md5-*.S
|
|||
|
|
|||
|
gnupg-*.diff Optional patch for gpg that increases password
|
|||
|
iteration and thus slows down dictionary attacks
|
|||
|
against gpg encrypted key files.
|
|||
|
|
|||
|
gpgkey[12].asc gpg encrypted key files that are used by
|
|||
|
Makefile when "make tests" command is run. These
|
|||
|
key files are encrypted with symmetric cipher
|
|||
|
using 12345678901234567890 password.
|
|||
|
|
|||
|
kernel-2.[46].*.diff Kernel patch for those people who prefer not to
|
|||
|
use modules. Before this patch can be applied to
|
|||
|
your kernel, drivers/block/loop.c and
|
|||
|
include/linux/loop.h source files must be
|
|||
|
removed using 'rm' command. Obviously applying
|
|||
|
this patch changes your kernel sources, so this
|
|||
|
is not entirely hassle free. This patch is
|
|||
|
against recent mainline kernel. If this patch
|
|||
|
doesn't apply cleanly to your kernel, I don't
|
|||
|
want to know about it. Note: you only need to
|
|||
|
build loop.o module or apply this patch but not
|
|||
|
both.
|
|||
|
|
|||
|
loop.c-2.[02].diff Kernel version specific patches that fix bugs
|
|||
|
and preregisters AES cipher transfer to latest
|
|||
|
loop.c source.
|
|||
|
|
|||
|
loop.c-2.[02].original Unmodified loop.c sources that are used as
|
|||
|
secondary source if patch does not apply cleanly
|
|||
|
to primary source. Primary source is the loop.c
|
|||
|
of your kernel.
|
|||
|
|
|||
|
loop.c-2.[46].patched Pre-patched loop.c sources for kernels where
|
|||
|
changes are so extensive that distributing
|
|||
|
*.original plus *.diff does not make sense.
|
|||
|
|
|||
|
md5-amd64.S Optimized assembler implementation of MD5
|
|||
|
transform function for AMD64 and compatible
|
|||
|
processors.
|
|||
|
|
|||
|
md5-x86.S Optimized assembler implementation of MD5
|
|||
|
transform function for x86 processors.
|
|||
|
|
|||
|
md5.[ch] MD5 transform function implementation that is
|
|||
|
used to compute IVs. This source code was copied
|
|||
|
from Linux kernel CryptoAPI implementation.
|
|||
|
|
|||
|
util-linux-2.12*.diff Util-linux patch that adds support for AES and
|
|||
|
other ciphers.
|
|||
|
|
|||
|
|
|||
|
11. Credits
|
|||
|
~~~~~~~~~~~
|
|||
|
This package uses AES cipher sources that were originally written by
|
|||
|
Dr Brian Gladman:
|
|||
|
|
|||
|
// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
|
|||
|
// All rights reserved.
|
|||
|
//
|
|||
|
// TERMS
|
|||
|
//
|
|||
|
// Redistribution and use in source and binary forms, with or without
|
|||
|
// modification, are permitted subject to the following conditions:
|
|||
|
//
|
|||
|
// 1. Redistributions of source code must retain the above copyright
|
|||
|
// notice, this list of conditions and the following disclaimer.
|
|||
|
//
|
|||
|
// 2. Redistributions in binary form must reproduce the above copyright
|
|||
|
// notice, this list of conditions and the following disclaimer in the
|
|||
|
// documentation and/or other materials provided with the distribution.
|
|||
|
//
|
|||
|
// 3. The copyright holder's name must not be used to endorse or promote
|
|||
|
// any products derived from this software without his specific prior
|
|||
|
// written permission.
|
|||
|
//
|
|||
|
// This software is provided 'as is' with no express or implied warranties
|
|||
|
// of correctness or fitness for purpose.
|
|||
|
|
|||
|
Util-linux patch has few lines of documentation copied from international
|
|||
|
crypto patch: -p option documentation in losetup and mount man pages were
|
|||
|
written by Marc Mutz.
|
|||
|
|
|||
|
Util-linux patch includes rmd160.[ch] files that were copied from
|
|||
|
international crypto patch: they were originally written by GnuPG team and
|
|||
|
modified by Marc Mutz.
|