Linux Unified Key Setup
Linux Unified Key Setup Full Disk Encryption
Transparent encryption on disk sector level
Transparent for filesystem
No user decision what to encrypt
Encryption of hibernation and swap partitions
Volume key – key used to encrypt data
Passphrase – unlocks encrypted disk
Linux Full Disk Encryption
dm-crypt (kernel module) + cryptsetup (control utility)
LUKS (Linux Unified Key Setup)
On-disk format to store encrypted volume key
Implemented inside cryptsetup library
LUKS Common Use Cases
Local encrypted disk
Encrypted notebook, portable drives, …
Corporate notebooks – on-demand recovery
Data center disks
Different physical access policies in-place
Data disks (also Gluster bricks, Ceph OSDs, …)
Automatic unlocking?
Mobile devices
Specific environment, usually non-LUKS metadata
LUKS Threat Example
Asset: Confidential data on-disk
Threat: Stolen disk
=> Strong encryption with random key
=> Dictionary password attack resistance
LUKS provides data confidentiality only
No integrity protection
Protection only of locked (powered-off) device
Key Management
It’s all about weak passwords :-)
Password-based key derivation functions
PBKDF2
Argon2 (PHC winner)
No Trusted Platform Module (TPM) bindings
No 2nd factors authentication.
No secret sharing.
Disk Encryption “User Survey”
6% does not use encryption (despite company policy :-)
96% believes that encryption increases security
20% lost data on encrypted disk at least once
59% of them lost data forever
18% of them suffered corruption of encrypted disk
62% have backups of encrypted data
1% have problem with slowdown caused by encryption
75% did not notice, 19% negligible slowdown
Device-Mapper’s “crypt” target dm-crypt is a transparent disk encryption subsystem in Linux kernel versions 2.6 and later and in DragonFly BSD . It is part of the device mapper (dm) infrastructure, and uses cryptographic routines from the kernel’s Crypto API .
dm-crypt is implemented as a device mapper target and may be stacked on top of other device mapper transformations. It can thus encrypt whole disks (including removable media ), partitions , software RAID volumes , logical volumes , as well as files . It appears as a block device, which can be used to back file systems , swap or as an LVM physical volume .
Configuring File Encryption 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 $ sudo apt-get install -y cryptsetup-bin $ truncate --size 4G secret-block.raw $ du -ms secret-block.raw 0 secret-block.raw $ cryptsetup -y luksFormat --sector-size 4096 secret-block.raw WARNING! ======== This will overwrite data on secret-block.raw irrevocably. Are you sure? (Type 'yes' in capital letters): YES Enter passphrase for secret-block.raw: Verify passphrase: $ du -ms secret-block.raw 16 secret-block.raw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 $ sudo cryptsetup luksOpen secret-block.raw secret-block Enter passphrase for secret-block.raw: $ sudo cryptsetup status secret-block /dev/mapper/secret-block is active. type : LUKS2 cipher: aes-xts-plain64 keysize: 512 bits key location: keyring device: /dev/loop0 loop: secret-block.raw sector size: 4096 offset: 32768 sectors size: 8355840 sectors mode: read /write $ sudo cryptsetup luksDump /dev/loop0 LUKS header information Version: 2 Epoch: 3 Metadata area: 16384 [bytes] Keyslots area: 16744448 [bytes] UUID: f5b87a43-f565-4078-a1f2-735d90c170d8 Label: (no label) Subsystem: (no subsystem) Flags: (no flags) Data segments: 0: crypt offset: 16777216 [bytes] length: (whole device) cipher: aes-xts-plain64 sector: 4096 [bytes] Keyslots: 0: luks2 Key: 512 bits Priority: normal Cipher: aes-xts-plain64 Cipher key: 512 bits PBKDF: argon2id Time cost: 5 Memory: 1048576 Threads: 4 Salt: cd 80 4c b7 06 c6 6c 21 e0 f6 1e a3 64 dc 2d 3e f3 5b e1 a3 be 38 95 20 34 d3 30 fc 03 f6 04 0b AF stripes: 4000 AF hash : sha256 Area offset:32768 [bytes] Area length:258048 [bytes] Digest ID: 0 Tokens: Digests: 0: pbkdf2 Hash: sha256 Iterations: 123419 Salt: 50 21 fd 06 c0 88 fa 3b 6a 34 08 a2 16 47 e6 b1 25 53 85 c5 2e ec 65 ae 53 94 f3 56 af df ae ef Digest: 64 a7 08 b0 8b ac cc bf cb a6 dc 9a a4 4c 41 f0 3e d5 da 70 e4 f8 95 36 99 83 70 b3 75 23 30 f2
Protect Against Disclosure of Usage Patterns File block data with zeros, protect against disclosure of usage patterns.
1 $ sudo dd if =/dev/zero of=/dev/mapper/secret-block
Create a Filesystem 1 2 3 4 5 6 7 8 9 10 11 $ sudo mkfs.xfs /dev/mapper/secret-block meta-data=/dev/mapper/secret-block isize=512 agcount=4, agsize=261120 blks = sectsz=4096 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 bigtime=0 inobtcount=0 data = bsize=4096 blocks=1044480, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=4096 sunit=1 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0
Mount and Use Encrypted Filesystem 1 2 3 4 5 6 7 8 9 $ sudo xfs_info /dev/mapper/secret-block $ sudo mount /dev/mapper/secret-block secret-fs $ echo "01234567890abcdefghijklmnopqrstuvwxyz" | sudo tee secret-fs/test.txt $ sudo umount secret-fs/ $ sudo cryptsetup luksClose /dev/mapper/secret-block $ grep "01234567890abcdefghijklmnopqrstuvwxyz" secret-block.raw
GnuPG Encrypted Key File 1 2 3 4 $ dd if =/dev/urandom count=64 bs=1k \ | gpg --symmetric --cipher-algo AES256 --armor > /path/to/secret-block-key.gpg $ gpg --decrypt /path/to/secret-block-key.gpg \ | cryptsetup luksFormat --sector-size 4096 secret-block.raw
Daily Usage of File Encryption 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ sudo cryptsetup luksOpen secret-block.raw secret-block Enter passphrase for secret-block.raw: $ gpg --decrypt /path/to/secret-block-key.gpg \ | sudo cryptsetup luksOpen secret-block.raw secret-block gpg: AES256.CFB encrypted data gpg: encrypted with 1 passphrase $ sudo mount /dev/mapper/secret-block secret-fs $ echo "01234567890abcdefghijklmnopqrstuvwxyz" | sudo tee secret-fs/test.txt $ sudo umount secret-fs/ $ sudo cryptsetup luksClose /dev/mapper/secret-block
Securely Integrating with QEMU Secrets
secret” object type (v2.6.0)
raw or base64
plain text or encrypted
inline or file
RBD, iSCSI, CURL, LUKS, x509 cert
One global master secret via file
Per object secrets inline & encrypted
Secrets: Creation
Password inline as clear text (insecure)
-object secret,id=sec0,data=letmein
Password from a clear text file (secure)
-object secret,id=sec0,file=passwd.txt
Password from a base64 clear text file (secure)
-object secret,id=sec0,file=passwd.b64,format=base64
Password inline as aes256 cipher text (secure)
-object secret,id=sec0,file=master.aes -object secret,id=sec1,data=CIPHERTEXT,keyid=sec0,iv=NNNNNNNNNNNNNNN
Secrets: Usage
Disks with “password-secret” property
1 2 3 -drive driver=rbd,\ filename=rbd:pool/image:id =myname:\ auth_supported=cephx,password-secret=sec0
TLS cert with “passwordid” property
1 2 -object tls-creds-x509,dir =/etc/tls/qemu,\ id =tls0,endpoint=server,paswordid=sec0
QEMU with Plain LUKS File 1 2 3 4 5 6 7 8 9 10 11 $ qemu-img create -f luks --object secret,id =sec0,data=demo-password -o key-secret=sec0 demo.luks 64G Formatting 'demo.luks' , fmt =luks size=68719476736 key-secret=sec0 $ ls -ln demo.luks -rw-r--r-- 1 1000 1000 68721545216 2021-09-21 21:19 demo.luks $ stat demo.luks File: demo.luks Size: 68721545216 Blocks: 2048 IO Block: 4096 regular file Device: fe01h/65025d Inode: 403937219 Links: 1 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ sudo modprobe nbd max_part=16 nbds_max=16 $ sudo qemu-nbd --connect=/dev/nbd0 --object secret,id =sec0,data=demo-password --image-opts driver=luks,key-secret=sec0,file.driver=file,file.filename=demo.luks $ sudo fdisk /dev/nbd0 -l $ sudo mkfs.ext4 /dev/nbd0p1 $ du -ms demo.luks 323 demo.luks $ sudo mount /dev/nbd0p1 nbd $ echo "01234567890abcdefghijklmnopqrstuvwxyz" | sudo tee nbd/test.txt $ sudo umount nbd/ $ sudo qemu-nbd --disconnect /dev/nbd0 /dev/nbd0 disconnected $ grep "01234567890abcdefghijklmnopqrstuvwxyz" demo.luks
QEMU with QCOW2 Have LUKS Payload 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ qemu-img create -f qcow2 -o encrypt.format=luks,encrypt.key-secret=sec_luks --object secret,data=demo-password,id =sec_luks demo.qcow2 64G Formatting 'demo.qcow2' , fmt =qcow2 encrypt.format=luks encrypt.key-secret=sec_luks cluster_size=65536 extended_l2=off compression_type=zlib size=68719476736 lazy_refcounts=off refcount_bits=16 $ ls -ln demo.qcow2 -rw-r--r-- 1 1000 1000 2359296 2021-09-21 21:47 demo.qcow2 $ du -ks demo.qcow2 3328 demo.qcow2 $ stat demo.qcow2 File: demo.qcow2 Size: 2359296 Blocks: 6656 IO Block: 4096 regular file Device: fe01h/65025d Inode: 403937216 Links: 1 ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 $ sudo modprobe nbd max_part=16 nbds_max=16 $ sudo qemu-nbd --connect=/dev/nbd0 --object secret,id =sec0,data=demo-password --image-opts driver=qcow2,encrypt.key-secret=sec0,file.driver=file,file.filename=demo.qcow2 $ sudo fdisk /dev/nbd0 -l $ sudo mkfs.ext4 /dev/nbd0p1 $ du -ms demo.qcow2 283 demo.qcow2 $ sudo mount /dev/nbd0p1 nbd $ echo "01234567890abcdefghijklmnopqrstuvwxyz" | sudo tee nbd/test.txt $ sudo umount nbd/ $ sudo qemu-nbd --disconnect /dev/nbd0 /dev/nbd0 disconnected $ grep "01234567890abcdefghijklmnopqrstuvwxyz" demo.qcow2