Commit Graph

126 Commits

Author SHA1 Message Date
Ondrej Kozina
99a3d328f0 Harden checksum resilience parameters verification. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
e8ec3e1005 Allocate buffer for checksum resilience on-demand. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
007e56727c Refactor reencrypt_recover_segment. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
4de09ace8f Minor code refactoring in reencryption loop. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
97b88d878e Refactor internal reencrypt_hotzone_protect_final.
Avoid passing whole reencryption context when not
needed.
2022-06-09 12:03:14 +02:00
Ondrej Kozina
b43ca18c64 Postpone reencryption dm segments refresh.
Refresh (and therefore suspend hotzone) reencryption dm
segments in-before actual hotzone reencryption takes place.

This commit shortens time window during which hotzone is
suspended. Also it avoids eventual deadlock if reencryption process
triggers page miss during storage wrapper reinitialization and required
data is stored in (previously) suspended hotzone (corner case).
2022-06-09 12:03:14 +02:00
Ondrej Kozina
582f2c3449 Replace memset with crypt_safe_memzero where reasonable.
Better safe than sorry.
2022-06-09 12:03:14 +02:00
Ondrej Kozina
bf0d0203e8 Add routine for erasing resilience structure. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
cfb54be9a3 Refactor reencrypt_length() function. 2022-06-09 12:03:14 +02:00
Ondrej Kozina
8f97d9b6e6 Do not refresh reencryption digest when not needed.
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.
2022-05-26 12:13:06 +00:00
Ondrej Kozina
d9dad29149 Move LUKS2 reencrypt keyslot update procedure.
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.
2022-05-26 12:13:06 +00:00
Ondrej Kozina
fc4b2cab25 Store proper resilience data in LUKS2 reencrypt initialization.
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).
2022-05-26 12:13:06 +00:00
Ondrej Kozina
d9eff7ffd7 Test passed resilience parameter is not NULL. 2022-05-26 12:13:06 +00:00
Ondrej Kozina
346f104f26 Move internal structure definition to internal header file. 2022-05-26 12:13:06 +00:00
Ondrej Kozina
082d23af92 Store data_shift value in rp structure.
data_shift value is part of recovery data
and should be stored in rp structure instead.
2022-05-26 12:13:06 +00:00
Ondrej Kozina
392b0136dc Store checksum protection data block size in rp structure.
The structure is supposed to store all data necessary to perform
reencryption crash recovery. The data block size stored
in LUKS2 metadata was missing and stored in reencryption top level handle
instead.
2022-05-26 12:13:06 +00:00
Ondrej Kozina
3a4ced84a6 Release lock on reencryption initialization error path. 2022-05-26 12:13:06 +00:00
Milan Broz
f1eea3a4b3 Clean reencrypt status struct for API call.
This function should not return unitialized struct as there
is no indication that it failed and caller can access it.

Also fixes a Coverity warning.
2022-04-19 08:53:44 +00:00
Ondrej Kozina
2a5483d8c3 Add progress function init before reencryption loop.
Otherwise elapsed time tracking is off and also breaks
speed estimation.
2022-03-07 12:35:38 +01:00
Ondrej Kozina
8340d0cb1a Remove useless condition in reencryption loop.
(always true)
2022-03-07 12:35:38 +01:00
Ondrej Kozina
8798aa0a75 Do not upload keys in keyring during offline reencryption.
Fixes: #696.
2022-02-05 10:29:55 +00:00
Ondrej Kozina
7ca1a233f1 Split reencrypt_verify_and_upload_keys function. 2022-02-05 10:29:55 +00:00
Milan Broz
ab975bc1c4 Update copyright year.
And unify format in several places.
2022-01-29 10:43:02 +01:00
Ondrej Kozina
230b80404d Remove parameters annotated by __attribute__((unused)).
Attribute unused is useless and makes code imcomprehensible
when decorates internal functions not exposed via API.

Let's cleanup internal funtion prototypes whenever possible.
2022-01-28 17:27:00 +00:00
Ondrej Kozina
ea47937187 Add CRYPT_REENCRYPT_REPAIR_NEEDED flag.
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.
2022-01-12 18:38:17 +01:00
Ondrej Kozina
6c8314b297 Make reencryption flag and keyslot inseparable.
LUKS2 validation code now requires reencrypt keyslot together with
online-reencryption flag or none of those.
2022-01-12 18:38:10 +01:00
Ondrej Kozina
59e39e484a Rename LUKS2_keyslot_reencrypt_create function.
The function never writes on-disk. Also removed validation
function call-in since it will be called later before
writing on-disk and metadata does not have to be complete
at the moment of LUKS2_keyslot_reencrypt_allocate call.
2022-01-12 18:38:06 +01:00
Milan Broz
139d663541 Add disable-luks2 reencryption configure option.
The option --disable-luks2-reencryption completely disable
LUKS2 reencryption code.

When used, the libcryptsetup library can read metadata with
reencryption code, but all reencryption API calls and cryptsetup
reencrypt commands are disabled.

Devices with online reencryption in progress cannot be activated.

This option can cause some incompatibilities. Please use with care.
2022-01-12 13:58:35 +01:00
Milan Broz
665816ae4d Print better error if resilience hash is not available. 2022-01-12 13:56:46 +01:00
Milan Broz
eb220d834d Fix debug message. 2022-01-12 13:55:39 +01:00
Ondrej Kozina
0113ac2d88 Fix CVE-2021-4122 - LUKS2 reencryption crash recovery attack
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.
2022-01-12 13:50:37 +01:00
Ondrej Kozina
6bc1378ddb Remove LUKS2 encryption data size restriction.
LUKS2 encryption with data shift required remaining
data size (size remaining after substracting --reduce-data-size value)
to be at least --reduce-data-size. This was wrong. Remaining
data size restriction should be correctly at least single sector
(whatever sector size is selected or auto-detected).
2021-11-24 19:58:57 +01:00
Milan Broz
a364355c16 Fix missing translation macros. 2021-11-10 15:29:29 +00:00
Ondrej Kozina
1569558503 Fix offset bug in LUKS2 encryption code.
The code did not account for data offset when
set via --offset when creating new header in-before
LUKS2 encryption took place.
2021-09-14 16:10:24 +02:00
Ondrej Kozina
ce704859b8 Fix offset error in decryption hotzone.
The hotzone segment offset has to be altered
accordingly no matter the segment type.

Note for testing: This feature is currently
blocked in cli but it should be tested via
API tests anyway.
2021-09-14 15:21:07 +02:00
Ondrej Kozina
06f132066b Add crypt_reencrypt_run superseding now deprecated crypt_reencrypt.
This reverts commit 367cb7a761
and retains original crypt_reencrypt() symbol marked as deprecated
in favour of new crypt_reencrypt_run(). This makes cryptsetup 2.4.0
release fully backward compatible.
2021-07-22 15:59:01 +02:00
Milan Broz
4cdd826282 Check exit value for snprintf where it makes sense. 2021-05-18 22:07:47 +02:00
Ondrej Kozina
e6089dd9c9 Reflect on some incompatible changes in GCC 10.
Starting with GCC10 and LTO enabled, current symbols
versioning hack does not work anymore. This patch
reflects on that and should be compatible with older
compilers that does not support __attribute__((symver))
yet.

Inspired by following code:
https://github.com/linux-rdma/rdma-core/blob/master/util/symver.h
2021-04-12 20:38:19 +02:00
Milan Broz
cea7a1489a Remove unnecessary goto and use out label for non-error path in reencrypt code. 2021-02-17 10:03:18 +01:00
Ondrej Kozina
bec7394722 Improve key handling with cipher_null in reencryption. 2021-02-16 18:08:35 +01:00
Milan Broz
4471452105 Remove some stale FIXME markings. 2021-02-11 11:12:11 +00:00
Milan Broz
d703301fe8 Mark or remove unused parameters.
Mark unused parameters with proper attribute where it is a part
of API or some internal logic.

And remove other unused parameters completely.
2021-02-11 11:12:11 +00:00
Milan Broz
2d10545e70 Check if there is a free space in keyslot area early (LUKS2).
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.
2021-02-01 11:57:35 +00:00
Milan Broz
d1d9dd8e20 Update Copyright year. 2021-01-25 22:00:25 +01:00
Samanta Navarro
38e631d174 Fix typos.
Typos found with codespell.
2020-11-28 11:41:48 +00:00
Ondrej Kozina
9bc45ae15f Make the crypt_reencrypt() API fix actually matter.
Pick one:
Thou shalt not skip writting tests!
One does not simply fix a bug
2020-11-23 14:09:46 +01:00
Ingo Franzki
1bce69cfde Support online reencryption for PAES cipher.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

(With few adjustments by Ondrej Kozina)
2020-08-20 18:16:48 +02:00
Ondrej Kozina
367cb7a761 Fix API mistake in crypt_reencrypt.
Introducing new version of crypt_reencrypt symbol including
previously missing usrptr parameter. This change should be
backward compatible for existing libcryptsetup users
until next recompilation where it needs to be fixed.
2020-08-09 13:16:57 +02:00
Milan Broz
1633f030e8 Rename reenc_keyslot_update to reencrypt_keyslot_update. 2020-07-07 14:20:39 +02:00
Milan Broz
4451df15b4 Rename luks2_reenc_context to luks2_reecrypt. 2020-07-07 14:20:39 +02:00