By now, most companies are employing disk encryption. Linux has for a long time supported disk encryption, and using it is imperative for mobile devices in case of loss or theft. Upon occasion, replacing the decryption key is a necessity, and thankfully, LUKS (Linux Unified Key Setup) allows this.
To create a test filesystem with encryption:
# cd /tmp # dd if=/dev/zero of=test.sparse bs=1 count=0 seek=100M 0+0 records in 0+0 records out 0 bytes (0 B) copied, 2.5627e-05 s, 0.0 kB/s # ls -als test.sparse 0 -rw-r--r-- 1 root root 104857600 Dec 31 04:14 test.sparse # losetup /dev/loop0 /tmp/test.sparse # losetup -a /dev/loop0: [fe00]:122882 (/tmp/test.sparse) # cryptsetup luksFormat /dev/loop0 WARNING! ======== This will overwrite data on /dev/loop4 irrevocably. Are you sure? (Type uppercase yes): YES Enter LUKS passphrase: FOO Verify passphrase: FOO # cryptsetup luksOpen /dev/loop0 TEST-ENCRYPTED Enter passphrase for /dev/loop0: # mke2fs -j /dev/mapper/TEST-ENCRYPTED mke2fs 1.41.12 (17-May-2010) Filesystem label= OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 25168 inodes, 100352 blocks 5017 blocks (5.00%) reserved for the super user First data block=1 Maximum filesystem blocks=67371008 13 block groups 8192 blocks per group, 8192 fragments per group 1936 inodes per group Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 31 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. # mount /dev/mapper/TEST-ENCRYPTED /tmp/mount # df -k /tmp/mount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/TEST-ENCRYPTED 97167 5663 86487 7% /tmp/mount
At this point we have an encrypted filesystem, 100 MB in size, mountable via the loopback filesystem (loopfs). Now, to examine the details of of test.sparse (remembering it could be any storage partition, logical volume, raid set, etc).
# cryptsetup luksDump /dev/loop0 LUKS header information for /dev/loop0 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: 88 e2 08 fb 6c 1f b3 cf 31 36 d6 b8 33 e5 26 e0 9e 00 87 3b MK salt: e9 9c 9b 35 f8 9f 72 f4 db 4d d7 aa 6d 6e 7e a3 85 38 41 65 b5 35 0a 88 08 c9 66 ee ad ba 77 30 MK iterations: 66500 UUID: 0b7452c4-1c2f-43d4-8768-fcf168d990a4 Key Slot 0: ENABLED Iterations: 266167 Salt: 66 dc d0 4c dd 22 a4 48 b7 9b 2e bd b2 6d af 9d c5 5c 43 f8 25 f3 d4 86 36 8d 78 28 75 7a 52 a5 Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
There are a lot of goodies here. One thing to note are the key slots – eight total. Isn’t that nice? Eight decryption keys can support one device. This means you can place an additional key in case one is lost, a back door. The next step is to add a key to a slot, and for this example, it is slot 7:
# cryptsetup --key-slot=7 luksAddKey /dev/loop0 Enter any passphrase: FOO Enter new passphrase for key slot: BAR Verify passphrase: BAR # cryptsetup luksDump /dev/loop0 LUKS header information for /dev/loop0 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: 88 e2 08 fb 6c 1f b3 cf 31 36 d6 b8 33 e5 26 e0 9e 00 87 3b MK salt: e9 9c 9b 35 f8 9f 72 f4 db 4d d7 aa 6d 6e 7e a3 85 38 41 65 b5 35 0a 88 08 c9 66 ee ad ba 77 30 MK iterations: 66500 UUID: 0b7452c4-1c2f-43d4-8768-fcf168d990a4 Key Slot 0: ENABLED Iterations: 266167 Salt: 66 dc d0 4c dd 22 a4 48 b7 9b 2e bd b2 6d af 9d c5 5c 43 f8 25 f3 d4 86 36 8d 78 28 75 7a 52 a5 Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: ENABLED Iterations: 255589 Salt: 5e 49 e4 72 6f 27 7a 76 64 b9 df ae 4e 92 bc 1e d9 0e 55 87 61 ba e6 13 af d8 a5 4d 5f 6e 02 14 Key material offset: 1800 AF stripes: 4000
Now we have two keys for decryption, one in slot zero, the other in slot seven. To confirm the filesystem can be mounted with both passwords:
# umount /tmp/mount # cryptsetup luksClose /dev/mapper/TEST-ENCRYPTED # cryptsetup luksOpen /dev/loop0 TEST-ENCRYPTED Enter passphrase for /dev/loop0: FOO # mount /dev/mapper/TEST-ENCRYPTED /tmp/mount # df -k /tmp/mount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/TEST-ENCRYPTED 97167 5663 86487 7% /tmp/mount # umount /tmp/mount # cryptsetup luksClose /dev/mapper/TEST-ENCRYPTED # cryptsetup luksOpen /dev/loop4 TEST-ENCRYPTED Enter passphrase for /dev/loop4: BAR # mount /dev/mapper/TEST-ENCRYPTED /tmp/mount # df -k /tmp/mount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/TEST-ENCRYPTED 97167 5663 86487 7% /tmp/mount
Everything works as expected. We now have two keys that can mount the encrypted loopback filesystem. The next step is to remove slot 0, and verify that its key no longer works.
# umount /tmp/mount # cryptsetup luksClose /dev/mapper/TEST-ENCRYPTED # cryptsetup luksKillSlot /dev/loop0 0 Enter any remaining LUKS passphrase: BAR # cryptsetup luksDump /dev/loop0 LUKS header information for /dev/loop0 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: 88 e2 08 fb 6c 1f b3 cf 31 36 d6 b8 33 e5 26 e0 9e 00 87 3b MK salt: e9 9c 9b 35 f8 9f 72 f4 db 4d d7 aa 6d 6e 7e a3 85 38 41 65 b5 35 0a 88 08 c9 66 ee ad ba 77 30 MK iterations: 66500 UUID: 0b7452c4-1c2f-43d4-8768-fcf168d990a4 Key Slot 0: DISABLED Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: ENABLED Iterations: 255589 Salt: 5e 49 e4 72 6f 27 7a 76 64 b9 df ae 4e 92 bc 1e d9 0e 55 87 61 ba e6 13 af d8 a5 4d 5f 6e 02 14 Key material offset: 1800 AF stripes: 4000
Slot zero is now removed, and trying to use FOO confirms it:
cryptsetup luksOpen /dev/loop0 TEST-ENCRYPTED Enter passphrase for /dev/loop0: FOO No key available with this passphrase. Enter passphrase for /dev/loop0: FOO No key available with this passphrase. Enter passphrase for /dev/loop0: FOO No key available with this passphrase.
To tidy things up, the last steps are to add new key to slot zero, and remove slot seven.
# cryptsetup --key-slot=0 luksAddKey /dev/loop0 Enter any passphrase: BAR Enter new passphrase for key slot: NEW Verify passphrase: NEW # cryptsetup luksKillSlot /dev/loop0 7 Enter any remaining LUKS passphrase: NEW # cryptsetup luksOpen /dev/loop0 TEST-ENCRYPTED Enter passphrase for /dev/loop0: # mount /dev/mapper/TEST-ENCRYPTED /tmp/mount # df -k /tmp/mount Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/TEST-ENCRYPTED 97167 5663 86487 7% /tmp/mount # cryptsetup luksDump /dev/loop0 LUKS header information for /dev/loop0 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: 88 e2 08 fb 6c 1f b3 cf 31 36 d6 b8 33 e5 26 e0 9e 00 87 3b MK salt: e9 9c 9b 35 f8 9f 72 f4 db 4d d7 aa 6d 6e 7e a3 85 38 41 65 b5 35 0a 88 08 c9 66 ee ad ba 77 30 MK iterations: 66500 UUID: 0b7452c4-1c2f-43d4-8768-fcf168d990a4 Key Slot 0: ENABLED Iterations: 251733 Salt: 4d a1 48 b7 26 15 a3 1c 53 e2 14 a4 75 7d f9 02 8b 0f 2c 3d e3 1f 34 05 fa 21 92 15 ea d0 1b a8 Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
This completes the key change. Looking at the above dump, one interesting item is the cipher. The default cipher can be changed at compile time for cryptsetup. From the man page (1.2.0 was used in this example), a few key points:
NOTES ON SUPPORTED CIPHERS, MODES, HASHES AND KEY SIZES
The available combinations of ciphers, modes, hashes and key sizes
depend on kernel support. See /proc/crypto for a list of available
options. You might need to load additional kernel crypto modules in
order to get more options.For –hash option all algorithms supported by gcrypt library are avail-
able.NOTES ON PASSWORDS
Mathematics can’t be bribed. Make sure you keep your passwords safe.
There are a few nice tricks for constructing a fallback, when suddenly
out of (or after being) blue, your brain refuses to cooperate. These
fallbacks are possible with LUKS, as it’s only possible with LUKS to
have multiple passwords.
Thank you to the folks who wrote cryptsetup. It is available here: