How to encrypt a disk with dm-crypt

Revision as of 16:34, 22 March 2023 by Registered User (→‎process)
Applicable for STM32MP13x lines

1. Purpose of article[edit source]

This article describes how to encrypt a storage block device as a Sdcard with the "dm-crypt" tool. The encrypting trusted key is protected by the secure OS OP-TEE. The encrypted key is wrapped with the SAES IP.

2. Pre-requesites[edit source]

You are already familiar with the Yocto build process and OpenSTLinux distribution.

3. Introduction[edit source]

This article describe a process to encrypt dynamically a block device with "dm-crypt", here a sdcard partition. We use the Linux in-kernel key managment Linux, to create a "trusted key" key type as the block device encrypting key. The "trusted key" so the encrypting key is a secure key generated, seal & unseal by the secure OS OP-TEE, the wrapping key is a secret key and can be the HUK or derived from the HUK. The Linux user-space application "keyctl" manage secure key blobs, the wrapping is performed by the secure IP SAES in the OP-TEE environment. We use AES encryption algorithm with CBC mode or (ESSIV or XTS). ESSIV and XTS provide more protection for disk encryption and the AES CBC encryption can be accelerated with the CRYP IP.

4. architecture overview[edit source]

Alternate text
dm_crypt

5. process[edit source]

  • New MMC partition creation

fdisk /dev/mmcblk0

enter "n" following by "+1G" for 1go size then "w".

  • check the new partition created

lsblk

NAME         MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mmcblk0      179:0    0  14.8G  0 disk
|-mmcblk0p1  179:1    0   256K  0 part
|-mmcblk0p2  179:2    0   256K  0 part
|-mmcblk0p3  179:3    0   256K  0 part
|-mmcblk0p4  179:4    0   256K  0 part
|-mmcblk0p5  179:5    0     4M  0 part
|-mmcblk0p6  179:6    0     4M  0 part
|-mmcblk0p7  179:7    0   512K  0 part
|-mmcblk0p8  179:8    0    64M  0 part /boot
|-mmcblk0p9  179:9    0    16M  0 part /vendor
|-mmcblk0p10 179:10   0   736M  0 part /
|-mmcblk0p11 179:11   0 710.5M  0 part /usr/local
`-mmcblk0p12 179:12   0     1G  0 part
  • Trusted Key creation in keyring session

keyctl add trusted my_key "new 64" @s

result :
53139771
  • check the created key, show the keyring session and print the sealed key.

keyctl show @s

result:
Keyring
989387511 --alswrv      0     0  keyring: _ses
809952222 ----s-rv      0     0   \_ user: invocation_id
 53139771 --alswrv      0     0   \_ trusted: my_key

keyctl print 53139771

result:
00334c376ecf6d8e80d7737506eec2456dea0baa119d86cb0aec5643edfe5bbdcdb736e94075fc6f
832731067e3452a16eb40891ee7cdf2133aa6fbce6b1bd8428f2ca9afece90153e84e0c3c1107f66
1ccc53b88f2e2d9dbb21223e9aeacafff2
  • save Key blob

keyctl pipe 53139771 > my_key.blob

  • create with "dmsetup" the logical device named "crypt_dev" with transparent encryption of block device using the kernel crypto API "crypt", specifically the AES XTS encryption with the trusted key "my_key"

dmsetup create crypt_dev --table "0 $(blockdev --getsz /dev/mmcblk0p12) crypt aes-xts-plain64 :64:trusted:my_key 0 /dev/mmcblk0p12 0"

result:
[ 3666.109846] cryptd: max_cpu_qlen set to 1000
  • check the device mapper

dmsetup table --showkeys

result:
crypt_dev: 0 2097152 crypt aes-xts-plain64 :64:trusted:my_key 0 179:12 0
  • delete the keys from the keyring session (optional)

keyctl clear @s

  • format the encrypted partition

mkfs.ext4 /dev/mapper/crypt_dev

result:
mke2fs 1.46.5 (30-Dec-2021)
Creating filesystem with 262144 4k blocks and 65536 inodes
Filesystem UUID: a9f98dbc-65b9-4e98-80cc-f46a0696ca7f
Superblock backups stored on blocks:
       32768, 98304, 163840, 229376
Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
  • mount the encrypted device

mkdir /usr/mydata
mount -t ext4 /dev/mapper/crypt_dev /usr/mydata

result:
[ 4259.306912] EXT4-fs (dm-0): mounted filesystem with ordered data mode. Opts: (null). Quota mode: 
disabled.
  • check the mountpoint

lsblk

result:
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
mmcblk0       179:0    0  14.8G  0 disk
|-mmcblk0p1   179:1    0   256K  0 part
|-mmcblk0p2   179:2    0   256K  0 part
|-mmcblk0p3   179:3    0   256K  0 part
|-mmcblk0p4   179:4    0   256K  0 part
|-mmcblk0p5   179:5    0     4M  0 part
|-mmcblk0p6   179:6    0     4M  0 part
|-mmcblk0p7   179:7    0   512K  0 part
|-mmcblk0p8   179:8    0    64M  0 part /boot
|-mmcblk0p9   179:9    0    16M  0 part /vendor
|-mmcblk0p10  179:10   0   736M  0 part /
|-mmcblk0p11  179:11   0 710.5M  0 part /usr/local
`-mmcblk0p12  179:12   0     1G  0 part
  `-crypt_dev 253:0    0     1G  0 dm   /usr/mydata
  • write some data to the device

cd /usr/mydata
echo "my private datas stored on mmcblk0p12" > my_fic.txt
sync

  • reboot the board
  • reload the trusted key in the keyring session

keyctl add trusted my_key "load `cat my_key.blob`" @s

result:
750687915
  • redefine with "dmsetup" the logical device.

dmsetup create crypt_dev --table "0 $(blockdev --getsz /dev/mmcblk0p12) crypt aes-xts-plain64 :64:trusted:my_key 0 /dev/mmcblk0p12 0"

result:
[ 3666.109846] cryptd: max_cpu_qlen set to 1000
  • remount the device

mount -t ext4 /dev/mapper/crypt_dev /usr/mydata

  • check the data stored

cd /usr/mydata
more my_fic.txt

result:
my private datas stored on mmcblk0p12