Hacking

LUKS: Formatting the Partition

Dejan Lukan
January 16, 2013 by
Dejan Lukan

Introduction

When writing this tutorial, I've referenced the [2] Gentoo Linux guide and added some of my own observations and scripts. This guide should provide you with steps of how you can create an encrypted system partition on Linux, but it will also provide you with general observations about doing just that. If you read this article series, you'll gain some knowledge of what is needed to encrypt your system partition as well as the knowledge of the booting processes under Linux. We'll talk about LUKS, LVM, Grub, Gentoo and Initrd.

Earn two pentesting certifications at once!

Earn two pentesting certifications at once!

Enroll in one boot camp to earn both your Certified Ethical Hacker (CEH) and CompTIA PenTest+ certifications — backed with an Exam Pass Guarantee.

It's often the case that we may lose our laptops, or that they get stolen. In such cases, the only real protection against data leakage is disk encryption. We need to ensure that even if we lose the laptop or the laptop is stolen, that attackers won't be able to access our data stored on the hard drive.

We'll be using block device encryption, which protects the data on a block device by encrypting it. To access the device's decrypted contents, a user must provide a password or key as authentication.

There are a number of alternatives we could use when encrypting the whole system partitions, which can be seen here: [1]. The best known encryption software products are Truecrypt and LUKS. Truecrypt is well known for having good support for Windows users. If we want to encrypt our whole Windows system partition, we should choose Truecrypt for our encrypting software, since we can do it easily with just a few clicks. However, the Truecrypt support in Linux is lacking; we can't encrypt the whole system partition with Truecrypt, which is its main drawback. Thus, we have to turn to alternative encryption software, such as LUKS, which is most well-known encryption program on Linux.

Since this article talks about encrypting partitions on Linux, we'll be using the LUKS software to encrypt our system partition. In addition to LUKS, which does the encryption part, we'll also be using the LVM, which can manage disk drives with ease. When using LVM, we're not bound to our hardware partitions, but we're rather using software logical volumes (software partitions), which is very scalable.

LUKS (Linux Unified Key Setup) is a specification for block device encryption. It establishes an on-disk format for the data, as well as passphrase/key management policy. LUKS uses the kernel device mapper subsystem via the dm-crypt module, which handles encryption and decryption of the device's data. User-level operations, such as creating and accessing encrypted devices, are accomplished through the use of the cryptsetup utility.

When we try to access the encrypted device after installation, we'll be presented with a password prompt. After the correct password has been provided, the system will continue to boot normally. If we used different passwords for multiple encrypted devices, we may need to enter more than one password during the startup of the Linux system.

First things first: we need to have the needed ciphers to be present in the kernel. We can execute the command below to check whether the cipher is available on the system or not:

[bash]

# cat /proc/crypto | grep name

name : cbc(serpent)

name : cbc(serpent)

name : stdrng

name : lzo

name : arc4

name : aes

name : tnepres

name : serpent

name : twofish

name : blowfish

name : des3_ede

name : des

name : wp256

name : wp384

name : wp512

name : sha512

name : sha384

name : sha256

name : sha224

name : sha1

name : rmd160

name : md5

name : md4

name : twofish

name : aes

[/bash]

There are multiple ciphers available: aes, twofish, etc.

Note that when the encryption is in use, we need to turn off write caching for our disk. We need to do this because write caching stores I/O data on its own volatile memory before writing it to the disk. So in the event of a power failure, data loss and filesystem corruption might occur. If we're applying the encryption on laptop, we need to make sure to shutdown/suspend the system when it's low on battery.

We'll use the cryptsetup command to setup cryptographic volumes for dm-crypt (including LUKS). LUKS is a standard for hard disk encryption - it standardizes a partition header, as well as the format of the data.

Preparing the Disk

From now on, we'll assume we're already in a livecd or some other linux distribution and we have at least one partition, which will be prepared for the new system encrypted partition. In our case, we have partition /dev/sda1 available:

[plain]

Device Boot Start End Blocks Id System

/dev/sda1 63 78124094 39062016 83 Linux

[/plain]

It's also a good idea to check the hard drive for bad blocks:

[bash]
# badblocks -c 10240 -s -w -t random -v /dev/sda1

Checking for bad blocks in read-write mode

From block 0 to 39062015

Testing with random pattern: done

Reading and comparing: done

Pass completed, 0 bad blocks found

[/bash]

The above command can be explained as follows: test 10240 blocks at a time (-c 10240), show the progress of the scan (-s), use write-mode test, which writes some bytes on every block of the partition, then reading every block back and comparing the contents (-w), use random test pattern to be read and written to disk blocks (-t random) and use verbose mode (-v). All of this is done on our partition /dev/sda1.

Now let's fill the disk with random data using the /dev/urandom, which will make it impossible to know how much data has been written (when we start storing encrypted data on the disk). Therefore, breaking it becomes much harder.

[bash]

# dd if=/dev/urandom of=/dev/sda1

[/bash]

Create the partitioning scheme:

[plain]

/boot /dev/sda1

swap /dev/sda2

/ /dev/sda3

[/plain]

DM-Crypt works by transparently translating between a physical partition, which is encrypted, and a logical partition, which we can mount and use normally. The physical root partition will be /dev/sda3 and the logical unencrypted partition will be /dev/mapper/root.

We need to load a few modules. The ones we load depend on the cipher we plan to use.

[bash]

# modprobe dm-crypt

# modprobe dm-mod

# modprobe serpent

# modprobe sha256

# modprobe blowfish

# modprobe aes

[/bash]

Formatting the Device as LUKS Encrypted Device

We can initialize a LUKS partition and set up initialization key by passing luksFormat to the cryptsetup command. To create a mapping for a partition with cryptsetup using a password, we can execute the command below:

[bash]
# cryptsetup --verify-passphrase --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda3

WARNING!

========

This will overwrite data on /dev/sda3 irrevocably.

Are you sure? (Type uppercase yes): YES

Enter LUKS passphrase:

Verify passphrase:

[/bash]

The cryptsetup asked us if we are sure we want to encrypt the partition and we had to confirm by typing an uppercase YES into the command prompt. After that, we supplied the password, which is used to encrypt/decrypt the partition. We don't necessarily have to use a password to protect our partition, but we can use a keyfile or a gpg protected keyfile. The commands for both those cases can be seen below:

To create a mapping for a partition with cryptsetup using keyfile:

[bash]

# cryptsetup --verify-passphrase --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda3 rootkey

[/bash]

To create a mapping for a partition with cryptsetup using gpg protected keyfile:

[bash]

# gpg --quiet --decrypt rootkey.gpg | cryptsetup --verify-passphrase --cipher serpent-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda3

[/bash]

We can use any of the three options presented above, but using a password is the best option in my option, at least for laptop users. If you use any other option you'll have a more secure system (because the chosen password can be weak and easily bruteforacable, while a keyfile cannot be bruteforced in real time), but you're sacrifice simplicity.

After supplying the password or key, the device will be formatted for use. To verify if that is true, we can execute the command below, which will output 'Yes' if the partition has indeed been encrypted or 'No' if some error occurred:

[bash]

# cryptsetup isLuks /dev/sda3; if [[ $? == 0 ]]; then echo "Yes"; else echo "No"; fi

Yes

[/bash]

To see a summary of the information about our encrypted device we can execute the luksDump command as follows:

[bash]

# cryptsetup luksDump /dev/sda3

LUKS header information for /dev/sda3

Version: 1

Cipher name: serpent

Cipher mode: cbc-essiv:sha256

Hash spec: sha1

Payload offset: 2056

MK bits: 256

MK digest: 16 2d 07 4b a5 ec 9b 84 14 45 1c 1d ad a9 3a 43 dd 00 d6 65

MK salt: aa 28 fc 71 e8 51 dc 12 40 bd 70 83 00 51 27 da

ef 83 37 11 27 f4 80 5d 76 19 29 31 cc 8b 17 14

MK iterations: 47625

UUID: bc883c93-ad97-4cb0-a6b2-07e0c5e918d5

Key Slot 0: ENABLED

Iterations: 190775

Salt: f6 cb b8 66 e4 ad bf c5 14 7c 20 7a 20 93 75 aa

74 51 3d e3 10 23 18 11 c4 fc f3 54 e7 07 38 e9

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

[/bash]

We can see that there are 8 key slots that can be used with each LUKS encrypted device. Currently, only the key slot 0 is in use, because we only supplied a password. We can fill optional number of key slots and then use multiple techniques to decrypt the partition. We could also add a keyfile into key slot 1 and decrypt the partition with a keyfile stored on USB drive. If we forgot the USB key somewhere or if we lost it, we could still decrypt the partition with a password stored in key slot 0.

Opening LUKS Partition

To access the device's decrypted contents, mapping must be established using the kernel device-mapper. It's useful to choose a meaningful name for this mapping. LUKS provides a UUID (Universally Unique Identifier) for each device. To find a LUKS device's UUID, we can run the command below:

[bash]

# cryptsetup luksUUID /dev/sda3

bc883c93-ad97-4cb0-a6b2-07e0c5e918d5

[/bash]

To open a LUKS partition which uses passwords, we need to run the following command:

[bash]

# cryptsetup luksOpen /dev/sda3 <strong>system</strong>

[/bash]

To open a LUKS partition that uses a keyfile:

[bash]

# cryptsetup --key-file rootkey luksOpen /dev/sda3<strong> system</strong>

[/bash]

To open a LUKS partition which uses a gpg protected keyfile:

[bash]

# gpg --decrypt keyfile.gpg 2>/dev/null | cryptsetup luksOpen /dev/sda3 <strong>system</strong>

[/bash]

Upon completion the above command, there will be a mapping in /dev/mapper/system. From now on, every time we need to operate on our system partition /dev/sda3 we need to do so using /dev/mapper/system, which represents the decrypted block device.

To see some information about the mapped device, we can use:

[bash]

# dmsetup info system

Name: system

State: ACTIVE

Read Ahead: 3072

Tables present: LIVE

Open count: 0

Event number: 0

Major, minor: 253, 1

Number of targets: 1

UUID: CRYPT-LUKS1-bc883c93ad974cb0a6b207e0c5e918d5-system

[/bash]

Creating a FileSystem on a Mapped Device

We must use mapped device node /dev/mapper/system as any other block device. To create an ext3 filesystem on the mapped device, we can use the following command:

[bash]

# mkfs.ext3 /dev/mapper/system

[/bash]

To mount the filesystem on /mnt mountpoint, we can run the command below:

[bash]

# mount /dev/mapper/system /mnt

[/bash]

Conclusion

We've successfully encrypted the whole /dev/sda3 partition and created a mapping between /dev/sda3 and /dev/mapper/system. We also created an ext3 filesystem on the decrypted partition /dev/mapper/system and mounted it on the /mnt mountpoint. Now we can freely copy/move and delete files in the /mnt directory and when the partition is unmounted, all the contents of that partition are encrypted and safely stored. If we later want to mount the partition again, we must first open it with cryptsetup and provide a password for the system to be able to access the contents of the partition. This ensures that a password is needed whenever we try to access the partition's contents.

References:

[1]: Comparison of disk encryption software, Wikipedia, accessible at http://en.wikipedia.org/wiki/Comparison_of_disk_encryption_software.

What should you learn next?

What should you learn next?

From SOC Analyst to Secure Coder to Security Manager — our team of experts has 12 free training plans to help you hit your goals. Get your free copy now.

[2]: DM-Crypt with LUKS, accessible at http://en.gentoo-wiki.com/wiki/SECURITY_System_Encryption_DM-Crypt_with_LUKS#Choosing_a_hibernation_implementation_with_dm-crypt.

Dejan Lukan
Dejan Lukan

Dejan Lukan is a security researcher for InfoSec Institute and penetration tester from Slovenia. He is very interested in finding new bugs in real world software products with source code analysis, fuzzing and reverse engineering. He also has a great passion for developing his own simple scripts for security related problems and learning about new hacking techniques. He knows a great deal about programming languages, as he can write in couple of dozen of them. His passion is also Antivirus bypassing techniques, malware research and operating systems, mainly Linux, Windows and BSD. He also has his own blog available here: http://www.proteansec.com/.