The check did not work properly for stacked dm_crypt over
hw opal devices.
Also it did not work at all for active dm mappings with
missing (or detached) LUKS2 metadata.
For device without a type code shoud not try to use
strcmp function.
This can happen for example if deferref flag is used
for device without proper DM-UUID where init_by_name
does not set know device type.
Thanks Clément Guérin for the report.
Fixes: #910
For LUKS2 headers with non zero data offset LUKS2_wipe_header_areas
will always erase the smallest from following:
- metadata device size
- data offset value
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
binary keyslot areas) even with detached header.
For zero value data offset (LUKS2 header can not be restored back to
data device), we erase up to smallest from the following values:
- metadata device size
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
This patch switches code to SPDX one-line license identifiers according to
https://spdx.dev/learn/handling-license-info/
and replacing long license text headers.
I used C++ format on the first line in style
// SPDX-License-Identifier: <id>
except exported libcryptsetup.h, when only C comments are used.
The only additional changes are:
- switch backend utf8.c from LGPL2+ to LGPL2.1+ (as in systemd)
- add some additional formatting lines.
Some Opal devices contain a bug that device reports different logical
size for block device and Opal SED layer.
This can happen for NVMe after reformatting with different LBAF (512/4096).
We will not support such configuration as Opal then calculates sizes
differently for locking range (that could lead to data corruption or
a partially unecrypted area).
Zoned device cannot be written with direct-io
and cannot be used for LUKS header logic without
significant changes. Do not allow to use them for LUKS header
but allow it for data device, as dm-crypt supports it.
Fixes: #877
hw-opal segment does not receive volume key for data
encryption, unlike crypt segment or hw-opal-crypt segment.
It gets key encryption key that is passed to device fw which
later unlocks the locking range key sealed in the device.
The assert may be skipped while volume key is not set.
Fixes: #875.
While properly calculated data segment needed compensation due to
misaligned partition (locking range had to be truncated),
we passed wrong value (original partition size) to LUKS2 metadata.
It has to use calculated locking range length in bytes.
Fixes: #873.
The opal_range_check_attributes_fd function expected both
offset and length parameters of a LR to be passed in sectors (512B).
During format we passed it wrongly in OPAL blocks which caused
bogus check provided OPAL block size was not 512B.
Fixes: #871.
Use -ESRCH for similar error code as with
crypt_activate_by_keyslot_context. Here it's not
confliciting with previous use for the very code but
let's make it easier and use same code for similar case.
While trying to activate device in LUKS2 reencryption
we originally used -ENOKEY error code for case
where one or more volume keys could not be unlocked or
were not provided direclty by (CRYPT_KC_TYPE_KEY or
CRYPT_KC_TYPE_VK_KEYRING) keyslot contexts.
We missed the fact the error code was already previously
used for signaling case when dm subsystem could not load
device table due to key in kernel keyring could not be
read from kernel. It's propagated by libdevmapper.
For it we replace -ENOKEY with -ESRCH for signaling the missing
keyslot context or volume key for devices in LUKS2 reencryption.
We already support activation of a device using a volume key in keyring.
However, in case of multi-key devices (i.e. device with reencryption
running) we need to supply two volume keys.
If the device is in reencryption, it has two active volume keys. Linking
the VK to keyring is not supported for such devices, because the API
only counts with one key. This commit modifies the API
crypt_set_keyring_to_link to allow passing multiple keyring key names.
For Argon2 native code (gcrypt, OpenSSL) a flag in debug output is printed.
If libargon is used, then [cryptsetup libargon2] is printed
(embedded code) or [external libargon2] for dynamic external library.
# Crypto backend (OpenSSL 3.0.11 19 Sep 2023 [default][legacy] [external libargon2])
or
# Crypto backend (OpenSSL 3.0.11 19 Sep 2023 [default][legacy] [cryptsetup libargon2])
Fixes: #851
Activating LUKS2 device with OPAL support is multistep process.
1) read LR state
2) unlock LR
3) activate dm device
4) in case step 3) failed lock the device
if in step 1) the device was locked.
Otherwise, in case parallel activation happened on one device
the process that failed to map dm device (device already active)
could relock the LR afterwards and effectively break already active
device.
To avoid that we do steps 1) through 4) protected by exclusive
opal lock unique per data block device configured for use with
LUKS2 OPAL support.
Currently we suspend top-level device only.
With OPAL, the underlying device will start to return errors
once OPAL LR is locked.
If the dm-integrity device is not suspended, regular journal
flush corrupts the device (journal write failure),
corrupting data above it.
Suspending the whole stack should fix the issue.
Unfortunately there is currently no way how
to make difference between device lacking SED OPAL support
state and kernel missing SED OPAL support via disabled interface
via configure option.
If LUKS2 keyslot area has to be overwritten (due to lack of free space),
do not wipe the affected area first. It will get overwritten anyway.
Originaly, in between the keyslot wipe and new key material write, pbkdf
calculation took place. The pbkdf calculation takes ~2 seconds by default
and it put the user in unnecesary risk of loosing the keysot data in case
of a crash.
With LUKS2 crypt_keyslot_change_by_passphrase() call
does not have to overwrite binary keyslot
area in-place when user asked for specific keyslot id.
If there's enough free space in keyslot binary area
we can write new keyslot material in the the free area
(identified temporarily by new keyslot id) and switch
pointers (json metadata) to point to the new keyslot area after
the keyslot area write is complete. The old keyslot
area gets deleted after the new area write is finished.
Otherwise we needlesly risk to lose the existing keyslot
if the operation gets interupted.
With this patch LUKS2 crypt_keyslot_change_by_passphrase()
overwrites existing keyslot (including keyslot area)
only if there's no free space and therefore in-place update
is necessary.
Fixes: #839.
Add more context to possibly failing kernel keyring routines
in log debug output.
Mostly split debug output for errors while trying to search the kernel
key by description and errors while trying to read/unlink the key
by its id.
We can not link internal VK kernel key in custom user
keyring. There are two reasons for it:
The internal VK kernel key description can not be
acquired via API and it may change over time
(LUKS2 reencryption).
With recent SED OPAL support volume key becomes a 'blob'
containing up to two keys (dm-crypt key for SWE and key
for unlocking SED OPAL locking range). The internal
kernel key contains only dm-crypt (if required) but
custom user keyring needs to be provided with whole
volume key (blob).
Added user specified key description for the linked key
in custom user keyring. The linked key can be reached by
the specified description after successful activation (resume).
Resize operation (crypt_resize) changes only size, so it is safe to
not flush IO (and freeze fs with lockfs) during suspend/resume cycle.
For dm-integrity there can be two suspend/resume cycles as the subsequesnt
call sets recalculating flag.
Based on patch from Yury Vostrikov <mon@unformed.ru>
Resolves: #832