User Tools

Site Tools


doc:appunti:linux:sa:cryptfs

Encrypted filesystem

Web

Linux kernel modules

Due possibilità offerte dal kernel Linux: cryptoloop (deprecata) e dm-crypt.

Cryptoloop

:!: WARNING: This device is not safe for journaled file systems like ext3 or Reiserfs. Please use the Device Mapper crypto module instead, which can be configured to be on-disk compatible with the cryptoloop device.

Cryptoloops is also vulnerable to known plaintext attacks and watermark attacks.

Kernel option: CONFIG_BLK_DEV_CRYPTOLOOP.

Dm-crypt

Kernel option: CONFIG_DM_CRYPT.

This device-mapper target allows you to create a device that transparently encrypts the data on it. You'll need to activate the ciphers you're going to use in the cryptoapi configuration.

modprobe dm-mod
/dev/mapper
/dev/mapper/control

Storing keys with LUKS

The Debian version of cryptsetup(8) is enhanced with LUKS (Linux Unified Key Setup) for keys handling.

LUKS works by prepending a partition header (luks_phdr) to the partition, where setup information like cipher, keysize is stored as well as key slots. A key slots is holding an encrypted version of the master key. The master key is used to encrypt bulk data. It will never be stored to disk directly, but encrypted version of the master key will be stored. To be more precise, every version of the master key is encrypted by a different passphrase and stored a separate key slot. The user needs to provide one passphrase only, since any correct passphrase will restore a copy of the master key.

Example

With those commands we initialize an encrypted (dm-crypt) filesystem sitting on a RAID1 partition.

Create a RAID level 1 (mirror) device /dev/md4:

mknod /dev/md4 b 9 4
mdadm --create /dev/md4 --level=1 -n 2 /dev/sda3 /dev/sdb3

Load the needed kernel modules and initialize the dm-crypt volume:

modprobe dm-mod
modprobe dm-crypt
modprobe twofish
cryptsetup isLuks /dev/md4; echo $?
cryptsetup --cipher twofish-cbc-essiv:sha256 --key-size 256 luksFormat /dev/md4
cryptsetup luksDump /dev/md4

In the example above we used the twofish crypto algorithm provided by the twofish kernel module. Another popular crypto algorithm is provided byt the aes kernel module; in that case use the parameter aes-cbc-essiv:sha256. You can ask the kernel which crypto modules are loaded with the command:

cat /proc/crypto
name         : aes
driver       : aes-generic
module       : aes
priority     : 100
type         : cipher
blocksize    : 16
min keysize  : 16
max keysize  : 32

name         : twofish
driver       : twofish-generic
module       : twofish
priority     : 0
type         : cipher
blocksize    : 16
min keysize  : 16
max keysize  : 32

Twofish was developed by indipendent cryptographers, leaded by Bruce Schneier. AES is instead approved by the U.S. National Security Agency (NSA).

The ecnryption key will be 256 bits long (how it is generated?). The key will be hashed with a passphrase typed by the user and stored in a LUKS keyslot contained in /dev/md4.

To start the dm-crypt device we must type the passphrase to unlock the crypt key. Finally we create an ext3 filsystem and mount it:

cryptsetup luksOpen /dev/md4 dm0
ls -l /dev/mapper/
mkfs.ext3 -m0 /dev/mapper/dm0
mount /dev/mapper/dm0 /mnt

Useful commands to see the status or to close a dm-crypt device:

cryptsetup status dm0
cryptsetup remove dm0
cryptsetup luksClose dm0; # Same as above!

To initialize automatically the dm-crypt volume at bootstrap (via /etc/init.d/cryptdisks), put the following line in /etc/crypttab:

dm0  /dev/md4  none  luks,tries=1,timeout=10

The passphrase will be asked only once with a 10 seconds timeout.

WARNING! See bug 495509. The timeout paramter does not work, use instead noauto and start the crypt disk manually with /etc/init.d/cryptdisks force-start. Beware to set noauto also into the fstab options for that device.

If you want to start automatically the crypto device at boot without prompting for the passphrase you have to:

  1. Generate a random key with the required size (32 bytes * 8 = 256 bits)
  2. Add the new key into one LUKS slot
  3. Open the crypto device using this key
dd if=/dev/urandom of=luks.key bs=1 count=32
cryptsetup luksAddKey /dev/md4 luks.key
cryptsetup --key-file luks.key luksOpen /dev/md4 mycryptdev

Starting a crypted device without LUKS

cryptsetup create crypted-hdd1 /dev/hdd1
ls -l /dev/mapper/
mount /dev/mapper/crypted-hdd1 /mnt

Other kernel modules

Loop-aes

Through politics and in-fighting the Loop-AES developers have alienated the Linux kernel team, including Linus himself. As a result loop-AES is not supported by the mainline Linux kernel.

One strong point of loop-aes is that Encryption keys can be stored in a GnuPG-encrypted keyfile, which allows the passphrase to be changed without re-encryption. Keyfiles can also be encrypted asymmetrically for multi-user access. Much like LUKS in cryptsetup and dm-crypt.

User space

enc-fs

Per creare una directory criptata in $HOME/encfs/crypt/:

mkdir ~/encfs
encfs ~/encfs/.crypt ~/encfs/crypt

Scegliendo l'opzione p si dovrebbe ottenere una Paranoia configuration. Viene ovviamente chiesta una password che protegge il filesystem, tale filesystem viene montato tramite fuse.encfs, quindi tutto in user-space.

La directory $HOME/encfs/.crypt/ contiene i dati veri e propri, criptati. La directory $HOME/encfs/crypt/ è invece una vista in chiaro dei dati.

Per smontare la directory in chiaro (e quindi lasciare solo la versione cifrata dei dati):

fusermount -u ~/encfs/crypt

Per montare nuovamente il filesystem cifrato (la directory) si usa lo stesso comando encfs utilizzato per inizializzarlo; viene ovviamente chiesta la password di cifratura. Per il montaggio è indispensabile conservare il file .encfs6.xml che è stato creato nella directory radice.

È possibile eliminare file e/o directory nel filesystem cifrato: ogni oggetto compare con un nome cifrato. Non è possibile invece spostare una directory: per decodificare correttamente il contenuto è necessario mantenere il percorso originale completo.

È possibile modificare la password; si tratta in realtà della password che protegge la chiave di cifratura vera e propria, pertanto non sarà necessario cifrare nuovamente tutto il contenuto. Si usa il comando:

encfsctl passwd ~/encfs/.crypt

Reverse enc-fs

È possibile usare encfs per ottenere una “vista” cifrata di una normale directory (ad esempio per effettuare un backup tramite rsync su host remoto e mantenere la riservatezza dei dati). Per automatizzare il processo la password deve essere memorizzata in un file, questo il comando per montare la vista cifrata della directory:

cat secret.txt | encfs --standard --reverse --stdinpass /home /home-crypt

L'opzione --standard serve a disabilitare la richiesta dei parametri quando si esegue il montaggio encfs per la prima volta. In tale circostanza infatti vengono chiesti via stdin alcuni parametri che “consumerebbero” una parte della password fornita appunto via stdin. I parametri di encfs vengono salvati nella directory radice in un file di nome .encfs6.xml.

Per smontare la directory cifrata si utilizza:

fusermount -u /home-crypt

Which encryption algorythm?

When the U.S. govt. and dept. of defense set out to search for a replacement for the previous encryption standard, DES, they launched a public process involving many cryptographers and evaluated a great many encryption algorithms. Eventually, through many rounds of expert consultation and review, the field was narrowed down to five really good, fast, flexible encryption algorithms:

  • Rijndael (now known as AES)
  • Serpent
  • Twofish
  • MARS
  • RC6

RC6 was abandoned for intellectual property reasons, and few of the reviewers like MARS. The other three were serious contenders, and all are available to you in the modern Linux kernel. All three are fast, flexible, cryptographically strong, and very well reviewed. In the end, Rijndael was selected and it is now known as AES. Strong arguments can still be made in favour of twofish or serpent as well.

Someone choosed Twofish because of: I elected to choose between the three based on performance benchmarks, counting on the fact that all three of them are strong enough cryptographically to meet my needs.

Crypto root filesystem

The most generic case is a crypto root filesystem with a modular kernel and initramfs.

Installing the cryptsetup and the initramfs-tools will provide a good infrastructure: just add the proper entries into /etc/fstab

/dev/mapper/root  /  ext3  defaults,errors=remount-ro  0  1

and /etc/crypttab

# <target name>  <source device>   <key file>            <options>
root             /dev/sda2         /etc/crypto_root.key  luks,keyscript=/bin/cat

Just to be on the safe side, add also the required kernel modules into /etc/initramfs-tools/modules:

# Modules for crypto device
dm-mod
dm-crypt
aes
twofish
sha256

Then run the command:

update-initramfs -v -u

The boot sequence that will be embedded into the initramfs is like this:

  1. The kernel boots and opens the ramdisk image.
  2. The kernel runs the init program which loads the kernel modules.
  3. init will run the /scripts/local because it wants a local root filesystem (this is took from the option BOOT=local contained in /etc/initramfs-tools/initramfs.conf).
  4. The /script/local will run the helper script /scripts/local-top/cryptroot. The script was included into the ramdisk image because of the entries found into fstab and crypttab (see above). All the configuration options will be read from /conf/conf.d/cryptroot.
  5. Also /script/local will mount the root filesystem. Default root filesystem is took from /conf/param.conf (ROOT=/dev/mapper/root in my case). This file is created during update-initramfs.

My case was a bit special: the crypto disk is opened with LUKS and using a key stored onto the disk itself, instead of asking the passphrase on the console. So I had to use a key file and the keyscript option.

I keep the key file in /etc/crypto_root.key, but this file must be present also into the initramfs. For this reason I had to provide to update-initramfs an hook script: /etc/initramfs-tools/hooks/cryptoroot_key:

#!/bin/sh
PREREQ=""
prereqs()
{
        echo "$PREREQ"
}
case $1 in
prereqs)
        prereqs
        exit 0
        ;;
esac
 
if [ -f /etc/crypto_root.key ]; then
        install -d $DESTDIR/etc
        cp -p /etc/crypto_root.key $DESTDIR/etc
fi

Using a key-file instead of an interactive password

If you want to store the key into a file instead of unlocking it via a passphrase:

dd if=/dev/urandom of=crypto.key bs=1 count=32
cat crypto.key | cryptsetup --key-file=- --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda8
cryptsetup --key-file=crypto.key luksOpen /dev/sda8 crypto_sda8

Manual start of encrypted disk

If an encrypted disk requires a password to be typed interactively, it is obviously not possible to start it automatically at boot time. In old Debian releases there was the timeout parameter to be added into /etc/crypttab. Using that parameter, the starting of a LUKS volume is skipped at boot time and can be executed later using /etc/init.d/cryptdisks start.

Starting with Debian 5 Lenny the timeout parameter was not longer available (see bug #495509). The noauto parameter is instead required in /etc/crypttab and eventually in /etc/fstab.

Starting with Debian 6 Squeeze the noauto parameter is still required. Once the system is running you can execute the command /etc/init.d/cryptdisks force-start to start the encrypted disk, asking for the password.

Starting with Debian 9 Stretch the noauto parameter is used as usual, but sysvinit init system was superceeded by systemd, so the script /etc/init.d/cryptdisks is no longer used. To start the encrypted disk interactively you should use the script cryptdisks_start instead, e.g.:

cryptdisks_start dm0
doc/appunti/linux/sa/cryptfs.txt · Last modified: 2020/01/29 10:48 by niccolo