Encrypting a partition with systemd

Sorry if this is known by everybody.
Please take this as a draft for an improvement of the wiki pages, which don’t cover the ways to do things with systemd.
= Introduction =
I wanted to encrypt the SD card of my very old samsung-rossa phone. I checked both the Alpine Wiki and the PmOS FDE pages, and they don’t mention systemd solutions. As I am familiar with encrypting partitions in my Debian computers I thought I could try and write a tutorial of how to do it using the systemd tools on a postmarketOS phone. It would be great to be able to start contributing to the project.
Basically this is no longer accurate
Alpine, like Gentoo, uses the dmcrypt service rather than /etc/crypttab.
Alpine maybe, in postmarketOS you can choose now. I’m going to go the crypttab way.
= How to find the partition to encrypt? =
First of all you’ll have find the partition you want to encrypt. lsblk is your tool.
# lsblk -a -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
loop0
loop1
loop2
loop3
loop4
loop5
loop6
loop7
mmcblk1
└─mmcblk1p1 ext4 61de6b0d-dcd6-4049-9fe8-3a15872992b5 3.6G 1% /run/media/my_user/61de6b0d-dcd6-4049-9fe8-3a15872992b5
mmcblk0
├─mmcblk0p1 vfat 00BC-614E 51.1M 20% /lib/firmware/msm-firmware-loader/mnt/apnhlos
├─mmcblk0p2 vfat 00BC-614E 19.6M 69% /lib/firmware/msm-firmware-loader/mnt/modem
├─mmcblk0p3
├─mmcblk0p4
├─mmcblk0p5
├─mmcblk0p6
├─mmcblk0p7
├─mmcblk0p8
├─mmcblk0p9
├─mmcblk0p10
├─mmcblk0p11
├─mmcblk0p12
├─mmcblk0p13 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b
├─mmcblk0p14
├─mmcblk0p15
├─mmcblk0p16
├─mmcblk0p17
├─mmcblk0p18
├─mmcblk0p19
├─mmcblk0p20
├─mmcblk0p21
├─mmcblk0p22 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b 3.7M 0% /lib/firmware/msm-firmware-loader/mnt/persist
├─mmcblk0p23 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b
├─mmcblk0p24
├─mmcblk0p25 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b
├─mmcblk0p26 ext4 57f8f4bc-abf4-655f-bf67-946fc0f9f25b
└─mmcblk0p27
 ├─userdata1 ext2 pmOS_boot 404cb4cc-292b-41b0-84ce-491cdecc565c 144M 31% /boot
 └─userdata2 ext4 pmOS_root 2327129a-45ee-4bdc-8eaa-f15751d19703 515.4M 84% /
mmcblk0boot0
mmcblk0boot1
You are going to encrypt the 4Gb card /dev/mmcblk1p1. As it was already in use (but not encrypted) first I must unmount it
# umount /run/media/my_user/61de6b0d-dcd6-4049-9fe8-3a15872992b5/
= Create the encrypted partition =
# cryptsetup luksFormat --type luks2 /dev/mmcblk1p1
We have created a container. Now
# cryptsetup open /dev/mmcblk1p1 secrets_crypt
creates /dev/mapper/secrets_crypt.
# lsblk -m -T -f
NAME SIZE OWNER GROUP MODE FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
mmcblk1 29G root disk brw-rw---- 
└─mmcblk1p1 3.9G root disk brw-rw---- crypto_LUKS 4e946a1e-444d-4aa2-a716-d7327b6349ba 
 └─secretos_crypt 3.9G root root brw------- ext4 4fe1078f-3e52-4296-9f88-0444c6e12997
...
Take note: UUID=4fe1078f-3e52-4296-9f88-0444c6e12997 (the numbering of disks and partitions can change, the UUID is unique).
Format it
# mkfs.ext4 /dev/mapper/secrets_crypt
Check
# cryptsetup status /dev/mapper/secrets_crypt
/dev/mapper/secrets_crypt is active.
 type: LUKS2
 cipher: aes-xts-plain64
 keysize: 512 bits
 key location: keyring
 device: /dev/mmcblk1p1
 sector size: 512
 offset: 32768 sectors
 size: 8216576 sectors
 mode: read/write
Manual Usage
Opening and mounting the encrypted partition
# cryptsetup open UUID=4e946a1e-444d-4aa2-a716-d7327b6349ba secrets_crypt
which is equivalent to
# (just in case)
# systemd-cryptsetup detach secrets_crypt
 
# systemd-cryptsetup attach secrets_crypt /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba /root/.secrets_key luks,nofail
Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba.
Now mount it
# mount -t ext4 /dev/mapper/secrets_crypt /mnt/.secrets
Closing the encrypted partition
# umount /mnt/.secrets
 
# cryptsetup close secrets_crypt
Automatic Usage
We don’t want to have to open and mount the partition every time we are going to use it, but want it mounted at boot.
Create a Key File only known to root (the Key File mentioned in the tutorials above). You can use the method in the tutorials
# dd bs=512 count=4 if=/dev/urandom of=/root/.secrets_key iflag=fullblock
 
# chmod 400 /root/.secrets_key
Add the key
# cryptsetup luksAddKey UUID="4e946a1e-444d-4aa2-a716-d7327b6349ba" /root/.secrets_key
# systemd-cryptenroll /dev/mmcblk1p1
 SLOT TYPE
 0 password
 1 password
The first password is the one you used to create the LUKS volume, the second one is the key file.
Add or create the information to /etc/crypttab
secrets_crypt UUID=4e946a1e-444d-4aa2-a716-d7327b6349ba /root/.secrets_key luks,nofail
The following step has to do -my guess- with the service not having a preset. I have to create the rule to start the service with the information provided in crypttab.
# /usr/lib/systemd/system-generators/systemd-cryptsetup-generator /etc/systemd/system
I don’t know if the subdirectory is the correct one - postmarketOS admins?
Rebooted. Did it work?
You can list all generated unit files using
# systemctl list-unit-files | grep systemd-cryptsetup
systemd-cryptsetup@secrets_crypt.service enabled disabled
# systemctl status systemd-cryptsetup@secrets_crypt.service
● systemd-cryptsetup@secrets_crypt.service - Cryptography Setup for secrets_crypt
 Loaded: loaded (/etc/crypttab; enabled; preset: disabled)
 Active: active (exited) since Sat 2025-02-01 10:03:25 CET; 6min ago
 Invocation: 60fbc3a29448409fa6121523c243c281
 Docs: man:crypttab(5)
 man:systemd-cryptsetup-generator(8)
 man:systemd-cryptsetup@.service(8)
 Main PID: 954 (code=exited, status=0/SUCCESS)
 Mem peak: 69.6M
 CPU: 4.746s
 
Feb 01 10:03:23 samsung-rossa systemd[1]: Starting Cryptography Setup for secrets_crypt...
Feb 01 10:03:23 samsung-rossa systemd-cryptsetup[954]: Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/disk/by-uuid/4e946a1e-444d-4aa2-a716-d7327b6349ba.
Feb 01 10:03:25 samsung-rossa systemd[1]: Finished Cryptography Setup for secrets_crypt.
This means that the command has worked (is enabled) and that there was no preset fot it - is wasn’t foreseen by the admins.
But does it really work?
# echo "this is a text" > /mnt/.secrets/test.txt
# ls -l /mnt/.secrets/test.txt 
-rw-r--r-- 1 root root 15 Feb 3 12:42 /mnt/.secretos/test.txt
It does!
The following step is to use a hardware token, but that would be the subject of a new post.
I hope this was useful to anybody.