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.
Adds support for LUKS2 decryption of devices with a
header put in the head of data device. During the initialization
header is exported to a file and first data segment
is moved to head of data device in place of original header.
The feature introduces several new resilience modes (combination
of existing modes datashift and "checksum" or "journal").
Where datashift resilience mode is applied for data moved towards
the first segment and first segment is decrypted in-place.
The mode is not backward compatible with prior LUKS2 reencryption
and therefor interrupted operation in progress can not be resumed
using older cryptsetup releases.
Fixes: #669.
Due to commit 0113ac2d88
we recalculate reencryption digest whenever LUKS2 reencryption
keyslot gets updated. Until now we perform reencryption digest
refresh every time we call LUKS2_keyslot_reencrypt_update even
when no metadata was updated.
This improves on it and should speed up reencryption resume
process.
The LUKS2 reencrypt keyslot update process should
not be performed in crypt_reencrypt_run() loop where
data reencryption takes place.
The proper location is reencryption process initialization
when we validate reencryption metadata and decide if
new user provided resilience metadata are valid.
Prior to commit 0113ac2d88 it did
not matter what resilince metadata we stored during initialization.
So we stored 'none' type unless 'datashift' operation was initialized.
After the commit, it triggered reencryption metadata digest refresh
almost each time (except 'datashift') which was suboptimal.
By storing proper resilience type during reencryption initialization
we will avoid the needless reencryption digest refresh later (after
update optimization).
Fix possible attacks against data confidentiality through LUKS2 online
reencryption extension crash recovery.
An attacker can modify on-disk metadata to simulate decryption in
progress with crashed (unfinished) reencryption step and persistently
decrypt part of the LUKS device.
This attack requires repeated physical access to the LUKS device but
no knowledge of user passphrases.
The decryption step is performed after a valid user activates
the device with a correct passphrase and modified metadata.
There are no visible warnings for the user that such recovery happened
(except using the luksDump command). The attack can also be reversed
afterward (simulating crashed encryption from a plaintext) with
possible modification of revealed plaintext.
The problem was caused by reusing a mechanism designed for actual
reencryption operation without reassessing the security impact for new
encryption and decryption operations. While the reencryption requires
calculating and verifying both key digests, no digest was needed to
initiate decryption recovery if the destination is plaintext (no
encryption key). Also, some metadata (like encryption cipher) is not
protected, and an attacker could change it. Note that LUKS2 protects
visible metadata only when a random change occurs. It does not protect
against intentional modification but such modification must not cause
a violation of data confidentiality.
The fix introduces additional digest protection of reencryption
metadata. The digest is calculated from known keys and critical
reencryption metadata. Now an attacker cannot create correct metadata
digest without knowledge of a passphrase for used keyslots.
For more details, see LUKS2 On-Disk Format Specification version 1.1.0.