Currently, direct-io is disabled if underlying device is suspended.
This was an unfortunate change, as it is part of data corruption
problem in online reenryption.
Let's relax the test to assume that suspended device
(suspended => must be a device-mapper device) supports direct-io.
The read test is still needed as some network based devices
misbehaves if opened with direct-io flag.
This patch allows dm_status_suspended() to report if device
is suspended or not also for unknown target types from
libcryptsetup perspective (e.g.: dm-cache).
Consider device is suspended only if dm_status_suspended return code
is true.
This function returned -EEXIST for dm devices with target types unknown
to libcryptsetup (for example dm-cache) and turned off O_DIRECT flag
for devices unexpectedly.
Turned out ignoring direct-io was a problem after all :).
Fixes: 0f51b5bacb (Do not run sector read check on suspended device.)
CRYPT_ACTIVATE_SHARED flag was silently ignored
while activating dm-verity devices by libcryptsetup.
This was a bug.
DM verity shared activation is generaly safe (single mapped data device
in multiple DM verity tables) since all verity devices are
read only.
The CRYPT_ACTIVATE_SHARED flag also fixes a race condition
when multiple processes compete for the same DM device name
(all dm-verity) while using same backing data device.
The exclusive open check in-before verity activation could
fail DM table load for a process that otherwise successfully acquired
DM device name (succeed in creating the DM device). This could (in some
cases) result in all processes competening for the DM verity device
to fail and none would activate the DM verity device.
Exclusive flag is defined only when creating a file,
for opening existing file it is undefinded operation.
Remove it from crypt_loop_attach as it was wrong since
the initial commit.
Due to internal retry-overengineering in libdevmapper, some dm-ioctl
failures can disappear. One such case is when there is a device
creation race and DM device is created but reload fails.
this can heppen because some block device used in table mapping is
already claimed (it needs exclusive access for bdev_open in kernel).
The kernel ioctl properly returns EBUSY, this errno is lost
in libdevmapper (dm_task_get_errno returns 0).
While this should be solved by libdevampper, we need some reliable
way on older systems to properly report "busy" error instead of
overloaded "invalid" error.
With modified reproducer (see check_concurrent in very compat test),
this situation can happen quite often.
This patch modifies dm_create_device to return ENODEV only if
dm-ioctl also reports no device (ENXIO); following dm status reports ENODEV
and also some referenced device is no longer accesible through stat().
In all other cases we return EBUSY. Command line translates EBUSY and EEXIST
to the same return vaules, for API users it now returns EBUSY instead
of generic EINVAL.
IOW, if device activation returns EEXIST or EBUSY, device-mapper
cannot create the device because it already exits (EEXIST) or some referenced
device is claimed by other subystem (EBUSY) and mapping table cannot be created.
There is no need to unlock keyslot if the provided name
has wrong format. Let's check for length and '/' in name early.
Note that other commands could accept path to the device
as libdevmapper translate it to the name (status /dev/mapper/xxx).
Add early check only to activate commands.
It still can fail later because of mangled characters.
Fixes: #893
Mbed-TLS is a tiny TLS implementation designed for embedded environment which
can greatly reduce the disk space requirement compared to OpenSSL. While we
already have crypto_kernel for this purpose and Mbed-TLS lacking hash/cipher
support can cause reduced functionality, there're situations where AF_ALG is
not available but we're fine with limited scenarios like LUKS2 only.
TrueCrypt/VeraCrypt supports full system encryption (only a partition
table is not encrypted) or system partition encryption
(only a system partition is encrypted).
The metadata header then contains the offset and size of the encrypted area.
Cryptsetup needs to know the specific partition offset to calculate encryption parameters.
To properly map a partition, you must specify a real partition device so cryptsetup can calculate this offset.
As user can specify various combination, we need to determine the proper
IV and data offsets.
The logic for CRYPT_TCRYPT_SYSTEM_HEADER flag should be (in this order):
- if data device is a real partition, calculate offset from it.
- if --header is a real partition , calculate offset from it.
- if device is a real disk, try to search for partition using decrypted offset and size
(works only for system partition-only encryption).
- if data and metadata (header) device is the same, map whole encrypted area
(this is the ost confusing for user)
- if data and metadata (header) divice differs, expect data image contains
only partition (setting offset to 0, but using IV offset from header).
There are still situation that can end with wrong mapping, but user now has the option
to setup it properly.
Also this patch fixes use of stored encryption size in header,
so we do not map larger area.
Fixes:#889
Print also volume sizes (if present) and flags.
This inforamtion is useful mainly for setting systemd encryption
where size determines encrypted region.
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
If an unbound keyslot is present (e.g.. slot 0 usual slot, slot 1 unbound),
the query loop could return ENOENT (keyslot not valid for segment) and this
will stop epxected retry for slot quewry (--tries option).
If any previous slot rerutned EPERM (no valid passphrase), prefer
this return code.
The HCTR2 encryption was added to Linux kernel for fscrypt,
but as it is length-preserving mode (with sector tweak) it
can be easily used for disk encryption too.
As it need larger IV of size 32 bytes, we need to add exception
for aes-hctr2[-plain64] to be accepted in cryptsetup commands.
Fixes: #883
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).
String.h and stdbool.h are already included in main backend header,
no need to include them again.
Stdio.h is missing for OpenSSL and NSS backed (for sprintf).
Strings.h is missing for cipher_generic, gcrypt and OpoenSSL (strcasecmp).
Fixes: #885
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
This function is used with block size, where 0 does
not make sense, so failing the check is the simple way
to avoid sividion by zero.
In reality, this should never happen, but it was seen
in (unreproducible) fuzzing input.
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.