It allows to get former (old) volume key size
from LUKS2 device in reencryption state when
there's at least one keyslot containing encrypted
volume key.
LUKS2 supports several jsom area length configurations. With
the largest size supported in megabytes we do not want to write full
metadata area unconditionaly (current code) with every metadata
update. This might generate noticeble overhead with LUKS2
reencryption.
With this patch we write only the real used json area
length plus necessary padding to overwrite remaining previous
metadata stored on the disk.
During LUKS2 format and LUKS2 autorecovery we always overwrite
whole json metadata area no matter the used size.
This patch add support for setting of integrity key size
for LUKS2 devices.
It adds new (optional) JSON "key_size" attribute in segment.integrity JSON object.
If not set, the code use hash length size (backward compatible).
For LUKS2, we do not allow smaller keys than 128 bits.
Mostly based on code from Ingo Franzki <ifranzki@linux.ibm.com>
The luks2_internal.h contains specific JSON implementations while
luks2.h is generic. Code outside of luks2/ dir should not use internals.
Also luks2.h includes functions prototypes that are used from setup.c.
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.
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.
Extends code so that later API may support LUKS2 device
activation via token with specified keyslot.
Also allows testing if specific token is able to unlock specific
keyslot.
Let's make LUKS2_generate_hdr as clean as possible. Cipher
specification string can be constructed in upper layers.
This will make future LUKS2_generate_hdr extension easier.
Move all metadata size and data offset calculations
logic away from LUKS2_generate_hdr. The function
was meant to generate solely LUKS2 header on disk json
format.
The aim is to have all logic related data offset and metadata
size in one place available to be calculated in advance so
that we can easily extend the code.
The crypt_keyslot_add_by_keyslot_context & associated
helper functions allow more options when adding new
keyslot. For example there was no simple way of
adding new LUKS2 keyslot when the only active keyslot
could be unlocked by passphrase (KEK) provided by LUKS2 token
(plugin). Now all available options for unlocking keyslots
may also be used when creating new keyslot and it combine
as called needs.
The available methods (keyslot contexts) are:
passphrase, keyfile, key (binary representation) and LUSK2 token.
Following API calls trigerred LUKS2 metadata reload
from storage in case of failure:
crypt_convert
crypt_keyslot_add_by_key
crypt_keyslot_add_by_keyfile_device_offset
crypt_keyslot_add_by_passphrase
crypt_keyslot_change_by_passphrase
crypt_reencrypt_init_by_keyring
crypt_reencrypt_init_by_passphrase
This patch replaces LUKS2 metadata reload with
backup LUKS2 metadata copy kept in memory that is updated on
each sucessfull metadata write and rolled back to it whenever
needed in any of those calls listed above.
Do not invalidate LUKS2 format when future online-reencrypt
requirement flag is encountered (by older releases).
But it must stop device from being activated, reencrypted
or modified.
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.
Attribute unused is useless and makes code imcomprehensible
when decorates internal functions not exposed via API.
Let's cleanup internal funtion prototypes whenever possible.
crypt_reencrypt_status() returns this flag if old
online-reencrypt requirement is detected and reencryption
keyslot digest is missing.
crypt_reencrypt_init_by_passphrase() with same flag applied
repairs (upgrade) reencryption metadata so that
automatic reencryption recovery during activation
is again possible and reencryption operation can be resumed
post CVE-2021-4122 fix.
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.
Add API call that can directly print JSON metadata area from LUKS2 device.
For commandline it also adds --dump-json-metadata option for luksDump action.
Note that the binary metadata (UUID, version etc) is not part of this output.
(We reserve flags parameter to be able to add this later.)
Fixes: #511
The code expects that change key is done in-place if there is not
a free space in keyslot area for safe key swap.
This patch makes the code behaves the same as in LUKS1,
luksChangeKey now works the same.
With JSON, we can actually retain the slot number in all cases
(except user intentionally set new slot #).
This patch changes the crypt_keyslot_change_by_passphrase() API
call to retain keyslot number for LUKS2.
Fixes: #464
Right now, cryptsetup makes an attempt to include the correct
definitions in all of its header files, allowing the headers to
compile regardless of the context in which they are included.
A few files were missed, this change fixes them by adding the minimal
set of #includes needed to get them to compile.
Signed-off-by: Joe Richey <joerichey@google.com>