2009-08-04. Encryption of computer data: files, subtrees, disk-partitions. Now I'm sort of doing what I accuse others of doing all the time --- changing something after the alarming event, rather than making an analysis and any desired changes before the event. One of my laptops was stolen recently. I've been reading about this sort of thing for years, in the context of government and corporate employees distributing unencrypted data by leaving it on laptops; encryption is obvious as a basic responsibility. For my use, disk encyption hasn't previously seemed worthwhile, for the hassle of more passwords, setting up, perhaps forgetting phrases, etc., bearing in mind my not terribly private data. It seems very unlikely, given the style of this burglary, that the culprit would have any idea about resetting root passwords or taking out disks and reading linux filesystems (or, reading this file on the web to see my list of what was on the computer ...). But it /is/ a little disturbing to have even the entire set of emails and writing in another's hands: and it would be good to know that one can be fairly uninhibited about what lives in the home directory that gets copied to a laptop when travelling. (The preservation of data is, for me, pretty unimportant, since I have little faith in disks and generally have automatic remote backup or regular backup to usb sticks if away from the net.) So, the purpose of the testing described below is just to see what methods I could use for encypting data on laptops and possible servers if I get really enthused by it... Recent Linux-based systems will be the main subject (I use almost always Gentoo); the only other systems I tend to have on a laptop are FreeBSD, which is covered at the end of these notes. One could encrypt the whole system and home, apart from /boot, and would then need to enter a passphrase on startup. For extra super-duper security, the swap and /tmp could be encrypted. But I don't really need this. All our desktop and laptop computers tend to auto-login a general-purpose user (called `user') on the first display, to allow all and sundry to use the computer. We then log in on further displays e.g. Ctrl-Alt-F10 etc. for our private settings and work. If the system is stolen, the only sensitive data outside our own home directories is the /etc/shadow file, a long processing of which might permit an attacker to get passwords rather similar to those of other systems: but these others would be changed anyway in the case of a theft. What seems initially the ideal method would allow just our private homes to be encrypted, with separate passphrases, and ideally using a single password on login so that no more steps are needed than currently. Failing that (bearing in mind that we don't often go travelling, and when we do the laptops are usually on for days at a time) it would be ok to ## Check disk and make random data on it. A suggestion from http://www.saout.de/tikiwiki/tiki-index.php?page=EncryptedDeviceUsingLUKS which is supposedly quicker than catting /dev/urandom, and it includes badblock checking, although the randomness is not as good. badblocks -c 10240 -s -w -t random -v /dev/hda4 ## Simple loop-device encryption of a filesystem within a file. This could be used so that each home directory lives within a regular file, which is then mounted as an encrypted block device by its user. This method is described in the manual page for losetup, and is deprecated due to its being superseded by the device-mapper and cryptsetup utility (see later!). In the kernel (2.6.24 in my case here), the block-devices section must include then loopback device and the extra option for encrypted loop devices: CONFIG_BLK_DEV_CRYPTOLOOP. Under Cryptographic API (top level in menuconfig), a suitable cipher should be enabled, e.g. CONFIG_CRYPTO_AES and CONFIG_CRYPTO_BLOWFISH. # setting up a file: straight way (file of constant disk-blocks) # (some sources think it worth using random bytes: /dev/zero is quicker) dd if=/dev/urandom of=img_file bs=1024 count=30K # OR, setting up a file: sparse way, so as not to use more disk # space than actually needed, but perhaps less efficient; note # that not all filesystems necessarily support sparseness dd if=/dev/zero of=img_file bs=1 count=1 seek=30M # set up image file and block device and make filesystem losetup -e aes /dev/loop1 img_file mkfs.ext2 /dev/loop1 # mount it manually mount -t ext2 /dev/loop1 /mnt/enc # or, automate the losetup and mount for regular use: a normal user # can mount/unmount, and is prompted for the password on mounting; # the following goes into /etc/fstab: /path/img_rand /home/me ext2 defaults,noauto,loop,encryption=aes,user 0 0 ## Device-mapper and cryptsetup. This allows actual block devices or loopback ones to be accessed via /dev/mapper/* , with on the fly (en|de)cryption. The cryptsetup command deals with all the in-kernel stuff, in the style of mdadm for linux md-raid devices. It's all very neat. /etc/crypttab is used to set up mappings automatically at boot. The `LUKS' (linux unified key setup) standard is an extension to cryptsetup, included as standard in several distributions, among them gentoo. It specifies a standard for the on-disk format and for handling multiple keys. # load or compile-in these modules: the order mattered (or try one at a time): modprobe dm_mod dm_crypt aes # initial setup of partition (or other block device) cryptsetup luksFormat /dev/hda4 cryptsetup luksOpen /dev/hda4 localhome mkfs.ext3 /dev/mapper/localhome # `cold start' of an existing device cryptsetup luksOpen /dev/hda4 localhome mount -t ext3 /dev/mapper/localhome /home # full shutting down umount /home cryptsetup luksClose localhome # automatic startup: echo '/dev/hda4 none luks,check=ext2,retry=5' >>/etc/crypttab echo '/dev/mapper/localhome /local auto defaults 0 0' >>/etc/fstab # add key (up to 8 parallel keys per partition) cryptsetup luksAddKey /dev/hda4 # remove second (#1) key: cryptsetup luksDelKey /dev/hda4 1 # dump information cryptsetup luksDump /dev/hda4 ## Auto-mounting on login. It is widely asserted on the web that the (complex) wonders of PAM (pluggable authentication modules) permit the automatic mounting of a user's home at login, with use of the user's supplied password as the partition's decryption password too. I look no further here, as PAM work generally takes me a long time to feel happy with, and I feel for the moment that plain cryptsetup together with manual start for servers, and possibly automatic qeuerying for password on boot for laptops, is enough for now. ## Auto-encrypted swap. From http://feeding.cloud.geek.nz/2008/03/encrypted-swap-partition-on.html : Not of interest to me just now: I'm not considering sophisticated attackers who'd really care enough to try to get a key or a bit of data from swap. But might be worth trying to see if there is any noticeable problem with speed, especially under heavy memory load. swapoff /dev/hdaX cryptsetup -h sha256 -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/hdaX cryptsetup luksOpen /dev/hdaX cswap mkswap /dev/mapper/cswap echo 'cswap /dev/hda2 none swap,luks,timeout=30' >>/etc/crypttab: echo '/dev/mapper/cswap none swap sw 0 0' >>/etc/fstab vi /etc/fstab # to remove old swap entry Then configure swsuspend (now tuxonice?) to use /dev/mapper/cswap for suspend. ## Partition encryption with FreeBSD. One of my laptops uses FreeBSD-7.0. The helpful page at http://www.freebsd.org/doc/en/books/handbook/disks-encrypting.html tells of the two systems for doing disk encryption: gbde and geli; of these, geli is the newer, and supports extra features such as root partitions, not needing lock-files stored elsewhere, several (modern) crypto algorithms available, indepdendent keys, and random keys for swap partitions. Again, I've used the encryption just for a home partition, with the user `user' being in a non-encrypted place: only my use of the laptop will require the (manual) mount of /home. # Kernel module kldload geom_eli # Initial setting up geli init -e AES -s 4096 /dev/ad0s1e # `cold start' of existing partition geli attach /dev/ad0s1e (the cleartext access to ad0s1e is now /dev/ad0s1e.eli) # new filesystem (skip the random writing if only testing) dd if=/dev/random of=/dev/ad0s1e.eli bs=1m newfs -O 2 -U /dev/ad0s1e.eli # mount / unmount mount /dev/ad0s1e.eli /home umount /home # stop geli detach /dev/ad0s1e.eli # For automated start and stop, add to /etc/rc.conf e.g.: geli_devices="ad0s1e" geli_ad0s1e_flags="" Note that the favoured (thorough) way of working with geli is to use both a passphrase and a file of random data (e.g. on a usb stick), in which case the random data is given on 'geli init' or 'geli attach' by the '-K filename' option, where 'filename' can be '-' for stdin. # For one-time encrypted swap, dd if=/dev/random of=/dev/ad0s1b bs=1m geli onetime -d -e 3des ad0s1b swapon /dev/ad0s1b.eli # Alternative initialisation, including data integrity verification; # by default this is not used, as it reduces available space and # slows access. geli init -e AES -a hmac/sha256 -s 4096 /dev/da0 ## Encryption at the cost of disk speed. Although the use of encryption for our laptop /home partitions seems sensible, it's certainly not negligible in terms of CPU requirements when really wanting to read or write lots of data. On making a new raid array for /home/ (peoples' homedirs, plus a huge load of other shared files under the `public' subdirectory) of some 2TB (3 disks raid5), I considered putting linux dm_crypt encryption on top of the array. Basic speed measurements with hdparm -tT suggested that while the raw devices (Hitachi 1TB SATA, made May2009) could manage continuous reads of about 100MBps (very impressive), a much lower speed was obtained with encryption on the array. The array itself was very slow when testing, as a degraded array of just two disks had been made for the initial setup (only two sata ports on the spare computer, and the old 4-disk array must stay in the server till switchover time). So, rather than definitely blame the encryption, I tried several algorithms, running dm_crypt directly on a single disk. Times were taken twice, showing only a couple of MB/s of variance for any particular case. These three ways of creating the encrypted device were used: cryptsetup luksFormat /dev/sda1 cryptsetup luksFormat -c twofish /dev/sda1 cryptsetup luksFormat -c blowfish /dev/sda1 Speeds in MB/s (buffered disk reads, from hdparm -tT): raw partition: ~95 dm_crypt default (aes): ~35 dm_crypt twofish: ~19 dm_crypt blowfish: ~23 This was on a 2.6GHz P4, with nothing else happening on those disks, and only an idle desktop running at all. During the reads, `system' CPU use (rather than iowait as common with disk access) was the dominant share of the 100% CPU load. It's interesting that the AES (I think the default is 128bit) is distinctly faster than the other two tried, just as is often touted as an AES `good point'. So, for the server, an ugly machine in a fairly secure flat, it seems not worth the extra troubles of encryption (password on mount, `losing' password, claimed higher danger for filesystem in presence of small disk errors, lower speed) for the benefit of encryption, for my data. On the other hand, the laptops are a reasonable case for encryption, since in spite of lower CPU performance they really are just used by one person at a time for modest loading, rather than being used for video copying, splitting, dumping loads of data from other computers while fixing them, rsyncing and rdiff-backuping lots of directories, etc. ##