Jump to content

Encrypting a partition with systemd

From postmarketOS Wiki

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.