# quick and painless: dm-crypt encrypted swap

## tuxophil

Quick and painless: dm-crypt encrypted swap

Introduction

This mini-HOWTO is a complement to other HOWTOs on encrypting various parts of your system (like your /home or / partitions). I decided to encrypt my swap partitions after I found some of my passwords in them:

```
strings < /dev/swapdevice | grep mypassword
```

Important:  Do not try this command at home. The command, including your password, will be saved in root's .bash_history! If you really want to search for it, better pipe strings' output to less and use the pager's search functionality.

To make this HOWTO as short as possible I will just post my init script that I've been using for a few months now.

Some particularities of my approach are the following:

 independent of any encryption of /home or /

 the new dm-crypt interface is used

 support for multiple swap partitions

 nice integration in Gentoo's boot sequence

 very easy configuration Please note that due to technical difficulties it's currently impossible to use encrypted swap files. More information can be found in this discussion on the dm-crypt mailing list.

Preliminaries

To use the device-mapper and the encryption based thereon (dm-crypt) you'll have to compile your kernel (at least 2.6.4) with the following options:

Device Drivers->Multi-device support (RAID and LVM)

```
[*] Multiple devices driver support (RAID and LVM)

<M>   Device mapper support

<M>     Crypt target support
```

(The loopback support could be useful too, but not for encrypted swap.)

Cryptographic options

```
<M>   AES cipher algorithms
```

Of course, you are free to chose any cipher algorithm you like. You'll just have to adapt the cryptoswap configuration file.

After you've rebooted, emerge the device-mapper userspace tools and modprobe a cipher algorithm:

```
emerge device-mapper

modprobe aes
```

Make sure your cipher algorithm is automatically loaded at startup:

```
echo aes >> /etc/modules.autoload.d/kernel-2.6
```

The init script

So, here's my init script. Save this as /etc/init.d/cryptoswap. Instructions within  :Wink: 

```
#!/sbin/runscript

# cryptoswap 0.04

# 

# This initscript uses the Device-Mapper and Crypto API of Linux >=2.6.4

# to create encrypted swap devices. Configuration is done in

# /etc/conf.d/cryptoswap.

# USING CRYPTOSWAP

# 1. Make sure your kernel is compiled with device-mapper and 

#    some cryptographic algorithms. Easiest is to compile them into 

#    the kernel. You also need sys-libs/device-mapper. 

# 2. Turn off swapping for all your swap partitions 

#    e.g. swapoff /dev/hdb2 

# 3. Remove all swap partitions from your /etc/fstab 

# 4. Overwrite all swap partitions with random data from /dev/urandom 

#    dd if=/dev/urandom of=/dev/hdb2 bs=1M 

# 5. Configure cryptoswap (/etc/conf.d/cryptoswap) 

# 6. rc-update add cryptoswap boot 

# 7. /etc/init.d/cryptoswap start 

CIPHER=${CIPHER:-aes}

KEYSIZE=${KEYSIZE:-32}

DMSETUP=/sbin/dmsetup

CONF=/etc/conf.d/cryptoswap

depend() {

   after urandom modules

}

# $1 = block device (e.g. /dev/hda2)

isswap () {

   PART=`fdisk -l | grep "^$1 "`

   [[ $PART == *Linux\ swap* ]]

}

cipheravailable() {

   modprobe $1 &> /dev/null

   # remove "mode" (e.g. plain, cbc, cbc-essiv-sha256)

   grep "name *: *${1%%-*}" /proc/crypto >& /dev/null

}

start() {

   if ! [ -r "$CONF" ] ; then

      eerror "ERROR: Configuration file $CONF does not exist"

      eerror "       or cannot be read."

      exit 1

   fi

   if ! [ -x $DMSETUP ] ; then

      eerror "ERROR: The $DMSETUP executable cannot be found."

      eerror "       Please emerge sys-libs/device-mapper."

      exit 2

   fi

        einfo "Setting up encrypted swap"

   NBR=0

   grep '^swap=' $CONF | while read SWAPLINE

   do

      swap="" pri="" cipher="" keysize=""

      eval $SWAPLINE

      ebegin "  Setting up $swap as /dev/mapper/cryptoswap$NBR"

      cipher=${cipher:-$CIPHER}

      keysize=${keysize:-$KEYSIZE}

      if ! cipheravailable "$cipher"; then

         eerror "ERROR: The specified cipher $cipher is not available."

         eend 1

         continue

      fi

      if ! isswap "$swap"; then

         ewarn "WARNING: $swap is not a swap partition. Skipping."

         eend 1

         continue

      fi

      if [[ ! -z "$pri" && $pri -ge 0 ]]

         then OPTS="-p $pri";

         else OPTS="";

      fi

      # make sure swap is turned off for $swap

      swapoff $swap &> /dev/null

      BLOCKS=`blockdev --getsize $swap`

      HEXDIGITS=$(($keysize * 2))

      KEY=`tr -cd 0-9a-f < /dev/urandom | head -c $HEXDIGITS`

      echo 0 $BLOCKS crypt $cipher $KEY 0 $swap 0 \

         | $DMSETUP create cryptoswap$NBR

      mkswap /dev/mapper/cryptoswap$NBR > /dev/null

      swapon $OPTS /dev/mapper/cryptoswap$NBR

      eend $?

      let ++NBR

   done

   if ! swapon -s | grep "/dev/mapper/cryptoswap" > /dev/null

   then

      eerror "ERROR: No encrypted swap devices were created!"

      eerror "       Please edit $CONF."

      exit 3

   fi

}

stop() {

        einfo "Turning off encrypted swap"

   # It's possible that the configuration file has changed.

   # Therefore the configuration file is ignored and we simply

   # remove all cryptoswap* mappings.

   MAPPINGS=`ls /dev/mapper/cryptoswap* 2> /dev/null`

   if [ -z "$MAPPINGS" ]; then

      ewarn "WARNING: No cryptoswap mapping found."

      exit 0

   fi

   for m in /dev/mapper/cryptoswap*; do

      MAPDEV=${m#/dev/mapper/}

      ebegin "  removing $m"

      swapoff $m

      $DMSETUP remove $MAPDEV

      eend $?

   done

}

status () {

   swapon -s

}

```

And the configuration file:

```
# /etc/conf.d/cryptoswap

# cryptoswap configuration file

# The configuration is simplistic: one line per swap device.

# The cipher and keysize (in bytes for coherence with /proc/crypto)

# can be set globally.

CIPHER=aes

KEYSIZE=16

# But it's also possible to override this default value on a per device

# basis. Here are some commented sample configuration lines:

#swap=/dev/hda1   pri=3   cipher=blowfish   keysize=32

#swap=/dev/hdb2   pri=3   cipher=twofish

#swap=/dev/hda6   pri=1

# NOTES

# The used cipher must be available through the kernel Crypto API. To

# get a list of available algorithms: cat /proc/crypto

# Since this parameter is directly passed to dmsetup, it can also contain

# IV generation modes for CBC. Examples:

# aes, blowfish-cbc, twofish-cbc-essiv:sha256

# Please refer to http://www.saout.de/misc/dm-crypt/ for more information.

#

# Set the same priority for multiple devices to enable RAID0-like

# striping. (Should be faster.) See man 2 swapon for more details.

```

Well, that's it. If there are any corrections, improvements or comments, I'd be glad to hear about them.

References

dm-crypt homepage

dm-crypt wiki

Changelog

10.01.2005: Added warning not to enter a command containing passwords.

17.01.2005: Added error checking, improved flexibility (swap priority).

23.01.2005: Added note about encrypted swap files.Last edited by tuxophil on Sun Jan 23, 2005 10:32 am; edited 3 times in total

----------

## Vanquirius

Very nice, thanks.

----------

## Bluepixel

I will use that next time I start from scratch. Thanks for posting this!

----------

## gaboonal

I copied the init script directly from your post, edited /etc/conf.d/cryptoswap and then ran "/etc/init.d/cryptoswap start". This failed with the following output: "* ERROR:  "/etc/init.d/cryptoswap" has syntax errors in it; not executing..." Unfortunately it did not specify the line in which these syntax errors exist. 

I have not modified the file in any way since copying it from the post so I am assuming that other people will have had the same problem.

----------

## tuxophil

 *gaboonal wrote:*   

> I copied the init script directly from your post, edited /etc/conf.d/cryptoswap and then ran "/etc/init.d/cryptoswap start". This failed with the following output: "* ERROR:  "/etc/init.d/cryptoswap" has syntax errors in it; not executing..." Unfortunately it did not specify the line in which these syntax errors exist. 
> 
> I have not modified the file in any way since copying it from the post so I am assuming that other people will have had the same problem.

 

This seems to be a phpbb bug  :Sad: 

The problem is that when copying a text file to the forums, phpbb generates crappy code that introduces superfluous spaces. This breaks line continuation. Let's have a look at an example:

```
                KEY=`dd if=/dev/urandom count=8 bs=1 2> /dev/null \

                | md5sum - | head -c $HEXDIGITS`
```

Here, there is a newline immediately after the backslash in my code. However the HTML code generated by phpbb looks like this (I removed some &nbsp;):

```
&nbsp; KEY=`dd if=/dev/urandom count=8 bs=1 2&gt; /dev/null \

<br />

&nbsp; | md5sum - | head -c $HEXDIGITS`

<br />
```

The newline between the backslash and the <br /> tag is considered as a space by your browser. This additional space breaks the script.

To cut a long story short: there should be no trailing whitespaces!

To correct this, just filter your file through perl:

```
perl -p -i -e 's/ $//' /etc/init.d/cryptoswap
```

----------

## gaboonal

Thanks, it's working now.

----------

## lysergicacid

anyone know how to get this to work with a file as swap plz ?  

```
-(root@lysergicacid:0)-(39 files:2.4M@~)-(0 jobs)-(05:11)-

-(~:#)-> /etc/init.d/cryptoswap start

 * Setting up encrypted swap

 *   Setting up /mnt/swap/swap.img as /dev/mapper/cryptoswap0 ...

 * WARNING: /mnt/swap/swap.img is not a swap partition. Skipping.                                   [ !! ]

 * ERROR: No encrypted swap devices were created!

 *        Please edit /etc/conf.d/cryptoswap.

```

 plz ? tried several variations of this kinda script / setup and neither work

----------

## ghettodev

Nice job.

One question though, how can I verify that the swap is actually being encrypted?  I've run the 'strings' command you posted above on common words and havent come up with anything but is there a more stringent test?

----------

## tuxophil

 *lysergicacid wrote:*   

> anyone know how to get this to work with a file as swap plz ?

 

Due to technical reasons it's extremely difficult to have an encrypted swap file. Currently there's no safe way to do it. I won't go into details; I'll just refer you to this very interesting discussion on the dm-crypt mailing list.

To make it short: encrypted swap files will freeze your system.

----------

## tuxophil

 *ghettodev wrote:*   

> One question though, how can I verify that the swap is actually being encrypted?  I've run the 'strings' command you posted above on common words and havent come up with anything but is there a more stringent test?

 

Well, first check the output of 

```
swapon -s
```

 to see if only /dev/mapper/cryptoswap* devices are used. Then you can use 

```
dmsetup table
```

 (or dmsetup table devname) to show the details of the mapping(s). There you'll see that the crypt target is used, and with which cipher. (The encryption key is also shown.)

----------

## ghettodev

Looks like it did the trick, watching 

```
strings < /dev/swapdevice
```

 for a few mintues convinced me as well  :Wink: 

----------

## lysergicacid

 *gschintgen wrote:*   

>  *lysergicacid wrote:*   anyone know how to get this to work with a file as swap plz ? 
> 
> Due to technical reasons it's extremely difficult to have an encrypted swap file. Currently there's no safe way to do it. I won't go into details; I'll just refer you to this very interesting discussion on the dm-crypt mailing list.
> 
> To make it short: encrypted swap files will freeze your system.

 

ok thank you.

----------

## Pjotrek

Hi!

Thanks for your nice script, it is a beauty. However, when using swap on raid or lvm(2), there is a problem.

The routine isswap fails in these cases - 

```
fdisk -l | grep "^$1 "
```

 gives something like:

```
Disk /dev/md1 doesn't contain a valid partition table

Warning: ignoring extra data in partition table 5

Warning: ignoring extra data in partition table 5

Warning: ignoring extra data in partition table 5

Warning: invalid flag 0x39b3 of partition table 5 will be corrected by w(rite)

Disk /dev/md2 doesn't contain a valid partition table

Disk /dev/sdc doesn't contain a valid partition table

```

I worked around that for now by disabling the check, but, of course, that is dangerous to say the least.

Any ideas how to modify the test?

/PjK

----------

## tuxophil

 *Pjotrek wrote:*   

> Thanks for your nice script, it is a beauty.

 Thanks  :Smile: 

 *Pjotrek wrote:*   

> I worked around that for now by disabling the check, but, of course, that is dangerous to say the least.
> 
> Any ideas how to modify the test?
> 
> /PjK

 

I'm not sure it's even possible to work around this issue. As far as I know, the partition type (as given by fdisk) has only informative character and is of no practical significance. As such I don't think there's an equivalent for LVM volumes. After all, in both cases the only thing that counts are the block devices themselves and the filesystem which is used.

Of course, since this external information is available in the case of normal devices it's a good idea to include a little sanity check, but you probably won't have any problems without it. Just be careful when you're changing your logical volumes/filesystems/swap devices...

----------

## jagomai

Hello, the script looks very good!

After setup, however, I get this when I start the script:

```

 * Setting up encrypted swap

 *   Setting up /dev/hda2 as /dev/mapper/cryptoswap0 ...

Disk /dev/dm-0 doesn't contain a valid partition table

Disk /dev/dm-1 doesn't contain a valid partition table

Disk /dev/dm-2 doesn't contain a valid partition table                                                                                              [ ok ]

```

But when I do "swapon -s", I get

```

# swapon -s

Filename                                Type            Size    Used    Priority

/dev/mapper/cryptoswap0                 partition       2008116 0       -2

```

And "dmsetup table | grep swap" gives me: 

```

# dmsetup table | grep swap

crypt-swap: 0 4016250 crypt twofish-cbc-plain 0000000000000000000000000000000000000000000000000000000000000000 0 3:2 0

cryptoswap0: 0 4016250 crypt twofish-cbc-plain 0000000000000000000000000000000000000000000000000000000000000000 0 3:2 0

```

Is all of this normal? And are all those zeroes normal?  :Smile:  I want to make sure the thing is actually well encrypted.

Thanks for any help.

----------

## woZa

This seems to be broken for me...

```
/etc/init.d/cryptoswap start
```

```
 * Caching service dependencies ...                                                                                                                              [ ok ]

 * Setting up encrypted swap

 *   Setting up /dev/sda3 as /dev/mapper/cryptoswap0 ...

Disk /dev/dm-0 doesn't contain a valid partition table

Disk /dev/dm-1 doesn't contain a valid partition table

Disk /dev/dm-2 doesn't contain a valid partition table

Disk /dev/dm-3 doesn't contain a valid partition table

Disk /dev/dm-4 doesn't contain a valid partition table

Disk /dev/dm-5 doesn't contain a valid partition table

Disk /dev/dm-6 doesn't contain a valid partition table

Disk /dev/dm-7 doesn't contain a valid partition table

 * WARNING: /dev/sda3 is not a swap partition. Skipping.                                                                                                         [ !! ]

 * ERROR: No encrypted swap devices were created!

 *        Please edit /etc/conf.d/cryptoswap.

 * DO NOT USE EXIT IN INIT.D SCRIPTS

 * This IS a bug, please fix your broken init.d
```

Have followed all the info in the init.d file...

Cheers

Alex

----------

## woZa

Found this post to encrypt swap in fstab...

https://forums.gentoo.org/viewtopic-t-473065-highlight-encrypt+swap.html

----------

## xces

 *woZa wrote:*   

> This seems to be broken for me...

 

Uhm, just take a look at /etc/conf.d/cryptfs. Encrypted swap is supported out-of-the-box with sys-fs/cryptsetup-luks.

----------

