/etc/fstab"> mount"> losetup"> ] >
Linux Encryption HOWTO <author>by Marc Mutz, <htmlurl name="Marc@Mutz.com" url="mailto:Marc@Mutz.com"> <date>v0.2.1, 28 September 2000 <abstract> How to set up a Linux 2.2 system to use encryption in both disk and network accesses. This document describes how you can use the International Kernel Patch and other packages to make harddisk contents and network traffic inaccessible to others by encrypting them. </abstract> <toc> <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Introduction<label id="intro"> <sect1>Legal Stuff <p> Encryption HOWTO for Linux Systems <p> Copyright (C)2000 Marc Mutz. <p> This document is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. <p> This document is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. <p> You can get a copy of the GNU GPL at <htmlurl url="http://www.gnu.org/copyleft/gpl.html" name="http://www.gnu.org/copyleft/gpl.html">. <p> <sect1>I've got nothing to hide <p> In this section I will briefly remind you of basic rules that must be taken care of if you want to use strong encryption, as all of the presented packages in this document support (or even require) it. As the fear of governments of cryptography being employed by criminal circles has produced some strange regulations concerning the use of strong encryption, it cannot be over-emphasized how important it is to know the law in your own country: <enum> <item>Am I allowed to use strong cryptography? <item>Am I allowed to use a particular cipher algorithm either for private or commercial use? Do I have to pay licence fees? <item>Am I allowed to participate in the development of software that contains strong cryptography? </enum> Maybe I will extend this discussion in a later version of this paper. As for now, check the following resources to find answers to the above questions: <itemize> <!--<item>The glossary of this document.--> <item>The Crypto Law Survey web page by Bert-Jaap Koops at <htmlurl url="http://cwis.kub.nl/~frw/people/koops/lawsurvy.htm" name="http://cwis.kub.nl/~frw/people/koops/ lawsurvy.htm">. <item>The RSA crypto FAQ at <htmlurl url="http://www.rsasecurity.com/rsalabs/faq/" name="http://www.rsasecurity.com/rsalabs/faq/"> <item>The <tt>alt.security.*</tt>, <tt>alt.privacy.*</tt> newsgroups. <item>The Department of Justice or lawyers if in doubt (likely only interesting for commercial applications). </itemize> <sect1>Aims of this document <p> This document will (eventually, more or less extensively) describe all major development activities around the Linux(tm) operating system that provide encryption features to the kernel. These effords are currently being collected by Alexander Kjeldaas (<htmlurl url="mailto:astor@fast.no" name="astor@fast.no">) in the so-called International Kernel Patch (see below). If some packages described here are currently not included in this patch, I will state that clearly at the beginning of the section that discusses it. This document will not speak about other security-related issues. See the excellent <htmlurl name="Security HOWTO" url="Security-HOWTO.html"> for that. You can always find the latest version and snapshots (pre-releases) of forthcoming versions of this document at it's homepage at <htmlurl url="http://marc.mutz.com/Encryption-HOWTO/" name="http://marc.mutz.com/Encryption-HOWTO/"> <sect1>Mailing List<label id="ml"> <p> If you have questions or suggestions regarding this document or Linux and cryptography in general, you can send them to the mailing list <htmlurl url="mailto:linux-crypto@nl.linux.org" name="linux-crypto@nl.linux.org">. To subscribe, just send a message with the single line <verb> subscribe linux-crypto </verb> in the <em>body</em> of a mail to <htmlurl url="mailto:majordomo@nl.linux.org" name="majordomo@nl.linux.org"> and follow the instructions in the reply. <sect1>Notations and Conventions used<label id="notations"> <p> I would like to give a few notations I will use throughout this document here. <p> When listing commands or command sequences, I will prepend each one with a prompt, either <tt>user$</tt> for an ordinary user's shell, <tt>root#</tt> for a root shell and <tt>user></tt> and <tt>root></tt> for continued lines in a user and root shell resp. <p> Also I would like to mention that links to HOWTO's are meant to work on the <htmlurl name="LDP site" url="http://www.linuxdoc.org"> and in any directory structure that keeps all HOWTO's in the same directory (e.g. <tt>/usr/doc/howto</tt>). They definitely do not work from within the <htmlurl url="http://marc.mutz.com/Encryption-HOWTO/" name="Encryption-HOWTO Homepage">. <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Obtaining and Installing the International Kernel Patch <label id="ikp"> <p> The International Kernel Patch is the primary souce for encryption support for the Linux kernel. Due to export restrictions in some countries that prohibit the free flow and exchange of software that contains strong cryptography, it is not possible to include crypto support in the main kernel source tree (i.e. Linus' one). <p> Therefore, you should not consider the packages contained therein unstable or even unusable only because they are not contained in the main kernel. Most of this stuff is actually quite stable and I partly wrote this HOWTO to broaden the base of installed international kernels, so that code development can go on faster. <p> The International Kernel Patches are maintained by <htmlurl url="mailto:astor@fast.no" name="Alexander Kjeldaas"> and can be obtained from any kernel.org mirror in the directory <tt>/pub/linux/kernel/crypto/v2.2</tt>. The files to download are named <tt>patch-int-a.b.c.d.gz</tt>, where <tt>a.b.c</tt> is the kernel version and <tt>d</tt> is the patch level of the International Kernel Patch for that particular kernel version. <p> I strongly recommend to get at least the version of the patch, as it fixes a problem with moving around files that are used as loopback devices, see <ref id="faq:disk" name="FAQ section">. As of this writing (Sep 2000) is the latest version. It should apply without rejects to all recent 2.2.1x kernels. <p> The international kernel is distributed in the form of patches. If you are not familiar with this distribution form, you should consult the <htmlurl name="Kernel HOWTO" url="Kernel-HOWTO.html"> for how to apply patches to the kernel source. For the purpose of this document it suffices if you issue the following commands as root: <verb> root# cd /usr/src/linux root# cp .config .. # this is a trick I use root# make mrproper # to avoid the changing of root# mv ../.config . # the .config file by mrproper root# zcat ~/patch-int-a.b.c.d.gz | patch -p1 </verb> assuming that you downloaded the patch to root's home directory. The patch should apply without rejects. <p> <sect>The Crypto API<label id="cryptoAPI"> <p> The Crypto API is an approach to unify the interface between kernel modules <em>using</em> crypto routines (such as the loop_gen driver or CIPE (eventually?)) and kernel modules <em>providing</em> crypto routines (such as cipher or hash modules). <p> It shows up as the ``Crypto Options'' menu in <tt>make menuconfig</tt>. At the time of this writing (Sep 2000), only the crypto loop device driver (<tt>CONFIG_BLK_DEV_LOOP_GEN</tt>) uses this facility and not all ciphers contained in the international kernel have been integrated into the Crypto Library. It is obviously desirable that all kernel modules using strong encryption use the Crypto API (where applicable). <p> To this end, this HOWTO will eventually include a discussion on the ``API of the Crypto API'', so developers trying to use this library are no longer forced to read the source to find the appropriate functions. <p> Developers who want to earn their merits will find here a great opportunity to play. Help to implement new ciphers and hashes and put them under the GPL. Help to convert existing ciphers already contained in the international kernel to use the crypto API. Help to enhance the performance of ciphers by implementing them in native assembler code for different platforms! You don't need to be a kernel hacker to support this project, as the modules involved are rather small and similar to each other. <p> Late International Kernel Patches (from on) extend the concept of the Crypto API from plain cipher modules to digest (i.e. cryptographic hash) modules. Currently MD5 and SHA1 are supported, where MD5 was contributed by Alan Smithee and SHA1 was ported from "public domain code by Steve Reid" by Andrew McDonald. RIPE-MD is in the works from me. <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Encrypting Disks<label id="disk"> <p> In this section I will show how to configure the kernel and some of its utilities to use the loop device mechanism to encrypt block devices (i.e. partitions or regular files containing whole filesystems). This is the preferred method, as it is fast, simple and reliable. <p> There are, however, some restrictions still not resolved that avoid its use in all and every situation (e.g. swap partitions and root filesystems cannot yet be encrypted reliably), so I will briefly discuss other approaches that may fix some of these issues in section <ref id="disk:other" name="Other Disk Encryption Approaches">. <sect1>Configuring the Kernel<label id="ikp:kernel"> <p> After successfully applying the patch to the kernel source tree, we are in the position to configure the kernel to actually use the encryption routines. As usual, this includes re-compilation of the kernel. If this should be the first time you compile a custom kernel yourself, get yourself the help of a friend or read the <htmlurl name="Kernel HOWTO" url="Kernel-HOWTO.html">. <p> <tt>make oldconfig</tt> will prompt you for only the new kernel options, while <tt>make xconfig</tt> or <tt>make menuconfig</tt> will somewhat hide the new features as they are spread over all the menus, as we will see in a minute. <p> After configuring the options you want (see below), you re-compile and install the kernel as usual and then reboot it. Your kernel has now all it needs to support encryption of disks. <p> <sect2>Overview of kernel options <p> This is a short summary of disk encryption related kernel config options. See section <ref id="net" name="Encrypting Network Traffic"> for options related to network traffic encryption. As of, the help texts of most of these options do not contain much information. <descrip> <tag>CONFIG_CIPHERS (Crypto Ciphers):</tag>This enables the use of a wide variety of crypto ciphers (= routines that de/encrypt data) for the Crypto API. The Crypto API can be employed to disk encryption via the generic crypto driver for the loop device (<tt>CONFIG_BLK_DEV_LOOP_GEN</tt>). That obsoletes the concept that the ``direct'' drivers <tt>CONFIG_BLK_DEV_LOOP_CAST</tt> and <tt>CONFIG_BLK_DEV_LOOP_FISH2</tt> are using. Use of the generic driver is strongly recommended. <tag>CONFIG_CIPHER_*:</tag>This set of options enables specific ciphers (= routines that de/encrypt data) to be used in CBC mode by the Crypto API (see above). <tag>CONFIG_BLK_DEV_LOOP (Loopback device support):</tag> This options has nothing to do with encryption per se. However, as the current disk encryption implementation uses the loop device, you must say ``Y'' here. <tag>CONFIG_BLK_DEV_LOOP_USE_REL_BLOCK (Use relative block numbers...):</tag> This options allows you to copy around the file containing your encrypted file system without affecting it's usability. Without this option enabled, you have to make sure it stays at the exact same place on the disk in order to use it, because the (absolute, as opposed to relative) block numbers the file occupies on disk affect the crypto cipher, see the question on copying files in the FAQ section. <tag>CONFIG_BLK_DEV_LOOP_GEN (General encryption support):</tag> This option provides an additional layer of abstraction for crypto ciphers. With this option enabled, you can use any of the ciphers (<tt>CONFIG_CIPHER_*</tt>) the Crypto API supports. <tag>CONFIG_BLK_DEV_LOOP_CAST (CAST128 encryption):</tag> This option provides 128-bit key CAST encryption in ECB mode for use with the loop device. This option does not depend on the general encryption support (<tt>CONFIG_BLK_DEV_LOOP_GEN</tt>) or the Crypto API above. Use of this option is deprecated. <tag>CONFIG_BLK_DEV_LOOP_FISH2 (Twofish encryption):</tag> This option provides Twofish encryption in CBC mode for use with the loop device. This options does not depend on the general encryption support (<tt>CONFIG_BLK_DEV_LOOP_GEN</tt>) or the Crypto API above. Use of this option is deprecated. </descrip> <sect2>Selecting the right options <p> This is easy. First, you choose which cipher you want to use. Make sure that you know what using a particular cipher implies (licensing fees and/or even break of law). The help texts as well as the glossary at the end of this document will help you with that, although these sources are not to be considered authorative. <p> Next, if you want to use CAST-128 or Twofish, then say ``yes'' to <tt>CONFIG_BLK_DEV_LOOP</tt> and <tt>CONFIG_BLK_DEV_LOOP_CAST</tt> or <tt>CONFIG_BLK_DEV_LOOP_FISH2</tt>. Note that the implementation of these ciphers will likely change in future releases, as they will become accessible through the Crypto API. I'm not sure the future implementation will be compatible with existing encryption, so use these only if you have no choice or want to experiment. Also, they conflict with the <tt>loop_gen</tt> driver, so you can only have one of them in the kernel at any given time. <p> If you want to use one of the ciphers in the Crypto API, then you need to say ``yes'' to <tt>CONFIG_CIPHERS</tt>, <tt>CONFIG_BLK_DEV_LOOP</tt>, <tt>CONFIG_BLK_DEV_LOOP_GEN</tt> and the cipher you wish to use under ``Crypto options''. I recommend to also enable <tt>CONFIG_BLK_DEV_LOOP_USE_REL_BLOCKS</tt> (available in <tt>patch-int-</tt> and later), as this solves problems with physically moving around the encrypted file on disk. <p> <bf>NOTE:</bf> Using relative block numbers will probably not help you if you plan to move the file containing the encrypted filesystem between underlying filesystems with different block sizes. I nearly lost my gigabyte of encrypted data while trying to do so. A solution is in the work. It will allow you to choose the encryption block size (currently equal to the block size of the underlying filesystem - this where the trouble stems from) on setup via <tt>losetup</tt>. <p> If you want to compile crypto ciphers as modules, see the FAQ section for how. <sect1>Patching the <tt>util-linux</tt> source<label id="losetup"> <p> After re-compiling the kernel and rebooting it, you need to patch some of its helper programs, namely &losetup; and/or &mount;. The patch used resides in the <tt>Documentation/crypto</tt> hierarchy of the kernel source tree. <p> &losetup; and &mount; need to be patched if you want to use any of the following ciphers: <itemize> <item>Blowfish <item>Twofish <item>DFC <item>3DES <item>Rijndael (broken - kills box when used) <item>IDEA <item>MARS <item>RC5 (missing test vectors) <item>RC6 <item>Serpent </itemize> Note that this collection is compiled from my own personal tests and is only valid for <tt>patch-int-</tt>. As it is one short-term goal to unify the conceptional design of the crypto modules (i.e. all will use the loop_gen abstraction someday), the size of this list is likely to monotonically increase as new releases come out. <p> In order to patch the mount utilities to support encrypted filesystems over the loop device, you need to fetch a recent source tree of the util-linux package, e.g. from <htmlurl url="ftp://ftp.kernel.org/pub/linux/utils/util-linux/" name="ftp.kernel.org/pub/linux/utils/util-linux/"> or oneof it's mirrors. <p> As usual, you issue the following commands to apply the patch: <verb> user$ tar xfzv util-linux*.tar.gz user$ cd util-linux* user$ patch -p1 < /usr/src/linux/Documentation/crypto/util-linux*.patch </verb> It should apply cleanly if you use the patch only on util-linux trees that have a higher version number than the patch file shows. <p> Next you have to make sure that only the mount utilities are built. You can get in all sorts of troubles if you mess around with <tt>init</tt> or the password authentication programs. <bf>You can render your computer unusable if you do not make sure that you only compile &mount; and &losetup;!</bf>. <p> In order to avoid this mess, you need to install the executable files yourself, so you can gain control over what is being installed. But that is not hard to do: <p> After paching the util-linux source tree as described above, issue the following commands in the <tt>util-linux*</tt> directory. Make sure you have not currently mounted any filesystems using the loop device. <verb> user$ ./configure user$ make -C lib setproctitle.o # mount depends on this user$ cd mount user$ make losetup mount umount root# for i in losetup mount umount; do root> j=$(locate bin/$i) root> cp $j{,.old} && chattr +i $j.old root> cp $i $j root> done </verb> If the make step fails, check that <tt>/usr/include/linux</tt> and <tt>/usr/include/asm</tt> resp. are symlinks to <tt>include/linux</tt> and <tt>include/asm-arch</tt> resp. Some distributions (e.g. Debian) only have a <em>copy</em> of the kernel include there. If you change the kernel, they become outdated. <p> Change the permissons and ownership of the new binaries according to your distribution's policy (check the old binaries for the right settings). <p> <sect1>Making an Encrypted Folder<label id="folder"> <p> Create a file that will hold the encrypted data. We will call it <tt>.crypto</tt> for now and assume it is placed in the home diretory of user ``user''. You can use any other name, though. Note that this file will not grow dynamically as you feed more and more data into it. On the other hand, it will permanently block the amount of disk space you allocate to it, even if there is no data stored in the encrypted folder. However, you can always grow or shrink the filesystem manually, see FAQ section for how. Choose a reasonable size, e.g. 10M in the following command (calculated as <it>bs * count</it>): <verb> user$ dd if=/dev/urandom of=~/.crypto bs=1024k count=10 </verb> This will take some time, as the urandom device emits random numbers that need to be created first. The above command takes about one minute to complete on my 300 MHz AMD K6-2. You might want to use <tt>/dev/zero</tt> instead, if you have a slow machine or want a huge crypto filesystem, but then your filesystem is said to be vulnerable to known-plaintext attacks. I cannot follow that argument, as we do not encrypt the zeros, but instead pretend they were the ciphertext. However, using zeros to create the file in the first place makes it possible for the attacker to know which blocks have not been written to. This <em>may</em> give him one or another hint as to how to attack your ciphertext. <p> You may also choose to encrypt a whole partition. Just make sure it contains no data and replace the filename <tt>~/.config</tt> in the following discussion with the name of the block device that you wish to use (e.g. <tt>/dev/sda3</tt>). <p> Now set up this file as the target of a loop device. You must do this as superuser, unless the loop device files can be written to by everyone (not recommended). Choose a loop device that is not currently in use. Try <tt>mount|grep loop</tt> to see which loop devices are currently used by mounted filesystems. <verb> root# losetup -e ciphername /dev/loop0 ~user/.crypto Password : </verb> Note that you should take your time as you enter the password, as you are not prompted to enter it again for typo checking! One way around this, if you have a recent bash (tested to work with bash-2.04, tested to not work with bash-2.01) and util-linux-2.10p or higher (which will hopefully include the <tt>-p</tt> option to &losetup; and &mount;), is to use the following <htmlurl url="http://marc.mutz.com/Encryption-HOWTO/scripts/mkloop.sh" name="little script">: <verb> #!/bin/bash # the cipher is the first command line argument CIPHER=$1 # the loop device to use is the second LOOPDEV=$2 # the underlying file is third UNDERLYING=$3 # until the two passphrases match and are not empty... until [ "$PASS1" = "$PASS2" -a -n "$PASS1" ]; do # the bash read buitlin has to support the -s option. # Don't use read without -s!! read -s -p "Enter Passphrase: " PASS1; echo read -s -p "Re-enter Passphrase: " PASS2; echo done # setup the loop device using the passphrase given on STDIN. echo "$PASS1" | losetup -e $CIPHER -p 0 $LOOPDEV $UNDERLYING </verb> <p> What you have done so far is to set up a so-called encrypted <em>block device</em> <tt>/dev/loop0</tt>. It is functionally equivalent to a partition device (e.g. <tt>/dev/hda1</tt>), so you next need to do what you (or your installation tool) did with naked partitions: Make a filesystem on it. Ext2 should be your choice, as it is Linux' native filesystem: (<bf>FIXME:</bf> what about journalling?) <verb> root# mke2fs /dev/loop0 </verb> Next, you mount it. We take the mount point to be <tt>~/crypto</tt> (notice the omission of the leading dot!): <verb> user$ mkdir ~/crypto root# mount -t ext2 /dev/loop0 ~user/crypto </verb> The last step needs to be done as root, as only the superuser is allowed to (un)mount filesystems, unless otherwise stated in &fstab;. <p> If all worked well, you now have a filesystem that encryptedly resides in the file <tt>~/.crypto</tt> and is mounted on <tt>~/crypto</tt>. You can enter it and look at the files in it (not many now as it is just newly created, only the <tt>lost+found</tt> folder should be visible). <p> Now, all this is nice but really clumsy to do everytime you want to access the encrypted data. But before you learn how to make mounting the encrypted file/folder more user-friendly, you first need to unmount and destroy the loop device. I'd like to make it very clear at this point that encryption does not buy you anything if you leave the filesystem mounted all the time and/or set the permissions not restrictive enough. You should be familiar with what the following commands do, so I will let them speak for themselves: <verb> root# grep -q "lost+found" /dev/loop0 && echo 'found!' root# chmod go= ~user/.crypto root# chown user -R ~user/crypto root# chmod go= -R ~user/crypto </verb> Now unmount the filesytem: <verb> root# umount /dev/loop0 </verb> and detach the loop device from the file: <verb> root# losetup -d /dev/loop0 </verb> <p> You next edit your &fstab; to include the following line: <verb> /home/user/.crypto /home/user/crypto ext2 \ defaults,noauto,loop,encryption=ciphername,user 0 0 </verb> where <tt>ciphername</tt> is the same as the one you used with the &losetup; command. <p> This approach has some advantages over the one previously used to initially create the filesystem: <enum> <item>You don't need to be root to (un)mount the filesystem (option <tt>user</tt>; this is not meant to be the example username ``user'' we used throughout this section!) <item>You don't need to call &losetup; yourself, as &mount; will do that for you (options <tt>loop</tt>, <tt>encryption</tt>) <item>You don't need to keep track of already used loop devices, as &mount; will do this for you, choosing free loop devices by itself as needed. </enum> <p> <bf>Warning:</bf> <tt>mount</tt> currently has a bug that leads to the assignment of additional loop devices, e.g. when remounting. The symtoms are that the sequence <verb> root# mount /my/crypto/fs.file root# mount -o remount,ro /my/crypto/fs.file root# umount /my/crypto/fs.file </verb> will leave <tt>/dev/loop0</tt> assigned to <tt>/my/crypto/fs.file</tt>. Temporary fix: issue <tt>losetup -d /dev/loop0</tt> after the <tt>umount</tt> command. Util-linux version 2.10p should fix this problem. <p> <sect1>Automagically Encrypting the Home Directory with ``EHD'' <label id="home"> <p> I cannot yet discuss this (additional) patch to the util-linux tree, as I have not yet successfully installed it on my system. <p> You may do your own experiments, though: The patch (written by Id Est) and some documentation can be obtained from <htmlurl url="http://members.home.net/id-est/" name="http://members.home.net/id-est/">. <p> Do not expect too much comfort from this patch, however. It does not work with <tt>rsh</tt>, which is OK, because <tt>rsh</tt> is inherently insecure, but also not with <tt>ssh</tt> (although you can instruct <tt>ssh</tt> to use <tt>login</tt> for access control) and <tt>su</tt>, which is not acceptable in a networked environment. Also, I have not seen how it should work for X sessions. <p> All these restrictions stem from the inherent need to enter the passphrase for decryption. Maybe PAM (pluggable authentication) modules are a better place to implement this functionality, but I have yet to see such an approach being taken. However, there is a quite concrete idea of how to do this floating around in my head. If you are interested, <htmlurl url="mailto:Marc@Mutz.com" name="give my a call">. <p> <sect1>Other Disk Encryption Approaches<label id="disk:other"> <p> The loop device approach has several drawbacks. Some will be resolved sometime soon, some are deeply buried in the design of the loop device mechanism. Some can be overcome with scripts and tricks, some are not that easy. <p> Major drawbacks---and a good reason for other approaches to exist---include (in order of increasing chance to overcome them): <enum> <item>You are not able to encrypt devices that are used for swap. Trying this will lead to deadlocks when swapping heavily: The kernel tries to free memory by swapping out some areas of memory, the device tries to encrypt the data, encryption requires memory---bingo. <item>You are not able to export directories encryptedly via NFS (loop device over NFS-mounted files doesn't work in current kernels, as far as I know). So you must export directories in the clear. <item>Root filesystem encryption is tricky. <item>(Automated) incremental backups are difficult. <item>Changing password. The hashed passphrase is used as the encryption key, so changing the passphrase changes the key, i.e. you are no longer able to access the encrypted data. </enum> Other disk encryption approaches known to me are: <itemize> <item>PPDD (Personal Privacy Disk Driver) by Allan Latham <htmlurl name="(alatham@flexsys-group.com)" url="mailto:alatham@flexsys-group.com">. It claims to be able to encrypt root and swap devices and be ``fool-proof'' in its usage. I have downloaded, but not yet installed it. Latest version as of this writing (Sep 2000) is 1.2, anything below it is not recommended by the author due to a severe bug. There is a mailing list where you can ask questions, just send a message with the single word <em>subscribe</em> in the body of the message to <htmlurl name="ppdd-request@linux01.gwdg.de" url="mailto:ppdd-request@linux01.gwdg.de">. You'll receive a message telling you what to do next. <p> <em>This is what Doobee writes about it in his document (see below for an URL):</em> <quote> You can read more about the design of PPDD in the specification or in the PPDD man page (available at the homepage, see below). One of the very nice features of PPDD is that you can decrypt devices without kernel support, if needed. And the author has thought extensively about ways to backup encrypted media and shows several solutions to solve this problem. He even made it possible to have an encrypted root partition. <p> One of the drawbacks of ppdd is that it doesn't use the now evolving Linux Crypto API. But you can use it together with the International Kernel Patch without big hassle. Perhaps you get a few rejects while patching the two together, but these are easy to resolve by hand. <p> You can find PPDD at <htmlurl url="http://linux01.gwdg.de/~alatham" name="http://linux01.gwdg.de/~alatham"> and <htmlurl url="ftp://ftp.gwdg.de/pub/linux/misc/ppdd" name="ftp://ftp.gwdg.de/pub/ linux/misc/ppdd">. If you want to know how to install PPDD, check out the file ppddhow.txt. <p> I have done some performance testing on a dual PII/266 MHz/256 MB using <tt>bonnie</tt>. Writing on an encrypted volume takes about twice the time as writing to a plain volume. But reading from an encrypted volume takes 4 times as long as reading from an unencrypted one: <verb> -------Sequential Output-------- ---Sequential Input-- -Per Char- --Block--- -Rewrite-- -Per Char- --Block--- Machine MB K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU K/sec %CPU plain 100 4022 95.0 13628 28.7 4036 17.8 3782 84.7 11663 20.4 encrypted 100 2609 75.5 5719 17.2 808 23.8 968 44.9 1165 28.1 --Random-- -----Time------ --Seeks--- -user- -system- Machine MB /sec %CPU sec sec plain 100 286.3 7.0 42.98 13.82 encrypted 100 18.2 5.1 43.40 103.28 </verb> While doing these tests my PS/2 mouse reacted like I was using Windows :-( but this should be tweakable by skewing with the buffer cache. </quote> </itemize> <em>The rest of this section is copied with kind permission of the author from Doobee R. Tzeck's <htmlurl url="mailto:drt@ailis.de" name="(drt@ailis.de)"> document "Encrypting your Disks with Linux" at <htmlurl url="http://drt.ailis.de/crypto/linux-disk.html" name="http://drt.ailis.de/crypto/linux-disk.html">.</em> <itemize> <item>CFS (Cryptographic Filesystem) <p> CFS is the first free UNIX disk encryption program hacked by well-known Matt Blaze. It hooks into NFS so one feature of CFS is the fact that you don't have to fiddle with the kernel to get it running and CFS is more portable among UNIXes than the other solutions. Another nice thing is that you can use CFS over NFS so that your files won't be transmitted in clear text over the wire. You can find more about the working of CFS by reading the <htmlurl url="cfs-linux-HOWTO.html" name="Cryptographic File System under Linux HOWTO"> or "A Cryptographic File System for Unix" by Matt Blaze at <htmlurl url="ftp://research.att.com/dist/mab/" name="ftp://research.att.com/dist/mab/">. <p> CFS supports DES, which is insecure because the key is too short, 3DES, which can be considered secure but painfully slow, MacGuffin, which is broken, and SAFER-SK128, which has an unusual design and is designed by some NSA buddys at Cylink---enough reason to not fully trust this algorithm. But <htmlurl url="mailto:darkstar@frop.org" name="darkstar@frop.org"> was kind enough to hack Blowfish into CFS and Matt Blaze integrated it into CFS 1.3.4. <p> The main problem of CFS even with Blowfish is the lack of speed. This results from CFS being an user space daemon forcing the data to be copied several times between kernel and user space. If you want to encrypt large amounts of data expect a significant performance penalty when using CFS. <itemize> <item><url url="http://drt.ailis.de/crypto/cfs-1.3.3.tar.gz" name="cfs source code"> <item><url url="http://drt.ailis.de/crypto/cfs-1.3.3bf.1.tar.gz" name="cfs with blowfish source code and bf_tab.h"> </itemize> <item>TCFS (Transparent CFS) which is being developed at the University of Salerno, Italy, claims to improve Matt Blaze's CFS by providing deeper integration between the encryption service and the filesystem, which results in a complete transparency of use to the user applications. But the developers seem to focus much more than Matt Blaze on substituting NFS. <p> A nice feature of TCFS is that it will allow you to securely share files among the members of a group. One big misfeature of TCFS is the fact that it needs kernel patches and that the patches are still made for the now obsolete 2.0 kernels. Nevertheless TCFS is under active development. Another problem with TCFS is that it only supports minimal (read: <em>no</em>) key management. There is some placebo-key management delivered with TCFS, but that is next to nothing, using only the login password to decrypt the key. <p> To learn more about TCFS, read the TCFS-FAQ at <htmlurl url="http://tcfs.dia.unisa.it/tcfs-faq.html" name="http://tcfs.dia.unisa.it/tcfs-faq.html">. Since it is from Italy, which is part of the free world, you can download it without any problems, from the TCFS Homepage at <htmlurl url="http://tcfs.dia.unisa.it/" name="http://tcfs.dia.unisa.it/">. <item>SFS (Steganographic File System) <p> The theoretical background of SFS was laid by Ross Anderson, Roger Needham and Adi Shamir in their paper "The Steganographic File System". You can grab it at <htmlurl url="http://drt.ailis.de/crypto/sfs3.ps.gz" name="http://drt.ailis.de/crypto/sfs3.ps.gz">. <p> The first implementation was done by Carl van Schaik and Paul Smeddle in a Project called vs3fs. They describe the code they have hacked this way: <quote> Ok, firstly we would like to note that this project evolved from a computer science project that had specific goals and deadlines and thus the code may not be complete in specific areas and still has many bugs to be stomped out. <p> Briefly, a steganographic filesystem aims to be more than just your every day encrypted file system. It tries to hide the information in such a way as to discredit its very existence. This has been a very difficult task to perform given such a short development time, but we have succeeded in attaining this goal despite a few alternative methods of doing things (read: kludges :). <p> We present this filesystem as is. We take no responsibility for any damage to disks or data while using this program. I repeat: This is still <em>very</em> experimental and you will probably lose data stored on steganographic partitions. We also hope that some of you will be able to work out some of our problems and perhaps try to modify the structure to be more flexible and to provide better security. After all... thats the beauty of open source :) <p> We must also note that we use encryption methods that may be stronger than those allowed in your country. We will accept no responsibility for your actions involving your country's regulations. </quote> They had a homepage at <htmlurl url="http://leg.uct.ac.za/~carl/vs3fs/" name="http://leg.uct.ac.za/~carl/vs3fs/"> with patches for Linux 2.0 and 2.1, but this page is now defunct. Seems they have left university and also left SFS alone. <p> Peter Schneider-Kamp <htmlurl url="mailto:peter@schneider-kamp.de" name="(peter@schneider-kamp.de)"> updated the stuff to 2.2. This stuff can be found at <htmlurl url="http://www.linux-security.org/sfs/" name="http://www.linux-security.org/sfs/">. But since his pages seem to be down, too, you can also get it at <htmlurl url="http://drt.ailis.de/crypto/sfspatch-2.2.10.tar.gz" name="http://drt.ailis.de/crypto/sfspatch-2.2.10.tar.gz">. <p> SFS still has a lot of rough edges and Peter doesn't seem to maintain it actively. <item>StegFS (Steganographic File System) <p> Andrew McDonald and Markus Kuhn did another implementation of the ideas outlaid in the paper of Anderson, Needham and Shamir. They claim that SFS is flawed and this claim seems reasonable. <p> StegFS seems to be really elaborate and looks much more usable to me than SFS. Since McDonald and Kuhn come from the same University as Anderson, it seems obvious that they tried hard to meet the criteria of the Steganographic Filesystem paper. <p> StegFS has a homepage at <htmlurl url="http://ban.joh.cam.ac.uk/~adm36/StegFS/" name="http://ban.joh.cam.ac.uk/~adm36/StegFS/">. <item>CryptFS <p> There is another good-looking crypto file system called CryptFS. It is described in <url url="http://www.cs.columbia.edu/~ezk/research/cryptfs/index.html" name='"CryptFS: A Stackable Vnode Level Encryption File System"'> and can be downloaded from <htmlurl url="http://www.cs.columbia.edu/~ezk/research/software/cryptfs/" name="http://www.cs.columbia.edu/~ezk/research/software/cryptfs/">. <p> But since this site is in the USA, which is a country keeping its scientists from publishing research worldwide, CryptFS is unusable for people from the free world until some dark figure smuggles it over here. <item>BestCrypt and Virtual Private Disk <p> <em>As they are commercial products, I (Marc Mutz) will not include a discussion of them here.</em> </itemize> <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Encrypting Network Traffic<label id="net"> <p> This section is in preparation. See the <htmlurl url="http://marc.mutz.com/Encryption-HOWTO/#rl" name="Release Notes"> for a planned roadmap. I included the CIPE documentation as a subsection, but the section layout is not complete, so this may change (Why doesn't linuxdoc provide a <em>part</em> commamd like LaTeX? :-( <p> Anyway, this section includes descriptions of Linux kernel add-ons that allow you to encrypt the flow of network traffic (at least IP traffic, don't know about IPX and such). <sect1>The Concept of IP Tunnels<label id="net:tunnel"> <p> All network encryption packages described in this document work on the same basis: A <em>private</em> network, which should be inaccessible to the outside world, is spread over many (physical) locations (read: company centres and/or roaming users) that are connected via the "evil" internet. This setup is commonly called VPN (virtual private network), because the private network shares its physical structure with the "real" internet. <p> The task is to route IP packets originating in the private network and destined for other hosts in the private network through the internet while preserving privacy. <p> This section describes problems and concepts common to all of the VPN packages to be described later on. <sect2>What are IP Tunnels?<label id="net:tunnel:w"> <p> The basic networking protocol nowadays is TCP/IP, mostly because it is the protocol the internet uses. But there were other network protocols and ever will be. When the internet began to grow, everyone was tempted to switch to the TCP/IP protocol, regardless of what he was using before. But many applications were not TCP/IP aware and it proved difficult to convert certain subnets to TCP/IP. However, one still wanted to benefit from the TCP/IP protocol and use it for communicating with the internet. <p> This was one major reason to invent <em>tunnels</em>. Just like TCP/IP packets are packed in Ethernet frames to send them over Ethernet or in PPP frames to send them over PPP links, one now wrappes TCP/IP packets with e.g. IPX frames to <em>tunnel</em> TCP/IP through IPX, or vice versa. <p> Thus, one was able to use TCP/IP in IPX or ATM---you name it---environments without fundamental changes to routers and so on. <p> The next picture shows an IP packet contained in an IPX frame: <p> <verb> +------------++-----------+------------------+ | IPX header || IP header | payload | +------------++-----------+------------------+ <----- IP packet --------------> <----- IPX packet containing IP packet ------> </verb> <p> Of cource, no-one prevents you from tunneling IP packets in IP packets. While this does not seem very useful at first sight, there are indeed situations where this concept makes your network admin's life much easier. <p> One typical example of ordinary IP-in-IP tunneling is the connection of a roaming user to a LAN. The roaming user can plug his laptop into whatever network is available (provided it has a connection to the internet), establish a tunnel to a gateway in the home LAN and route everything through the tunnel. This means that the roaming user will always find the same configuration of networking services available once he gets the tunnel to the home LAN up and running. Another typical example is LAN-LAN coupling. <p> You can find out more about ordinary tunneling (as opposed to encrypted tunnels) in the <htmlurl name="NET-3-HOWTO" url="NET-3-HOWTO.html">. We will instead concentrate on tunnels that encrypt everything that is put into them. <sect2>Private vs. Carrier Networks<label id="net:tunnel:pc"> <p> The main thing to keep in mind when discussing VPN setups is the existence of <em>two</em> logical networks sharing the same physical network hardware. It is important not to confuse those two. <p> On the one hand, one has the <em>private network</em>, consisting of possibly many sites and hosts, which have no (inherently) secure connection between each other. One has to provide for a secured, transparent connection between them in order to make the pieces a whole. <p> On the other hand, one has the <em>carrier network</em> (often the internet) that is used to connect the different sites the private network is physically located at. <p> Typically, the private network uses IP subnets that are reserved for use in closed networks with no connection to the internet. Those subnets include the class A, the class B 172.[16-31].0.0/16 and the class C 192.168.[0-255].0/8 subnets. Those IP addresses will not be routed by internet routers and thus can only be used for their intended use: private networks. (There are, however, examples where the carrier network uses these addresses and the "private" network uses ordinary, routable addresses, see Section <ref id="net:tunnel:e:le" name="Encrypt the Local Ethernet">.) <p> All VPN packages establish an encrypted point-to-point connection on top of an existing network between two hosts. This connection belongs to the <em>private</em> network, while the existing network serves as the <em>carrier</em> of the encrypted datagrams. <sect2>Routing Issues<label id="net:tunnel:ri"> <p> The toughest part in setting up a VPN seems to be the correct routing. But this is only so if one confuses the two distinct networks described above. Indeed, one has to maintain two disjoint routing tables: <p> One for routing the private traffic within the private network (usually through the tunnel interfaces) and one for routing the encrypted datagrams over the carrier network (usually through the physical interfaces like <tt>eth0</tt>, <tt>ppp0</tt>). <p> Be careful, though: Not all physical network interfaces belong to the carrier network! The internal Ethernet of a company may well belong to the private network. <p> The problem is now that Linux knows nothing of our ambition to create a VPN setup. Also, it does not know about private and carrier networks and their distinction. All Linux can do is, based on its routing table, send an IP packet destined to a particular IP address through an appropriate network interface. <p> Therefore, the logical distinction of the two networks has to be expressed in terms of routing rules. The best practice proves ever so often to be to consider the carrier network alone first. Once you have the routing table for the carrier network, you start creating the tunnels and add routing rules for the private network, independent of the carrier networks' rules. <sect2>Example: Encrypt the Local Ethernet <label id="net:tunnel:e:le"> <p> The simplest class of a VPN is where the private and the carrier network coincide. As an example, I picked the case where a company wants to encrypt all traffic in the local Ethernet. This can be useful, if the LAN carries sensible data and one wants to make the EM radiation of the ethernet cables unusable to possible spies. <p> In this setup one hits the limit of most current VPN packages: They only know of point-to-point connections. Only FreeS/WAN has/will eventually have the ability to connect two arbitrary hosts transparently. <p> So, the only way out is to either select a host as internal gateway, and route all packets through it or to set up point-to-point connections for every single combination of hosts on the network. <p> While the first method minimizes configuration overhead, it also minimizes performance, because each packet has to be sent from the originating host to the gateway and back to the destination host. So network performance is roughly halved, not even counting the additional de/encryption process on the gateway host. <p> The second method maximizes both network performance and configuration overhead, because each change in the network topology needs to be reflected in the local (w.r.t. each host) configuration files. <p> Assume that the company's LAN is a single Ethernet segment and an IP subnet with net address and subnet mask, i.e. the class C network It has a gateway to the internet (to exchange mail, etc) with IP address Security is enforced by a firewall in front of the gateway, so our task is only to encrypt all traffic in the local part of the ethernet. <p> <verb> ethernet - - - -----+----------+----------+ eth0 | | | ... host C host B host A (gateway) | eth1 +-----------| firewall |------> INTERNET </verb> <p> As the hosts behind the firewall have transparent access to the internet (within the rules of the firewall), it is necessary that the private network has IP addresses that are routable. The carrier network does not need to have routable IP addresses, so we choose to assign IP address to the private network and IP address to the carrier network. <p> In the configuration-friendly model where all traffic is routed via the gateway ( in our setup), host A's routing table would look like this: <p> Routes for the carrier network and the connection to the firewall: <verb> Destination Gateway Genmask Flags Metric Ref Use Iface U 0 0 0 eth0 firewall UH 0 0 0 eth1 U 0 0 0 lo [ U! 0 0 0 eth0] firewall UG 0 0 0 eth1 </verb> The routing table entry in parenthesis is a <em>reject route</em> preventing that local traffic is sent unencryptedly via the default route if the point-to-point route for a particular host is not set or there is no host corresponding to a given IP address. <p> Routes for the private network: <verb> Destination Gateway Genmask Flags Metric Ref Use Iface UH 0 0 0 tunl0 UH 0 0 0 tunl1 UH 0 0 0 tunl2 ... ... ... ... ... ... ... ... </verb> Here <tt>tunl</tt><em>x</em> stands as a placeholder for the interface name of the particular software used (e.g. <tt>cipcb</tt><em>x</em> for CIPE or <tt>ipsec</tt><em>x</em> for FreeS/WAN). <p> The routing table on the other hosts (B, C, etc) would look simply thus: <verb> Destination Gateway Genmask Flags Metric Ref Use Iface U 0 0 0 lo UH 0 0 0 eth0 UH 0 0 0 tunl0 UG 0 0 0 tunl0 </verb> Here, is the IP address of host A in the carrier network (this is all any given host needs to know for its routing job, but the first route can safely be changed to be a <em>net</em> route). <p> In the performance-friendly model, host A's routing table would look the same, but the other hosts would have a routing table like the following: <verb> Destination Gateway Genmask Flags Metric Ref Use Iface U 0 0 0 lo U 0 0 0 eth0 UH 0 0 0 tunl0 UH 0 0 0 tunl1 UH 0 0 0 tunl2 ... ... ... ... ... ... ... ... UG 0 0 0 tunl0 </verb> Note that the point-to-point routes are usually set up automatically by the controlling daemon, so in the last routing table, you only need to set the default and net routes by yourself. <sect2>Example: Connect Two Private Ethernets <label id="net:tunnel:e:c2"> <p> The classical class of VPNs is the situation where two or more physically separated offices are to be connected in a transparent and secure way via the internet. <p> We first look at the routing required to connect two offices: <p> <verb> OFFICE A if0 +-------> INTERNET <--------+ if0 OFFICE B / \ carrier - - - - - / - - - - - - - - - - \ - - - - - network - / \ private / \ +------ gw.a ------------------------------- gw.b ------+ | eth0 tunl0 tunl0 eth0 | v v LAN A LAN B </verb> <p> We have two LANs A and B with private IP address spaces and, respectively and we assume that one host in LAN A (called gw.a) is connected to the internet via the network interface <tt>if0</tt> (this is a generic name, think of it as <tt>ppp0</tt> for a PPP link or <tt>eth1</tt> for a DSL or leased line, etc.) with IP The same is true for a host gw.b in LAN B, connected to the internet via <tt>if0</tt> with IP address The <tt>eth0</tt> IP address of the gateways is, as usual, and, respectively. <p> We want to connect these two LANs with a tunnel, so that traffic can flow between them, although they use IP addresses that are not allowed to travel the internet. <p> The advantage of using private IP addresses is that these need not be reserved (and possibly paid for) and that they make it hard for external intruders to attack hosts, simply due to the fact that IP packets destined for these IP addresses are immediately dropped by every internet router. <p> We identify the internet, together with the <tt>if0</tt> interfaces of each gateway, to be the <em>carrier network</em>, while the two LANs and the tunnel between the two gateways constitute the <em>private network</em>. <p> If we first consider the routing needed for the carrier network, we simply get the following tables: <p> <verb> gw.a's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface UH 0 0 0 if0 U 0 0 0 lo gw.b's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface UH 0 0 0 if0 U 0 0 0 lo </verb> <p> On top of this, we construct the routing tables for the private network: <p> <verb> gw.a's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface UH 0 0 0 tunl0 U 0 0 0 eth0 UG 0 0 0 tunl0 gw.b's Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface UH 0 0 0 tunl0 U 0 0 0 eth0 UG 0 0 0 tunl0 </verb> <p> <sect2>Example: Connect a Mobile Host to the Internal LAN <label id="net:tunnel:e:mh"> <p> This class of VPNs is a special case of Example <ref id="net:tunnel:e:c2" name ="Connect Two Private Ethernets">, and the routing involved is in fact easier when considering the tables only. <p> What makes this example special and interesting from a configuration point of view, is the fact that the tunnels are dynamically created and destroyed possibly quite often (as opposed to created at boot time and destroyed at system shutdown) and that the IP address of the mobile host may change frequently, depending on what LAN or ISP the laptop is currently plugged into. <p> Often one part of the carrier network consists of a dynamically established PPP link, which adds even more configuration overhead and variables to consider. <p> This setup depends heavily on the VPN software used, so further discussion of this is postponed to the sections on specific VPN software below. <sect1>CIPE - Cryptographic IP Encapsulation<label id="net:cipe"> <p> CIPE by Olaf Titz (<htmlurl url="mailto:Olaf.Titz@inka.de" name="Olaf.Titz@inka.de">) ships with the International Kernel Patch (see Section <ref id="ikp" name="Obtaining and Installing the International Kernel Patch">). The userspace tools needed are in the <tt>net/cipe</tt> subdirectoy of the patched kernel source. The package is also available from <htmlurl url="http://sites.inka.de/~bigred/devel/cipe.html" name="http: //sites.inka.de/~bigred/devel/cipe.html">. I only document version 1.3.0 (Apr 1999) here, although there is a newer version out (1.4.2). It will not inter-operate with earlier versions due to a bug in the key handling or so in those earlier versions, but it finally supports Windows! See <htmlurl url="http://CIPE-Win32.sourceforge.net/" name="http://CIPE-Win32.sourceforge.net/">. There is also a mailing list dedicated to CIPE. You can subscribe to it by sending a message with the single line <em>subscribe cipe-l</em> in its body to <htmlurl url="mailto:majordomo@inka.de" name="majordomo@inka.de">. <p> <sect2>Concepts and Features<label id="net:cipe:cf"> <p> CIPE is a very simple package in that it requires you to make some decisions at compile-time, which leads to specialized and simpler code, which in turn is supposedly less bug-loaden than a complicated protocol like IPSec. CIPE is only compatible to itself, but often enough that is no limitation. <p> These disadvantages turn out to be big wins when it comes to maintaining the package, as configuration is much easier done than e.g. the disk encryption in Section <ref id="disk" name="Disk Encryption">. <p> CIPE intercepts the network stack just above the network layer by adding a new network interface (e.g. <tt>cipcb0</tt>). (IP-)Packets routed through it will be encrypted and put through a tunnel to a peer gateway, where they will be decrypted and delivered. <p> It employs symmetric ciphers (Blowfish and IDEA) and a shared secret (key) with dynamic re-keying, i.e. the shared secret is only used for authentication and exchanging the first dynamically generated, actual encryption key. Data is encrypted using these dynamic keys. <p> The package consists of a kernel module (<tt>cipcb</tt> for Blowfish and <tt>cipci</tt> for IDEA) and a user space deamon (<tt>ciped-cb</tt> resp. <tt>ciped-ci</tt>). <sect2>Compiling and Installing<label id="net:cipe:ci"> <p> The only thing you need to do in your kernel is to enable loadable module support (<tt>CONFIG_MODULES</tt>). Of course you need to have some kind of (carrier) network running, but I assume that this is in a working state. See the appropriate HOWTOs for how to configure that. <p> CIPE currently only works as modules and I do not see anything indicating a change to that. Also, the building of the CIPE modules is currently not included in the kernel build process, not even with the international kernel, although the entries in <tt>make config</tt> suggest otherwise. At least on my CIPE modules were not build resp. installed by <tt>make modules modules_install</tt>. <p> So you have to do that yourself: Change into the CIPE directory. It is the <tt>net/cipe</tt> subfolder of the kernel source tree if you use CIPE from the international kernel patch or <tt>cipe-1.3.0</tt> if you extracted it from the tar archive on <htmlurl url="http://sites.inka.de/~bigred/devel/cipe.html" name="inka.de">. <p> If you have the source of the kernel under <tt>/usr/src/linux</tt>, then you can just enter <tt>./configure</tt> to let CIPE figure out the details of your kernel. Otherwise you have to tell the configuration script where to find the kernel source with the <tt>--with-linux</tt> option, e.g. <verb> root# ./configure --with-linux=/usr/src/linux-2.2.17 </verb> if your kernel source resides in <tt>/usr/src/linux-2.2.17</tt>. If you want to use the IDEA cipher instead of the default Blowfish, then call <tt>./configure</tt> with the option <tt>--enable-idea</tt>. These are the compile-time options mentioned in the <ref id="net:cipe:cf" name="Concepts and Features"> Section. You can compile different versions of the CIPE modules and userspace tools one after the other to allow the use of both ciphers. <p> After the configure script has successfully finished, you will find a new folder named something like <tt>2.2.17-i386-cb</tt> in the CIPE directory. This helps you with the compilation of multiple versions of the CIPE package (e.g. for using both ciphers). The first part of the folder name consists of the kernel version (like <tt>uname -r</tt>) for which the modules will be compiled, followed by the machine type (like <tt>uname -m</tt>) and by the CIPE features: The first character stands for the protocol version (only c=3 allowed) and the cipher used (b=Blowfish and i=IDEA). <p> To compile and install the modules and userspace tools, enter the newly created directory and type <verb> root# make && make install </verb> That was it! Have a look at the file <tt>cipe.info</tt> which accompanies the CIPE sources if you want to compile CIPE for special cases (e.g. if you do not have the kernel source, but only the includes installed). <sect2>Testing the Installation<label id="net:cipe:t"> <p> First, you have to do a minimal configuration: Copy the <tt>samples</tt> directory to <tt>/etc/cipe</tt> and edit the file <tt>/etc/cipe/options</tt> to include only the parameter <tt>key</tt>. For a first test you can safely go with the value provided by the <tt>options</tt> file of the <tt>samples</tt> directory. Later, you have to change this key, of course. <p> It is important that the key is the same on both machines you want to connect with a CIPE tunnel. For first tests, I would recommend that you set up a CIPE connection between hosts on the local Ethernet segment, if possible. Things like CIPE over PPP are covered in more depth later on. <p> To be specific, assume that we are living on an ethernet that consists of two boxes and uses IP addresses from the private range We want to use Blowfish encryption. The two boxes, called A and B, have IP addresses and respectively. <p> The first step after compiling and installing CIPE on both machines is to load the modules on both hosts: <verb> root@A# modprobe cipcb root@B# modprobe cipcb </verb> Next, you start the CIPE-daemon on each machine: <verb> root@A# ciped-cb me= peer= ipaddr= ptpaddr= root@B# ciped-cb peer= me= ptpaddr= ipaddr= </verb> As you can see, the configuration parameters have to be swapped, so to speak, as me's peer is peer's me. Also, we need to use additional IP addresses for the CIPE interface (called <tt>cibcb</tt> here), see next section. <p> If everything worked well, you can try to ping the peer to see if the tunnel has been successfully established: <verb> user@A$ ping user@B$ ping </verb> A common mistake is to have a firewalling policy of DENY or REJECT and no ACCEPT rule corresponding to the UDP port numbers used. <tt>ping</tt> will report "sendto: write: operation not permitted" if this is the case. See the ipchains-HOWTO for how to add such rules. If you are using masquerading together with CIPE, you may want to look at the CIPE+Masquerading-miniHOWTO, too. <p> If you were able to ping the other host, you can now try to telnet or ssh the other host. If all works well, you have successfully completed the first tests. <sect2>Configuration Overview<label id="net:cipe:c"> <p> In this subsection you will learn of the various parameters that influence CIPE's behaviour. You have seen the most important ones in the last section, here we discuss their meaning in detail: <descrip> <tag>key, nokey</tag> For security reasons, the <tt>key</tt> parameter must be set via an options file, owned by root and unreadable for anyone else. It is followed by the 128-bit shared secret, i.e. the key that is used for authentication and generation of session keys. To generate a truly random key and add it directly to your options file, so no-one can sneak it, issue the following command: <verb> root# echo key $(head -c 16 /dev/random | md5sum) >> /etc/cipe/options </verb> It is your responsibility that you transfer the key from one machine to the other in a secure fashion. <em>Do not use ftp or other unencrypted protocols to send the key!</em> The recommended way is to learn the key by heart and type it into the other box by hand or to send it via PGP/GnuPG-encrypted E-Mail. But also transferring it via removable media or through a ssh session is acceptable. Make sure you are <em>absolutely certain</em> that the other end of the ssh connection is indeed the box you think it is. <tt>nokey</tt> leads to simple (and unauthenticated) IP-in-IP tunnelling, useful only for testing. <tt>key</tt> and <tt>nokey</tt> are mutually exclusive options. <tag>me, peer</tag> The IP address of my host, followed by the colon-separated port number the CIPE daemon should listen to (<tt>me</tt>) and the IP address of the other end of the CIPE tunnel, followed by the colon-separated port number to which we wish to connect to (<tt>peer</tt>). These are the IP addresses that hosts of the <em>carrier network</em> "see". Make sure that all firewalls between the two hosts let pass UDP packets destined for those ports. <tt>peer</tt> can be, in which case the IP address is taken as the one of the host connecting to us, provided it successfully authenticates itself. <tt>me</tt> needs not be specified. In this case CIPE will pick appropriate values and report them to the <tt>ip-up</tt> script. <tag>ipaddr, ptpaddr</tag> The IP address of the <tt>cipcb</tt> (resp. <tt>cipci</tt>) interface on my host (<tt>ipaddr</tt>) and the IP address of the <tt>cipcb</tt> (resp. <tt>cipci</tt>) interface of the peer (<tt>ptpaddr</tt>). The CIPE daemon uses this information to automatically set a point-to-point route between the two interfaces after a connection has been established (just like the PPP daemon does after successful dial-in). These are the IP addresses that hosts in the <em>private network</em> "see". <tt>ptpaddr</tt> can be, in which case the peer's IP address is determined when the other end tries to connect and successfully authenticates itself. <tag>mtu, cttl, metric</tag> These optional parameters specify the <tt>cipcb/i</tt> device MTU (maximum transfer unit), the UDP packets' TTL (time to live) value and the <tt>cipcb/i</tt> device metric. See the appropriate (networking) HOWTOs if you don't know what I am talking about. <tag>tokxc, tokey, tokxts, ping, toping, maxerr</tag> These optional parameters specify the key exchange timeout (10), the dynamic key lifetime (600), the key exchange timestamp window (0), the time between two successive keep-alive pings (0), the timeout for those pings (0) and the maximum number of network errors between two key exchanges (8). All these parameters take their values to be specified in seconds and a value of 0 (zero) means "disable this feature/no timeout". Default values are listed in parenthesis. <tt>maxerr</tt> is different, though: The value is just a number (no seconds) and a value of 0 (zero) means "accept no errors", while "accept any number of errors" corresponds to a value of -1 (minus one). You normally want to go with the default values, but sometimes adjusting the <tt>maxerr</tt> parameter is needed if your connection is not so reliable (e.g. PPP). <tag>ipup, ipdown, arg</tag> These optional parameters specify the name of the <tt>ip-ip</tt> and <tt>ip-down</tt> scripts to run resp. (default: <tt>/etc/cipe/ip-up</tt> resp. <tt>/etc/cipe/ip-down</tt>) and an optional argument to pass to the <tt>ip-up</tt> script. Useful if you intend to run more than one <tt>ciped</tt>. </descrip> There is also the <tt>socks</tt> parameter, which allows you to connect to a SOCKS5 server with CIPE. If you need it, you'll want to read the <tt>cipe.info</tt> file that comes with CIPE. Two other parameters, <tt>device</tt> and <tt>debug</tt>, are only useful in testing, since CIPE 1.3.0 can automatically grab free <tt>cipcb/i</tt> interfaces as needed, and <tt>debug</tt> is useful for just that: debugging. All these options can be specified in either of three ways: <enum> <item>via the default options file <tt>/etc/cipe/options</tt>, <item>via an options file specified as <tt>-o file</tt> on the command line, <item>via the command line as <tt>parameter=value</tt>, </enum> in order of processing (i.e. command line options override <tt>-o file</tt> options override <tt>/etc/cipe/options</tt> options). <p> <sect1>Other Network Traffic Encryption Approaches<label id="net:other"> <p> I will just give you the necessary links to find other documentation on the following packages: <itemize> <item>FreeS/WAN (IPSec implementation) is available at <htmlurl url="http://www.freeswan.org" name="www.freeswan.org">. Current version is 1.5 (Sep 2000). <p> FreeS/WAN is a Linux based implementation of the IETF IPSec standard. If you want to know all there is to know about IPSec, see the RFC's concerned with it, esp. the famous RFC's <em>2401: Security Architecture for the Internet Protocol</em> thru <em>2412: The OAKLEY Key Determination Protocol</em>. Note, however, that these documents add up to 20,000 lines of pure text or 800K. <p> This package is very complex indeed, but as it is based on an IETF standard, it inter-operates with many other (commercial) VPN products, including PGPnet. This makes it the single obvious choice for admins that need extensive cross-platform capabilities. <p> There is a very active mailing list you can subscribe to, if you send a message with the single line <em>subscribe linux-ipsec</em> in the body of the message to <htmlurl url="mailto:majordomo@clinet.fi" name="majordomo@clinet.fi">. <p> <item>ENSkip is an implementation of Sun's SKIP protocol. Its advantages over other approaches include a long history, which implies a relative stableness, and good cross-platform capabilities (at least within the Unices department). You can find its homepage at <htmlurl url="http://www.tik.ee.ethz.ch/~skip/" name="http://www.tik.ee.ethz.ch/~skip/"> <p> <item>VPND is another approach out there for Linux (and FreeBSD). You can fetch additional information from its homepage at <htmlurl url="http://sunsite.auc.dk/vpnd/" name="http://sunsite.auc.dk/vpnd/">. There is also a mailing list, which you can subscribe to if you send an empty message to <htmlurl url="mailto:vpnd-subscribe@sunsite.auc.dk" name="vpnd-subscribe@sunsite.auc.dk"> and follow the directions given in the reply. <p> <item>SSH (Secure Shell) can also be employed to establish an encrypted IP-tunnel between two hosts. There is a VPN mini-HOWTO already covering the setup, but it is rather dated (Aug 1997). get OpenSSH, the free implementation of SSH, from <htmlurl url="http://www.openssh.org/" name="www.OpenSSH.org"> <p> <item>VTUN, a (TUN/TAP) driver for Linux, *BSD, and Solaris is a tunneling suite with encryption capability. See <htmlurl url="http://vtu.sourceforge.net" name="vtu.sourceforge.net">. It's encryption libraries do not support RC4/5/6 (YET) but it works well with lower level algs. <p> <item>PoPToP server for Linux, a PPTP (for Windows clients) <em>does</em> support encryption with a series of kernel patches and patches to pppd to enable PPTP encrypted tunnels for mobile Windows boxen VPNs. See <htmlurl url="http://www.moretonbay.com/vpn/pptp.html" name="http://www.moretonbay.com/vpn/pptp.html">. However, I strongly recommend to not use PPTP, regardless of the implementation. It's a flawed protocol, Bruce Schneier broke it twice and Microsoft is still unable or unwilling to employ well-known protocols and algorithms, see<htmlurl url="http://www.comterpane.com/pptp.html" name="http://www.comterpane.com/pptp.html"> for a detailed discussion. </itemize> <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Frequently Asked Questions<label id="faq"> <sect1>Disk Encryption<label id="faq:disk"> <sect2>General Questions<label id="faq:disk:gen"> <p> <enum> <item><bf>How can I encrypt swap?</bf> <p> With the loop device approach, you cannot. PPDD claims you can. I don't know about (T)CFS. See the sections on individual approaches below. </enum> <sect2>Loop Device Encryption<label id="faq:loop"> <p> <enum> <item><bf>Can I use a journalling filesystem onto of <tt>/dev/loop</tt>?</bf> <p> I don't know. <p> <item><bf>Can I use all this as modules?</bf> <p> Sure! In <tt>make menuconfig</tt> (or whatever), under ``Crypto options'', say M to ``Crypto ciphers (<tt>CONFIG_CIPHERS</tt>)'' and to the ciphers you want. Under ``Block Device'', say M to ``loopback device (<tt>CONFIG_BLK_DEV_LOOP</tt>)'' and to ``General Encryption Support (<tt>CONFIG_BLK_DEV_LOOP_GEN</tt>)''. Don't select any other encryption modules unless you can't live without them and they are no longer supported by the Crypto API. <p> Build your kernel and modules, <tt>make modules_install</tt>, reboot, <tt>depmod -a</tt>. <p> In <tt>/etc/conf.modules</tt>, add: <verb> alias loop-xfer-gen-0 loop_gen alias loop-xfer-gen-10 loop_gen alias cipher-4 blowfish # Blowfish alias cipher-6 idea # IDEA alias cipher-7 serp6f # Serpent alias cipher-8 mars6 # MARS alias cipher-9 twofish # Twofish alias cipher-11 rc62 # RC6 alias cipher-15 dfc2 # DFC </verb> <p> <item><bf>Why all those funny numbers?</bf> <p> In short, the kernel knows ciphers only by number. If you really want to know how it works, you can <tt>grep request_module</tt> in <tt>linux/crypto/api.c</tt> and <tt>linux/drivers/block/loop.c</tt>. <p> If the cipher you wish to use is not in the above list, then see the file <tt>include/linux/crypto.h</tt> in the kernel source tree. There you'll find the defines for all cipher numbers. See the directory <tt>crypto</tt> in the kernel tree for the (file)name of the module that implements the cipher. <p> <item><bf>How do I change the password / the cipher?</bf> <p> You can't. At least not easily. Well, you can, but you won't be able to access your data anymore. Seriously: The passphrase is hashed and then used as the encryption key. You cannot change the password and expect the hash value (ie. the encryption key) to stay the same. <p> What you <em>can</em> do, however, is the following. Make sure, you have not currently set up or even mounted the filesystem you want to change. In the notation of section <ref id="folder" name="Making an Encrypted Folder"> you then issue: <verb> root# losetup -e oldcipher /dev/loop0 ~user/.crypto Password : (old one) root# losetup -e newcipher /dev/loop1 ~user/.crypto Password : (new one) root# dd if=/dev/loop0 of=/dev/loop1 bs=1k conv=notrunc root# losetup -d /dev/loop0 root# losetup -d /dev/loop1 </verb> If you changed the cipher, you will need to change the entry in &fstab; accordingly. <p> If you plan to do this often (and maybe you should do that), it pays to write a script for it that prompts you twice for the new password. If you are really lucky, then I will have written this for you already :-). <p> <item><bf>My encrypted filesystem is (nearly) full. How do I enlarge it?</bf> <p> If you have enough free space left so that you can create the new-size file without having to remove the old first, then the solution is obvious: <p> <itemize> <item>Mount the old filesystem, e.g. on <tt>crypto</tt>. <item>Setup and mount a new filesystem as described in section <ref id="folder" name="Making an Encrypted Folder">, e.g. on <tt>newcrypto</tt>. <item>Copy the files thus: <verb> user$ tar cf - -C crypto . | tar xf - -C newcrypto </verb> </itemize> <p> <item><bf>But I do not have that much free space left! Is there still hope?</bf> <p> Yes: <tt><url name="ext2resize" url="http://www.dsv.nl/~buytenh/ext2resize/"></tt>. It is, as the name suggests, a tool that allows you to grow or shrink ext2 filesystems. And that seems to be exactly what we'll need. <p> Basically, what you have to do is: <p> <itemize> <item>Enlarge the file wherein the filesystem is contained by e.g. 10M: <verb> user$ dd if=/dev/urandom bs=1024k count=10 >> ~/.crypto </verb> <item>Set up the loop device and check the filesystem: <verb> root# losetup -e cipher /dev/loop0 ~user/.crypto Password : root# e2fsck /dev/loop0 e2fsck 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09 /dev/loop0: clean, 11/1920 files, 506/10240 blocks </verb> <item>Resize the filesystem. The second parameter to <tt>ext2resize</tt> is the new size in blocks. In our example: <it>10240 + 10M/1k = 20480</it> <verb> root# ext2resize /dev/loop0 20480 </verb> <item>Now detach the loop device again: <verb> root# losetup -d /dev/loop0 </verb> </itemize> You have now an enlarged filesystem. Note, however, that power failure or the like can easily destroy your data while resizing is running! There is a patch floating around that will let you do this with a mounted filesystem. With this solution, however, you have to unmount the filesystem before resizing. <p> <item><bf>Can I encrypt my swap partition? Can I page to a swapfile that's on an encrypted filesystem?</bf> <p> No, not yet. First, some issues with memory allocations in the driver have to be resolved. <p> <item><bf>Cipher xyz does not work. It says ``unsupported cipher xyz'' / ``ioctl: LOOP_SET_STATUS: Invalid argument'' although I have compiled it into the kernel.</bf> <p> Not for all ciphers does a user-space setup tool currently exist. Please see section <ref id="losetup" name="Patching the util-linux source"> for a list of working ciphers or try them all in turn. <p> <item><bf>I copied the file containing the crypto filesystem to another directory / I defragged my partitions and now I cannot access my data any more.</bf> <p> Most probably you have compiled the kernel without <tt>CONFIG_BLK_LOOP_DEV_USE_REL_BLOCK</tt>. As the copy now occupies different blocks on the filesystem and you are not using relative block numbers, the ciphers get it wrong. The only thing that will help you now is the <tt><url name="ext2recover" url="http://www.iki.fi/markus.stenberg/ext2recover.html"></tt> tool by Markus Stenberg (<htmlurl url="mailto:markus.stenberg@abacus-solutions.com" name="markus.stenberg@abacus-solutions.com">). It will recover your data except the first four bytes of every block. If your lost data was only text files, that should be enough. If it was binary data it will most probably not be enough. <p> <item><bf>I use an older 2.2 kernel. How do I avoid the above mess?</bf> <p> You can use the ``double loop trick'': <verb> root# losetup /dev/loop0 crypto root# losetup -e ciphername /dev/loop1 /dev/loop0 </verb> This will create a new block device <tt>/dev/loop0</tt>, where it is guaranteed that blocks are sequentially numbered starting with zero. That's the same as using relative block numbers on <tt>crypto</tt> directly. If you create your crypto loop device this way, you can be sure it will still work after defrag etc. <p> Note that <tt>mount</tt> does currently not support this trick, so you will have to set up your loop devices by hand. All in all, you should really update to a newer kernel :-) <p> <item><bf>How do I make backups?</bf> <p> You can't (at least not easily) when you equal "backup" with "incremental backup". If you can sleep well with image backups instead, and if you used relative block numbers for your loop device (see questions above), you can copy your file containing the crypto filesystem to wherever you want. This includes DAT tapes and removable media, as well as CDR(W). <p> You may want to use tricks like the ones presented above to change the cipher and/or passphrase to use another password for the backup file, dedicated to backups. That is because you have a better chance to remember one of the passwords if the other one gets lost. Also, if you change your password regularly, then how do you remember the password you used two months ago? <p> However, if you do <em>not</em> use relative block numbers, then you cannot easily copy your file around for backups. You can mount the filesystem and have it backed up as plaintext or on another encrypted device. But that will undermine your encryption thoroughly. You'll have to do something along the following lines instead: <verb> root# losetup -e cipher /dev/loop0 ~user/.crypto root# losetup /dev/loop1 ~user/crypto-backup root# losetup -e cipher /dev/loop2 /dev/loop1 root# dd if=/dev/loop0 of=/dev/loop2 bs=1k root# for i in 2 1 0; do losetup -d /dev/loop$i; done root# cp ~user/crypto-backup /backup-media </verb> This will make <tt>crypto-backup</tt> immune to copies (see questions further above for why). <tt>crypto-backup</tt> needs to be at least the same size as <tt>.crypto</tt>, of course. <p> </enum> <!-- ******************************************************* --> <!-- ******************************************************* --> <sect>Glossary<label id="glossary"> <p> This is only a very minimal glossary, which contains only two acronyms used, but not detailed in the text. The descriptions are based on the corresponding entries of the glossary that comes with the FreeS/WAN 1.3 distribution. <p> <descrip> <label id="gloss:cbc"><tag>CBC</tag> <bf>C</bf>ipher <bf>B</bf>lock <bf>C</bf>haining mode, a method of using a block cipher in which for each block except the first, the result of the previous encryption is XORed into the new block before it is encrypted. CBC is the mode used in IPSEC and the current Crypto-API ciphers. <p> An initialisation vector (IV) must be provided. It is XORed into the first block before encryption. The IV need not be secret but should be different for each message and unpredictable. <p> For loop device encryption, the IV is taken to be the physical block numbers of the file which contains the crypted filesystem. <label id="gloss:ecb"><tag>ECB</tag> <bf>E</bf>lectronic <bf>C</bf>ode<bf>B</bf>ook mode, the simplest way to use a block cipher. Each block is encrypted independently. <p> The loop device crypto drivers that do not use the Crypto-API use their respective ciphers in ECB mode. <p> ECB mode is less secure than <htmlurl url="#gloss:cbc" name="CBC mode">. </descrip> <p> <sect>Credits<label id="credits"> <p> Thanks go to the following people for suggesting improvements of this document or even contributing part of it: <p> Dale Amon, Randolph Bentson, Andries Brouwer, Lennert Buytenhek, dath@sequent.com, Michael Gende, Davide Giunchi, Josef Höök, Alexander S. A. Kjeldaas, Allan Latham, TheSpectra (AKA Pablo Lorenzzoni), Gary E. Miller, Richard Polton, Rik van Riel, Mark Ryan, Todd Sabin, Kurt Seifried, Gisle Sælensminde, Pim Snel, A. Steinmetz, Lion Templin, trb@eastpac.com.au, Doobee R. Tzeck, Erik Walthinsen, Frank v Waveren </article>