Welcome the company of trees

Setting up Encryption on disks and USB sticks

2010-08-20

Revision History
Revision 0.12010-08-20FU
Initital version

Background

Having a server on the Internet nowadays is not so easy. Security is an important issue. So before we get started with complex setup of software we will sit down and create a safe area to where we can retract, drink a nice cup of coffee and feel and hopefully be really safe with our data.

Why do we need this? If not to protect any secret recipes of pumpkin pie from your great grandmother, it is very useful to know that one have a safe place to store different keys used for encryption. Or just to be able to brag about that you have a really secure encrypted vault for your data. We might not need that kind of security, but they do not know that. Being paranoid is not the target here, learning about encryption is. It will be really fun. Yrg'f trg fgnegrq!

Battle plan

It is good to have a plan of what kind of safe storage one would like. This is also a very difficult step for the beginner. We do not know all the options, or the problems with different setups. What are we trying to protect? What hazards lie in the configuration of a good secure data storage? What scenarios of data loss are possible and how probable are they? To what cost do we want protect against them?

Encryption will always bring overhead. The CPU will be busy restoring the encrypted bits before you can use them. One can easily test how your computer slows down with an I/O benchmark. We do that in Section [I/O benchmarking an encrypted file system - apt-get install tiobench], but lets not run ahead of ourselves.

As many banks already have adapted with key-cards and code lists it is a good practice to separate the different keys that unlock your secret. By using different tokens, the attacker needs to collect all of them to successfully break into your system.

Instead of going ahead and encrypting your whole computer and by some mistake make it unusable, lets create a system that you could restart with if something goes wrong. We will encrypt a simple USB-stick that costs no more than $10, and can be tossed away or formated if something goes really wrong, but to increase the security even more we will also use a SD card to store the keys. This will also bring some neat features for laptops with SD card readers. If you do not have a SD card reader, do not worry. We just need a few Mb somewhere to store the keys. We will however also touch the computer hard disk. We will encrypt the swap partition so that our keys will be safe when they are in memory. This is rather trivial and does not destroy your data if we do not specify the wrong partition. To encrypt the swap just follow the instruction given by /usr/share/doc/cryptsetup/CryptoSwap.HowTo from the cryptsetup package.

SD Card

Why a SD Card you ask? It has several advantages over USB-sticks. They are smaller (especially the SD micro cards) and can be carried in your wallet. In laptops or computers that have a SD card reader it is often more easily accessible than the USB ports. It is more protected as it does not stick out like a stick. Lastly, if they come to get your data the card can easily be destroyed with a lighter.

First we need to prepare the SD card so it can hold all our important keys. Normally the SD cards are vfat formated but we want to use a Linux file system. One can pick a journaling file system but as SD cards are sensitive to many read and writes, and tend to break after some time we pick ext2 as a more simple file system.

When you insert the card in the reader the command

dmesg | tail

will tell you something like mmcblk0: mmc0:04cd S016B 14560KiB mmcblk0: p1. Are you sure that the card is clean and does not contain any family photos? If not check the card by

mkdir /mnt/mmc ; mount /dev/mmcblk0p1 /mnt/mmc ; ls -la
      /mnt/mmc

if it is empty you can

umount
      /dev/mmcblk0p1

and create a new file system on the card.

mkfs.ext2 -L "Key card" /dev/mmcblk0p1

Now lets create a mounting point for our key card.

mkdir /mnt/keystore

and set up /etc/fstab with options proper for a SD card. We add the following line to /etc/fstab: /dev/mmcblk0p1 /mnt/keystore ext2 ro,noauto,sync,noatime 0 0. The noatime limits the access to the card when used and sync makes sure that the file system is not buffered, to make it easier to remove the card when a write operation is done.The option ro is selected since the card will mostly contain keys that will only be read, and mounting read only would avoid stressing the SD card with writes.

For convenience we would like the card to be auto mounted but we specify noauto in /etc/fstab. This is to avoid that every SD card gets mounted under /mnt/keystore. A card full with family photos will not work very well as a key. We will instead use udev to make the mounting for us, and by doing so we get some special features.

We would really like to recognize our SD card when it gets put into the reader. But all SD cards are alike? No, with the help of the udev command

udevinfo --name mmcblk0
      --attribute-walk

we can find out a lot about our SD card. Most of the stuff does not really interest us, but we see that there exists a keyword serial. That sounds promising! But what does that long keyword cid stand for? It looks even more unique.

A quick search at the Linux cross reference points us to the mmc part of the kernel, and after some further research to include/linux/mmc/card.h. But how do I find this on my debian machine? By using apt-file we can find the file with the command

apt-file search
      include/linux/mmc/card.h

and if the package linux-kernel-headers is installed we can read the file with the command

less /usr/include/linux/mmc/card.h

And there we can read that the cid attribute is built up of different values like manufacturer id and also the serial number. That means that although the serial number would probably be enough to identify our card we might as well use cid as it contains more information plus the serial number.

Now that we have an unique way if identifying our SD card we need to make use of it. It is time to dig into the dark art of writing udev scripts. Brr. First lets go to the directory /etc/udev. There we need to create a new file for our card. Let's call the file encryption-system.rules, as we might use it for other things regarding our encryption system later. We start out with adding the following to the file :

SUBSYSTEMS=="mmc", ACTION=="add", ATTRS{cid}=="015041533031364241469904cc0046c7", RUN+="/bin/mount /mnt/keystore"
      

Oh, you did not put in the above cid, did you? You need to find the cid of your card by running

udevinfo --name mmcblk0
      --attribute-walk | grep cid

. At last we need to enable the rule by creating a link from rules.d. Go to /etc/udev/rules.d and run the command

ln -s ../encryption-system.rules
      000-encryption-system.rules

.

Now you can test it by inserting your SD card, and

df
      -h /mnt/keystore

should show that your card have been mounted. Remove the card and the mount should disappear.

Now we can start setting up the card. After you insert it you need to remount it with read write rights with this command

mount -o remount,rw /mnt/keystore

. Then you can change the owner of the card to your user.

chown
      username.username /mnt/keystore

and restrict the rights of the card.

chmod 700 /mnt/keystore

. As user you can now create the directory that will store the keys for encrypting the USB-stick.

mkdir -p keys/secure
      keys/ca keys/doc

and securing it

chmod -R 700
      keys

.

USB stick

The size of the USB stick is nowadays larger than a CD and you can not easily do a backup of them. The SD card will only store keys, and their size will fit on a CD without problems. As the USB stick partition will be encrypted we will need to backup the whole partition as an image. More about this later in the backup section, but this is the main reason why we partition the USB stick.

When inserting a new USB stick in your computer Debian will recognize it and automount it. Using the command

dmesg

you can find out more information about your stick. There we see that the USB stick gets added as sda. A check with

df -h

also shows that we have added an USB stick at /media/usb0. We can find out more information if we ask the udev subsystem by

udevinfo --name sda --attribute-walk

The resulting tree tells us the model name and vendor of the target. At the USB port level we also find the product USB Mass Storage Device and a serial number. This means we can recognize this stick when inserted and do some udev tricks.

Before we start with these udev tricks we need to create the partition we would like to use. Now is also the time to check /media/usb0 so that the USB stick does not contain any important files. Then we need to unmout the USB stick with

umount /media/usb0

With

fdisk -l /dev/sda

we see that we have one large partition on the USB stick. But lets use

cfdisk
      /dev/sda

to do the actual partitioning as it is recommended by the fdisk manpage.

If the current partition table is broken

What if

cfdisk /dev/sda

directly tells you that something is wrong with the partition : FATAL ERROR: Bad primary partition 0: Partition ends in the final partial cylinder. USB sticks are not hard disks and this creates a problem. The fdisk manpage also gave a tip about sfdisk, so lets see what that reports.

sfdisk
	-g /dev/sda

. It tells us that /dev/sda: 1015 cylinders, 32 heads, 62 sectors/track but

sfdisk -G /dev/sda

gives /dev/sda: 125 cylinders, 255 heads, 63 sectors/track Since the chip on the stick does not have cylinders/heads/sectors, the notation is really false. As there are not anything better, we still have to live with it. Lets remove the current partition and get on with our lives. Then we can use cfdisk to create a new correct partition table.

fdisk /dev/sda

and press

d

. Then we need to write table to disk and exit with

w

.

cfdisk /dev/sda

opens up a text gui to create new partitions. First we can delete any unwanted partitions but then it is time to decide how big our partition should be. Let's create one partition of 180 Mb. That means we can do a full backup of the partition to the small form factor CD-R21 discs (185 Mb) + have 5 Mb to back up the keys for the encrypted partition.

Select

[ New ]

, then

[ Primary
      ]

. Size (in MB) : 180 and we add it to the

[
      Beginning ]

of the memory stick. While we are at it we can add 2 other partitions to fill up the stick. Let's make another 180 Mb partition, and for the last partition we can just fill up the stick. In the case of a 1 Gb stick it gives us 3 backupable partitions with 2 x 180 Mb and one 670 Mb. All fits on CD-R mediums. Now we need to write the changes to the stick with the command

[ Write ]

, and confirm rewriting the partition table with

yes

. Once the table is written we can leave cfdisk with

[ Quit
      ]

.

Now we can get on with the next step to create an encrypted file system. There are several packages but the oldest, most stable seems to be the loop-aes package. Our setup will use the loop-AES.README and primarily Example 2 from the May 15 2007 Readme. Let's use the first partition to store often used passwords and other important information. The second we can use for our future ???. It is important that this is kept separate on a partition that not so often is used, as the CA main key control all your SSL certificates on your server. It should be kept separate. The last partition we use for important documents like your grandmothers pumpkin pie recipe.

Insert the SD card, and remount it rw.

mount -o
      remount,rw /mnt/keystore/

, and lets start with the secure partition.

cd
      /mnt/keystore/keys/secure

. Now we can create a gpg key for the partition we will create. We are building a multi-key-v3 key with

head -c 2925 /dev/random | uuencode -m - |
      head -n 66 | tail -n 65 | gpg --symmetric -a >
      keyfile.gpg

. Select a very secret passphrase. After this the console hangs until /dev/random has produced enough random values. That can take time if the kernel's random entropy pool is empty. If you write your mother a nice letter in another console it will not only be a good deed, it will also help the generation of random numbers. Keyboard, mouse and disk influence the /dev/random generation. We can do the same in the ca and doc directory to have the keys ready.

Now they keys are generated, lets create the mountpoints under /mnt/crypt.

mkdir -p
      /mnt/crypt/secure /mnt/crypt/ca /mnt/crypt/doc

. Set the directories to your user

chown -R user.user
      /mnt/crypt

and protect them with

chmod -R 700
      /mnt/crypt

.

Now it is time to initialize and format the partitions. With

fdisk -l /dev/sda

you should see the partitions we created earlier. With

head -c 15
      /dev/urandom | uuencode -m - | head -n 2 | tail -n 1 | losetup
      -p 0 -e AES128 /dev/loop5 /dev/sda1

you set up the loopdevice and

dd if=/dev/zero of=/dev/loop5

we can randomize the partition. Release the loopdevice with

losetup -d /dev/loop7

. Now repeat for the other partitions as well.

Done. Good! We have now randomized the partition so that when an encrypted file system is written on it will be hard/impossible to use the fact that the largest part of the file system is empty. Now we set up the /etc/fstab to include the settings for the encryption.

/dev/sda1 /mnt/crypt/secure ext2    defaults,noauto,loop=/dev/loop5,encryption=AES256,gpgkey=/mnt/keystore/keys/secure/keyfile.gpg  0       0
/dev/sda2 /mnt/crypt/ca     ext2    defaults,noauto,loop=/dev/loop6,encryption=AES256,gpgkey=/mnt/keystore/keys/ca/keyfile.gpg      0       0
/dev/sda3 /mnt/crypt/doc    ext2    defaults,noauto,loop=/dev/loop7,encryption=AES256,gpgkey=/mnt/keystore/keys/doc/keyfile.gpg     0       0
      

We use the highest encryption, AES256. Now make sure that the SD card is in, we need the prior generated keys to format the partitions.

losetup -F /dev/loop5

sets up the loop. Create the filesystem (ext2, journaling file system is not recommended)

mkfs -t ext2 /dev/loop5

and then we can disconnect the loop again and do the next,

losetup -d /dev/loop5

.

YES! We are done. Lets mount the file systems with

mount /mnt/crypt/secure

,

mount
      /mnt/crypt/ca

and

mount
      /mnt/crypt/doc

. The file systems are visible with

df -h /mnt/crypt/*

. To check in what key mode the encryption runs use

losetup -a

. There we see

/dev/loop5: [000d]:11595 (/dev/sda1) encryption=AES256 multi-key-v3
/dev/loop6: [000d]:11603 (/dev/sda2) encryption=AES256 multi-key-v3
/dev/loop7: [000d]:11587 (/dev/sda3) encryption=AES256 multi-key-v3
      

Great! We made it. That was not so hard. Now if we feel like it we can finish off this section with some udev magic.

Lets go edit our old file. Before we had a simple unmount when the SD card was removed. Wouldn't it make sense to kill all access to the encrypted partitions when the SD card is pulled ? One disadvantage is of course that one can not use the SD card reader to load something onto the encrypted partition. But when they storm in through the door, or you just need to take a bathroom break, just pull the SD card and everything closes and un-mounts. Add to /etc/udev/encryption-system.rules :

SUBSYSTEMS=="mmc", ACTION=="remove", RUN+="/bin/fuser -mk /dev/loop5 /dev/loop6 /dev/loop7"
SUBSYSTEMS=="mmc", ACTION=="remove", RUN+="/bin/umount -d -l /mnt/keystore /mnt/crypt/*"
      

Restart udev, as it is cached

/etc/init.d/udev
      restart

. If you now start a terminal and cd to /mnt/crypt/secure

fuser -m /dev/loop5

will show that a process access the device. Now pull the SD card and the terminal will be killed.

USB Hard disk

To encrypt spaces for larger data it is also possible to use an USB Hard disk. As the disk is attached we can find the mount point with

dmesg

. We will make one partition without encryption and one partition with encryption. Let's start to create a key on the SD card.

mount -o
      remount,rw /mnt/keystore/

,

cd
      /mnt/keystore/keys/disk

(create a directory and set correct permissions). Generate key

head -c 2925
      /dev/random | uuencode -m - | head -n 66 | tail -n 65 | gpg
      --symmetric -a > keyfile.gpg

. As the key is being created we can set up partitions with cfdisk and format the partitions. For the unencrypted partition we will use ext3. A simple

mkfs -t ext3 /dev/sdb1

will do. For the encrypted part we do like we did before :

head -c
      15 /dev/urandom | uuencode -m - | head -n 2 | tail -n 1 |
      losetup -p 0 -e AES128 /dev/loop4 /dev/sdb2

you set up the loopdevice and

dd if=/dev/zero
      of=/dev/loop4

. Initiating the encrypted 40 Gb partition with dd took me over three hours. Disconnect with

losetup -d /dev/loop4

. Add the partition to /etc/fstab and make an ext2 filesystem.

Passwords

A short word about passwords and pass-phrases. For pass-phrases I have seen recommendations for more than 20 characters. These can be hard to remember. We have now an encrypted partition /mnt/crypt/secure and there we can set up an pesafe database. There we can then securely store our long, and hard to remember passwords that we do not use so often. And when our fantasy for a new password fails us we can always use pwgen and generate a good one. This combination brings us the advantage of hard passwords with a fail-over if our memory is not as good as it used to be. Set the PWSAFE_DATABASE variable to /mnt/crypt/secure/keys/.pwsafe.dat and create the database with

pwsafe --createdb

. Now we can start adding important passwords with

pwsafe
      -a entryname

Conclusions

To be written