Creating a volume for pervasive encryption
With cryptsetup, you can conveniently set up volume encryption. It formats the volume and performs the necessary device mapper setup tasks.
Before you begin
As a prerequisite, you require free disk devices or partitions on disk devices that are configured to be persistently available to your Linux® instance.
About this task
Also, you must define a passphrase for each volume that you want to encrypt. This passphrase encrypts the LUKS volume encryption key (LVEK) and you can use it for all interactive setup actions on the encrypted volume. In the infrastructure for protected volume encryption, the LVEK is a secure key. Because secure keys are already encrypted by a master key, these passphrases are of limited relevance to security.
For automated opening of the encrypted volume during system startup, you can use a key file containing some random data that fulfills the same purpose as a passphrase.
Generate a secure key in the secure key repository using
the zkey utility.
You can generate secure keys (AES DATA keys, AES CIPHER keys as shown in the example, or EP11 AES secure keys) with a length of 128, 192, or 256 bits. When generating secure keys for the XTS cipher mode, only 128 or 256 bit keys are supported. For XTS cipher mode keys, two secure key parts are generated and concatenated to each other.
For the scenario, issue the following command for the XTS cipher mode with a key name of secure_xtskey1 and a key length of 256 bits. Create four different keys with names secure_xtskey1 up to secure_xtskey4.
# zkey generate --name secure_xtskey1 --key-type CCA-AESCIPHER --keybits 256 --xts \ --volumes /dev/mapper/disk1:enc-disk1 --volume-type LUKS2 \ --apqns 03.0039,04.0039 --sector-size 4096 ... # zkey generate --name secure_xtskey4 --key-type CCA-AESCIPHER --keybits 256 --xts \ --volumes /dev/mapper/disk4:enc-disk4 --volume-type LUKS2 \ --apqns 03.0039,04.0039 --sector-size 4096
The keys to be encrypted by the AES master key are generated by random inside a domain of the cryptographic coprocessor and are thus never exposed in clear outside the coprocessor. After the successful generation of the secure key, the randomly generated key is destroyed by the coprocessor. This is possible because during cryptographic operations within the coprocessor, effective keys are always reconstructed by decrypting the secure key with the master key.
In the shown example, you specify the volumes that are to be encrypted with the new secure key, and you also associate the APQNs where the related master key is located.
Use a different key for each encrypted volume. Only for certain reasons, if you want to use a particular secure key for selected volumes, generate only one key and associate it to all these selected volumes.Note: With the optional parameter --sector-size, you can set the size of the blocks to be encrypted or decrypted. It must be a power of two and in the range 512 - 4096 bytes. cryptsetup chooses a default sector size of 512 bytes. Using 4096-byte sectors provides the best performance on Linux on Z and LinuxONE.You can list information about the generated secure keys:
# zkey list Key : secure_xtskey1 --------------------------------------------------------------------- Description : Secure key size : 272 bytes Clear key size : 512 bits XTS type key : Yes Key type : CCA-AESCIPHER Volumes : /dev/mapper/disk1:enc-disk1 APQNs : 03.0039 04.0039 Key file name : /etc/zkey/repository/secure_xtskey1.skey Sector size : 4096 bytes Volume type : LUKS2 Verification pattern : 303344b12b8258840fa11852a4ecc6d5 84c7a867f893a5dcc0d499557c45bee6 Created : 2020-08-20 15:27:20 Changed : (never) Re-enciphered : (never) ...
Generate the commands to format the volume to be encrypted using cryptsetup. The formatting process writes the LUKS2 header onto the volume. During formatting, the
LUKS2 volume encryption key, which is the
previously generated secure key, is encrypted with a KEK that is derived from the
passphrase or from a provided key file.
When you format a volume, you need to specify values for the following parameters, which are retrieved or calculated during command generation:
- The LUKS2 type of formatting.
- The PAES cipher, its operation mode
XTS), and the algorithm to generate the initialization vector (
- The location and name of the secure key file generated in step 1.
- The size of the secure key file in bits. In our example, an AES CIPHER key used with the XTS cipher mode is generated with a size of 272 bytes = 2176 bits. (An AES DATA key has 64 bytes = 512 bits. An EP11 AES key used with XTS of size 640 bytes has a file size of 5120 bits).
In addition, you specify the name of the volume. In our case, this is /dev/mapper/disk1 through /dev/mapper/disk4.
For the sample system, invoke the zkey cryptsetup command for the first volume as follows:
Two commands are generated and displayed as shown:
# zkey cryptsetup --volumes /dev/mapper/disk1 cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 --master-key-file '/etc/zkey/repository/secure_xtskey1.skey' --key-size 2176 --cipher paes-xts-plain64 --sector-size 4096 /dev/mapper/disk1 zkey-cryptsetup setvp /dev/mapper/disk1
- the cryptsetup luksFormat command to format the volume
- the zkey-cryptsetup setvp command to set the verification pattern into the LUKS2 header. The verification pattern is used to identify the valid effective key during recovery actions.
Run the generated commands.
Copy and paste the generated commands into the command line.Note: If the you use an older distribution, the --pbkdf pbkdf2 option may be missing in the generated command. In such a case, edit the command by adding option --pbkdf pbkdf2. This is to avoid an out-of-memory error for a LUKS2 volume during automated opening via /etc/crypttab at system startup. For more information, see Out-of-memory errors when opening a LUKS2 volume.
For each volume, define a passphrase like
When you type the passphrase, it is not displayed.
# cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 \ --master-key-file '/etc/zkey/repository/secure_xtskey1.skey' \ --key-size 2176 --cipher paes-xts-plain64 --sector-size 4096 /dev/mapper/disk1 WARNING! ======== This will overwrite data on /dev/mapper/disk1 irrevocably. Are you sure? (Type uppercase yes): YES Enter passphrase for /dev/mapper/disk1: disk1pw Verify passphrase: disk1pw # zkey-cryptsetup setvp /dev/mapper/disk1 Enter passphrase for '/dev/mapper/disk1': disk1pwTip: In newer distributions where the --pbkdf pbkdf2 option is automatically generated, you can use the --run option to let the generated commands run directly after creation, without the need to copy and paste:
# zkey cryptsetup --volumes /dev/mapper/disk1 --run
Open the volume using a generated command:
# zkey cryptsetup --volumes /dev/mapper/disk1 --open --run
The following command is generated and immediately run:
# cryptsetup luksOpen /dev/mapper/disk1 enc-disk1
When prompted, enter the passphrase from step 3.
This creates a device-mapper device named /dev/mapper/enc-disk1 (see step 5).
Check the result of step 4
with the command ls /dev/mapper/:
# ls /dev/mapper control disk2 disk4 disk6 disk8 enc-disk2 enc-disk4 disk1 disk3 disk5 disk7 enc-disk1 enc-disk3
As of now, any I/O operation to or from /dev/mapper/enc-disk1 is transparently encrypted or decrypted onto the /dev/mapper/disk1 device. Do not write to this device directly. The same is valid for disks disk2 through disk4.
Create a key file and specify it in an entry in /etc/crypttab to
persistently configure the opening at system startup.
- Create the key file named disk1.key in directory
/etc/luks_keys/ with random content with a size of 4096 bytes (specified by
bs=1024 count=4). If the directory does not yet exist, you must create it first.
# dd if=/dev/urandom of=/etc/luks_keys/disk1.key bs=1024 count=4 # chmod 0400 /etc/luks_keys/disk1.key
The second command makes the key file readable by the root user only. Repeat these commands for each volume adequately.
- Add a key slot with the previously generated key file:
You must also specify option --pbkdf pbkdf2 with the luksAddKey command to avoid an out-of-memory error for a LUKS2 volume during automated opening via /etc/crypttab at system startup. For more information, see Out-of-memory errors when opening a LUKS2 volume.
# cryptsetup luksAddKey --pbkdf pbkdf2 /dev/mapper/disk1 /etc/luks_keys/disk1.key
Repeat this for each disk. When prompted, enter the passphrase from step 3.
- Edit /etc/crypttab and add one entry for each encrypted volume:
The format of the /etc/crypttab file depends on your Linux distribution. See the crypttab man page for more details.
# /etc/crypttab # # See crypttab(5) for more information. # # <target name> <source device> <key file> <options> enc-disk1 /dev/mapper/disk1 /etc/luks_keys/disk1.key luks enc-disk2 /dev/mapper/disk2 /etc/luks_keys/disk2.key luks enc-disk3 /dev/mapper/disk3 /etc/luks_keys/disk3.key luks enc-disk4 /dev/mapper/disk4 /etc/luks_keys/disk4.key luks
Alternatively you can have a skeleton for a crypttab entry automatically generated by the zkey crypttab command:
# zkey crypttab --volumes /dev/mapper/disk<n>
You only need to add the <key file> column manually.
You can, however, specify the key file with the command, then you do not need to add the<key file> column manually:
# zkey crypttab --volumes /dev/mapper/disk<n> --key-file /etc/luks_keys/disk<n>.key
- Create the key file named disk1.key in directory /etc/luks_keys/ with random content with a size of 4096 bytes (specified by
Prepare your volumes for being managed by LVM. For this purpose, you need to perform the following sub-steps:
- Define and initialize the physical volumes that you plan to use in order to make them available to LVM. Use the pvcreate command. Each such command creates what is called an LVM physical volume.
- Define an LVM volume group where you combine
the LVM physical volumes that you want to manage within such a
group. Use the
- Add logical volumes to the volume group using the
lvcreatecommand. With the -n option, you specify a meaningful name for the logical volume. With the -L option, you specify a size, which can be independent from the sizes of any existing hardware disks, except for the overall capacity.
# pvcreate /dev/mapper/enc-disk1 # pvcreate /dev/mapper/enc-disk2 # pvcreate /dev/mapper/enc-disk3 # pvcreate /dev/mapper/enc-disk4 # vgcreate MY_VOLGROUP /dev/mapper/enc-disk* # lvcreate -L 10GB MY_VOLGROUP -n LV1 # lvcreate -L 30GB MY_VOLGROUP -n LV2 # lvcreate -L 35GB MY_VOLGROUP -n LV3 # ls /dev/mapper control disk3 disk6 enc-disk1 enc-disk4 MY_VOLGROUP-LV3 disk1 disk4 disk7 enc-disk2 MY_VOLGROUP-LV1 disk2 disk5 disk8 enc-disk3 MY_VOLGROUP-LV2Note: For logical volume LV3, only 35 GB are defined, though 40 GB physical space are available. Thus you can enlarge the volume for further purposes.
Create a file system - in the example, an ext4 file system - on the encrypted LVM logical volume created in step 7 or the encrypted volume created
in step 4 (if you did not use
The kernel transparently encrypts or decrypts I/O requests to or from the encrypted volume. Thus, the end-to-end encryption for the data at-rest is implemented.
# mkfs.ext4 /dev/mapper/MY_VOLGROUP-LV1 # mkfs.ext4 /dev/mapper/MY_VOLGROUP-LV2 # mkfs.ext4 /dev/mapper/MY_VOLGROUP-LV3
Create mount points and update /etc/fstab to later mount the file systems
on the encrypted volumes.
- Create the mount
# mkdir /crypted_lv1 # mkdir /crypted_lv2 # mkdir /crypted_lv3
- Edit file /etc/fstab and add similar entries like follows:
/dev/mapper/MY_VOLGROUP-LV1 /crypted_lv1 ext4 defaults 0 0 /dev/mapper/MY_VOLGROUP-LV2 /crypted_lv2 ext4 defaults 0 0 /dev/mapper/MY_VOLGROUP-LV3 /crypted_lv3 ext4 defaults 0 0
- Create the mount points:
Mount the file system through /etc/fstab.
# mount /crypted_lv1 # mount /crypted_lv2 # mount /crypted_lv3Note: To let users issue the mount command for a particular mount point, add the
useroption to the entry for this mount point in /etc/fstab.
The result of this task is illustrated in Figure 1.
What to do next
- Create permissions for users to access data on the mounted file system.
- Now a user can start to read and write data on the mounted file system, which is transparently
encrypted or decrypted.
For example, issue:
$ echo ’what is secret’ > /crypted_lv1/mysecret $ ls /crypted_lv1 $ cat /crypted_lv1/mysecret