Tutorial: Full disk encryption on Librem5

I tried to flash a new image, but the flash_script ./scripts/librem5-flash-image doesn’t exists anymore :frowning:

Hui, since 3 months …

Ok, got it …

Looks like they got moved to here: git clone https://source.puri.sm/Librem5/librem5-flash-image.git

Thanks, I used a combination of @Cc281080’s bash code (that was cleaned up by @nretro and me) and OP’s partition expansion steps to successfully reencrypt the LUKS partition of a fresh Byzantium image which I flashed to my Librem 5’s eMMC.

I suspected that simply adding --variant luks to the existing image flash procedure would simply download the same public image that other Librem 5 users would download when they ran librem5-flash-image. Not wanting the encryption key for my Librem 5 to be held by Purism and everyone who uses default settings, I am glad I found this procedure to generate my own encryption key locally by creating a new LUKS container and filling it with the public image’s data. I hope librem5-flash-image incorporates local generation of encryption keys in the future.

Parent.
Archive.

Thank you so much to @Cc281080, @nretro, and @baltakatei for doing all the heavy lifting on this. I can’t imagine running a Librem 5 as a daily driver without properly encrypting the device. I know factory Librem 5s come LUKS encrypted with full disk size from the factory now, but I like testing pmOS and Mobian from time to time and this is my way home.

For anyone else, I spent a few hours wrapping my head around this one. I wrote up my notes as a guide for myself and anyone else. https://github.com/williamtries/linuxmobileguides/wiki/12.-Starting-Fresh-with-a-Used-Librem-5-(with-LUKS-Encryption,-Expanded-File-System,-and-New-Encryption-Key)

5 Likes

I did not feel comfortable with “Delete” and “New” partition with cfdisk. So I used jumpdrive and gparted to “resize” the partition graphically. Choose the 29.12 GB drive, which was /dev/sdb in my case. Use “Resize/Move” option from right click menu when selecting the encrypted partition. Set free size after the partition to 0. Now click apply (the gree tick mark) to complete resizing.

Once resized, use “Open encryption” option from gparted which mapped the drive to /dev/dm-4 (check cat /proc/partitions before and after Open encryption).


Now run

sudo e2fsck -f /dev/dm-4
sudo resize2fs /dev/dm-4

Changing luks password can be done from the phone directly using GNOME Disks (it does not support resizing - likely because it is already mounted).

There are a couple of ways to reencrypt a device in place. The device to reencrypt can be a loop device of a freshly downloaded image, as in the OP, or it can be a jumpdrive straight to the eMMC, for a chance to continue using the device without losing data. ( Always have a backup; the usual DISCLAIMER. )

Here, I did it on a freshly downloaded image:

librem5-flash-image --variant luks --skip-cleanup --skip-flash --dir devkit_image
sudo losetup -P -f --show devkit_image/librem5r4.img

Note the output, which was /dev/loop0 in my case.

Alternative #1 – convert to LUKS2

This is the one I tried successfully. The downloaded image comes with LUKS1 encryption, but the boot partition is unencrypted, so no need to worry about GRUB with LUKS2.

sudo cryptsetup convert /dev/loop0p2 --type luks2
sudo cryptsetup reencrypt /dev/loop0p2

The second command requires the old password ( 123456 ).

Alternative #2 – stay with LUKS1

I haven’t tried this, but it seems pretty straightforward:

sudo cryptsetup-reencrypt /dev/loop0p2

Now give it a strong mount passphrase :

sudo cryptsetup luksChangeKey /dev/loop0p2

From here, continue as usual to boot the device. In the case of a downloaded image, remove the loop device and flash the image:

sudo losetup -d /dev/loop0
cd devkit_image/
uuu flash_librem5r4.lst

Once inside the freshly booted Librem 5, open the terminal application and expand the partition:

sudo parted /dev/mmcblk0 resizepart 2 100%
sudo cryptsetup resize crypt_root
sudo resize2fs /dev/mapper/crypt_root
5 Likes

I’ve followed all the instructions here to reflash device:
https://developer.puri.sm/Librem5/Development_Environment/Phone/Troubleshooting/Reflashing_the_Phone.html

but I’m getting error when running the script:

INFO Looking for librem5r4 luks byzantium image
ERROR No matching image found

nothing I’ve tried has worked sadly

That is because there are no Byzantium images from Jenkins at the moment, other than QEMU plain. I also mentioned this in a different thread.

https://arm01.puri.sm/job/Images/job/Image%20Build/

Another Librem 5 owner was able to reflash the Librem 5 using the argument “stable”, so use it for now until Jenkins builds images succcessfully again or the script itself is updated to default to stable.

./scripts/librem5-flash-image --stable

can you encrypt the drive with LUKS1 or LUKS2 once an unencrypted image has been flashed using jumpdrive?

Yes (cryptsetup reencrypt --encrypt) but …

  • you will definitely want to image (make backup of) the disk before doing this (just in case!)
  • you will need to tell it to make the device smaller by 32 MB to allow for the LUKS header (hence wouldn’t be possible if your existing unencrypted file system is very close to full)
  • avoid any power interruption or other interruption during the process
  • and anything else I haven’t thought of so … caveat emptor

Read man cryptsetup-reencrypt carefully, note warnings and note examples.

I think the right approach to the second bullet point is to shrink the file system before starting this exercise. That is, I don’t think the above procedure will itself shrink the file system.

Personally, I did not take the above approach, instead just taking a copy of important files, reflashing from the LUKS variant disk image, and then manually reconfiguring / restoring important files.

2 Likes

awesome thanks @irvinewade I will give it a try, this is just for testing so if something goes wrong no loss

One question i have on

Encrypt LUKS2 device (in-place). Make sure last 32 MiB on /dev/plaintext is unused (e.g.: does not contain filesystem data):

cryptsetup reencrypt --encrypt --type luks2 --reduce-device-size 32m /dev/plaintext_device

Does that mean that a new 32MB partition on the device has to be created that is free? Or just that there needs to be 32MB free on the partition you are going to encrypt in place? Also when formatting the 32MB free partition what format is ideal FAT? I guess the other question is if the command --reduce-device-size 32m automatically resizes existing partition by creating a new free partition, so you don’t have to manually do it?

With the disclaimer that I did not do this …

No

Yes, this.

But not just any 32 MB that is free. I believe it has to be the last 32 MB that is free.

Not applicable.

That’s half correct. There’s no new partition. There is an effective adjustment to the size of the existing partition - but whatever happens you don’t have to make that adjustment because the command does it for you. The existing partition is reduced automatically by that command (in order to allow space for the LUKS header). So you don’t have to change the size of the partition.

(Actually, the 32 MB free space at the end, apart from allowing room for the LUKS header, may also allow the process to be done “in place” - because it is using that free space as part of rewriting the entire plaintext partition while not stuffing it up. But I don’t know the details of the implementation. Might have to read sources.)

PS To save you having to mess around further, you may want to choose the key slot encryption parameters at the time of first encryption. That is, if you use the example command as shown then you are taking default parameters for both the disk encryption and the key slot encryption. The default for disk encryption will likely be appropriate (based on recent testing, and only in my opinion of course) but the default for key slot encryption may not be ideal for the Librem 5 (although “ideal” is in the eye of the beholder). Refer e.g. Our LUKS fde may not be enough anymore - #66 by Loki and discussion around that post.

However it’s not that big a deal. While (re-)encrypting the entire disk is going to be slow, changing the encryption of the key slot after the fact is quite quick.

yeiks

sudo cryptsetup reencrypt --encrypt --type luks2 --reduce-device-size 32m /dev/plaintext_device

took about 50min, however on reboot mobian was stuck on the screen showing all the device mapping warts (like gnss etc.), the LUKS passphrase entry window never showed.

sudo cryptsetup reencrypt --decrypt --header detached-luks2-header /dev/plaintext_device

took about 50min, now it is back to normal and booting.

I encrypted the main usable partition ~32GB in /dev/sdx2, I wonder if I should have encrypted the entire eMMC /dev/sdx instead, though I don’t think so. Maybe I will try to do the default type or LUKS1 encryption, maybe that works better, I remember having used that in the past without issues.

I think just the individual (root) partition. But then:

I don’t think you mentioned that little detail.

You would need to know what Mobian expects! Assuming that it expects an unencrypted boot partition, you would need to know whether you have to change anything in the boot partition in order to handle an encrypted root partition and you would need to know what specific encryption support it has.

Unless this is a test phone, I would not put LUKS1 on it. LUKS1 lacks important features that contribute to security (hence the existence of LUKS2). LUKS1 is much better than plaintext but if you really find that Mobian only has support for LUKS1 then I think you are driving yourself into a corner. Alternatively, maybe it is possible to upgrade Mobian before even starting this exercise so that it does have full support for LUKS2. You would need to investigate Mobian’s documentation.

Regardless of any of the above … after the reencrypt --encrypt it can be helpful to verify the encrypted partition on the host computer i.e. by opening it and mounting it on the host. If it all looks fine on the host then that is a good sign that adding encryption did at least work. I appreciate that you have now reverted the change and hence can’t immediately do that.

1 Like

I looked at it and it was fine, cryptsetup did it’s job as expected, so most likely mobian boot order or setup not knowing what to do with encrypted root.

1 Like