anatol / booster

Fast and secure initramfs generator
MIT License
504 stars 45 forks source link

Fail to unlock LUKS by password #202

Closed ZJaume closed 6 months ago

ZJaume commented 1 year ago

I'm booting Arch with a booster UKI bundled with sbctl (maybe this is causing the issue?) and have LVM on LUKS for root partition. Booster is asking for the passphrase but no matter what it always fails. imatge

My password does not have any special character but I enabled vconsole anyway to see if it was a problem with the keymap, but the same. I've also tried to add a very simple password entry but it also fails. The LUKS partition is ok because I'm currently able to boot through a dracut image. I don't know if booster works on my machine bundling the image with a bootloader because I have an encrypted boot and it's a bit more complicated to configure anything that is not an UKI.

This is the current config:

enable_lvm: true
strip: false
universal: true
mount_timeout: 1m
vconsole: true
extra_files: busybox,fsck,fsck.ext4

EDIT: commands to generate the image:

sudo booster build -f /boot/booster-linux.img
sudo sbctl bundle -a /boot/amd-ucode.img -f /boot/booster-linux.img /efi/Linux/archlinux.efi

and the content of /etc/kernel/cmdline which is sourced by sbctl:

rd.luks.name=UUID=cryptolvm rd.luks.options=discard root=/dev/mapper/root rootfstype=ext4 rootflags=rw,relatime,data=ordered
anatol commented 1 year ago

In your boot parameters you specify crypt device name cryptolvm. It will add /dev/mapper/cryptolvm device file.

But your root is /dev/mapper/root and booster never sees such device, thus times out.

Try to change root to root=/dev/mapper/cryptolvm and see if it makes any difference for you.

anatol commented 1 year ago

Also why there are so many password retries for cryptolvm? Did you enter an invalid password? Or is it some problem with booster?

ZJaume commented 1 year ago

Sorry about the confusion, I was hiding the real name of the root volume. The scheme is an LVM on LUKS and the parameter real value is root=/dev/mapper/Vol-root, so I guess it's ok, right? It's been like that with mkinitcpio and was working well.

Also why there are so many password retries for cryptolvm ? Did you enter an invalid password? Or is it some problem with booster?

That is reason of my question. I was writing the right password. I tried many times and always giving me this. Furthermore, I'm able to boot through another efi binary that has been bundled with the mkinitcpio, so the partition and the password are ok.

If we need to debug this, is there any way of testing the booster decryption separately? Maybe a simple small program to open it using the luks go module? I've enable the debug mode and no other messages appear during the unlocking attempts.

anatol commented 1 year ago

LVM on LUKS and the parameter real value is root=/dev/mapper/Vol-root, so I guess it's ok, right?

LVM-on-LUKS is supported by booster. So it should be fine.

The best way to start debugging is to enable debug logs with booster.debug kernel parameter. It will print a lot of information to the console. Once you type the password it will print the reason why the password did not match. It will give clues on what is going on at your host.

ZJaume commented 1 year ago

The debug option does not say anything more. Just incorrect password during the attempts. imatge

anatol commented 1 year ago

It is a weird issue. If the password failed due to some missing modules, then an error message would be printed. But here we have no any messages.

Are you sure you type the correct password for cryprolvm? Do you use non-ASCII symbols in your password? Do you have non-English keyboard that needs to be configured?

I would start with trying the latest changes from master branch and see if the problem still exists. Then try to modify requestKeyboardPassword() function https://github.com/anatol/booster/blob/d8348d24abb47a0161bebd4305a3902eb8fdc8d6/init/luks.go#L363 and print the entered password just to make sure it is precisely the same as expected.

Also, do you use any non-standard cyphers/hash functions for your LUKS partition? Do you remember how did you format it?

ZJaume commented 1 year ago

The password doesn't seem to be the problem neither the keyboard. I have an Spanish keyboard, but the main password does not have any non-ASCII character. Furthermore, I added vconsole module and mount timeout, and when the console starts, I type the password and the characters are correct. I've also tried to add a new keyslot, with a dummy password (1234) but didn't work neither. I never used any custom parameter when adding keyslots. They key derivation functions are pkdf2 for the old one and argon2id for the dummy, both are standard and supported, right? The only thing that could be strange in my partition is that it was LUKS1 and I converted it to LUKS2 when it came out. But mkinitcpio has always been able to decrypt it.

I've tried master with the booster-git package from the aur, plus adding some debug messages and didn't work.

This is the code:

diff --git a/init/luks.go b/init/luks.go
index 8845f60..0ebc392 100644
--- a/init/luks.go
+++ b/init/luks.go
@@ -364,6 +364,7 @@ func requestKeyboardPassword(volumes chan *luks.Volume, d luks.Device, checkSlot
        for {
                prompt := fmt.Sprintf("Enter passphrase for %s:", mappingName)
                password, err := readPassword(prompt, "   Unlocking...")
+                debug("entered password: %s", password)
                if err != nil {
                        warning("reading password: %v", err)
                        return
@@ -373,8 +374,10 @@ func requestKeyboardPassword(volumes chan *luks.Volume, d luks.Device, checkSlot
                }

                for _, s := range checkSlots {
+                        debug("trying slot %v", s)
                        v, err := d.UnsealVolume(s, password)
                        if err == luks.ErrPassphraseDoesNotMatch {
+                                debug("passphrase does not match for slot %v", s)
                                continue
                        } else if err != nil {
                                warning("unlocking slot %v: %v", s, err)

and the messages trying the dummy password that I added for debugging purposes: imatge

The command that I've used to add this new slot was cryptsetup luksAddKey /dev/nvme0n1p2 and for the migration it was cryptsetup format --type luks2 /dev/nvme0n1p2.

anatol commented 1 year ago

and for the migration it was cryptsetup format --type luks2 /dev/nvme0n1p2.

I believe you need to use cryptsetup convert tool for format conversion.

They key derivation functions are pkdf2 for the old one and argon2id for the dummy, both are standard and supported, right?

Correct, both derivation functions are supported. If the problem was related to a missing algorithm it would print an error message.

Could you please provide the luks partition info with cryptsetup luksDump /dev/nvme0n1p2? (clear Salt/Digest fields before sharing it).

ZJaume commented 1 year ago

I believe you need to use cryptsetup convert tool for format conversion.

I didn't remember that command, I suppose that I used that.

Could you please provide the luks partition info with cryptsetup luksDump /dev/nvme0n1p2? (clear Salt/Digest fields before sharing it).

Sure, this is the whole output of the command, omitting salts, digests and UUID.

LUKS header information
Version:        2
Epoch:          14
Metadata area:  16384 [bytes]
Keyslots area:  2064384 [bytes]
UUID:           
Label:          (no label)
Subsystem:      (no subsystem)
Flags:          (no flags)

Data segments:
  0: crypt
    offset: 2097152 [bytes]
    length: (whole device)
    cipher: aes-xts-plain64
    sector: 512 [bytes]

Keyslots:
  0: luks2
    Key:        256 bits
    Priority:   normal
    Cipher:     aes-xts-plain64
    Cipher key: 256 bits
    PBKDF:      pbkdf2
    Hash:       sha256
    Iterations: 2267994
    Salt:       

    AF stripes: 4000
    AF hash:    sha256
    Area offset:32768 [bytes]
    Area length:131072 [bytes]
    Digest ID:  0
  1: luks2
    Key:        256 bits
    Priority:   normal
    Cipher:     aes-xts-plain64
    Cipher key: 256 bits
    PBKDF:      argon2id
    Time cost:  7
    Memory:     1048576
    Threads:    4
    Salt:       

    AF stripes: 4000
    AF hash:    sha256
    Area offset:163840 [bytes]
    Area length:131072 [bytes]
    Digest ID:  0
  2: luks2
    Key:        256 bits
    Priority:   normal
    Cipher:     aes-xts-plain64
    Cipher key: 256 bits
    PBKDF:      argon2id
    Time cost:  6
    Memory:     1048576
    Threads:    4
    Salt:       

    AF stripes: 4000
    AF hash:    sha256
    Area offset:294912 [bytes]
    Area length:131072 [bytes]
    Digest ID:  0
Tokens:
Digests:
  0: pbkdf2
    Hash:       sha256
    Iterations: 283250
    Salt:       

    Digest: 

EDIT: I also realised that I had no_read_workqueue and no_write_queue enabled as flags. I have now disabled those and retried, but the issue still persists.

deathtrip commented 1 year ago

I'm having the same problem, with LUKS2 (also converted from LUKS1) on LVM and ext4 as root filesystem. The password is good as i can boot with mkinitcpio image. What's interesting is i can boot using booster into an different arch installation with XFS as rootfs , even on the same hardware and same booster and LUKS configs. However that installation was using LUKS2 from the beginning. So maybe its the ext4 + LUKS/LVM combo that's causing this, or booster has some issue reading converted LUKS2 headers.... Will try to investigate further...

deathtrip commented 1 year ago

After checking debug messages i got the unknown digest error : whirlpool. I forgot the other install was using sha-3, as the ciphers were the same.

However the error message should give the unknown cipher/digest error by default, without adding the debug kernel parameter, as i was getting the same Incorrect passphrase... error, which is confusing.

Anyway, i guess i'll have to wait until support is added, as per this issue.

anatol commented 1 year ago

@deathtrip I just added whirlpool hash algorithm support to luks.go library: https://github.com/anatol/luks.go/commit/fb3724ed7db791fb2b8d785bd5eb95d39c8c58ed

deathtrip commented 1 year ago

After trying the new release, i still can't unlock the volume with my password. Except now i don't get any unknown digest error warnings. The install without whirlpool works fine. So now i'm not sure if it's the hash or something else.

nmeum commented 10 months ago

I'm having the same problem, with LUKS2 (also converted from LUKS1) on LVM and ext4 as root filesystem.

I am also running into this. I cannot open a LUKS2 device that was converted from LUKS1. As described in this issue, the password always seems wrong even though it is definitely correct. Prior to the conversion, booster worked fine. Additionally, I have other machines which use a freshly installed LUKS2 (instead of a converted one) where Booster also works fine.

I suppose cryptsetup convert results in a format that is somehow incompatible with Boosters LUKS code?

nmeum commented 10 months ago

I am also running into this. I cannot open a LUKS2 device that was converted from LUKS1.

I debugged this further and this seems to be a bug in luks.go.

See: https://github.com/anatol/luks.go/issues/11

deathtrip commented 10 months ago

I also only had problems on a device converted from LUKS1 to LUKS2. OP was also using LUKS2 that was converted, so it looks like the cause of the problem is now known. Hopefully the pull request to luks.go will be accepted soon.