util-linux/README.loop-AES-v2.2d

1232 lines
53 KiB
Plaintext
Raw Blame History

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.