Description of problem: Formatting a LUKS device again as a new LUKS device does not completely wipe the luksdata on it. Version-Release number of selected component (if applicable): luksmeta-8-3.fc28.x86_64 cryptsetup-2.0.3-4.fc28.x86_64 How reproducible: Always Steps to Reproduce: Make a LUKS device with luksmeta data in slot 0 # dd if=/dev/zero of=/dev/sdb # cryptsetup luksFormat /dev/sdb # luksmeta init -d /dev/sdb # echo hello | luksmeta save -d /dev/sdb -s 0 -u cb6e8904-81ff-40da-a84a-07ab9ab5715f # luksmeta show -d /dev/sdb 0 active cb6e8904-81ff-40da-a84a-07ab9ab5715f ... Format the device again as LUKS # cryptsetup luksFormat /dev/sdb # luksmeta show -d /dev/sdb 0 active cb6e8904-81ff-40da-a84a-07ab9ab5715f Actual results: The luksmeta data is still there after a "cryptsetup luksFormat". If that data is from "clevis luks bind" it is useless now and confusing. Expected results: luksmeta data should be gone.
LUKS never touches the header gap. Use: luksmeta nuke -d /dev/sdb.
> LUKS never touches the header gap. Use: luksmeta nuke -d /dev/sdb. Wouldn't it be nice if cryptsetup itself would wipe its gap? I'll reassign to find out. I have also filed https://github.com/storaged-project/libblockdev/issues/391.
I'm inclining to close it again, but few thoughts: LUKS1 header size (including keyslots areas) depends on volume key size used during format action. If you change key size the respective luksmeta offset may change as well. IOW, even if add such wipe it will not work in all cases. Nathaniel is right, luksmeta nuke is the correct way forward here. Something like: a) cryptsetup isLuks --type luks1 /dev/sdb ? b) luksmeta nuke -d /dev/sdb c) cryptsetup luksFormat... But we already check for luksmeta presence if user wants to do up-conversion to LUKSv2 format.
(In reply to Ondrej Kozina from comment #3) > Something like: > a) cryptsetup isLuks --type luks1 /dev/sdb ? > b) luksmeta nuke -d /dev/sdb > c) cryptsetup luksFormat... Why not the following sequence? a) cryptsetup luksFormat --type luks1 /dev/sdb b) luksmeta nuke -d /dev/sdb Step b) could actually also be "luksmeta init", no? What else would people do with the gap anyway?
Here is a scenario that shows the potential harm of this bug: # dd if=/dev/zero of=/dev/sdb # cryptsetup luksFormat /dev/sdb # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }' # cryptsetup luksFormat /dev/sdb # cryptsetup luksAddKey /dev/sdb # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }' # luksmeta show -d /dev/sdb 0 active empty 1 active cb6e8904-81ff-40da-a84a-07ab9ab5715e 2 active cb6e8904-81ff-40da-a84a-07ab9ab5715e Clevis is now broken for /dev/sdb because the passphrase in slot 1 does not match the result of decryption with the tang pin anymore. # clevis luks unlock -d /dev/sdb No key available with this passphrase. If /dev/sdb should be unlocked during boot, the next boot will time out and end up in the rescue shell. I will lobby for a fix in libblockdev.
(In reply to Marius Vollmer from comment #5) > I will lobby for a fix in libblockdev. They don't want it either. I can put a workaround in Cockpit, but that is arguably the worst place. Please advise.
(In reply to Marius Vollmer from comment #5) > Here is a scenario that shows the potential harm of this bug: > > # dd if=/dev/zero of=/dev/sdb > # cryptsetup luksFormat /dev/sdb > # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }' > > # cryptsetup luksFormat /dev/sdb > # cryptsetup luksAddKey /dev/sdb > # clevis luks bind -d /dev/sdb tang '{ "url": "http://192.168.100.1:88" }' > # luksmeta show -d /dev/sdb > 0 active empty > 1 active cb6e8904-81ff-40da-a84a-07ab9ab5715e > 2 active cb6e8904-81ff-40da-a84a-07ab9ab5715e > > Clevis is now broken for /dev/sdb because the passphrase in slot 1 does not > match the result of decryption with the tang pin anymore. And it would also break if user reencrypted the device, or performed LUKS header restore from backup where there is no 'nbde' keyslot. My point is that even if we fix this very case there will always be another one. 'bind' should probably check if the keyslot can be unlocked before it finishes the bind operation. It's a simple 'test passphrase for a keyslot' case from cryptsetup/luks perspective.
(In reply to Ondrej Kozina from comment #7) > And it would also break if user reencrypted the device, or performed LUKS > header restore from backup where there is no 'nbde' keyslot. My point is > that even if we fix this very case there will always be another one. Always? Isn't the list of cases finite? Anyway, y'all know about the problem and I let you go ahead and do the right thing.
The right thing is to move to LUKSv2 where luksmeta isn't needed. It was always a stop-gap.
It gets mostly fixed by following upstream commit: https://gitlab.com/cryptsetup/cryptsetup/commit/c2bce3e93ecee41f661b589ee28f112eb538259e It'll not guarantee cryptstup erase luksmeta metadata in every case (see comment #3) but it fixes the problem you see after formating fresh LUKS device.
cryptsetup-2.0.5-1.fc28 has been submitted as an update to Fedora 28. https://bodhi.fedoraproject.org/updates/FEDORA-2018-8936092f99
cryptsetup-2.0.5-1.fc28 has been pushed to the Fedora 28 testing repository. If problems still persist, please make note of it in this bug report. See https://fedoraproject.org/wiki/QA:Updates_Testing for instructions on how to install test updates. You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2018-8936092f99
cryptsetup-2.0.5-1.fc28 has been pushed to the Fedora 28 stable repository. If problems still persist, please make note of it in this bug report.