How do I unlock my LUKS disks on Ubuntu 26.04 from a Live USB (if my computer is ubootable)?

Ubuntu Version: 26.04

Desktop Environment (if applicable): GNOME

Background

I have installed Ubuntu 26.04 using full-disk TPM-backed LUKS encryption.

Problem Description:

Suppose that my computer is unbootable because of some serious problem. Prior to Ubuntu 26.04, I could boot from a Live USB, and unlock my LUKS partition using my LUKS passphrase.

This doesn’t work with an Ubuntu 26.04 machine.

There are two LUKS partitions, namely ubuntu-save and ubuntu-data. The following discussion applies to both of them.

If I open gnome-disks, choose to unlock either of the LUKS partitions, and enter the recovery key (from the installation process), it says that the passphrase is invalid.

The same thing happens if I try from the terminal using cryptsetup or systemd-cryptsetup.

According to AI, I have to write a Python script to do this! I have searched and cannot find where the correct method is documented.

Question:

How do I unlock my Ubuntu 26.04 LUKS partitions from a Live USB, when my recovery key (which I have quadruple-checked) doesn’t work?

Relevant System Information:

In case it makes a difference, I am testing this in a virtual machine (VirtualBox). The host is Ubuntu 24.04.

1 Like

Step 1: Mount the Seed Partition

First, you need to mount the ubuntu-seed partition so the recovery system can access the sealed key files.

sudo mkdir -p /mnt/seed
sudo mount /dev/sda2 /mnt/seed

Step 2: Install or Run the FDE Key Reveal Tool

Ubuntu provides an internal utility to handle the cryptographic handshake between your recovery key and the files on the seed partition. In your terminal on the Live USB, run:

sudo snap run ubuntu-core-fde-utils.fde-reveal-key --key-file /mnt/seed/device/fde/recovery.key

(Note: Depending on your exact live image state, if the utility isn’t present, you can install the helper tools via sudo apt install ubuntu-core-fde-utils or check /usr/share/ubuntu-core-fde/ for the revelation scripts).

Alternatively, if you are using the official recovery workflow integrated into systemd/snapd on newer images, you can pass the recovery key to the snapd FDE agent:

sudo systemd-cryptsetup attach ubuntu-data-enc /dev/sda5 none --key-file=<(_)

Step 3: Unlock via standard Cryptsetup using the derived key

Once the ubuntu-core-fde-utils or the underlying snap components process your recovery key against the seed, it reveals the actual pass-token. You can pipe or pass this master token directly into standard cryptsetup:

# If using the specialized tool to output the decrypted master passphrase:
sudo cryptsetup luksOpen /dev/sda5 ubuntu-data --key-file=/path/to/revealed/master.key

Summary of Why cryptsetup Alone Failed

Method Why it failed
Traditional LUKS Passphrase directly opens a keyslot in the LUKS header.
Ubuntu TPM-backed FDE The recovery key decrypts a master key payload stored inside /dev/sda2 (ubuntu-seed), which then opens the LUKS partition.

Note on VirtualBox: Since you are testing this in VirtualBox, ensure that your Virtual Machine has TPM 2.0 enabled in its settings if you ever intend to test the automatic, non-recovery boot flow. However, for this Live USB recovery test, the virtual TPM status doesn’t matter since the recovery key bypasses it completely.

1 Like

I’ve already tried. As @Actionparsnip explains, the recovery key isn’t the LUKS key, which is part of what confused me.

Yes, I have done this.

Here, I get stuck.

$ sudo snap run ubuntu-core-fde-utils.fde-reveal-key --key-file /mnt/seed/device/fde/recovery.key
error: snap "ubuntu-core-fde-utils" is not installed

And

$ ls -l /usr/share/ubuntu-core-fde
ls: cannot access '/usr/share/ubuntu-core-fde': No such file or directory

And

$ sudo systemd-cryptsetup attach ubuntu-data-enc /dev/sda5 none --key-file=<( echo '[recovery key]' )
systemd-cryptsetup: unrecognized option '--key-file'=/dev/fd/63'

And

$ sudo systemd-cryptsetup attach ubuntu-data-enc /dev/sda5 none
Please enter passphrase for disk ubuntu-data (ubuntu-data-enc): *******…
Failed to activate with specified passphrase. (Passphrase incorrect?)

Unfortunately, I have absolutely no clue how to proceed.

Do you know where the process is documented? Because I can’t find it.

I found something else, but it didn’t help:

sudo snap install snap-tpmctl
sudo snap-tpmctl mount-volume /dev/sda5 /mnt/data

This mounts the volume, but it contains directories that I don’t understand, and don’t contain my home folder!

1 Like

Since I had nuked my FDE/TPM VM already but wanted to see for myself I’ve just spun up a new one; offline install to get through as quickly as possible. I then booted the VM once; when asked for the recovery key, I entered it (without the dashes) and the system was unlocked, booted fine. Then I tried to reproduce @paddylandau’s scenario, so I rebooted into the live session (“Try Ubuntu”). In my since deleted post I posited to try and enter the recovery key without the dashes as well, but I have now found out that it doesn’t work.

Now I’m trying to follow your steps, @Actionparsnip and they don’t seem to work either.

Check.

I get:

error: snap "ubuntu-core-fde-utils" is not installed
$ sudo snap install ubuntu-core-fde-utils
error: snap "ubuntu-core-fde-utils" not found
$ sudo apt install --update ubuntu-core-fde-utils
Ign:1 file:/cdrom resolute InRelease
Get:2 file:/cdrom resolute Release [664 B]
Get:2 file:/cdrom resolute Release [664 B]                               
Hit:4 http://security.ubuntu.com/ubuntu resolute-security InRelease            
Hit:5 http://archive.ubuntu.com/ubuntu resolute InRelease                
Hit:6 http://archive.ubuntu.com/ubuntu resolute-updates InRelease
Hit:7 http://archive.ubuntu.com/ubuntu resolute-backports InRelease
206 packages can be upgraded. Run 'apt list --upgradable' to see them.
Notice: Skipping acquire of configured file 'restricted/binary-i386/Packages' as repository 'file:/cdrom resolute InRelease' doesn't support architecture 'i386'
Notice: Skipping acquire of configured file 'main/binary-i386/Packages' as repository 'file:/cdrom resolute InRelease' doesn't support architecture 'i386'
Error: Unable to locate package ubuntu-core-fde-utils

And /usr/share/ubuntu-core-fde/ doesn’t exist either.

I guess I can just skip this because I have no key yet. BTW, what is <(_) supposed to do; is that some kind of Bash magic? IIUC, this should be the equivalent:

_ | sudo systemd-cryptsetup attach ubuntu-data-enc /dev/sda5 none
1 Like

You must also have found this then :wink:

That command (mount-volume) is a little misleading, because it didn’t mount the partition at all — perhaps because the seed partition was already mounted there(?); it just activates a device mapping of it in /dev/mapper/dev-sda5. You can mount that wherever you like:

sudo mount /dev/mapper/dev-sda5 /mnt

:tada:

1 Like

Nope, I just rebooted afresh and that was the first thing I did.

$ ls /mnt
$

(nothing)

According to the journal, however, it was mounted but it’s nowhere to be found; not in the output of mount nor in /proc/mounts:

Jun 22 18:38:34 ubuntu systemd[1]: Started snap.snap-tpmctl.snap-tpmctl-93525cfc-fc8f-442f-a9d1-8e4149cd02f3.scope.
Jun 22 18:38:34 ubuntu kernel: kauditd_printk_skb: 6 callbacks suppressed
Jun 22 18:38:34 ubuntu kernel: audit: type=1400 audit(1782153514.377:230): apparmor="DENIED" operation="open" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/sys/fs/cgroup/system.slice/snap.snap-tpmctl.snap-tpmctl-93525cfc-fc8f-442f-a9d1-8e4149cd02f3.scope/cpu.max" pid=9501 comm="snap-tpmctl" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jun 22 18:38:38 ubuntu kernel: audit: type=1326 audit(1782153518.806:231): auid=1000 uid=0 gid=0 ses=2 subj=snap.snap-tpmctl.snap-tpmctl pid=9501 comm="snap-tpmctl" exe="/snap/snap-tpmctl/96/bin/snap-tpmctl" sig=0 arch=c000003e syscall=424 compat=0 ip=0x40e1ae code=0x50000
Jun 22 18:38:39 ubuntu sudo[9561]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=0)
Jun 22 18:38:39 ubuntu sudo[9561]: root :  PWD=/snap/ubuntu-desktop-bootstrap/589/bin/subiquity ; USER=root ; COMMAND=/usr/sbin/dmsetup info /dev/dm-0 -C -o name,uuid,blkdevname,blkdevs_used,subsystem --noheading --separator =
Jun 22 18:38:39 ubuntu sudo[9561]: pam_unix(sudo:session): session closed for user root
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.482:232): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9566 comm="pvscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.482:233): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9566 comm="pvscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.482:234): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9566 comm="pvscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.482:235): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9566 comm="pvscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.534:236): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9567 comm="vgscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.534:237): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9567 comm="vgscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.534:238): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9567 comm="vgscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.534:239): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9567 comm="vgscan" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.598:240): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9568 comm="vgchange" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: audit: type=1400 audit(1782153519.598:241): apparmor="ALLOWED" operation="getattr" class="posix_mqueue" profile="snap.ubuntu-desktop-bootstrap.subiquity-server" name="/" pid=9568 comm="vgchange" requested="getattr" denied="getattr" class="posix_mqueue" fsuid=0 ouid=0 olabel="unconfined"
Jun 22 18:38:39 ubuntu kernel: EXT4-fs (dm-0): mounted filesystem b13e6b1d-3a46-437f-9f2f-a2d522f0ca10 r/w with ordered data mode. Quota mode: none.
Jun 22 18:38:39 ubuntu systemd[1]: snap.snap-tpmctl.snap-tpmctl-93525cfc-fc8f-442f-a9d1-8e4149cd02f3.scope: Deactivated successfully.
$ grep -e b13e6b1d-3a46-437f-9f2f-a2d522f0ca10 -e ext4 /proc/mounts
$ mount | grep -e b13e6b1d-3a46-437f-9f2f-a2d522f0ca10 -e ext4

:cricket:

Even snap-tpmctl can’t unmount it:

$ sudo snap-tpmctl unmount-volume /mnt
ERROR: unable to remove mount point: openfdat //mnt: permission denied

This is what the journal has to say about that:

Jun 22 19:12:31 ubuntu sudo[7839]: pam_unix(sudo:session): session opened for user root(uid=0) by ubuntu(uid=1000)
Jun 22 19:12:31 ubuntu sudo[7839]: ubuntu : TTY=/dev/pts/0 ; PWD=/home/ubuntu ; USER=root ; COMMAND=/snap/bin/snap-tpmctl unmount-volume -v /mnt
Jun 22 19:12:32 ubuntu systemd[1]: Started snap.snap-tpmctl.snap-tpmctl-c60cd226-26be-41a0-bca2-08e652b067a5.scope.
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.044:207): apparmor="DENIED" operation="open" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/sys/fs/cgroup/system.slice/snap.snap-tpmctl.snap-tpmctl-c60cd226-26be-41a0-bca2-08e652b067a5.scope/cpu.max" pid=7842 comm="snap-tpmctl" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.118:208): apparmor="DENIED" operation="unlink" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/mnt/" pid=7842 comm="snap-tpmctl" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.119:209): apparmor="DENIED" operation="rmdir" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/mnt/" pid=7842 comm="snap-tpmctl" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.119:210): apparmor="DENIED" operation="unlink" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/mnt/" pid=7842 comm="snap-tpmctl" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.119:211): apparmor="DENIED" operation="open" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/mnt/" pid=7842 comm="snap-tpmctl" requested_mask="r" denied_mask="r" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu kernel: audit: type=1400 audit(1782155552.119:212): apparmor="DENIED" operation="rmdir" class="file" profile="snap.snap-tpmctl.snap-tpmctl" name="/mnt/" pid=7842 comm="snap-tpmctl" requested_mask="d" denied_mask="d" fsuid=0 ouid=0
Jun 22 19:12:32 ubuntu systemd[1]: snap.snap-tpmctl.snap-tpmctl-c60cd226-26be-41a0-bca2-08e652b067a5.scope: Deactivated successfully.
Jun 22 19:12:32 ubuntu sudo[7839]: pam_unix(sudo:session): session closed for user root

Looks like some AppArmor issue; perhaps a missing profile?

If I hadn’t done this again:

$ sudo snap-tpmctl mount-volume -v /dev/sda5 /mnt
ERROR: unable to activate device: resource is already mapped as "/dev/mapper/dev-sda5"

I wouldn’t have found out where to go next. From there it was just sudo mount /dev/mapper/dev-sda5 /mnt, as I said.

So far this experience has been a bit of a letdown. I mean, how are actual newbies going to fare in such a situation?

1 Like

@peterwhite23 Thank you for taking the trouble to test! By having the same results as me, you’ve confirmed that I’m not the only one to struggle with this.

Curiously not! I found it somewhere else; I think that it was from Google’s search AI.

But, I’m glad that you pointed it out. I’ve saved the link.

For whatever reason, yesterday I was completely unable to get it working; today, I have managed, partly thanks to your comments!

The process

For future reference, here’s the process. In this case, my data partition (ubuntu-data) is on /dev/sda5.

sudo snap install snap-tpmctl
sudo mkdir /mnt/data
sudo snap-tpmctl mount-volume /dev/sda5 /mnt/data
    # Enter the recovery key when prompted. If you forget to use
    # "sudo", this will fail but without an error message.

At this point, /dev/sda5 is unlocked but it isn’t mounted! The directory /mnt/data has been utterly spurious despite being required on the command line.

mount | grep -E 'sda5|data'    # Nothing found.

So, it remains to mount the unlocked partition.

ls -l /dev/mapper      # Discover the unlocked partition's name.
                       # In my case, it's "dev-sda5".
sudo mount /dev/mapper/dev-sda5 /mnt/data

Finally, the partition has been mounted in /mnt/data.

You can repeat this process for ubuntu-save (in my case, sda4) if required.

Unmounting and locking

According to the documentation, the way to unmount and lock is this:

sudo snap-tpmctl unmount-volume /mnt/data     # or, maybe, /dev/sda5

But, it doesn’t work. It returns an error. The correct way:

sudo umount /mnt/data                           # Unmount the partition.
sudo cryptsetup luksClose /dev/mapper/dev-sda5  # Lock the LUKS partition.

Bugs

It appears that snap-tpmctl has three bugs:

  • Locking and mounting is incomplete; it only unlocks, not mounts.
  • Unmounting and locking doesn’t work at all.
  • It should return a meaningful error message if you try to mount without using sudo.

Exactly. I’m a seasoned Ubuntu user (since 2008), and I needed plenty of help to figure it out.

I’ll wait for a response by @Actionparsnip or anyone else, and unless I’m corrected, I’ll raise a bug report for this (which I’ll post here once done).

2 Likes

I have reported the bug for snap-tpmctl here:

1 Like

In a more general context, imagine your topic title to be “How do I unlock my disks on a different machine?”. The way I see it, the recovery key can only work with the TPM of the machine it was created on, hence the snap-tmpctl to derive the actual LUKS2 key from key material stored in the TPM in a write-only fashion; you’ll never be able to read it from the TPM. So, if your machine dies, the decryption key dies with it. :warning:

Unless you keep your backups current, your data will be lost. I think the lesson here is to also use one of the LUKS2 key slots for a key that’s independent of the TPM.

1 Like

That is precisely the next question that I’ve been working on! My next mini-project is to take my hard drive (actually a virtual drive) onto another machine (VM, of course) and test this.

Supposedly, according to what I can figure out (but with low confidence), the recovery key is an encrypted version of the LUKS key.

I’m trying to figure out how to get that LUKS key. According to the documentation, it’s this:

$ snap-tpmctl get-luks-key
Enter recovery key: *****-*****-*****-*****-*****-*****-*****-*****
LUKS key (hex): [32-digit hex string]

But, it doesn’t work. It’s not machine-dependent, because it returns the same result on a different machine. But I cannot get the returned key or the recovery key to work at all, even after trying various mechanisms including with the help of AI.

The alternative, of course, is to create a second key with your own passphrase (LUKS partitions can have up to 32 separate keys). This is what I’ll use if I can’t get the official method to work.

Success! I’ve just done this, and it works like a charm.

Therefore, this proves that the recovery key is, somehow, related to the LUKS key. It’s not the key, because it doesn’t work when using cryptsetup to unlock the LUKS partition.

I am so curious as to how to get the LUKS key from the recovery key!

Can you elaborate a bit on what you’ve done? From my understanding it shouldn’t work with a different TPM; maybe you VM setup reuses the same TPM including its inner state?

That much, I think, we can take for granted. The question is, how the TPM is involved in deriving the actual LUKS key. I think it must be something to do with PCR’s; you (snap-tpmctl) strip the dashes and write the raw value into the right PCR and it responds with the decrypted LUKS key, is my guess, from what little I understand of the whole TPM topic. After all, the TPM is like a smartcard (think: Yubikey/Nitrokey). It stores crypto material in a black box and one can never get it out of there[1].


  1. unless there is a bug in its implementation, which cracks the black box open ↩︎

The TPM chip merely stores the key on behalf of the user, so that the user doesn’t have to repeatedly type it. The TPM chip doesn’t derive the key at all; it merely releases the key when given the right credentials.

All that happens, on boot, is that Ubuntu’s security system checks that the boot section hasn’t been tampered with. If it checks out OK, it gives permission to the TPM chip to release the key, which the boot process can then use to unlock the drive.

I don’t know whether the TPM chip stores the LUKS key or the recovery key. If the latter, presumably snap-tpmctl creates the LUKS key from the recovery key.

  • Remember that I was using the recovery key, and snap-tpmctl creates the LUKS key from the recovery key. It doesn’t retrieve it from the TPM chip. That’s the whole point: If the TPM chip loses the key (eg some firmware updates do this), or if you have to move your drive to a different machine because your machine died, you can still access your partition with the recovery key.
  • Each VM has its own independent virtual TPM chip (vTPM). They cannot access each others’ vTPM.
  • When you export a VirtualBox VM (extension .ova), the vTPM isn’t included. This means, for example, that exporting a Windows 11 VM with bitlocker enabled will render the VM unusable on restore. To retain the vTPM, you have to back up the VM itself (extension .vbox). Or, get the bitlocker recovery key before you export the Windows VM, so the vTPM isn’t required.

Sure. All that I did was to attach the virtual drive to a different VM, and follow the process that I documented in comment #9. In this case, the drive was /dev/sdb instead of sda.

1 Like

The actual LUKS recovery key is 16 bytes binary value which is printed as 32 digits hex string. You need to convert this string into binary form, e.g. using xxd -r -p.

bor@resolute:~$ snap-tpmctl  get-luks-key
Enter recovery key: *****-*****-*****-*****-*****-*****-*****-*****
LUKS key (hex): d204d5ddd204d5ddd204d5ddd204d5dd
bor@resolute:~$ echo d204d5ddd204d5ddd204d5ddd204d5dd | xxd -r -p > /tmp/key
bor@resolute:~$ ll /tmp/key
-rw-rw-r-- 1 bor bor 16 Jun 25 13:12 /tmp/key
bor@resolute:~$ hexdump -C /tmp/key
00000000  d2 04 d5 dd d2 04 d5 dd  d2 04 d5 dd d2 04 d5 dd  |................|
00000010
bor@resolute:~$ 

The TPM is not used in converting the external textual representation (8 groups of digits) into binary LUKS key, so it can be used on any system.

2 Likes

This is one of the methods that I already tried. I create the binary file, and attempt to unlock the LUKS partition with it using:

sudo cryptsetup luksOpen --volume-key-file=/tmp/key /dev/sda5 data

The problem is that cryptsetup rejects this with the error message:

Cannot read 64 bytes from keyfile /tmp/key.

I don’t know why it’s complaining, because the absolute minimum size for a LUKS key is 128 bits, ie 16 bytes. EDIT: I was using the wrong parameter! When I used --key-file, it worked!

Having said that, why does Ubuntu installation generate such a small LUKS key? Surely 128 bits is not that secure?

Thanks. I’d figured that out, but it’s nice to have confirmation.

I would not read that as “the whole disk encryption is only 128-bit because Ubuntu was careless”. With `–key-file` cryptsetup is treating that 16-byte value as keyslot input, not as the raw LUKS volume key. If the value is generated randomly, 128 bits is still a very large search space; it is not comparable to a 16-character human password. The important practical bit is what you already found: convert the hex to binary and use `–key-file`, not `–volume-key-file`. The latter is for the actual decrypted volume key and expects the exact key size from the LUKS header.

1 Like

Thank you, that makes sense.

LOL, it’s all so much simpler:

$ printf "%.4x " $(tr - ' ' <recovery-key.txt | sed -E 's/\b0*//g' ); printf "\b\n"
4c6b 0d52 6395 7d23 cd05 8bc1 76b9 ac81
$ sudo snap-tpmctl get-luks-key --hex
Enter recovery key: *****-*****-*****-*****-*****-*****-*****-*****
6b4c520d9563237d05cdc18bb97681ac

Do you see the pattern yet? :grin:

The first command line just replaces the -'s with spaces and the printf "%.4x " converts the arguments from decimal to hexadecimal (the last printf is just for cosmetics). The only thing to look out for is endianness; since x86 is little endian, the bytes are swapped when printed. Other than that the recovery key is the key for the slot just encoded in a more human-readable form.

The only thing that’s left is to swap endianness of the byte groups and you’ve got yourself a recovery key that LUKS can understand.

BTW, snap-tpmctl get-luks-key also supports --escaped; feed that output into your key file and no more conversion is necessary. So, in all, get-luks-key is just a helper to convert the (human-readable) recovery key into machine code. I bet, under the hood snap-tpmctl mount-volume takes a detour to get-luks-key --escaped, so it never even touches the TPM for this operation, which is a huge relief. :sweat_smile:

1 Like

Thank you, Peter, that’s interesting. It’s nice to know the mechanism that snap-tpmctl is using.

I was aware of --escaped, but you can’t put that directly into the key file. It needs to be the actual binary data.

So, to create the printable key from the recovery key without using snap-tpmctl, you can do this (figured out with your help!).

$ RK=40353-54138-02919-59702-05071-13346-12699-00484
$ printf '%04x' $( tr - ' ' <<<${RK} | sed -E 's/\b0*//g' ) | sed -E 's/([0-9a-f]{2})([0-9a-f]{2})/\2\1/g' ; printf '\n'

Or, to create the binary key file:

$ RK=40353-54138-02919-59702-05071-13346-12699-00484
$ printf '%04x' $( tr - ' ' <<<${RK} | sed -E 's/\b0*//g' ) | sed -E 's/([0-9a-f]{2})([0-9a-f]{2})/\2\1/g' | xxd -plain -revert >luks.key

Nice to know!