Secure Storage with Encrypted file systems
Encryption is done through dm-crypt using LUKS as the key setup using kernel crypto API.
Linux Kernel 4.14.18-106 and above included this feature
Exynos5422 Slim SSS (Security Sub-System) driver supports AES/SHA-1/SHA-256/HMAC-SHA-1/HMAC-SHA-256.
device-mapper target provides transparent encryption of block devices using the kernel crypto API.
- AES cipher with support of aes-cbc/aes-ctr.
- Cipher-block chaining (CBC).
- Counter (CTR) known as integer counter mode (ICM) and segmented integer counter (SIC) mode.
- ESSIV (“Encrypted salt-sector initialization vector”) allows the system to create IVs based on a hash including the sector number and encryption key.
- SHA-256 is the hashing algorithm used for key derivation.
- XTS is counter-oriented chaining mode.
- PLAIN64 is an IV generation mechanism that simply passes the 64-bit sector index directly to the chaining algorithm as the IV.
Parameters: <cipher> <key> <iv_offset> <device path> <offset> [<#opt_params> <opt_params>]
<cipher> Encryption cipher, encryption mode and Initial Vector (IV) generator.
The cipher specifications format is: cipher[:keycount]-chainmode-ivmode[:ivopts] Examples: aes-cbc-essiv:sha256 aes-xts-plain64 serpent-xts-plain64
Cipher format also supports direct specification with kernel crypt API format (selected by capi: prefix). The IV specification is the same as for the first format type. This format is mainly used for specification of authenticated modes.
The crypto API cipher specifications format is: capi:cipher_api_spec-ivmode[:ivopts] Examples: capi:cbc(aes)-essiv:sha256 capi:xts(aes)-plain64 Examples of authenticated modes: capi:gcm(aes)-random capi:authenc(hmac(sha256),xts(aes))-random capi:rfc7539(chacha20,poly1305)-random
Cryptsetup Benchmark testing with DRAM
# root@odroid:~# cryptsetup benchmark # Tests are approximate using memory only (no storage IO). PBKDF2-sha1 297552 iterations per second PBKDF2-sha256 195338 iterations per second PBKDF2-sha512 125068 iterations per second PBKDF2-ripemd160 247305 iterations per second PBKDF2-whirlpool 27935 iterations per second # Algorithm | Key | Encryption | Decryption aes-cbc 128b 73.8 MiB/s 97.7 MiB/s serpent-cbc 128b 40.9 MiB/s 42.9 MiB/s twofish-cbc 128b 58.0 MiB/s 62.0 MiB/s aes-cbc 256b 59.8 MiB/s 74.0 MiB/s serpent-cbc 256b 41.5 MiB/s 42.7 MiB/s twofish-cbc 256b 59.1 MiB/s 62.0 MiB/s aes-xts 256b 110.6 MiB/s 95.2 MiB/s serpent-xts 256b 41.6 MiB/s 42.2 MiB/s twofish-xts 256b 59.7 MiB/s 61.9 MiB/s aes-xts 512b 86.1 MiB/s 72.5 MiB/s serpent-xts 512b 42.1 MiB/s 42.4 MiB/s twofish-xts 512b 60.7 MiB/s 61.6 MiB/s
Cryptsetup Benchmark testing with HDD
Below test results are from ODROID-HC2 using a WD 4TB 5400RPM NAS HDD.
iozone -e -I -a -s 100M -r 4k -r 16k -r 512k -r 1024k -r 16384k -i 0 -i 1 -i 2
Encryption cipher | DD result (MB/sec) | Iozone result (kB/sec) | |||||||
Write speed | Read speed | write | rewrite | read | reread | random read | random write | ||
aes-cbc-essiv:sha256 (128 bit key) | 69.2 | 75.2 | 39662 | 46940 | 94300 | 112724 | 97757 | 61227 | |
aes-cbc-essiv:sha256 (192 bit key) | 82.2 | 70.4 | 39674 | 48221 | 104894 | 115422 | 97860 | 52920 | |
aes-cbc-essiv:sha256 (256 bit key) | 80.7 | 64.4 | 38797 | 47699 | 99172 | 108811 | 101844 | 56758 | |
aes-ctr-plain (128 bit key) | 76.6 | 99.6 | 40956 | 49572 | 129875 | 160192 | 141948 | 61756 | |
aes-xts-plain64 (256 bit key) | 86.5 | 87.6 | 41149 | 47190 | 105411 | 131470 | 127655 | 66905 | |
aes-xts-plain64 (512 bit key) | 81.6 | 69.4 | 37643 | 39412 | 104134 | 109492 | 97255 | 57694 | |
twofish-cbc-essiv:sha256 (128 bit key) | 77.1 | 69.3 | 44008 | 48753 | 107413 | 128105 | 100541 | 66445 | |
twofish-cbc-essiv:sha256 (256 bit key) | 76.9 | 68.0 | 42128 | 50422 | 109972 | 120566 | 107068 | 58512 | |
twofish-xts-plain64 (256 bit key) | 80.2 | 55.9 | 40206 | 44363 | 97249 | 108703 | 88713 | 53685 | |
twofish-xts-plain64 (512 bit key) | 74.4 | 57.0 | 39311 | 43484 | 97468 | 109982 | 112207 | 57647 | |
serpent-cbc-essiv:sha256 (128 bit key) | 80.1 | 55.9 | 39309 | 41447 | 87069 | 106448 | 111989 | 52004 | |
serpent-cbc-essiv:sha256 (256 bit key) | 80.1 | 56.4 | 38312 | 41841 | 88125 | 104045 | 102048 | 61575 | |
serpent-xts-plain64 (256 bit key) | 71.9 | 48.1 | 36857 | 44134 | 86668 | 92474 | 92731 | 51055 | |
serpent-xts-plain64 (512 bit key) | 72.3 | 48.0 | 37968 | 41449 | 82182 | 90441 | 85489 | 55216 |
Note: These result will vary at your end.
Encrypt the Hard Drive using cryptsetup
Install cryptsetup, and so as not to need rebooting, start the dm-crypt modules.
- target
$ sudo apt-get install cryptsetup $ sudo modprobe dm-crypt sha256 aes
Test verify the cryptsetup and dm-crypt are working.
- target
$ fallocate -l 128MiB /tmp/test.bin $ dd if=/dev/urandom of=/tmp/testkey.key bs=128 count=1 $ sync $ cryptsetup luksFormat --debug -q -d /tmp/testkey.key --cipher aes-cbc-essiv:sha256 -h sha256 -s 128 /tmp/test.bin $ fallocate -l 128MiB /tmp/test.bin $ dd if=/dev/urandom of=/tmp/testkey.key bs=128 count=1 $ sync $ cryptsetup luksFormat --debug -q -d /tmp/testkey.key --cipher aes-ctr-plain -h sha256 -s 128 /tmp/test.bin
Once the you verify the cryptsetup is working fine you could start encrypt the disk. Note : this is full disk encryption so we need to format the disk.
- target
$ sudo wipefs -a /dev/sda1
/dev/sda1: 6 bytes were erased at offset 0x00000000 (crypto_LUKS): 4c 55 4b 53 ba be
Create a key to unlock the volume
Luks encryption supports multiple keys. These keys can be passwords entered interactively or key files passed as an argument while unlocking the encrypted partition.
- target
$ sudo dd if=/dev/urandom of=/root/keyfile bs=1024 count=4 $ sudo chmod 400 /root/keyfile
Create luks encrypted partition. To create the encrypted partition on /dev/sda1, luks is used. The encryption of the partition will be managed using the cryptsetup command.
- target
$ sudo cryptsetup --verify-passphrase luksFormat /dev/sda1 -c aes-cbc-essiv:sha256 -h sha256 -s 128
Note: This will ask for passphrase which should be long more than 8 characters you should note this.
Opening up the encrypted drive and map the dp-crypt to filesystem Next, we will open up the drive using the passphrase we just gave, and create a filesystem on the device.
- target
$ sudo cryptsetup luksOpen /dev/sda1 securebackup
Format the partition
- target
$ sudo mkfs -t ext4 -m 1 /dev/mapper/securebackup
Add luks key to support auto mounting at boot time.
- target
$ sudo cryptsetup -v luksClose securebackup $ sudo cryptsetup luksAddKey /dev/sda1 /root/keyfile
Now also update the /etc/crypttab file, to refer to the keyfile as below
- target
$ cat /etc/crypttab # <target name> <source device> <key file> <options> securebackup /dev/sda1 /root/keyfile luks
We need to tell the dm-crypt subsystem that this stick must be mounted before the encrypted HDD partition. To do this, open the /etc/default/cryptdisks file and look for the line CRYPTDISKS_MOUNT=“”.
- target
$ cat /etc/default/cryptdisks # Run cryptdisks initscripts at startup? Default is Yes. CRYPTDISKS_ENABLE=Yes # Mountpoints to mount, before cryptsetup is invoked at initscripts. Takes # mountpoins which are configured in /etc/fstab as arguments. Separate # mountpoints by space. # This is useful for keyfiles on removable media. Default is unset. CRYPTDISKS_MOUNT="/root/keyfile" # Default check script. Takes effect, if the 'check' option is set in crypttab # without a value. CRYPTDISKS_CHECK=blkid # Default precheck script. Takes effect, if the 'precheck' option is set in # crypttab without a value. # Default is 'un_blkid' for plain dm-crypt devices if unset here. CRYPTDISKS_PRECHECK=
Verify the drive is mapped to the crypto device
- target
$ sudo cryptsetup luksOpen /dev/sda1 securebackup $ lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT mmcblk1 179:0 0 29.8G 0 disk |-mmcblk1p1 179:1 0 128M 0 part /media/boot `-mmcblk1p2 179:2 0 29.7G 0 part / sda 8:0 0 149G 0 disk `-sda1 8:1 0 149G 0 part `-securebackup 254:0 0 149G 0 crypt
Auto mount the disk on next boot up you need to update the /etc/fstab entry.
- target
$ mkdir -p /media/secure $ sudo cat /etc/fstab UUID=e139ce78-9841-40fe-8823-96a304a09859 / ext4 errors=remount-ro,noatime 0 1 LABEL=boot /media/boot vfat defaults 0 1 /dev/mapper/securebackup /media/secure ext4 defaults,rw 0 2
Note: Test manual mount of the disk if all succeed you will be able to mount drive the disk
- target
$ mount /dev/mapper/securebackup /media/secure
CIFS/Samba performance on an encrypted HDD
Environments:
- HC2 + ubuntu-16.04.3-4.14-minimal-odroid-xu4-20171213.img.xz with updated 4.14.18-106 kernel
- 8GB MicroSD card
- Seagate 8TB HDD (ST8000AS0002)
- Encryption: aes-xts-plain64 (256 bit key, SHA256 hash)
Samba configuration:
[HDD INTERNAL] comment = NAS path = /media/internal valid users = odroid writable = yes create mask = 0775 directory mask = 0775 # Tweaks write cache size = 524288 getwd cache = yes use sendfile = yes min receivefile size = 16384 socket options = TCP_NODELAY IPTOS_LOWDELAY
And the results here.
- Before encryption
- After encryption
- HELIOS LanTest: Before / After
The CIFS/Samba performance degrades around ~30% if we use the hardware accelerated security.
But you can protect your important data and privacy.