Difference between revisions of "Dm-crypt/Device encryption"

From ArchWiki
Jump to: navigation, search
m (Encryption options for plain mode: remove needless attributes from wiki tables and/or use class="wikitable")
(Re-encrypting devices: rm done expansion template)
 
(153 intermediate revisions by 26 users not shown)
Line 1: Line 1:
 
{{Lowercase title}}
 
{{Lowercase title}}
[[Category:Security]]
+
[[Category:Encryption]]
 
[[Category:File systems]]
 
[[Category:File systems]]
 +
[[ja:Dm-crypt/デバイスの暗号化]]
 
Back to [[Dm-crypt]].
 
Back to [[Dm-crypt]].
  
Line 10: Line 11:
  
 
== Cryptsetup usage ==
 
== Cryptsetup usage ==
''Cryptsetup'' is the command line tool to interface with ''dm-crypt'' for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel '''d'''evice-'''m'''apper and the '''crypt'''ographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. See [[Disk_encryption#Block_device_encryption]] for further information.  
+
''Cryptsetup'' is the command line tool to interface with ''dm-crypt'' for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel '''d'''evice-'''m'''apper and the '''crypt'''ographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see [[Disk encryption#Block device encryption]].  
  
 
The tool is used as follows:  
 
The tool is used as follows:  
  # cryptsetup <OPTIONS> <action> <action-specific> <device> <dmname>
+
 
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at  
+
  # cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname>
 +
 
 +
It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at  
 +
 
 
  $ cryptsetup --help  
 
  $ cryptsetup --help  
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options {{ic|cryptsetup}} accepts can be found in the [http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=cryptsetup manpage].
+
 
Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is delicate, it is important to check ''dm-crypt'' performance for the individual system before setup:  
+
which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page.
 +
Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check ''dm-crypt'' performance for the individual parameters in advance:  
 +
 
 
  $ cryptsetup benchmark  
 
  $ cryptsetup benchmark  
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable (e.g. tenfold) higher throughput, these are probably the ones with hardware support in the CPU.
+
 
 +
can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.
  
 
{{Tip|You may want to practise encrypting a virtual hard drive in a [[:Category:Virtualization|virtual machine]] when learning.}}
 
{{Tip|You may want to practise encrypting a virtual hard drive in a [[:Category:Virtualization|virtual machine]] when learning.}}
  
 
=== Cryptsetup passphrases and keys ===
 
=== Cryptsetup passphrases and keys ===
An encrypted blockdevice is protected by a key. A key is either a:  
+
An encrypted blockdevice is protected by a key. A key is either:  
  
*Passphrase, see [[Disk_encryption#Choosing_a_strong_passphrase]]
+
* a passphrase: see [[Disk encryption#Choosing a strong passphrase]].
*Keyfile, see [[#Cryptsetup and keyfiles]]
+
* a keyfile, see [[#Keyfiles]].
  
Both key types have default maximum sizes: A passphrase can be up to 512 characters and a keyfile can have 8192kB.  
+
Both key types have default maximum sizes: passphrases can be up to 512 characters and keyfiles up to 8192kB.  
 
   
 
   
An important distinction of ''LUKS'' to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See [[Disk_encryption#Block_device_encryption]] for details.
+
An important distinction of ''LUKS'' to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See [[Disk encryption#Block device encryption]] for details.
  
 
== Encryption options with dm-crypt ==
 
== Encryption options with dm-crypt ==
Line 48: Line 55:
  
 
=== Encryption options for LUKS mode ===
 
=== Encryption options for LUKS mode ===
 +
 
The ''cryptsetup'' action to set up a new dm-crypt device in LUKS encryption mode is ''luksFormat''. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options.  
 
The ''cryptsetup'' action to set up a new dm-crypt device in LUKS encryption mode is ''luksFormat''. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options.  
  
As LUKS is the default encryption mode:
+
As LUKS is the default encryption mode,
  # cryptsetup -v luksFormat <device>
+
 
is all needed to perform it with default parameters ({{ic|-v}} optional). For comparison, we can specify the default options manually too:   
+
  # cryptsetup -v luksFormat ''device''
  # cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha1 --iter-time 1000 --use-urandom --verify-passphrase luksFormat <device>
+
 
 +
is all that is needed to create a new LUKS device with default parameters ({{ic|-v}} is optional). For comparison, we can specify the default options manually too:   
 +
 
 +
  # cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat ''device''
  
These options used are compared below in the left column, with another set in the right column:  
+
Defaults are compared with a cryptographically higher specification example in the table below, with accompanying comments:  
  
 
{| class="wikitable"
 
{| class="wikitable"
 
! scope="col" style="text-align:left" | Options
 
! scope="col" style="text-align:left" | Options
! scope="col" style="text-align:left" | Cryptsetup (1.6.2) defaults  
+
! scope="col" style="text-align:left" | Cryptsetup 1.7.0 defaults  
 
! scope="col" style="text-align:left" | Example
 
! scope="col" style="text-align:left" | Example
 
! scope="col" style="text-align:left" | Comment
 
! scope="col" style="text-align:left" | Comment
Line 66: Line 77:
 
| {{ic|aes-xts-plain64}}
 
| {{ic|aes-xts-plain64}}
 
| {{ic|aes-xts-plain64}}
 
| {{ic|aes-xts-plain64}}
| The example uses the same cipher as the default: the AES-[[Disk_Encryption#Ciphers_and_modes_of_operation|cipher]] with [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS]].
+
| [https://www.kernel.org/pub/linux/utils/cryptsetup/v1.6/v1.6.0-ReleaseNotes Release 1.6.0] changed the defaults to an AES [[Disk encryption#Ciphers_and_modes_of_operation|cipher]] in [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS]] mode (see item 5.16 [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects of the FAQ]). It is advised against using the previous default {{ic|--cipher aes-cbc-essiv}} because of its known [https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 issues] and practical [http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ attacks] against them.
 
|-
 
|-
 
! scope="row" style="text-align:right" | --key-size, -s
 
! scope="row" style="text-align:right" | --key-size, -s
 
| {{ic|256}}
 
| {{ic|256}}
 
| {{ic|512}}
 
| {{ic|512}}
| The default uses a 256 bit key-size. [[wikipedia:XEX-TCB-CTS#Issues_with_XTS|XTS splits the supplied key]] into fraternal twins. For an effective AES-256 the XTS key-size must be {{ic|512}}.
+
| By default a 256 bit key-size is used. Note however that [[wikipedia:Disk_encryption_theory#XEX-based_tweaked-codebook_mode_with_ciphertext_stealing_.28XTS.29|XTS splits the supplied key in half]], so to use AES-256 instead of AES-128 you have to set the XTS key-size to {{ic|512}}.
 
|-
 
|-
 
! scope="row" style="text-align:right" | --hash, -h
 
! scope="row" style="text-align:right" | --hash, -h
| {{ic|sha1}}
+
| {{ic|sha256}}
 
| {{ic|sha512}}
 
| {{ic|sha512}}
| Hash algorithm used for [[Disk_Encryption#Keys, keyfiles and passphrases|PBKDF2]]. Due to this processing, SHA1 is considered [http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/7093 adequate] as of January 2014.  
+
| Hash algorithm used for [[Disk_encryption#Cryptographic_metadata|key derivation]]. Release 1.7.0 changed defaults from {{ic|sha1}} to {{ic|sha256}} "''not for security reasons [but] mainly to prevent compatibility problems on hardened systems where SHA1 is already [being] phased out''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. The former default of {{ic|sha1}} can still be used for compatibility with older versions of ''cryptsetup'' since it is [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#5-security-aspects considered secure] (see item 5.20).  
 
|-
 
|-
 
! scope="row" style="text-align:right" | --iter-time, -i
 
! scope="row" style="text-align:right" | --iter-time, -i
| {{ic|1000}}
+
| {{ic|2000}}
 
| {{ic|5000}}
 
| {{ic|5000}}
| Number of milliseconds to spend with PBKDF2 passphrase processing. Using a hash stronger than sha1 results in less iterations if iter-time is not increased.  
+
| Number of milliseconds to spend with PBKDF2 passphrase processing. Release 1.7.0 changed defaults from {{ic|1000}} to {{ic|2000}} to "''try to keep PBKDF2 iteration count still high enough and also still acceptable for users.''"[https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes]. This option is only relevant for LUKS operations that set or change passphrases, such as ''luksFormat'' or ''luksAddKey''. Specifying 0 as parameter selects the compiled-in default..
 
|-
 
|-
! scope="row" style="text-align:right" | --use-random
+
! scope="row" style="text-align:right" | --use-{u,}random
| {{ic|--use-'''u'''random}}
+
| {{ic|--use-urandom}}
 
| {{ic|--use-random}}
 
| {{ic|--use-random}}
| [[Random number generation|/dev/urandom]] is used as randomness source for the (long-term) volume master key. Avoid generating an insecure master key if low on entropy. The last three options only affect the encryption of the master key and not the disk operations.  
+
| Selects which [[random number generator]] to use. Quoting the cryptsetup manual page: "In a low-entropy situation (e.g. in an embedded system), both  selections are problematic. Using /dev/urandom can lead to weak keys. Using /dev/random can block a long time, potentially forever, if not enough entropy can be harvested  by the kernel."
 
|-
 
|-
 
! scope="row" style="text-align:right" | --verify-passphrase, -y
 
! scope="row" style="text-align:right" | --verify-passphrase, -y
Line 94: Line 105:
 
|}
 
|}
  
The options used in the example column result in the following:
+
If you want to deep-dive into cryptographic features of LUKS, the [https://gitlab.com/cryptsetup/cryptsetup/wikis/Specification LUKS specification] (e.g. its appendices) is a resource.
# cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat <device>
+
{{Tip|It is anticipated that the LUKS header receives another major revision in due course. If you are interested in the plans, the developers' [https://mbroz.fedorapeople.org/talks/DevConf2016/devconf2016-luks2.pdf devconfcz2016] (pdf) presentation summarizes.}}
 
+
Please note that with release 1.6.0, the defaults have changed to an AES cipher in ''XTS'' mode. It is advised against using the previous default {{ic|--cipher aes-cbc-essiv}}, because of its known [https://en.wikipedia.org/wiki/Disk_encryption_theory#Cipher-block_chaining_.28CBC.29 issues] and practical [http://www.jakoblell.com/blog/2013/12/22/practical-malleability-attack-against-cbc-encrypted-luks-partitions/ attacks] against them.
+
  
 
=== Encryption options for plain mode ===
 
=== Encryption options for plain mode ===
Line 105: Line 114:
 
  # cryptsetup <options> open --type plain <device> <dmname>
 
  # cryptsetup <options> open --type plain <device> <dmname>
 
Executing it will prompt for a password, which should have very high entropy.  
 
Executing it will prompt for a password, which should have very high entropy.  
Below a comparison of default parameters with the example in [[Dm-crypt/Encrypting_an_entire_system#Plain dm-crypt]]
+
Below a comparison of default parameters with the example in [[Dm-crypt/Encrypting an entire system#Plain dm-crypt]]
  
 
{| class="wikitable"
 
{| class="wikitable"
! Option !! Cryptsetup defaults (1.6.2) !! Example !! Comment !!
+
! Option !! Cryptsetup 1.7.0 defaults !! Example !! Comment
 
|-
 
|-
| '''--hash''' || {{ic|ripemd160}} || {{ic|sha512}} || The hash is used to create the key from the passphrase or keyfile  
+
| '''--hash''' || {{ic|ripemd160}} || - || The hash is used to create the key from the passphrase; it is not used on a keyfile.
 
|-
 
|-
| '''--cipher'''|| {{ic|aes-cbc-essiv:sha256}}|| {{ic|twofish-xts-plain64}} || The cipher consists of three parts: cipher-chainmode-IV generator. Please see [[Disk_Encryption#Ciphers_and_modes_of_operation]] for an explanation of these settings, and the [https://code.google.com/p/cryptsetup/wiki/DMCrypt DMCrypt documentation] for some of the options available.   
+
| '''--cipher'''|| {{ic|aes-cbc-essiv:sha256}}|| {{ic|twofish-xts-plain64}} || The cipher consists of three parts: cipher-chainmode-IV generator. Please see [[Disk encryption#Ciphers and modes of operation]] for an explanation of these settings, and the [https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt DMCrypt documentation] for some of the options available.   
 
|-
 
|-
| '''--key-size'''||{{ic|256bits}}||{{ic|512}}||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc.  
+
| '''--key-size'''||{{ic|256}}||{{ic|512}}||The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc.  
 
|-
 
|-
 
| '''--offset'''||{{ic|0}}||{{ic|0}}||The offset from the beginning of the target disk from which to start the mapping
 
| '''--offset'''||{{ic|0}}||{{ic|0}}||The offset from the beginning of the target disk from which to start the mapping
 
|-
 
|-
| '''--key-file'''||default uses a passphrase||{{ic|/dev/sd''Z''}} (or e.g. /boot/keyfile.enc)||The device or file to be used as a key. See [[Dm-crypt/Device_Encryption#Cryptsetup_and_keyfiles|here]] for further details.
+
| '''--key-file'''||default uses a passphrase||{{ic|/dev/sd''Z''}} (or e.g. /boot/keyfile.enc)||The device or file to be used as a key. See [[#Keyfiles]] for further details.
 
|-
 
|-
| '''--keyfile-offset'''||{{ic|0}}||{{ic|0}}||Offset from the beginning of the file where the key starts (in bytes).
+
| '''--keyfile-offset'''||{{ic|0}}||{{ic|0}}||Offset from the beginning of the file where the key starts (in bytes). This option is supported from ''cryptsetup'' 1.6.7 onwards.  
 
|-
 
|-
| '''--keyfile-size'''||{{ic|8192kB}}||- (default applies)||Limits the bytes read from the key file.  
+
| '''--keyfile-size'''||{{ic|8192kB}}||- (default applies)||Limits the bytes read from the key file. This option is supported from ''cryptsetup'' 1.6.7 onwards.  
 
|}
 
|}
  
 
Using the device {{ic|/dev/sd''X''}}, the above right column example results in:
 
Using the device {{ic|/dev/sd''X''}}, the above right column example results in:
{{bc|<nowiki># cryptsetup --hash=sha512 --cipher=twofish-xts-plain64 --offset=0 --key-file=</nowiki>/dev/sd''Z'' <nowiki>--key-size=512 open --type=plain /dev/sdX enc</nowiki>}}
+
{{bc|<nowiki># cryptsetup --cipher=twofish-xts-plain64 --offset=0 --key-file=</nowiki>/dev/sd''Z'' <nowiki>--key-size=512 open --type=plain /dev/sdX enc</nowiki>}}
 
Unlike encrypting with LUKS, the above command must be executed ''in full'' whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.
 
Unlike encrypting with LUKS, the above command must be executed ''in full'' whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details.
 
We can now check that the mapping has been made:
 
We can now check that the mapping has been made:
Line 136: Line 145:
  
 
=== Encrypting devices with LUKS mode ===
 
=== Encrypting devices with LUKS mode ===
'''Formatting LUKS Partitions'''
+
==== Formatting LUKS partitions ====
  
 
In order to setup a partition as an encrypted LUKS partition execute:
 
In order to setup a partition as an encrypted LUKS partition execute:
{{hc|# cryptsetup -c <cipher> -y -s <key size> luksFormat /dev/<partition name>|
 
Enter passphrase: <password>
 
Verify passphrase: <password>}}
 
first to setup the encrypted master-key. Checking results can be done with:
 
# cryptsetup luksDump /dev/<drive>
 
  
This should be repeated for all partitions to be encrypted (except for {{ic|/boot}}). You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition.  
+
  # cryptsetup luksFormat ''device''
  
The following example will create an encrypted root partition using the AES cipher in XTS mode with an effective 256-bit encryption
+
You will then be prompted to enter a password and verify it.
{{bc|# cryptsetup -c aes-xts-plain -y -s 512 luksFormat /dev/sda3}}
+
  
'''Unlocking/Mapping LUKS Partitions with the Device Mapper'''
+
See [[#Encryption options for LUKS mode]] for command line options.
  
Once the LUKS partitions have been created it is time to unlock them.
+
You can check the results with:
  
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|/dev/<partition name>}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/<name>}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[Dm-crypt/Device_Encryption#Backup_and_restore|backup the cryptheader]] after finishing setup.
+
# cryptsetup luksDump ''device''
 +
 
 +
You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition. 
 +
 
 +
The following example will create an encrypted root partition on {{ic|/dev/sda1}} using the default AES cipher in XTS mode with an effective 256-bit encryption
 +
{{bc|# cryptsetup -s 512 luksFormat /dev/sda1}}
 +
 
 +
=====Using LUKS to format partitions with a keyfile=====
 +
 
 +
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:
 +
 
 +
# cryptsetup luksFormat ''device'' ''/path/to/mykeyfile''
 +
 
 +
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.
 +
 
 +
See [[#Keyfiles]] for instructions on how to generate and manage keyfiles.
 +
 
 +
====Unlocking/Mapping LUKS partitions with the device mapper ====
 +
 
 +
Once the LUKS partitions have been created, they can then be unlocked.
 +
 
 +
The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that {{ic|''device''}} is actually an encrypted device and should be addressed through LUKS using the {{ic|/dev/mapper/''dm_name''}} so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to [[Dm-crypt/Device encryption#Backup_and_restore|backup the cryptheader]] after finishing setup.
  
 
In order to open an encrypted LUKS partition execute:
 
In order to open an encrypted LUKS partition execute:
{{hc|# cryptsetup open --type luks /dev/<partition name> <device-mapper name>|
 
Enter any LUKS passphrase: <password>
 
key slot 0 unlocked.
 
Command successful.}}
 
  
Usually the device mapped name is descriptive of the function of the partition that is mapped, example:
+
# cryptsetup open --type luks ''device'' ''dm_name''
  
# cryptsetup open --type luks /dev/sda3 root
+
You will then be prompted for the password to unlock the partition. Usually the device mapped name is descriptive of the function of the partition that is mapped. For example the following unlocks a luks partition {{ic|/dev/sda1}} and maps it to device mapper named {{ic|cryptroot}}:
Once opened, the root partition device address would be {{ic|/dev/mapper/root}} instead of the partition (e.g. {{ic|/dev/sda3}}).
+
  
  # cryptsetup open --type luks /dev/sda3 lvmpool
+
  # cryptsetup open --type luks /dev/sda1 cryptroot
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/lvmpool}} instead of {{ic|/dev/sda3}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.
+
  
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem 
+
Once opened, the root partition device address would be {{ic|/dev/mapper/cryptroot}} instead of the partition (e.g. {{ic|/dev/sda1}}).  
# mkfs -t ext4 /dev/mapper/root
+
and mount it
+
# mount -t ext4 /dev/mapper/root /mnt
+
The mounted blockdevice can then be used like any other partition. Once done, closing the device locks it again
+
# umount /mnt
+
# cryptsetup close root
+
  
====Using LUKS to Format Partitions with a Keyfile====
+
For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like {{ic|/dev/mapper/cryptroot}} instead of {{ic|/dev/sda1}}. LVM will then give additional names to all logical volumes created, e.g. {{ic|/dev/mapper/lvmpool-root}} and {{ic|/dev/mapper/lvmpool-swap}}.
  
When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:
+
In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to [[File_systems#Formatting|create a filesystem]]. For example:
  
  # cryptsetup -c <desired cipher> -s <key size> luksFormat /dev/<volume to encrypt> '''/path/to/mykeyfile'''
+
  # mkfs -t ext4 /dev/mapper/cryptroot
  
This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.
+
The device {{ic|/dev/mapper/cryptroot}} can then be [[mount]]ed like any other partition.
 +
 
 +
To close the luks container, unmount the partition and do:
  
See [[#Cryptsetup and keyfiles]] for instructions on how to generate and manage keyfiles.
+
# cryptsetup close cryptroot
  
 
=== Encrypting devices with plain mode ===
 
=== Encrypting devices with plain mode ===
  
The creation and subsequent access of a ''dm-crypt'' plain mode encryption both require not more than using the ''cryptsetup'' {{ic|open}} action with correct [[Dm-crypt/Device_Encryption#Encryption_options_for_plain_mode|parameters]]. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage.  
+
The creation and subsequent access of a ''dm-crypt'' plain mode encryption both require not more than using the ''cryptsetup'' {{ic|open}} action with correct [[Dm-crypt/Device encryption#Encryption_options_for_plain_mode|parameters]]. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage.  
  
 
A first mapper is created with ''cryptsetup's'' plain-mode defaults, as described in the table's left column above   
 
A first mapper is created with ''cryptsetup's'' plain-mode defaults, as described in the table's left column above   
Line 245: Line 259:
 
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.
 
As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.
  
== Opening and closing an encrypted partition with cryptsetup ==
 
 
== Cryptsetup actions specific for LUKS ==
 
== Cryptsetup actions specific for LUKS ==
 
=== Key management ===
 
=== Key management ===
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again. Passphrases or key-files to a key may be changed.  
+
It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again.  
  
 
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing  
 
Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing  
Line 293: Line 306:
 
==== Removing LUKS keys ====
 
==== Removing LUKS keys ====
  
There are two different actions to remove keys from the header:  
+
There are three different actions to remove keys from the header:  
*{{ic|luksRemoveKey}} is used to remove a key by specifying its passphrase/key-file and
+
*{{ic|luksRemoveKey}} is used to remove a key by specifying its passphrase/key-file
 
*{{ic|luksKillSlot}} may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it.  
 
*{{ic|luksKillSlot}} may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it.  
 
+
*{{ic|luksErase}} is used to quickly remove '''all''' active keys.
{{warning|Both above actions can be used to irrevocably delete the last active key for an encrypted device!}}  
+
{{warning|
 +
*All above actions can be used to irrevocably delete the last active key for an encrypted device!  
 +
*The {{ic|luksErase}} command was added in version 1.6.4 to quickly nuke access to the device. This action '''will not''' prompt for a valid passphrase! It will not [[Dm-crypt/Drive_preparation#Wipe_LUKS_header|wipe the LUKS header]], but all keyslots at once and you will, therefore, not be able to regain access unless you have a valid backup of the LUKS header.}}  
  
 
For above warning it is good to know the key we want to '''keep''' is valid. An easy check is to unlock the device with the {{ic|-v}} option, which will specify which slot it occupies:   
 
For above warning it is good to know the key we want to '''keep''' is valid. An easy check is to unlock the device with the {{ic|-v}} option, which will specify which slot it occupies:   
Line 305: Line 320:
 
Command successful.}}
 
Command successful.}}
  
Now we remove can remove the key added above like:  
+
Now we can remove the key added in the previous subsection using its passphrase:  
 
  # cryptsetup luksRemoveKey /dev/<device>
 
  # cryptsetup luksRemoveKey /dev/<device>
 
  Enter LUKS passphrase to be deleted:  
 
  Enter LUKS passphrase to be deleted:  
Line 320: Line 335:
  
 
=== Backup and restore ===
 
=== Backup and restore ===
If the header of your encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much as a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. A damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table.
+
If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much of a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. Damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table. Therefore, having a backup of the header and storing it on another disk might be a good idea.
  
Therefore, having a backup of the headers and storing them on another disk might be a good idea.
+
{{Note|If the LUKS-encrypted  partitions' master passphrase becomes compromised, you must revoke it on ''every'' copy of the cryptheader, even those you have backed up. Otherwise, a copy of the backed-up cryptheader that uses the compromised passphrase can be used to decrypt the associated partition. See [https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions#6-backup-and-data-recovery LUKS FAQ] for further details.}}
 
+
'''Attention:''' Many people recommend NOT backing up the cryptheader, but even so it's a single point of failure!
+
In short, the problem is that LUKS is not aware of the duplicated cryptheader, which contains the master key which is used to encrypt all files on your partition. Of course this master key is encrypted with your passphrases or keyfiles.
+
But if one of those gets compromised and you want to revoke it you have to do this on all copies of the cryptheader!
+
I.e. if someone has got your cryptheader and one of your keys he can decrypt the master key and access all your data.
+
Of course the same is true for all backups you create of your partions.
+
So you decide if you are one of those paranoids brave enough to go without a backup for the sake of security or not.
+
See also the [http://code.google.com/p/cryptsetup/wiki/FrequentlyAskedQuestions#6._Backup_and_Data_Recovery| LUKS FAQ] for further details on this.
+
  
 
==== Backup using cryptsetup ====
 
==== Backup using cryptsetup ====
Line 336: Line 343:
 
  # cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img
 
  # cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img
 
where <device> is the partition containing the LUKS volume.
 
where <device> is the partition containing the LUKS volume.
 
{{Note|Using {{ic|-}} as header backup file writes to a file named {{ic|-}}.}}
 
  
 
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}
 
{{Tip|You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.}}
Line 348: Line 353:
 
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}
 
{{Warning|Tmpfs can swap to harddisk if low on memory so it is not recommended here.}}
  
===== Backup manually =====
+
==== Restore using cryptsetup ====
First you have to find out the payload offset of the crypted partition:
+
 
 +
{{Warning|Restoring the wrong header or restoring to an unencrypted partition will cause data loss! The action can not perform a check whether the header is actually the ''correct'' one for that particular device.}}
 +
 
 +
In order to evade restoring a wrong header, you can ensure it does work by using it as a remote {{ic|--header}} first:
 +
 
 +
# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test
 +
Key slot 0 unlocked.
 +
Command successful.
 +
# mount /dev/mapper/test /mnt/test && ls /mnt/test
 +
# umount /mnt/test
 +
# cryptsetup close test
 +
 
 +
Now that the check succeeded, the restore may be performed:
 +
# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img
 +
 
 +
Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.
 +
 
 +
==== Manual backup and restore ====
 +
The header always resides at the beginning of the device and a backup can be performed without access to ''cryptsetup'' as well. First you have to find out the payload offset of the crypted partition:
 
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|
 
{{hc|# cryptsetup luksDump /dev/<device> <nowiki>|</nowiki> grep "Payload offset"|
 
  Payload offset: 4040}}
 
  Payload offset: 4040}}
Line 359: Line 382:
 
and store it safely.
 
and store it safely.
  
==== Restore using cryptsetup ====
+
A restore can then be performed using the same values as when backing up:
Be careful before restore: make sure that to choose the right partition (again replace sdaX with the corresponding partition).
+
  # dd if=./<file>.img of=/dev/<device> bs=512 count=4040
Restoring the wrong header or restoring to an unencrypted partition will cause data loss.
+
  # cryptsetup luksHeaderRestore /dev/sdaX --header-backup-file ./backup.img
+
  
'''Note:''' All the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing this command.
+
=== Re-encrypting devices ===
  
===== Restory manually =====
+
The {{Pkg|cryptsetup}} package features the ''cryptsetup-reencrypt'' tool. It can be used to convert an existing unencrypted filesystem to a LUKS encrypted one (option {{ic|--new}}) and permanently remove LUKS encryption ({{ic|--decrypt}}) from a device. As its name suggests it can also be used to re-encrypt an existing LUKS encrypted device, though, re-encryption is not possible for a detached LUKS header or other encryption modes (e.g. plain-mode). For re-encryption it is possible to change the [[#Encryption options for LUKS mode]]. ''cryptsetup-reencrypt'' actions can be performed to unmounted devices only.  See {{ic|man cryptsetup-reencrypt}} for more information.  
Using the same values as when backing up:
+
# dd if=./backup.img of=/dev/sdX bs=512 count=4040
+
  
== Cryptsetup and keyfiles ==
+
One application of re-encryption may be to secure the data again after a passphrase or [[#Keyfiles|keyfile]] has been compromised ''and'' one cannot be certain that no copy of the LUKS header has been obtained. For example, if only a passphrase has been shoulder-surfed but no physical/logical access to the device happened, it would be enough to change the respective passphrase/key only ([[#Key management]]).
  
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [[Dm-crypt/Specialties#Using_GPG_or_OpenSSL_Encrypted_Keyfiles|Using GPG or OpenSSL Encrypted Keyfiles]] for details, but please still read this section.}}
+
{{Warning|Always make sure a '''reliable backup''' is available and double-check options you specify before using the tool!}}
  
'''What is a Keyfile?'''
+
The following shows an example to encrypt an unencrypted filesystem partition and a re-encryption of an existing LUKS device.
 +
 +
==== Encrypt an unencrypted filesystem ====
  
A keyfile is any file in which the data contained within it is used as the passphrase to unlock an encrypted volume.
+
A LUKS encryption header is always stored at the beginning of the device. Since an existing filesystem will usually be allocated all partition sectors, the first step is to shrink it to make space for the LUKS header.  
Therefore if these files are lost or changed, decrypting the volume will no longer be possible.
+
  
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}
+
The [[#Encryption_options_for_LUKS_mode|default]] LUKS header encryption cipher requires {{ic|4096}} 512-byte sectors. We already checked space and keep it simple by shrinking the existing {{ic|ext4}} filesystem on {{ic|/dev/sdaX}} to its current possible minimum:
  
'''Why use a Keyfile?'''
+
{{bc|# umount /mnt
 +
# e2fsck -f /dev/sdaX
 +
e2fsck 1.43-WIP (18-May-2015)
 +
Pass 1: Checking inodes, blocks, and sizes
 +
...
 +
/dev/sda6: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks
 +
# resize2fs -M /dev/sdaX
 +
resize2fs 1.43-WIP (18-May-2015)
 +
Resizing the filesystem on /dev/sdaX to 26347 (4k) blocks.
 +
The filesystem on /dev/sdaX is now 26347 (4k) blocks long.}}
  
There are many kinds of keyfile. Each type of keyfile used has benefits and disadvantages summarized below:
+
Now we encrypt it, using the default cipher we do not have to specify it explicitly. Note there is no option (yet) to double-check the passphrase before encryption starts, be careful not to mistype:  
  
:'''keyfile.passphrase:'''
+
{{hc|# cryptsetup-reencrypt /dev/sdaX --new  --reduce-device-size 4096S|
::this is my passphrase I would have typed during boot but I have placed it in a file instead
+
WARNING: this is experimental code, it can completely break your data.
 +
Enter new passphrase:  
 +
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed  37,6 MiB/s}}
  
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.
+
After it finished, the encryption was performed to the full partition, i.e. not only the space the filesystem was shrunk to ({{ic|sdaX}} has {{ic|2.6GiB}} and the CPU used in the example has no hardware AES instructions). As a final step we extend the filesystem of the now encrypted device again to occupy available space:
  
:'''keyfile.randomtext:'''
+
{{bc|# cryptsetup open /dev/sdaX recrypt
::fjqweifj830149-57 819y4my1- 38t1934yt8-91m 34co3;t8y;9p3y-
+
Enter passphrase for /dev/sdaX:  
 +
...
 +
# resize2fs /dev/mapper/recrypt
 +
resize2fs 1.43-WIP (18-May-2015)
 +
Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks.
 +
The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.
 +
# mount /dev/mapper/recrypt /mnt}}
  
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.
+
and are done.
  
:'''keyfile.binary:'''
+
==== Re-encrypting an existing LUKS partition ====
::where any binary file, images, text, video could be chosen as the keyfile
+
  
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.
+
In this example an existing LUKS device is re-encrypted.  
  
'''Creating a Keyfile with Random Characters'''
+
{{Warning|Double-check you specify encryption options for ''cryptsetup-reencrypt'' correctly and ''never'' re-encrypt without a '''reliable backup'''! As of September 2015 the tool '''does''' accept invalid options and damage the LUKS header, if not used correctly!}}
  
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes.
+
In order to re-encrypt a device with its existing encryption options, they do not need to be specified. A simple:
  
# dd if=/dev/urandom of=mykeyfile bs=512 count=4
+
{{hc|# cryptsetup-reencrypt /dev/sdaX|
 +
WARNING: this is experimental code, it can completely break your data.
 +
Enter passphrase for key slot 0:
 +
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed  36,5 MiB/s}}
  
The usage of {{ic|dd}} is similar to initially wiping the volume with random data prior to encryption.  
+
performs it.  
  
=== Storing the Key File ===
+
A possible usecase is to re-encrypt LUKS devices which have non-current encryption options. Apart from above warning on specifying options correctly, the ability to change the LUKS header may also be limited by its size. For example, if the device was initially encrypted using a CBC mode cipher and 128 bit key-size, the LUKS header will be half the size of above mentioned {{ic|4096}} sectors:
{{Expansion|The default method to store a keyfile and reference it via crypttab should be added.}}  
+
{{hc|# cryptsetup luksDump /dev/sdaX <nowiki>|</nowiki>grep -e "mode" -e "Payload" -e "MK bits"|
==== External Storage on a USB Drive ====
+
Cipher mode:  cbc-essiv:sha256
 +
Payload offset: '''2048'''
 +
MK bits:      128}}
 +
While it is possible to upgrade the encryption of such a device, it is currently only feasible in two steps. First, re-encrypting with the same encryption options, but using the {{ic|--reduce-device-size}} option to make further space for the larger LUKS header. Second, re-encypt the whole device again with the desired cipher. For this reason and the fact that a backup should be created in any case, creating a new, fresh encrypted device to restore into is always the faster option.
  
=====Preparation for Persistent block device naming=====
+
== Keyfiles ==
  
For reading the file from an external storage device it is very convenient to access it through udev's [[Persistent block device naming]] features and not by ordinary device nodes like {{ic|/dev/sdb1}} whose naming depends on the order in which devices are plugged in. So in order to assure that the {{ic|encrypt}} HOOK in the initcpio finds your keyfile, you must use a permanent device name.  
+
{{Note|This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see [[Dm-crypt/Specialties#Using_GPG_or_OpenSSL_Encrypted_Keyfiles|Using GPG or OpenSSL Encrypted Keyfiles]] for details, but please still read this section.}}
  
=====Persistent symlinks=====
+
'''What is a keyfile?'''
  
{{Merge|Persistent block device naming|Anything not specific to storing LUKS keyfiles should get merged there.}}
+
A keyfile is a file whose data is used as the passphrase to unlock an encrypted volume.
 +
That means if such a file is lost or changed, decrypting the volume may no longer be possible.
  
A quick method (as opposed to setting up a [[udev]] rule) for doing so involves referencing the right partition by its UUID, id (based on hardware info and serial number) or filesystem label.
+
{{Tip|Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.}}
  
Plug the device in and print every file name under /dev/disk:
+
'''Why use a keyfile?'''
  
{{hc|#ls -lR /dev/disk/|
+
There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:
/dev/disk/:
+
total 0
+
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-id
+
drwxr-xr-x 2 root root  60 Feb 12 10:11 by-label
+
drwxr-xr-x 2 root root 100 Feb 12 10:11 by-path
+
drwxr-xr-x 2 root root 180 Feb 12 10:11 by-uuid
+
  
/dev/disk/by-id:
+
=== Types of keyfiles ===
total 0
+
==== passphrase ====
lrwxrwxrwx 1 root root  9 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0 -> ../../sdb
+
lrwxrwxrwx 1 root root 10 Feb 12 10:11 usb-Generic_STORAGE_DEVICE_000000014583-0:0-part1 -> ../../sdb1
+
  
/dev/disk/by-label:
+
This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.
total 0
+
lrwxrwxrwx 1 root root 10 Feb 12 10:11 Keys -> ../../sdb1
+
  
/dev/disk/by-path:
+
Example: 1234
total 0
+
lrwxrwxrwx 1 root root  9 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0 -> ../../sdb
+
lrwxrwxrwx 1 root root 10 Feb 12 10:11 pci-0000:00:1d.7-usb-0:1:1.0-scsi-0:0:0:0-part1 -> ../../sdb1
+
  
/dev/disk/by-uuid:
+
==== randomtext ====
total 0
+
lrwxrwxrwx 1 root root 10 Feb 12 10:11 baa07781-2a10-43a7-b876-c1715aba9d54 -> ../../sdb1}}
+
  
'''UUID'''
+
This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.
  
Using the filesystem UUID for persistent block device naming is considered very reliable. Filesystem UUIDs are stored in the filesystem itself, meaning that the UUID will be the same if you plug it into any other computer, and that a dd backup of it will always have the same UUID since dd does a bitwise copy.
+
Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-
  
The right device node for what is now {{ic|/dev/sdb1}} will always get symlinked by {{ic|/dev/disk/by-uuid/baa07781-2a10-43a7-b876-c1715aba9d54}}. Symlinks can be used in a bootloader "cryptkey" kernel option or anywhere else.
+
==== binary ====
  
For legacy filesystems like FAT the UUID will be much shorter but collision is still unlikely to happen if not mounting many different FAT filesystems at once.
+
This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.
  
'''Label'''
+
Example: images, text, video, ...
  
In the following example a FAT partition is labeled as "Keys" and will always get symlinked by {{ic|/dev/disk/by-label/Keys}}:
+
=== Creating a keyfile with random characters ===
  
#mkdosfs -n >volume-name< /dev/sdb1
+
==== Storing the keyfile on a filesystem ====
  
{{hc|#blkid -o list|
+
A keyfile can be of arbitrary content and size.
device    fs_type label    mount point    UUID
+
<nowiki>-------------------------------------------------------</nowiki>
+
/dev/sdb1  vfat    Keys    (not mounted)  221E-09C0}}
+
  
=====Persistent udev rule=====
+
Here {{ic|dd}} is used to generate a keyfile of 2048 random bytes, storing it in the file {{ic|/etc/mykeyfile}}:
Optionally you may choose to set up your flash drive with a [[udev]] rule. There is some documentation in the Arch wiki about that already; if you want more in-depth, structural info, read [http://reactivated.net/writing_udev_rules.html this guide]. Here is quickly how it goes.
+
  
Get the serial number from your USB flash drive:
+
  # dd bs=512 count=4 if=/dev/urandom of=/etc/mykeyfile iflag=fullblock
  lsusb -v | grep -A 5 Vendor
+
  
Create a udev rule for it by adding the following to a file in {{ic|/etc/udev/rules.d/}}, such as {{ic|8-usbstick.rules}}:
+
If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:
KERNEL=="sd*", ATTRS{serial}=="$SERIAL", SYMLINK+="$SYMLINK%n"
+
  
Replace {{ic|$SYMLINK}} and {{ic|$SERIAL}} with their respective values. {{ic|%n}} will expand to the partition (just like sda is subdivided into sda1, sda2, ...). You do not need to go with the 'serial' attribute. If you have a custom rule of your own, you can put it in as well (e.g. using the vendor name).
+
# dd bs=512 count=4 if=/dev/urandom of=/media/usbstick/mykeyfile iflag=fullblock
  
Rescan your sysfs:
+
===== Securely overwriting stored keyfiles =====
udevadm trigger
+
Now check the contents of {{ic|/dev}}:
+
ls /dev
+
It should show your device with your desired name.
+
  
==== Generating the keyfile ====
+
If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like
Optionally you can mount a tmpfs for storing the temporary keyfile.
+
# mkdir ./mytmpfs
+
# mount tmpfs ./mytmpfs -t tmpfs -o size=32m
+
# cd ./mytmpfs
+
The advantage is that it resides in RAM and not on a physical disk, so after unmounting your keyfile is securly gone.
+
So copy your keyfile to some place you consider as secure before unmounting.
+
If you are planning to store the keyfile as a plain file on your USB device, you can also simply execute the following command in the corresponding directory, e.g. {{ic|/media/sdb1}}
+
  
The keyfile can be of arbitrary content and size. We will generate a random temporary keyfile of 2048 bytes:
+
  # shred --remove --zero mykeyfile
  # dd if=/dev/urandom of=secretkey bs=512 count=4
+
  
If you stored your temporary keyfile on a physical storage device, remember to not just (re)move the keyfile later on, but use something like
 
cp secretkey /destination/path
 
shred --remove --zero secretkey
 
 
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.
 
to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to [[Securely wipe disk|wipe the entire device]] or at least the keyfiles partition.
  
Add a keyslot for the temporary keyfile to the LUKS header:
+
==== Storing the keyfile in tmpfs ====
{{hc|# cryptsetup luksAddKey /dev/sda2 secretkey|
+
 
 +
Alternatively, you can mount a tmpfs for storing the keyfile temporarily:
 +
 
 +
# mkdir mytmpfs
 +
# mount tmpfs mytmpfs -t tmpfs -o size=32m
 +
# cd mytmpfs
 +
 
 +
The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.
 +
 
 +
=== Configuring LUKS to make use of the keyfile ===
 +
 
 +
Add a keyslot for the keyfile to the LUKS header:
 +
 
 +
{{hc|# cryptsetup luksAddKey /dev/sda2 /etc/mykeyfile|
 
Enter any LUKS passphrase:
 
Enter any LUKS passphrase:
 
key slot 0 unlocked.
 
key slot 0 unlocked.
 
Command successful.}}
 
Command successful.}}
  
==== Storing the keyfile ====
+
=== Unlocking a secondary partition at boot ===
The following uses an USB-stick to store the key file and modifies the {{ic|initramfs}} to load and use it on boot to unlock the root partition.
+
  
==== Configuration of initcpio ====
+
If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via [[Dm-crypt/System configuration#crypttab|crypttab]]. Following on from the first example above
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system and one for the codepage. Further if you created a udev rule, you should tell {{ic|mkinitcpio}} about it:
+
{{hc|/etc/crypttab|home    /dev/sda2    /etc/mykeyfile}}
  MODULES="ata_generic ata_piix nls_cp437 vfat"
+
is all needed for unlocking, and
FILES="/etc/udev/rules.d/8-usbstick.rules"
+
{{hc|/etc/fstab|/dev/mapper/home        /home  ext4        defaults        0      2}} for mounting the LUKS blockdevice with the generated keyfile.
In this example it is assumed that you use a FAT formatted USB drive. Replace those module names if you use another file system on your USB stick (e.g. ext2) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here.
+
{{Tip|If you prefer to use a {{ic|--plain}} mode blockdevice, the encryption options necessary to unlock it are specified in {{ic|/etc/crypttab}}. Take care to apply the systemd workaround mentioned in [[Dm-crypt/System configuration#crypttab|crypttab]] in this case.}}
 +
 
 +
=== Unlocking the root partition at boot ===
 +
 
 +
This is simply a matter of configuring [[mkinitcpio]] to include the necessary modules or files and configuring the [[Dm-crypt/System_configuration#cryptkey|cryptkey]] [[Kernel_parameters|kernel parameter]] to know where to find the keyfile.
 +
 
 +
Two cases will be covered:
 +
 
 +
# Using a keyfile stored on an external media (here a USB stick)
 +
# Using a keyfile embedded in the initramfs
 +
 
 +
==== With a keyfile stored on an external media ====
 +
 
 +
===== Configuring mkinitcpio =====
 +
 
 +
You have to add two extra modules in your {{ic|/etc/mkinitcpio.conf}}, one for the drive's file system ({{ic|vfat}} module in the example below) and one for the codepage ({{ic|nls_cp437}} module) :
 +
  MODULES="nls_cp437 vfat"
 +
 
 +
In this example it is assumed that you use a FAT formatted USB drive ({{ic|vfat}} module). Replace those module names if you use another file system on your USB stick (e.g. {{ic|ext2}}) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need {{ic|nls_iso8859-1}} module for {{ic|iso8859-1}} codepage.
  
 
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.
 
If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the {{ic|keymap}} hook before {{ic|encrypt}}.
  
Generate a new image (maybe you should backup a copy of your old {{ic|/boot/initramfs-linux.img}} first):
+
Generate a new initramfs image:
 +
 
 
  # mkinitcpio -p linux
 
  # mkinitcpio -p linux
  
==== Storing the key as a plain (visible) file ====
+
===== Configuring the kernel parameters =====
Be sure to choose a plain name for your key &ndash; a bit of 'security through obscurity' is always nice ;-). Avoid using dotfiles (hidden files) &ndash; the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.
+
 
 +
Add the following options to the [[kernel parameters]]:
 +
 
 +
cryptdevice=/dev/''<partition1>'':root cryptkey=/dev/''<partition2>'':<fstype>:<path>
 +
 
 +
For example:
 +
 
 +
cryptdevice=/dev/sda3:root cryptkey=/dev/sdb1:vfat:/keys/secretkey
 +
 
 +
Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the {{ic|encrypt}} hook will fail to find the keyfile during the boot process.
 +
 
 +
The naming of device nodes like {{ic|/dev/sdb1}} is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's [[persistent block device naming]] instead. To assure that the {{ic|encrypt}} hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article [[persistent block device naming]].
 +
 
 +
==== With a keyfile embedded in the initramfs ====
 +
 
 +
{{Warning|Use an embedded keyfile '''only''' if you have some form of authentication mechanism beforehand that protects the keyfile sufficiently. Otherwise auto-decryption will occur, defeating completely the purpose of block device encryption.}}
 +
 
 +
This method allows to use a specially named keyfile that will be embedded in the [[initramfs]] and picked up by the {{ic|encrypt}} [[Mkinitcpio#HOOKS|hook]] to unlock the root filesystem ({{ic|cryptdevice}}) automatically. It may be useful to apply when using the [[GRUB#Boot partition|GRUB early cryptodisk]] feature, in order to avoid entering two passphrases during boot.
 +
 
 +
The {{ic|encrypt}} hook lets the user specify a keyfile with the {{ic|cryptkey}} kernel parameter: in the case of initramfs, the syntax is {{ic|rootfs:''path''}}, see [[Dm-crypt/System configuration#cryptkey]]. Besides, the code defaults to use {{ic|/crypto_keyfile.bin}}, and if the initramfs contains a valid key with this name, decryption will occur automatically without the need to configure the {{ic|cryptkey}} parameter.
 +
 
 +
[[#Creating_a_keyfile_with_random_characters|Generate the keyfile]], give it suitable permissions and [[#Adding_LUKS_keys|add it as a LUKS key]]:
 +
 
 +
# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
 +
# chmod 000 /crypto_keyfile.bin
 +
# chmod 600 /boot/initramfs-linux*
 +
# cryptsetup luksAddKey /dev/sdX# /crypto_keyfile.bin
 +
 
 +
{{Warning|When initramfs' permissions are set to 644 (by default), then all users will be able to dump the keyfile. Make sure the permissions are still 600 if you install a new kernel.}}
 +
 
 +
Include the key in [[Mkinitcpio#BINARIES_and_FILES|mkinitcpio FILES array]]:
 +
 
 +
{{hc|/etc/mkinitcpio.conf|2=FILES="/crypto_keyfile.bin"}}
 +
 
 +
Finally [[Mkinitcpio#Image_creation_and_activation|Regenerate your initramfs]].
  
You have to add {{ic|1=cryptdevice=/dev/sda3:root cryptkey=/dev/usbstick:vfat:/secretkey}} to your [[kernel parameters]]. This assumes {{ic|/dev/usbstick}} is the FAT partition of your choice. Replace it with {{ic|/dev/disk/by-...}} or whatever your device is.
+
On the next reboot you should only have to enter your container decryption passphrase once.
  
That is all, reboot and have fun!
+
([http://www.pavelkogan.com/2014/05/23/luks-full-disk-encryption/#bonus-login-once source])

Latest revision as of 19:47, 22 July 2016

Back to Dm-crypt.

This section covers how to manually utilize dm-crypt from the command line to encrypt a system.

Preparation

Before using cryptsetup, always make sure the dm-crypt kernel module is loaded.

Cryptsetup usage

Cryptsetup is the command line tool to interface with dm-crypt for creating, accessing and managing encrypted devices. The tool was later expanded to support different encryption types that rely on the Linux kernel device-mapper and the cryptographic modules. The most notable expansion was for the Linux Unified Key Setup (LUKS) extension, which stores all of the needed setup information for dm-crypt on the disk itself and abstracts partition and key management in an attempt to improve ease of use. Devices accessed via the device-mapper are called blockdevices. For further information see Disk encryption#Block device encryption.

The tool is used as follows:

# cryptsetup <OPTIONS> <action> <action-specific-options> <device> <dmname>

It has compiled-in defaults for the options and the encryption mode, which will be used if no others are specified on the command line. Have a look at

$ cryptsetup --help 

which lists options, actions and the default parameters for the encryption modes in that order. A full list of options can be found on the man page. Since different parameters are required or optional, depending on encryption mode and action, the following sections point out differences further. Blockdevice encryption is fast, but speed matters a lot too. Since changing an encryption cipher of a blockdevice after setup is difficult, it is important to check dm-crypt performance for the individual parameters in advance:

$ cryptsetup benchmark 

can give guidance on deciding for an algorithm and key-size prior to installation. If certain AES ciphers excel with a considerable higher throughput, these are probably the ones with hardware support in the CPU.

Tip: You may want to practise encrypting a virtual hard drive in a virtual machine when learning.

Cryptsetup passphrases and keys

An encrypted blockdevice is protected by a key. A key is either:

Both key types have default maximum sizes: passphrases can be up to 512 characters and keyfiles up to 8192kB.

An important distinction of LUKS to note at this point is that the key is used to unlock the master-key of a LUKS-encrypted device and can be changed with root access. Other encryption modes do not support changing the key after setup, because they do not employ a master-key for the encryption. See Disk encryption#Block device encryption for details.

Encryption options with dm-crypt

Cryptsetup supports different encryption operating modes to use with dm-crypt. The most common (and default) is

  • --type LUKS

The other ones are

  • --type plain for using dm-crypt plain mode,
  • --type loopaes for a loopaes legacy mode, and
  • --type tcrypt for a Truecrypt compatibility mode.

The basic cryptographic options for encryption cipher and hashes available can be used for all modes and rely on the kernel cryptographic backend features. All that are loaded at runtime can be viewed with

$ less /proc/crypto 

and are available to use as options. If the list is short, execute cryptsetup benchmark which will trigger loading available modules.

The following introduces encryption options for the first two modes. Note that the tables list options used in the respective examples in this article and not all available ones.

Encryption options for LUKS mode

The cryptsetup action to set up a new dm-crypt device in LUKS encryption mode is luksFormat. Unlike the name implies, it does not format the device, but sets up the LUKS device header and encrypts the master-key with the desired cryptographic options.

As LUKS is the default encryption mode,

# cryptsetup -v luksFormat device

is all that is needed to create a new LUKS device with default parameters (-v is optional). For comparison, we can specify the default options manually too:

# cryptsetup -v --cipher aes-xts-plain64 --key-size 256 --hash sha256 --iter-time 2000 --use-urandom --verify-passphrase luksFormat device

Defaults are compared with a cryptographically higher specification example in the table below, with accompanying comments:

Options Cryptsetup 1.7.0 defaults Example Comment
--cipher, -c aes-xts-plain64 aes-xts-plain64 Release 1.6.0 changed the defaults to an AES cipher in XTS mode (see item 5.16 of the FAQ). It is advised against using the previous default --cipher aes-cbc-essiv because of its known issues and practical attacks against them.
--key-size, -s 256 512 By default a 256 bit key-size is used. Note however that XTS splits the supplied key in half, so to use AES-256 instead of AES-128 you have to set the XTS key-size to 512.
--hash, -h sha256 sha512 Hash algorithm used for key derivation. Release 1.7.0 changed defaults from sha1 to sha256 "not for security reasons [but] mainly to prevent compatibility problems on hardened systems where SHA1 is already [being] phased out"[1]. The former default of sha1 can still be used for compatibility with older versions of cryptsetup since it is considered secure (see item 5.20).
--iter-time, -i 2000 5000 Number of milliseconds to spend with PBKDF2 passphrase processing. Release 1.7.0 changed defaults from 1000 to 2000 to "try to keep PBKDF2 iteration count still high enough and also still acceptable for users."[2]. This option is only relevant for LUKS operations that set or change passphrases, such as luksFormat or luksAddKey. Specifying 0 as parameter selects the compiled-in default..
--use-{u,}random --use-urandom --use-random Selects which random number generator to use. Quoting the cryptsetup manual page: "In a low-entropy situation (e.g. in an embedded system), both selections are problematic. Using /dev/urandom can lead to weak keys. Using /dev/random can block a long time, potentially forever, if not enough entropy can be harvested by the kernel."
--verify-passphrase, -y Yes - Default only for luksFormat and luksAddKey. No need to type for Arch Linux with LUKS mode at the moment.

If you want to deep-dive into cryptographic features of LUKS, the LUKS specification (e.g. its appendices) is a resource.

Tip: It is anticipated that the LUKS header receives another major revision in due course. If you are interested in the plans, the developers' devconfcz2016 (pdf) presentation summarizes.

Encryption options for plain mode

In dm-crypt plain mode, there is no master-key on the device, hence, there is no need to set it up. Instead the encryption options to be employed are used directly to create the mapping between an encrypted disk and a named device. The mapping can be created against a partition or a full device. In the latter case not even a partition table is needed.

To create a plain mode mapping with cryptsetup's default parameters:

# cryptsetup <options> open --type plain <device> <dmname>

Executing it will prompt for a password, which should have very high entropy. Below a comparison of default parameters with the example in Dm-crypt/Encrypting an entire system#Plain dm-crypt

Option Cryptsetup 1.7.0 defaults Example Comment
--hash ripemd160 - The hash is used to create the key from the passphrase; it is not used on a keyfile.
--cipher aes-cbc-essiv:sha256 twofish-xts-plain64 The cipher consists of three parts: cipher-chainmode-IV generator. Please see Disk encryption#Ciphers and modes of operation for an explanation of these settings, and the DMCrypt documentation for some of the options available.
--key-size 256 512 The key size (in bits). The size will depend on the cipher being used and also the chainmode in use. Xts mode requires twice the key size of cbc.
--offset 0 0 The offset from the beginning of the target disk from which to start the mapping
--key-file default uses a passphrase /dev/sdZ (or e.g. /boot/keyfile.enc) The device or file to be used as a key. See #Keyfiles for further details.
--keyfile-offset 0 0 Offset from the beginning of the file where the key starts (in bytes). This option is supported from cryptsetup 1.6.7 onwards.
--keyfile-size 8192kB - (default applies) Limits the bytes read from the key file. This option is supported from cryptsetup 1.6.7 onwards.

Using the device /dev/sdX, the above right column example results in:

# cryptsetup --cipher=twofish-xts-plain64 --offset=0 --key-file=/dev/sdZ --key-size=512 open --type=plain /dev/sdX enc

Unlike encrypting with LUKS, the above command must be executed in full whenever the mapping needs to be re-established, so it is important to remember the cipher, hash and key file details. We can now check that the mapping has been made:

# fdisk -l

An entry should now exist for /dev/mapper/enc.

Encrypting devices with cryptsetup

This section shows how to employ the options for creating new encrypted blockdevices and accessing them manually.

Encrypting devices with LUKS mode

Formatting LUKS partitions

In order to setup a partition as an encrypted LUKS partition execute:

# cryptsetup luksFormat device

You will then be prompted to enter a password and verify it.

See #Encryption options for LUKS mode for command line options.

You can check the results with:

# cryptsetup luksDump device

You will note that the dump not only shows the cipher header information, but also the key-slots in use for the LUKS partition.

The following example will create an encrypted root partition on /dev/sda1 using the default AES cipher in XTS mode with an effective 256-bit encryption

# cryptsetup -s 512 luksFormat /dev/sda1
Using LUKS to format partitions with a keyfile

When creating a new LUKS encrypted partition, a keyfile may be associated with the partition on its creation using:

# cryptsetup luksFormat device /path/to/mykeyfile

This is accomplished by appending the bold area to the standard cryptsetup command which defines where the keyfile is located.

See #Keyfiles for instructions on how to generate and manage keyfiles.

Unlocking/Mapping LUKS partitions with the device mapper

Once the LUKS partitions have been created, they can then be unlocked.

The unlocking process will map the partitions to a new device name using the device mapper. This alerts the kernel that device is actually an encrypted device and should be addressed through LUKS using the /dev/mapper/dm_name so as not to overwrite the encrypted data. To guard against accidental overwriting, read about the possibilities to backup the cryptheader after finishing setup.

In order to open an encrypted LUKS partition execute:

# cryptsetup open --type luks device dm_name

You will then be prompted for the password to unlock the partition. Usually the device mapped name is descriptive of the function of the partition that is mapped. For example the following unlocks a luks partition /dev/sda1 and maps it to device mapper named cryptroot:

# cryptsetup open --type luks /dev/sda1 cryptroot 

Once opened, the root partition device address would be /dev/mapper/cryptroot instead of the partition (e.g. /dev/sda1).

For setting up LVM ontop the encryption layer the device file for the decrypted volume group would be anything like /dev/mapper/cryptroot instead of /dev/sda1. LVM will then give additional names to all logical volumes created, e.g. /dev/mapper/lvmpool-root and /dev/mapper/lvmpool-swap.

In order to write encrypted data into the partition it must be accessed through the device mapped name. The first step of access will typically be to create a filesystem. For example:

# mkfs -t ext4 /dev/mapper/cryptroot

The device /dev/mapper/cryptroot can then be mounted like any other partition.

To close the luks container, unmount the partition and do:

# cryptsetup close cryptroot

Encrypting devices with plain mode

The creation and subsequent access of a dm-crypt plain mode encryption both require not more than using the cryptsetup open action with correct parameters. The following shows that with two examples of non-root devices, but adds a quirk by stacking both (i.e. the second is created inside the first). Obviously, stacking the encryption doubles overhead. The usecase here is simply to illustrate another example of the cipher option usage.

A first mapper is created with cryptsetup's plain-mode defaults, as described in the table's left column above

# cryptsetup --type plain -v open /dev/sdaX plain1 
Enter passphrase: 
Command successful.
# 

Now we add the second blockdevice inside it, using different encryption parameters and with an (optional) offset, create a filesystem and mount it

# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10  open /dev/mapper/plain1 plain2
Enter passphrase: 
# lsblk -p   
NAME                                                     
/dev/sda                                     
├─/dev/sdaX          
│ └─/dev/mapper/plain1     
│   └─/dev/mapper/plain2              
...
# mkfs -t ext2 /dev/mapper/plain2
# mount -t ext2 /dev/mapper/plain2 /mnt
# echo "This is stacked. one passphrase per foot to shoot." > /mnt/stacked.txt

We close the stack to check access works

# cryptsetup close plain2
# cryptsetup close plain1

First, let's try to open the filesystem directly:

# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/sdaX plain2
# mount -t ext2 /dev/mapper/plain2 /mnt
mount: wrong fs type, bad option, bad superblock on /dev/mapper/plain2,
      missing codepage or helper program, or other error

Why that did not work? Because the "plain2" starting block (10) is still encrypted with the cipher from "plain1". It can only be accessed via the stacked mapper. The error is arbitrary though, trying a wrong passphrase or wrong options will yield the same. For dm-crypt plain mode, the open action will not error out itself.

Trying again in correct order:

# cryptsetup close plain2    # dysfunctional mapper from previous try
# cryptsetup --type plain open /dev/sdaX plain1
Enter passphrase: 
# cryptsetup --type plain --cipher=serpent-xts-plain64 --hash=sha256 --key-size=256 --offset=10 open /dev/mapper/plain1 plain2 
Enter passphrase: 
# mount /dev/mapper/plain2 /mnt && cat /mnt/stacked.txt
This is stacked. one passphrase per foot to shoot.
# exit

dm-crypt will handle stacked encryption with some mixed modes too. For example LUKS mode could be stacked on the "plain1" mapper. Its header would then be encrypted inside "plain1" when that is closed.

Available for plain mode only is the option --shared. With it a single device can be segmented into different non-overlapping mappers. We do that in the next example, using a loopaes compatible cipher mode for "plain2" this time:

# cryptsetup --type plain --offset 0 --size 1000 open /dev/sdaX plain1 
Enter passphrase: 
# cryptsetup --type plain --offset 1000 --size 1000 --shared --cipher=aes-cbc-lmk --hash=sha256 open /dev/sdaX plain2
Enter passphrase: 
# lsblk -p
NAME                    
dev/sdaX                    
├─/dev/sdaX               
│ ├─/dev/mapper/plain1     
│ └─/dev/mapper/plain2     
...

As the devicetree shows both reside on the same level, i.e. are not stacked and "plain2" can be opened individually.

Cryptsetup actions specific for LUKS

Key management

It is possible to define up to 8 different keys per LUKS partition. This enables the user to create access keys for save backup storage: In a so-called key escrow, one key is used for daily usage, another kept in escrow to gain access to the partition in case the daily passphrase is forgotten or a keyfile is lost/damaged. Also a different key-slot could be used to grant access to a partition to a user by issuing a second key and later revoking it again.

Once an encrypted partition has been created, the initial keyslot 0 is created (if no other was specified manually). Additional keyslots are numbered from 1 to 7. Which keyslots are used can be seen by issuing

# cryptsetup luksDump /dev/<device> |grep BLED
Key Slot 0: ENABLED
Key Slot 1: ENABLED
Key Slot 2: ENABLED
Key Slot 3: DISABLED
Key Slot 4: DISABLED
Key Slot 5: DISABLED
Key Slot 6: DISABLED
Key Slot 7: DISABLED

Where <device> is the volume containing the LUKS header. This and all the following commands in this section work on header backup files as well.

Adding LUKS keys

Adding new keyslots is accomplished using cryptsetup with the luksAddKey action. For safety it will always, i.e. also for already unlocked devices, ask for a valid existing key ("any passphrase") before a new one may be entered:

# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) 
Enter any passphrase:
Enter new passphrase for key slot:
Verify passphrase: 

If /path/to/<additionalkeyfile> is given, cryptsetup will add a new keyslot for <additionalkeyfile>. Otherwise a new passphrase will be prompted for twice. For using an existing keyfile to authorize the action, the --key-file or -d option followed by the "old" <keyfile> will try to unlock all available keyfile keyslots:

# cryptsetup luksAddKey /dev/<device> (/path/to/<additionalkeyfile>) -d /path/to/<keyfile>

If it is intended to use multiple keys and change or revoke them, the --key-slot or -S option may be used to specify the slot:

# cryptsetup luksAddKey /dev/<device> -S 6 
Enter any passphrase: 
Enter new passphrase for key slot: 
Verify passphrase:
# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'
Key Slot 6: ENABLED

To show an associated action in this example, we decide to change the key right away:

# cryptsetup luksChangeKey /dev/<device> -S 6 
Enter LUKS passphrase to be changed: 
Enter new LUKS passphrase: 

before continuing to remove it.

Removing LUKS keys

There are three different actions to remove keys from the header:

  • luksRemoveKey is used to remove a key by specifying its passphrase/key-file.
  • luksKillSlot may be used to remove a key from a specific key slot (using another key). Obviously, this is extremely useful if you have forgotten a passphrase, lost a key-file, or have no access to it.
  • luksErase is used to quickly remove all active keys.
Warning:
  • All above actions can be used to irrevocably delete the last active key for an encrypted device!
  • The luksErase command was added in version 1.6.4 to quickly nuke access to the device. This action will not prompt for a valid passphrase! It will not wipe the LUKS header, but all keyslots at once and you will, therefore, not be able to regain access unless you have a valid backup of the LUKS header.

For above warning it is good to know the key we want to keep is valid. An easy check is to unlock the device with the -v option, which will specify which slot it occupies:

# cryptsetup -v open /dev/<device> testcrypt
Enter passphrase for /dev/<device>: 
Key slot 1 unlocked.
Command successful.

Now we can remove the key added in the previous subsection using its passphrase:

# cryptsetup luksRemoveKey /dev/<device>
Enter LUKS passphrase to be deleted: 

If we had used the same passphrase for two keyslots, the first slot would be wiped now. Only executing it again would remove the second one.

Alternatively, we can specify the key slot:

# cryptsetup luksKillSlot /dev/<device> 6
Enter any remaining LUKS passphrase:

Note that in both cases, no confirmation was required.

# cryptsetup luksDump /dev/sda8 |grep 'Slot 6'
Key Slot 6: DISABLED

To re-iterate the warning above: If the same passphrase had been used for key slots 1 and 6, both would be gone now.

Backup and restore

If the header of a LUKS encrypted partition gets destroyed, you will not be able to decrypt your data. It is just as much of a dilemma as forgetting the passphrase or damaging a key-file used to unlock the partition. Damage may occur by your own fault while re-partitioning the disk later or by third-party programs misinterpreting the partition table. Therefore, having a backup of the header and storing it on another disk might be a good idea.

Note: If the LUKS-encrypted partitions' master passphrase becomes compromised, you must revoke it on every copy of the cryptheader, even those you have backed up. Otherwise, a copy of the backed-up cryptheader that uses the compromised passphrase can be used to decrypt the associated partition. See LUKS FAQ for further details.

Backup using cryptsetup

Cryptsetup's luksHeaderBackup action stores a binary backup of the LUKS header and keyslot area:

# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /mnt/<backup>/<file>.img

where <device> is the partition containing the LUKS volume.

Tip: You can also back up the plaintext header into ramfs and encrypt it in example with gpg before writing to persistent backup storage by executing the following commands.
# mkdir /root/<tmp>/
# mount ramfs /root/<tmp>/ -t ramfs
# cryptsetup luksHeaderBackup /dev/<device> --header-backup-file /root/<tmp>/<file>.img
# gpg2 --recipient <User ID> --encrypt /root/<tmp>/<file>.img 
# cp /root/<tmp>/<file>.img.gpg /mnt/<backup>/
# umount /root/<tmp>
Warning: Tmpfs can swap to harddisk if low on memory so it is not recommended here.

Restore using cryptsetup

Warning: Restoring the wrong header or restoring to an unencrypted partition will cause data loss! The action can not perform a check whether the header is actually the correct one for that particular device.

In order to evade restoring a wrong header, you can ensure it does work by using it as a remote --header first:

# cryptsetup -v --header /mnt/<backup>/<file>.img open /dev/<device> test 
Key slot 0 unlocked.
Command successful.
# mount /dev/mapper/test /mnt/test && ls /mnt/test 
# umount /mnt/test 
# cryptsetup close test 

Now that the check succeeded, the restore may be performed:

# cryptsetup luksHeaderRestore /dev/<device> --header-backup-file ./mnt/<backup>/<file>.img

Now that all the keyslot areas are overwritten; only active keyslots from the backup file are available after issuing the command.

Manual backup and restore

The header always resides at the beginning of the device and a backup can be performed without access to cryptsetup as well. First you have to find out the payload offset of the crypted partition:

# cryptsetup luksDump /dev/<device> | grep "Payload offset"
 Payload offset:	4040

Second check the sector size of the drive

# fdisk -l /dev/<device> |grep "Sector size"
Sector size (logical/physical): 512 bytes / 512 bytes

Now that you know the values, you can backup the header with a simple dd command:

# dd if=/dev/<device> of=/path/to/<file>.img bs=512 count=4040

and store it safely.

A restore can then be performed using the same values as when backing up:

# dd if=./<file>.img of=/dev/<device> bs=512 count=4040

Re-encrypting devices

The cryptsetup package features the cryptsetup-reencrypt tool. It can be used to convert an existing unencrypted filesystem to a LUKS encrypted one (option --new) and permanently remove LUKS encryption (--decrypt) from a device. As its name suggests it can also be used to re-encrypt an existing LUKS encrypted device, though, re-encryption is not possible for a detached LUKS header or other encryption modes (e.g. plain-mode). For re-encryption it is possible to change the #Encryption options for LUKS mode. cryptsetup-reencrypt actions can be performed to unmounted devices only. See man cryptsetup-reencrypt for more information.

One application of re-encryption may be to secure the data again after a passphrase or keyfile has been compromised and one cannot be certain that no copy of the LUKS header has been obtained. For example, if only a passphrase has been shoulder-surfed but no physical/logical access to the device happened, it would be enough to change the respective passphrase/key only (#Key management).

Warning: Always make sure a reliable backup is available and double-check options you specify before using the tool!

The following shows an example to encrypt an unencrypted filesystem partition and a re-encryption of an existing LUKS device.

Encrypt an unencrypted filesystem

A LUKS encryption header is always stored at the beginning of the device. Since an existing filesystem will usually be allocated all partition sectors, the first step is to shrink it to make space for the LUKS header.

The default LUKS header encryption cipher requires 4096 512-byte sectors. We already checked space and keep it simple by shrinking the existing ext4 filesystem on /dev/sdaX to its current possible minimum:

# umount /mnt
# e2fsck -f /dev/sdaX 
e2fsck 1.43-WIP (18-May-2015)
Pass 1: Checking inodes, blocks, and sizes
...
/dev/sda6: 12/166320 files (0.0% non-contiguous), 28783/665062 blocks
# resize2fs -M /dev/sdaX
resize2fs 1.43-WIP (18-May-2015)
Resizing the filesystem on /dev/sdaX to 26347 (4k) blocks.
The filesystem on /dev/sdaX is now 26347 (4k) blocks long.

Now we encrypt it, using the default cipher we do not have to specify it explicitly. Note there is no option (yet) to double-check the passphrase before encryption starts, be careful not to mistype:

# cryptsetup-reencrypt /dev/sdaX --new  --reduce-device-size 4096S
WARNING: this is experimental code, it can completely break your data.
Enter new passphrase: 
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed  37,6 MiB/s

After it finished, the encryption was performed to the full partition, i.e. not only the space the filesystem was shrunk to (sdaX has 2.6GiB and the CPU used in the example has no hardware AES instructions). As a final step we extend the filesystem of the now encrypted device again to occupy available space:

# cryptsetup open /dev/sdaX recrypt 
Enter passphrase for /dev/sdaX: 
...
# resize2fs /dev/mapper/recrypt 
resize2fs 1.43-WIP (18-May-2015)
Resizing the filesystem on /dev/mapper/recrypt to 664807 (4k) blocks.
The filesystem on /dev/mapper/recrypt is now 664807 (4k) blocks long.
# mount /dev/mapper/recrypt /mnt

and are done.

Re-encrypting an existing LUKS partition

In this example an existing LUKS device is re-encrypted.

Warning: Double-check you specify encryption options for cryptsetup-reencrypt correctly and never re-encrypt without a reliable backup! As of September 2015 the tool does accept invalid options and damage the LUKS header, if not used correctly!

In order to re-encrypt a device with its existing encryption options, they do not need to be specified. A simple:

# cryptsetup-reencrypt /dev/sdaX
 
WARNING: this is experimental code, it can completely break your data.
Enter passphrase for key slot 0: 
Progress: 100,0%, ETA 00:00, 2596 MiB written, speed  36,5 MiB/s

performs it.

A possible usecase is to re-encrypt LUKS devices which have non-current encryption options. Apart from above warning on specifying options correctly, the ability to change the LUKS header may also be limited by its size. For example, if the device was initially encrypted using a CBC mode cipher and 128 bit key-size, the LUKS header will be half the size of above mentioned 4096 sectors:

# cryptsetup luksDump /dev/sdaX |grep -e "mode" -e "Payload" -e "MK bits"
Cipher mode:   	cbc-essiv:sha256
Payload offset:	2048
MK bits:       	128

While it is possible to upgrade the encryption of such a device, it is currently only feasible in two steps. First, re-encrypting with the same encryption options, but using the --reduce-device-size option to make further space for the larger LUKS header. Second, re-encypt the whole device again with the desired cipher. For this reason and the fact that a backup should be created in any case, creating a new, fresh encrypted device to restore into is always the faster option.

Keyfiles

Note: This section describes using a plaintext keyfile. If you want to encrypt your keyfile giving you two factor authentication see Using GPG or OpenSSL Encrypted Keyfiles for details, but please still read this section.

What is a keyfile?

A keyfile is a file whose data is used as the passphrase to unlock an encrypted volume. That means if such a file is lost or changed, decrypting the volume may no longer be possible.

Tip: Define a passphrase in addition to the keyfile for backup access to encrypted volumes in the event the defined keyfile is lost or changed.

Why use a keyfile?

There are many kinds of keyfiles. Each type of keyfile used has benefits and disadvantages summarized below:

Types of keyfiles

passphrase

This is a keyfile containing a simple passphrase. The benefit of this type of keyfile is that if the file is lost the data it contained is known and hopefully easily remembered by the owner of the encrypted volume. However the disadvantage is that this does not add any security over entering a passphrase during the initial system start.

Example: 1234

randomtext

This is a keyfile containing a block of random characters. The benefit of this type of keyfile is that it is much more resistant to dictionary attacks than a simple passphrase. An additional strength of keyfiles can be utilized in this situation which is the length of data used. Since this is not a string meant to be memorized by a person for entry, it is trivial to create files containing thousands of random characters as the key. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase.

Example: fjqweifj830149-57 819y4my1-38t1934yt8-91m 34co3;t8y;9p3y-

binary

This is a binary file that has been defined as a keyfile. When identifying files as candidates for a keyfile, it is recommended to choose files that are relatively static such as photos, music, video clips. The benefit of these files is that they serve a dual function which can make them harder to identify as keyfiles. Instead of having a text file with a large amount of random text, the keyfile would look like a regular image file or music clip to the casual observer. The disadvantage is that if this file is lost or changed, it will most likely not be possible to access the encrypted volume without a backup passphrase. Additionally, there is a theoretical loss of randomness when compared to a randomly generated text file. This is due to the fact that images, videos and music have some intrinsic relationship between neighboring bits of data that does not exist for a text file. However this is controversial and has never been exploited publicly.

Example: images, text, video, ...

Creating a keyfile with random characters

Storing the keyfile on a filesystem

A keyfile can be of arbitrary content and size.

Here dd is used to generate a keyfile of 2048 random bytes, storing it in the file /etc/mykeyfile:

# dd bs=512 count=4 if=/dev/urandom of=/etc/mykeyfile iflag=fullblock

If you are planning to store the keyfile on an external device, you can also simply change the outputfile to the corresponding directory:

# dd bs=512 count=4 if=/dev/urandom of=/media/usbstick/mykeyfile iflag=fullblock
Securely overwriting stored keyfiles

If you stored your temporary keyfile on a physical storage device, and want to delete it, remember to not just remove the keyfile later on, but use something like

# shred --remove --zero mykeyfile

to securely overwrite it. For overaged filesystems like FAT or ext2 this will suffice while in the case of journaling filesystems, flash memory hardware and other cases it is highly recommended to wipe the entire device or at least the keyfiles partition.

Storing the keyfile in tmpfs

Alternatively, you can mount a tmpfs for storing the keyfile temporarily:

# mkdir mytmpfs
# mount tmpfs mytmpfs -t tmpfs -o size=32m
# cd mytmpfs

The advantage is that it resides in RAM and not on a physical disk, therefore it can not be recovered after unmounting the tmpfs. On the other hand this requires you to copy the keyfile to another filesystem you consider secure before unmounting.

Configuring LUKS to make use of the keyfile

Add a keyslot for the keyfile to the LUKS header:

# cryptsetup luksAddKey /dev/sda2 /etc/mykeyfile
Enter any LUKS passphrase:
key slot 0 unlocked.
Command successful.

Unlocking a secondary partition at boot

If the keyfile for a secondary file system is itself stored inside an encrypted root, it is safe while the system is powered off but can be sourced to automatically unlock the mount during with boot via crypttab. Following on from the first example above

/etc/crypttab
home    /dev/sda2    /etc/mykeyfile

is all needed for unlocking, and

/etc/fstab
/dev/mapper/home        /home   ext4        defaults        0       2
for mounting the LUKS blockdevice with the generated keyfile.
Tip: If you prefer to use a --plain mode blockdevice, the encryption options necessary to unlock it are specified in /etc/crypttab. Take care to apply the systemd workaround mentioned in crypttab in this case.

Unlocking the root partition at boot

This is simply a matter of configuring mkinitcpio to include the necessary modules or files and configuring the cryptkey kernel parameter to know where to find the keyfile.

Two cases will be covered:

  1. Using a keyfile stored on an external media (here a USB stick)
  2. Using a keyfile embedded in the initramfs

With a keyfile stored on an external media

Configuring mkinitcpio

You have to add two extra modules in your /etc/mkinitcpio.conf, one for the drive's file system (vfat module in the example below) and one for the codepage (nls_cp437 module) :

MODULES="nls_cp437 vfat"

In this example it is assumed that you use a FAT formatted USB drive (vfat module). Replace those module names if you use another file system on your USB stick (e.g. ext2) or another codepage. Users running the stock Arch kernel should stick to the codepage mentioned here. If it complains of bad superblock and bad codepage at boot, then you need an extra codepage module to be loaded. For instance, you may need nls_iso8859-1 module for iso8859-1 codepage.

If you have a non-US keyboard, it might prove useful to load your keyboard layout before you are prompted to enter the password to unlock the root partition at boot. For this, you will need the keymap hook before encrypt.

Generate a new initramfs image:

# mkinitcpio -p linux
Configuring the kernel parameters

Add the following options to the kernel parameters:

cryptdevice=/dev/<partition1>:root cryptkey=/dev/<partition2>:<fstype>:<path>

For example:

cryptdevice=/dev/sda3:root cryptkey=/dev/sdb1:vfat:/keys/secretkey

Choosing a plain filename for your key provides a bit of 'security through obscurity'. The keyfile can not be a hidden file, that means the filename must not start with a dot, or the encrypt hook will fail to find the keyfile during the boot process.

The naming of device nodes like /dev/sdb1 is not guaranteed to stay the same across reboots. It is more reliable to access the device with udev's persistent block device naming instead. To assure that the encrypt hook finds your keyfile when reading it from an external storage device, persistent block device names must be used. See the article persistent block device naming.

With a keyfile embedded in the initramfs

Warning: Use an embedded keyfile only if you have some form of authentication mechanism beforehand that protects the keyfile sufficiently. Otherwise auto-decryption will occur, defeating completely the purpose of block device encryption.

This method allows to use a specially named keyfile that will be embedded in the initramfs and picked up by the encrypt hook to unlock the root filesystem (cryptdevice) automatically. It may be useful to apply when using the GRUB early cryptodisk feature, in order to avoid entering two passphrases during boot.

The encrypt hook lets the user specify a keyfile with the cryptkey kernel parameter: in the case of initramfs, the syntax is rootfs:path, see Dm-crypt/System configuration#cryptkey. Besides, the code defaults to use /crypto_keyfile.bin, and if the initramfs contains a valid key with this name, decryption will occur automatically without the need to configure the cryptkey parameter.

Generate the keyfile, give it suitable permissions and add it as a LUKS key:

# dd bs=512 count=4 if=/dev/urandom of=/crypto_keyfile.bin
# chmod 000 /crypto_keyfile.bin
# chmod 600 /boot/initramfs-linux*
# cryptsetup luksAddKey /dev/sdX# /crypto_keyfile.bin
Warning: When initramfs' permissions are set to 644 (by default), then all users will be able to dump the keyfile. Make sure the permissions are still 600 if you install a new kernel.

Include the key in mkinitcpio FILES array:

/etc/mkinitcpio.conf
FILES="/crypto_keyfile.bin"

Finally Regenerate your initramfs.

On the next reboot you should only have to enter your container decryption passphrase once.

(source)