Do not print sed-opal spefic debug messages with confusing
error codes if ioctl() call failed with -1. Usually that means
the kernel does not support sed-opal interface or the requested
ioctl number is not implemented.
ioctl syscall always returns -1 on error (see ioctl(2)).
On error the actual reason is reported via errno varible.
Let's store the original errno code in the variable
so that it can be printed out in debug mode.
Before this fix the debug message always reported "Operation not
permited" (the translation of errno EPERM (1)).
The lr member in opal_lr_act kernel structure is
ingnored unless the device is being activated in SUM
mode.
See kernel implementation of IOC_OPAL_ACTIVATE_LSP
in block/sed-opal.c
The PSID reset erases the block device it's submitted to
succesfully.
By submitting the command to read-only fd previously
there were partition device nodes still visible in
the /dev directory because kernel does not trigger rescan
after OPAL2 PSID reset. Even though all the partition were
actually erased (including the partition table).
We workaround the issue by submitting the PSID reset
to R/W fd so that it triggers rescan event on close.
The IOC_OPAL_ERASE_LR uses Erase method, that is defined only
in Single user mode (SUM) and works only on SUM-enabled LRs.
As we do not use SUM yet, this always fails.
Moreover, Erase has many side effects - it resets user password to ""
and disables locking for LR.
We already use fallback to IOC_OPAL_SECURE_ERASE_LR, which is GenKey
method (defined in Core spec) that must be always available.
It effectively regenerates the LR encryption key.
Switch current code to use following volume key helpers
for accessing internal properties:
crypt_volume_key_length(), crypt_volume_key_get_key(),
crypt_volume_key_description() and crypt_volume_key_kernel_key_type()
Remaining direct access to volume key internals will be dealt with in
later commits since it requires some further changes.
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.
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.
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.
It affects only HW OPAL locking range KEK.
After unlocking opal locking range we cache the key in kernel
so that we do not have to pass the key again for locking the
range later (the OPAL std requires key for lock command).
Unfortunately the key remains cached in kernel even after we
lock the range on purpose during crypt_deactivate* or crypt_suspend.
This had 2 side effects:
1) key remained in system memory even though the LUKS device was
inactive (and all keys should be erased from memory).
2) when system gets suspended the locking range got automatically
unlocked later after system resume because the key caching is used
primarly to automatically unlock locking ranges that got locked
after system suspend (due to power cut off on storage device).
Since kernel does not directly support dropping cached keys we achieve
that by overwritting the original key structure with empty one.