Closed UndeadDevel closed 11 months ago
Hi I could reproduce the issuse the Problem is that, if you change the Password with cryptsetup luksChangeKey in Qubes this changes the Keyslot, and the re encrypt feature is hardwired to use keyslot 0. see here https://github.com/linuxboot/heads/blob/1f39d16c25b426b176cefe4f8ef786c8743aed3d/initrd/etc/luks-functions#L338
So Workaround would be to use: cryptsetup luksChangeKey --key-slot=0
Edit: massively modified, please re-read.
Be cautious here.
As the re-ownership wizard explains, changing the luks passphrase alone doesn't prevent anyone that could have made a backup of the luks header prior of the hardware being in end user hands to restore it later on and use old luks passphrase to unlock the encrypted container later on. Here, that is PleaseChangeMe
.
As we understand here, Nitrokey pre-installs operating systems automatically with a LUKS slot 0 passphrase which is PleaseChangeMe
:
https://web.archive.org/web/20221127103205/https://docs.nitrokey.com/nitropad/faq
This means that any shipment having tamper bag seals broken imply a possible luks header backup that could be restored later on and that passphrase used to access its content unless the luks container is reencrypted. It also implies that if tamper bag seal is broken, content of encrypted container could have been accessed and modified. This makes the tamper seal bag really important since everyone interested knows that the disk encryption key passphrase is PleaseChangeMe
for all nitrokey in transit shipments to end users. Doing so is as easy as using the luksHeaderBackup and luksHeaderRestore subcommands of cryptsetup from Heads recovery shell without tampering anything else then the sealed bag for in-transit shipments.
This is why the re-ownership wizard proposes to reencrypt the luks container, which reencrypts in place the the luks container, not modifying its content. Then and only then, changing the luks header passphrase would prevent someone having a luks header backup to restore it and use old luks header's slot passphrase to unlock encrypted container and access its content. https://web.archive.org/web/20231121141735/https://docs.nitrokey.com/nitropad/qubes/factory-reset-heads shows it in action:
Would you like to change the current LUKS Disk Recovery Key passphrase? (Highly recommended if you didn't install the Operating System yourself, so that past provisioned passphrase would not permit to access content. Note that without re-encrypting disk, a backuped header could be restored to access encrypted content with old passphrase) [y/N]: N
Would you like to re-encrypt LUKS encrypted container and generate new Disk Recovery key? (Highly recommended if you didn't install the operating system yourself: this would prevent any LUKS backuped header to be restored to access encrypted data) [y/N]: N
On Heads side, I see that more output could be given here to explain why it fails. @nestire was right: heads expects the disk recovery key slot to be under slot 0, and expects TPM Disk Unlock Key to be injected in key slot 1.
It currently fails changing luks header 0 passphrase because none is there. By nitrokey documentation instructions, slot 0 was replaced by slot 1. This is what a LuksChange command does by default.
As @nestire said, if done without the luks header slot specified on the command line, a change passphrase on luks will permutate keys lots. So now your Disk Recovery Key is on slot 1 and none are on slot 0. Heads bails preventively here since manual changes has been made by the user.
Changing the luks header passphrase alone doesn't make a lot of sense really. Maybe it should be removed from Heads options? And maybe reencrypting luks container should propose to change passphrase at the same time?
I see.
The instructions on Nitrokey website are not consistent with how Heads currently works following above explanations
Each of the page referred from this link (ubuntu, debian, QubesOS) tells end users to do the command leading to this user bug report: https://docs.nitrokey.com/nitropc/
Example archived for debian: https://web.archive.org/web/20230521080526/https://docs.nitrokey.com/nitropc/debian/
Says to
sudo cryptsetup luksChangeKey /dev/nvme0n1p3
to change the luks encrypted key passphrase.
This should have been:
sudo cryptsetup luksChangeKey --key-slot=0 /dev/nvme0n1p3
Where again, changing keys slot passphrase is enough for prevent someone knowing the previous passphrase to unlock the disk, but won't prevent someone having a backup of the luks header to restore it and then use 'PleaseChangeMe' as explained earlier because of how nitrokey preinstalled the operating system: https://web.archive.org/web/20221127103205/https://docs.nitrokey.com/nitropad/faq
@daringer once again this is why oem factory reset/re-ownership wizard concept was so important for security : it takes care of replacing all OEM configured secrets with owner ones, reducing the liability on the OEM to what was shipped to the moment the hardware gets into user hands. But for that to happen, documentation needs to encourage the user to reencrypt the disk or at least explain the risks of not doing so.
Reencrypting luks container takes a while, needs to be applied at least once by end user (or whenever needed depending of threat model), but is the only way to end liability toward OEM possibly having leaked luks header. Yes, all luks containers are different (not cloned) but all disks having the same disk encryption key passphrase is a liability that needs to end on first boot of users computer.
Or at least users knowing that by not doing so, they accept the risks (data extraction possible for targeted users while traveling) when they refused to reencrypt their encrypted container on first boot following their OEM instructions (which should be to do Re-Ownership, as discussed many times across the years off-channel).
Proposing to change the passphrase only is not explaining the risks of not reencrypting an installation done by a third party, and the trust in that third party lasts forever unless the disk is reencrypted or otherwise when OS is reinstalled, of course without a disk encryption passphrase having been once PleaseChangeMe
otherwise same risks exist.
Thank you @tlaurion for the elaborations! I did indeed simply follow the FAQ, which is what lead to the situation; it would be nice if the FAQs could be looked over and improved, as this is not the only case where the instructions given are outdated or don't work.
I have now fixed the issue by running the same command in dom0 again (as adding the --keyslot=0
argument doesn't work if there's nothing in keyslot 0, while running without it if 0 is empty will use 0 by default, at least in my case). After that, re-encrypting the LUKS header did work, at least I assume so, as I've left the notebook alone for a bit and when I returned it was showing the standard Heads main menu again, so it probably rebooted or returned there after completing the process. If errors would stop that and instead show me what's wrong then this is fine. It also failed to boot properly until I resigned all checksums and the content of /boot, but I assume this is also as expected; might I suggest, however, that this be "chained" into the process of re-encrypting the header? A new user won't necessarily know to do these things. It would also be nice if the passphrase was not displayed there for the entire time on screen, as for some, who don't live alone in their house/apartment, it means that the laptop needs to have a towel covering it until the process has finished.
I'd also like to point out that Heads changed the PBKDF back to argon2i, while I had changed it to the more robust argon2id when I ran the command to put the key back in slot 0; the iteration count is also less than half than what it was before...it would be nice if Heads could detect what PBKDF and parameters are used and then apply the same when creating a new header, or at least default to more secure settings.
Another minor issue is that after re-encryption it now asks me for a TPM disk unlock key, which I have not set, while before it would go straight to the OS LUKS prompt. I suppose I could set a TPM passphrase, but I'm still on Heads 2.1, waiting for 2.4 until I upgrade since I want my iGPU to continue working and 2.3 seems to have too many issues, and I saw quite a lot of bugs regarding TPM disk unlock that were only fixed recently (e.g. no TRIM ops when TPM disk unlock is used), so it's probably better not to use it for now. If I don't set a TPM disk unlock passphrase then it shouldn't ask me for one, though.
The instructions on Nitrokey website are not consistent with how Heads currently works following above explanations Each of the page referred from this link (unbutu, debian, QubesOS) https://docs.nitrokey.com/nitropc/
NitroPCs are not running HEADS, this part of the documentation is correct to the FDE of this device. Nevertheless there is no description of how to do this for the Nitropads, so we added it into the FAQ for the Nitropads - including some explanation for re-ownership/re-encryption. Hope this clears up some things.
@UndeadDevel please close is issue if you see the initial point as being solved - or do you have other suggestions what might be explained more clearly?
@daringer Yes, it is solved; should I open a new issue for the inadequate TPM disk unlock passphrase prompt?
@daringer Yes, it is solved; should I open a new issue for the inadequate TPM disk unlock passphrase prompt?
@UndeadDevel Upstream under Heads would be great, yes, where it should be fixed. Same for re-encrypting disk which outputs a file that upstream thinks as being part of tpm Disk unlock key being set. Also, not setting specific settings for cryptsetup so that same options are reused to reencrypt the disk. Heads should not choose, or maybe should?
So basically I see 3 issues to be opened under Heads master.
@tlaurion alright, I'll try to get to it before the end of the week after I do some more testing.
Please identify some basic details to help process the report
Just did a OEM-Factory Reset and Re-Ownership of my Nitropad NV41 running Heads 2.1 and checked all options, including LUKS container re-encryption. The factory reset process overall succeeded but the part that was supposed to change my LUKS password and re-encrypt the container failed, saying that the current password I entered was invalid. I retried this at least 5 times and I'm 100% sure that the password is correct...it works when entering it in the LUKS prompt of the OS (Qubes). I then tried the separate "Re-encrypt LUKS container" option in the Heads menu, but that failed in the same way. I haven't tested Heads 2.2 due to the GPU bug, but I hope this is fixed for 2.3.
The only time I changed the password was after delivery from within dom0.
A. Provide Hardware Details
1. What board are you using (see list of boards here)? Nitropad NV41
2. Does your computer have a dGPU or is it iGPU-only?
3. Who installed Heads on this computer?
4. What PGP key is being used?
5. Are you using the PGP key to provide HOTP verification?
B. Identify how the board was flashed
1. Is this problem related to updating heads or flashing it for the first time?
2. If the problem is related to an update, how did you attempt to apply the update?
3. How was Heads initially flashed
4. Was the board flashed with a maximized or non-maximized/legacy rom?
5. If Heads was externally flashed, was IFD unlocked?
C. Identify the rom related to this bug report
I did not flash any version yet...still stock Heads 2.1 1. Did you download or build the rom at issue in this bug report?
2. If you downloaded your rom, where did you get it from?
Please provide the release number or otherwise identify the rom downloaded
3. If you built your rom, which repository:branch did you use?
4. What version of coreboot did you use in building?
5. In building the rom where did you get the blobs?
Please describe the problem
Describe the bug Heads boot menu function "Re-encrypt LUKS container" doesn't work, as it can't seem to mount the container, saying that the entered current password is invalid.
To Reproduce Steps to reproduce the behavior: If it has to do with changing the LUKS passphrase without using the Heads menu, then:
sudo cryptsetup luksChangeKey /dev/nvme0n1p2
Expected behavior Re-encrypts the LUKS container
Additional context It would also be nice if the re-encrypt function used argon2id (PBKDF) with 512 bit hash, if that's not already the case.