Compare commits

...

141 Commits

Author SHA1 Message Date
Milan Broz
1f7ed87e6c Prepare version 2.3.1. 2020-03-12 09:39:20 +01:00
Milan Broz
c59ea422cc Add 2.3.1 release notes. 2020-03-10 16:03:53 +01:00
Ondrej Kozina
0bcb71f742 Add experimental warning in bitlk man section. 2020-03-10 12:26:26 +01:00
Yuri Chornoivan
7e38a3386e po: update uk.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Jakub Bogusz
c25b5ef215 po: update pl.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Hiroshi Takekawa
72fb507de2 po: update ja.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Frédéric Marchal
45c4c95b98 po: update fr.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Antonio Ceballos
e8861d1043 po: update es.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Roland Illig
c48fcb743b po: update de.po (from translationproject.org) 2020-03-09 08:18:30 +01:00
Joe Hansen
d5d732ddf4 po: update da.po (from translationproject.org) 2020-03-09 08:18:29 +01:00
Petr Pisar
f83bd5cdf6 po: update cs.po (from translationproject.org) 2020-03-09 08:18:29 +01:00
Milan Broz
76c87c628f Update cryptsetup.pot. 2020-03-09 08:18:16 +01:00
Milan Broz
fa125a354d Set version to 2.3.1-rc0. 2020-03-08 10:56:09 +01:00
Aaron Rogers
f184b54796 Improve hexdigest printing for large key-size 2020-03-01 16:17:27 +01:00
Vojtěch Trefný
75925fb2f7 bitlk: Strip extra newline from potential recovery keys
There might be a trailing newline added by the text editor when
the recovery passphrase was passed using the '--key-file' option
so we'll remove it before trying to use the passphrase.
2020-03-01 16:11:42 +01:00
Antonio Ceballos
b780228ade po: update es.po (from translationproject.org) 2020-03-01 16:07:42 +01:00
Ondrej Kozina
91c012eff0 Do not wipe device with no integrity profile.
With '--integrity none' we performed useless full
device wipe.

Fixes: #539.
2020-02-27 16:23:06 +01:00
Milan Broz
05d45c6948 Check for dm_device_get_name.
And fail dependency scan if not available.

Currently this call uses syfs DM extensions, these are
usually not available anyway on such old systems.
2020-02-21 12:13:04 +01:00
Milan Broz
a2c13fbc48 Used CLOCK_MONOTONIC in benchmark on ancient systems. 2020-02-21 10:42:47 +01:00
Milan Broz
16c7aab99b Fix some (ancient) compiler warnings. 2020-02-21 10:30:39 +01:00
Milan Broz
0cf5e309a0 Print warning if running without O_CLOEXEC. 2020-02-21 10:23:07 +01:00
Milan Broz
b5fbd682f2 Move fcntl.h to internal defines and check for O_CLOEXEC. 2020-02-21 10:10:11 +01:00
Milan Broz
90e04b0046 Remove O_CLOEXEC from block utils.
It is not needed here, used only in utilities.
2020-02-21 10:09:09 +01:00
Milan Broz
329f6562c2 Add autoconf check for O_CLOEXEC. 2020-02-21 10:08:17 +01:00
Milan Broz
852bad1ef4 Fix acompiler warning with --disable-blkid. 2020-02-21 08:28:55 +01:00
Henrik Grimler
aa44a61ab2 lib/Makemodule.am: convert some spaces to tabs 2020-02-21 08:25:41 +01:00
Milan Broz
3e237cb490 Detect separate libiconv library.
This patch should fix compilation issues on distributions with
iconv implemented in a separate library (instead libc internally).
2020-02-21 08:20:14 +01:00
Milan Broz
7b206fb13d Workaround for dm-integrity kernel table bug.
Some kernels show invalid dm-integrity table if suberblock
contains "recalculate" bit.

We can workaround that by setting recalculate option in table
(kernel uses bits from superblock anyway), so the table displayed
is always correct.

Fixes: #538
2020-02-20 14:19:57 +01:00
Milan Broz
8f7e898341 Print error message if LUKS1 keyslot cannot be processed.
If crypto backend is missing support for hash algorithms used
in PBKDF2 during slot derivatiom the fail was not visible.

Print at least error message to user in this case.

Fixes: #536
2020-02-20 14:19:53 +01:00
Ondrej Kozina
7499d9f245 Return -EINVAL when validation fails.
LUKS2_hdr_validate() returns positive integer on error. Replace returned
value with negative errno instead so that failed upconversion stops
sooner. It failed anyway but debug messages were misleading.
2020-02-19 11:18:46 +01:00
Ondrej Kozina
ba6e6f051a Properly align LUKS2 keyslots area on conversion.
If LUKS1 payload offset (data offset) is not aligned to
4KiB we create unaligned keyslots area in LUKS2 metadata
during upconversion. Unaligned keyslots area is not valid
from LUKS2 perspective. Fix it by properly aligning future
keyslots area and also check if LUKS1 keyslots area fit
in the new one.

Fixes: #534.
2020-02-17 22:19:39 +01:00
Ondrej Kozina
d4f4dfb54f Validate LUKS2 in-before moving keyslots on conversion.
During LUKS2 upconversion we moved binary keyslots area before
validating future LUKS2 header. If later LUKS2 validation failed
for some reason keyslots were already moved to new offsets and
LUKS1 offsets were therefore invalid. Following effort to unlock
such device failed because keyslots were efectively corrupted.

See issue #534.
2020-02-17 22:18:58 +01:00
Ondrej Kozina
3e7dedaf99 Minor code cleanup. 2020-02-17 22:18:36 +01:00
Milan Broz
f18cd7ae81 tcrypt: Suport VeraCrypt 128 bytes passwords
VeraCrypt now allows passwords of maximal length 128 bytes
(compared to legacy TrueCrypt where it was limited by 64 bytes).

This patch implements support for such a passphrases for TCRYPT format.

The whole extension seems to be quite dubious, the original TCRYPT
passphrase limit was IMO because of internal block length in PBKDF2
(SHA1/SH256 block size is 64 bytes), this patch make sense for SHA512
where the block size is 128 bytes.

Another strange thing is enlarging keyfile pool according to real
entered password size.

Fixes: #532.
2020-02-17 22:08:47 +01:00
Milan Broz
0ae4fcf8eb Update Readme.md. 2020-02-02 17:37:24 +01:00
Milan Broz
d3d1e30c7c Prepare version 2.3.0. 2020-02-02 16:58:29 +01:00
Ondrej Kozina
47d0cf495d Fail crypt_keyslot_get_pbkdf for inactive LUKS1 keyslot.
With LUKS1 we returned pbkdf values even for inactive keyslot.
Only iterations count was wrong. Remaining values are not
specific keyslot bound with LUKS1.

Fixes: #528.
2020-01-31 13:52:38 +01:00
Ondrej Kozina
2e883f9d91 Fix misleading hint in integritysetup man page.
--journal-crypt example values are not accepted by
crurrent integritysetup.

Fixes: #510.
2020-01-30 17:58:54 +01:00
Vojtech Trefny
af0c30e3ea bitlk: Add a test image for the EOW format
The image was created by pausing the encryption in progress.
2020-01-30 09:57:43 +01:00
Vojtech Trefny
da5a35356a bitlk: Remove unused constant 2020-01-30 09:57:43 +01:00
Vojtech Trefny
d98cc3bb6c bitlk: Do not allow activation of EOW and unknown devices
We currently do not support these BITLK devices.
2020-01-30 09:57:43 +01:00
Vojtech Trefny
9697f17b9d bitlk: Do not allow to activate devices in an unknown state
According to Dislocker, two unknown numbers in the FVE metadata
indicate "state" of the BITLK device. We were able to identify
only one of the states and we shouldn't allow activating devices
in other states for now.
2020-01-30 09:57:43 +01:00
Vojtech Trefny
ce3a9d172d bitlk: Fix reading metadata entries total length
FVE metadata header contains size of the header itself + size of
the metadata entries so we need to take this value and substract
48 (length of the FVE metadata header).
2020-01-30 09:57:39 +01:00
Yuri Kozlov
4448ddc488 po: update ru.po (from translationproject.org) 2020-01-26 10:15:41 +01:00
Yuri Chornoivan
b77d3c66ae po: update uk.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Jakub Bogusz
2debdfead5 po: update pl.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Benno Schulenberg
b168c65fa1 po: update nl.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Hiroshi Takekawa
2b46d171db po: update ja.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Frédéric Marchal
64c131d132 po: update fr.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Roland Illig
678a251858 po: update de.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Petr Pisar
bf9d2f6cb0 po: update cs.po (from translationproject.org) 2020-01-17 14:34:16 +01:00
Vojtěch Trefný
61f5dcb11e Return correct data offset for BITLK in crypt_get_data_offset
First part of the encrypted data will be always directly after
the header.

Fixes: #518
2020-01-17 14:02:12 +01:00
Milan Broz
e4387d2bd1 Update Readme.md. 2020-01-12 12:48:19 +01:00
Milan Broz
48906f354e Remove EOL in debug message. 2020-01-12 12:30:36 +01:00
Milan Broz
1ddc098e43 Prepare version 2.3.0-rc0. 2020-01-12 12:14:27 +01:00
Milan Broz
165e6c234c Fix some error and debug messages.
Use BITLK as format name.

Avoid using doesn't -> does not.
2020-01-11 22:10:59 +01:00
Milan Broz
1be631f43f Add status flag for verity device with signature.
This patch adds CRYPT_VERITY_ROOT_HASH_SIGNATURE flag to verity info.

Veritysetup status now display "with signature" if an active
device was activated with root hash signature.
2020-01-11 19:57:39 +01:00
Vojtěch Trefný
f5f34c2f50 bitlk: Add recovery passphrases for Elephant test images 2020-01-08 09:23:06 +01:00
Vojtěch Trefný
33f3619e98 bitlk: Update testing images for AES-CBC with Elephant
Images now contain valid NTFS filesystem after opening and the
test data also contain sha256sum of the opened device.
2020-01-05 17:09:16 +01:00
Vojtěch Trefný
3720b66d00 bitlk: Fix getting FVEK for AES-CBC 128 bit with Elephant
For this 128 bit Elephant the key data is 512 bit (2 * 156 bit,
same as for 256 bit Elephant) so we need to adjust reading the
key to not include the empty "parts" of the key.
2020-01-05 17:07:15 +01:00
Milan Broz
864bbc5472 Fix string leak in BITLK attribute name handling. 2020-01-03 13:44:57 +01:00
Milan Broz
080566a1fd Update copyright year. 2020-01-03 13:04:55 +01:00
Milan Broz
d9766037a3 Fix some extended compiler warnings. 2020-01-03 12:29:49 +01:00
Milan Broz
02821adc47 Fix a signed/unsigned comparison compiler warning. 2020-01-03 11:26:44 +01:00
Milan Broz
7b08fd4b7d Remove undeeded version test for BITLK compat tests.
Otherwise it starts failing with dm-crypt version bump.
2020-01-03 10:23:28 +01:00
Milan Broz
0505c70be2 Implement BITLK status info.
Cryptsetup status <device> should print info about active device.

Also fix mistake in BITLK volume key size (should return bytes, not bits).
2020-01-03 10:14:47 +01:00
Jaskaran Khurana
f247038e65 Add --root-hash-signature parameter to veritysetup
Optional parameter root hash signature is added that can be added to
veritysetup.

The signature file is opened and the signature is added to the keyring.

The kernel will use the signature to validate the roothash.

Usage: veritysetup open <data_device> name <hash_device> <root_hash> --root-hash-signature=<roothash_p7_sig_file>

Signed-off-by: Jaskaran Khurana <jaskarankhurana@linux.microsoft.com>
Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>

[Original patch rewritten by Milan Broz]
2020-01-02 13:08:21 +01:00
jbit
d7667e9e6e bitlk: Support for name strings in VMK metadata 2020-01-02 08:54:19 +00:00
Luca Boccassi
188cb114af Add support for verity in crypt_volume_key_get and use it in status
Other APIs use the root hash in place of keys when using verity
devices, so do the same for crypt_volume_key_get to allow users
to retrieve the root hash of an active verity device.
Use it in veritysetup status to print the root hash.

[Patch slightly modified by Milan Broz]
2019-12-31 21:44:50 +01:00
Milan Broz
35c49ababf Fix some compiler warnings. 2019-12-31 17:49:38 +01:00
Ondrej Kozina
faafe09bd0 Use crypt_volume_key_next where appropriate. 2019-12-31 17:37:33 +01:00
Milan Broz
a0e87c9420 Calculate hash integrity size instead of requiring an explicit tag size.
When integritysetup formats a device with hash or HMAC integrity checksums,
it requires explicitly tag size entry from a user (or default value).

This leads to confusion and shortened tags.

This patch calculates tag size according to real hash output, and
if tag size is specified, it warns if these values differ.

Fixes: #492.
2019-12-31 17:37:33 +01:00
Milan Broz
d9d39f1812 po: update pot file 2019-12-31 12:36:39 +01:00
Milan Broz
82af225742 Add bitlk compat test to distro tar. 2019-12-31 12:30:44 +01:00
Milan Broz
919f4df1a7 Remove wip-bitlocker branch from CI. 2019-12-31 12:20:06 +01:00
Milan Broz
71a1698bf2 Add bitlk.c to translation. 2019-12-31 11:16:01 +01:00
Milan Broz
a987dd95b8 Remove unused bitlk params structure. 2019-12-30 21:57:42 +01:00
Milan Broz
ab6ab8e65c Fix BITLK command aliases descriptions. 2019-12-30 21:53:06 +01:00
Milan Broz
3b28d66410 Add BitLocker man page extentsion. 2019-12-30 21:53:06 +01:00
Milan Broz
eee46ef2f4 Detect support for BitLocker EBOIV and Elephant diffuser.
If kernel is missing support, print a more friendly error.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
3c189b4183 bitlk: Fix displaying key length in bitlkDump 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
fd5ab0edf7 bitlk: Add Smart Card protected VMKs
Test image protected with smart card is included.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
420387a7a5 bitlk: Ignore unknown metadata entries for unsupported VMKs
VMKs (keyslots) protected with a smart card or TPM have some
additional metadata entries that are currently unkwnon. We can
safely ignore these because we don't support unlocking the device
using these VMKs so we should still be able to parse the metadata
and unlock the device using other VMKs like the recovery password.
2019-12-30 21:53:06 +01:00
Milan Broz
fc740f8b6d Simplify bitlk test and be sure to load dm-crypt module. 2019-12-30 21:53:06 +01:00
Vojtech Trefny
834059ddfa Do not hardcode number of DM segments for BitLocker devices
Sometimes there is no gap between the metadata so we don't want to
create a dm-crypt segment there.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
5ec2fbcd38 Allow empty passphrases when opening BitLocker devices
It's probably not possible to create a BitLocker device with an
empty passphrase but we want to support it. And it's definitely
better to ask for the passphrase again instead of returning
ENOMEM.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
2fbf5cd79f Covert the BitLocker test images to sparse images 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
64ebe95751 Check sha256 sums of the bitlk images in tests 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
77109b3a33 Edit BitLocker test images to be compatible with older blkid
We need to keep the mirror NTFS MFT too because older versions of
blkid check it too.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
b43429e684 Fix parsing BitLocker metadata on Big Endian architectures 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
97e39f0744 Fix displaying error for not supported BitLocker key decryption
'crypt_bitlk_decrypt_key' can also fail because of wrong
passphrase and other reasons.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
fad592b512 Fix open on devices with no supported VMKs 2019-12-30 21:53:06 +01:00
Milan Broz
565de3c536 Fix check for bitlk iv overflow in crypto backend. 2019-12-30 21:53:06 +01:00
Milan Broz
c802269ea3 Bitlk: fix some additional gcc warnings. 2019-12-30 21:53:06 +01:00
Milan Broz
06268963fb Bitlk: clean up some inlcudes and warnings. 2019-12-30 21:53:06 +01:00
Milan Broz
2227797691 Bitlk: move test for older blkid. 2019-12-30 21:53:06 +01:00
Milan Broz
f0888c1fe0 Add AEAD define on older kernel headers. 2019-12-30 21:53:06 +01:00
Milan Broz
eda2e62589 Add other backends (Nettle, NSS) for Bitlk decryption (through kernel wrapper). 2019-12-30 21:53:06 +01:00
Milan Broz
494d8ec04c Add kernel backend for Bitlk key decryption. 2019-12-30 21:53:06 +01:00
Milan Broz
bb8088ca0f Another fix for ancient systems. 2019-12-30 21:53:06 +01:00
Milan Broz
26f4bc39fc Fix tes for very old bash. 2019-12-30 21:53:06 +01:00
Milan Broz
025e4d9fc6 Fix bitlk test on older systems. 2019-12-30 21:53:06 +01:00
Milan Broz
b2774d57ba Bitlk: Propagare errno from key decryption. 2019-12-30 21:53:06 +01:00
Milan Broz
51edfb4ec9 Bitlk: add gcrypt key backend. 2019-12-30 21:53:06 +01:00
Milan Broz
79019b1ced Bitlk: Move crypt key handling to crypto backend. 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
bc87140b5b Do not declare control variables in for loops
C89 doesn't like this.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
1c5251069b Define UUID_STR_LEN not defined in older versions of libuuid 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
0b6dfefcec Add tests and test images for BitLocker 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
a9e32c55c0 Fix parsing BitLocker metadata from latest Windows
Newest version added a new metadata entry to the recovery
passphrase protected VMK containing two new timestamps. We are
ignoring these for now.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
a494228407 Do not try to activate partially decrypted BitLocker devices 2019-12-30 21:53:06 +01:00
Vojtěch Trefný
9932b5fc5c Do not try to activate BitLocker devices with diffuser
The CBC mode with Elephant Diffuser is currently not supported
by DM crypt.
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
966ba44a33 Add support for opening of BitLocker devices
It's now possible to open/activate the device using passphrase or
recovery passphrase. Support is limited to devices using encryption
modes supported in the DM crypt module (AES-XTS and AES-CBC).
2019-12-30 21:53:06 +01:00
Vojtěch Trefný
62c872eb49 Add support for parsing BitLocker metadata
Currently only support for metadata version 2 is implemented.
2019-12-30 21:53:06 +01:00
Milan Broz
434fee2e13 Add empty template for BITLK device type.
Also add DM_ZERO type for multi-segment mapping.
2019-12-30 21:53:06 +01:00
Andrei Shevchuk
d3f829c065 Add note on integrity mode not supporting discards (TRIM) 2019-12-23 14:31:46 +00:00
Ondrej Kozina
83934bdcf3 Clarify LUKS2 error message related to reencryption.
Original messages could evoke reencryption is currently
in progress. That was inaccurate because code only
detected flag marking such device is in transition state
from metadata pov. We should not imply anything about
running processes. That's detected via reencryption locks.
2019-11-28 16:38:53 +01:00
Ondrej Kozina
3691add163 Minor code cleanup. 2019-11-28 16:38:53 +01:00
Ondrej Kozina
cc7a9e4607 Fix lookup function for keyslot-segment assignment.
In reencryption we can have more than 3 segments.
2019-11-28 16:38:53 +01:00
Ondrej Kozina
943fa69da6 Reduce code duplication in LUKS2 keyslot handling. 2019-11-28 16:38:53 +01:00
Ondrej Kozina
3bef291184 Unify low level LUKS2 keyslot unlock and verify code.
Function is now unused, see later commit
2019-11-28 16:38:53 +01:00
Ondrej Kozina
7316c53b04 Remove redundant digest id to key assignement. 2019-11-28 16:38:52 +01:00
Ondrej Kozina
5e1d1e1850 Add missing validation when unlocking keys for reencryption.
We missed keyslot json validation when unlocking all keys necessary
for reencryption. Also assign appropriate verified digest id to
keys in volume key structure.
2019-11-28 16:38:52 +01:00
Ondrej Kozina
e52c8e148c Remove unnecessary query for volume key size.
In fact we need only stored key size in examined keyslot. It's valid for
default segment volume keys and in case of non-default segment
keys it always returns -1 and fallbacks to stored key size query
instead.
2019-11-28 16:38:52 +01:00
Ondrej Kozina
7eb47f3db1 Split reencryption locking in two variants. 2019-11-28 16:38:52 +01:00
Milan Broz
ec59d31d04 Remove AEAD tests dor MORUS and AEGIS ciphers.
These variants were removed from mainline kernel.
2019-11-25 23:16:53 +01:00
Milan Broz
ddd15b63b2 Add backward compatibility flags API.
We need to have some way hot to configure old integrity devices
with legacy padding.

For now, also use in tests to not fail checksum with new kernel.
2019-11-25 23:14:58 +01:00
Milan Broz
e91b35a53d Print info and warning if dm-integrity fix_padding is set.
The dump operation prints the fix_padding flag if set.

Also try to print warning if an old kernel is used and th edevice
cannot be activated because of missing fix padding support.
2019-11-25 19:48:54 +01:00
Mikulas Patocka
fb4079aa4d cryptsetup: add support for the "fix_padding" option
This patch adds support for fixed padding to cryptsetup.

* Cryptsetup will accept superblocks version 4.
* If the dm-integrity target version is greater than 1.4, cryptsetup will
  add a flag "fix_padding" to the dm-integrity target arguments.

There is still one quirk: if we have an old libdm without
DM_DEVICE_GET_TARGET_VERSION and if dm-integrity module is not loaded,
cryptsetup will not detect that it can use the "fix_padding" option.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2019-11-24 20:58:47 +01:00
Milan Broz
48b203a134 Add crypt_resume_by_volume_key() function.
If user has volume key available, LUKS device can be resumed
directly using provided volume key.
No keyslot derivation is needed, only key digest is checked.

Fixes: #502.
2019-11-24 18:04:41 +01:00
Milan Broz
2746fd708f Implement active device suspend info.
Add CRYPT_ACTIVATE_SUSPENDED bit to crypt_get_active_device() flags
that informs the caller that device is suspended (luksSuspend).

Fixes: #501.
2019-11-24 16:56:26 +01:00
Ondrej Kozina
684f43d84d Clarify confirmation prompt text.
Fixes: #473
2019-11-22 15:34:16 +01:00
Milan Broz
6b1be52e6b Fix LUKS1 format if pkbdf benchamr is disabled.
We use minimum iteration for key digest in this case
(the same already used in LUKS2).

Fixes: #478.
2019-11-22 13:02:41 +01:00
Ondrej Kozina
de6258d366 Allow --test-passphrase for detached header alone.
Before this fix we required data device specified on cmd line
even though it was not necessary for testing passphrase.

Fixes: #487.
2019-11-19 14:36:06 +01:00
Ondrej Kozina
5e4dbf33be Allow --key-file option in legacy offline encryption.
The option was ignored for LUKS1 encryption initialization.

Fixes: #491.
2019-11-19 12:41:14 +01:00
Milan Broz
b03cb3f3d8 Export memory safe functions.
Make crypt_safe_alloc/realloc/free and memzero part of API.
2019-11-16 21:28:54 +01:00
Ondrej Kozina
e08401a2ec Properly fix encryption initialization message. 2019-11-08 13:15:37 +01:00
Ondrej Kozina
0a9e7028ae Fix LUKS2 encryption initialization with non-zero keyslot.
Positive keyslot number was interpreted as a failure.
2019-11-08 13:15:37 +01:00
Milan Broz
ba0ecc54df Test Bionic distro in Travis. 2019-11-05 22:09:05 +01:00
Milan Broz
6920f9dc27 Set devel version. 2019-11-05 17:56:58 +01:00
Milan Broz
ba2547212e Allow bitlk branch for CI tests. 2019-11-05 17:53:07 +01:00
Milan Broz
bbe1a8a5b6 Update Readme.md for 2.2.2. 2019-11-01 10:16:05 +01:00
133 changed files with 16779 additions and 10016 deletions

View File

@@ -1,7 +1,7 @@
language: c
sudo: required
dist: xenial
dist: bionic
compiler:
- gcc
@@ -15,7 +15,6 @@ branches:
only:
- master
- wip-luks2
- v2_0_x
before_install:
- uname -a

View File

@@ -5,8 +5,8 @@ What the ...?
**Cryptsetup** is a utility used to conveniently set up disk encryption based
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
and **TrueCrypt** (including **VeraCrypt** extension) formats.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
The project also includes a **veritysetup** utility used to conveniently setup
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
@@ -44,16 +44,16 @@ Download
--------
All release tarballs and release notes are hosted on [kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
**The latest cryptsetup version is 2.2.1**
* [cryptsetup-2.2.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.xz)
* Signature [cryptsetup-2.2.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.1.tar.sign)
**The latest stable cryptsetup version is 2.3.0**
* [cryptsetup-2.3.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.xz)
* Signature [cryptsetup-2.3.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.2.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.1-ReleaseNotes).
* [Cryptsetup 2.3.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.0-ReleaseNotes).
Previous versions
* [Version 2.2.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-ReleaseNotes).
* [Version 2.2.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.2.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.2-ReleaseNotes).
* [Version 2.0.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.2.2])
AC_INIT([cryptsetup],[2.3.1])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=17:0:5
LIBCRYPTSETUP_VERSION_INFO=18:0:6
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c)
@@ -33,6 +33,7 @@ AC_PROG_MAKE_SET
AC_ENABLE_STATIC(no)
LT_INIT
PKG_PROG_PKG_CONFIG
AM_ICONV
dnl ==========================================================================
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
@@ -59,6 +60,12 @@ AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
[[
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
]])
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
@@ -348,6 +355,7 @@ AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_task_deferred_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_mounted_fs], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_holders], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_get_name], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_DEVICE_GET_TARGET_VERSION], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
if test "x$enable_udev" = xyes; then

View File

@@ -1,7 +1,7 @@
/*
* libcryptsetup API log example
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -1,7 +1,7 @@
/*
* libcryptsetup API - using LUKS device example
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

209
docs/v2.3.0-ReleaseNotes Normal file
View File

@@ -0,0 +1,209 @@
Cryptsetup 2.3.0 Release Notes
==============================
Stable release with new experimental features and bug fixes.
Cryptsetup 2.3 version introduces support for BitLocker-compatible
devices (BITLK format). This format is used in Windows systems,
and in combination with a filesystem driver, cryptsetup now provides
native read-write access to BitLocker Full Disk Encryption devices.
The BITLK implementation is based on publicly available information
and it is an independent and opensource implementation that allows
to access this proprietary disk encryption.
Changes since version 2.2.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* BITLK (Windows BitLocker compatible) device access
BITLK userspace implementation is based on the master thesis and code
provided by Vojtech Trefny. Also, thanks to other opensource projects
like libbde (that provide alternative approach to decode this format)
we were able to verify cryptsetup implementation.
NOTE: Support for the BITLK device is EXPERIMENTAL and will require
a lot of testing. If you get some error message (mainly unsupported
metadata in the on-disk header), please help us by submitting an issue
to cryptsetup project, so we can fix it. Thank you!
Cryptsetup supports BITLK activation through passphrase or recovery
passphrase for existing devices (BitLocker and Bitlocker to Go).
Activation through TPM, SmartCard, or any other key protector
is not supported. And in some situations, mainly for TPM bind to some
PCR registers, it could be even impossible on Linux in the future.
All metadata (key protectors) are handled read-only, cryptsetup cannot
create or modify them. Except for old devices (created in old Vista
systems), all format variants should be recognized.
Data devices can be activated read-write (followed by mounting through
the proper filesystem driver). To access filesystem on the decrypted device
you need properly installed driver (vfat, NTFS or exFAT).
Foe AES-XTS, activation is supported on all recent Linux kernels.
For older AES-CBC encryption, Linux Kernel version 5.3 is required
(support for special IV variant); for AES-CBC with Elephant diffuser,
Linux Kernel 5.6 is required.
Please note that CBC variants are legacy, and we provide it only
for backward compatibility (to be able to access old drives).
Cryptsetup command now supports the new "bitlk" format and implement dump,
open, status, and close actions.
To activate a BITLK device, use
# cryptsetup open --type bitlk <device> <name>
or with alias
# cryptsetup bitlkOpen <device> <name>
Then with properly installed fs driver (usually NTFS, vfat or exFAT),
you can mount the plaintext device /dev/mapper<name> device as a common
filesystem.
To print metadata information about BITLK device, use
# crypotsetup bitlkDump <device>
To print information about the active device, use
# cryptsetup status <name>
Example (activation of disk image):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Recent blkid recognizes BitLocker device,just to verity
# blkid bitlocker_xts_ntfs.img
bitlocker_xts_ntfs.img: TYPE="BitLocker"
# Print visible metadata information (on-disk, form the image)
# cryptsetup bitlkDump bitlocker_xts_ntfs.img
Info for BITLK device bitlocker_xts_ntfs.img.
Version: 2
GUID: ...
Created: Wed Oct 23 17:38:15 2019
Description: DESKTOP-xxxxxxx E: 23.10.2019
Cipher name: aes
Cipher mode: xts-plain64
Cipher key: 128 bits
Keyslots:
0: VMK
GUID: ...
Protection: VMK protected with passphrase
Salt: ...
Key data size: 44 [bytes]
1: VMK
GUID: ...
Protection: VMK protected with recovery passphrase
Salt: ...
Key data size: 44 [bytes]
2: FVEK
Key data size: 44 [bytes]
# Activation (recovery passphrase works the same as password)
# cryptsetup bitlkOpen bitlocker_xts_ntfs.img test -v
Enter passphrase for bitlocker_xts_ntfs.img:
Command successful.
# Information about the active device
# cryptsetup status test
/dev/mapper/test is active.
type: BITLK
cipher: aes-xts-plain64
keysize: 128 bits
...
# Plaintext device should now contain decrypted NTFS filesystem
# blkid /dev/mapper/test
/dev/mapper/test: UUID="..." TYPE="ntfs"
# And can be mounted
# mount /dev/mapper/test /mnt/tst
# Deactivation
# umount /mnt/tst
# cryptsetup close test
* Veritysetup now supports activation with additional PKCS7 signature
of root hash through --root-hash-signature option.
The signature uses an in-kernel trusted key to validate the signature
of the root hash during activation. This option requires Linux kernel
5.4 with DM_VERITY_VERIFY_ROOTHASH_SIG option.
Verity devices activated with signature now has a special flag
(with signature) active in device status (veritysetup status <name>).
Usage:
# veritysetup open <data_device> name <hash_device> <root_hash> \
--root-hash-signature=<roothash_p7_sig_file>
* Integritysetup now calculates hash integrity size according to algorithm
instead of requiring an explicit tag size.
Previously, when integritysetup formats a device with hash or
HMAC integrity checksums, it required explicitly tag size entry from
a user (or used default value).
This led to confusion and unexpected shortened tag sizes.
Now, libcryptsetup calculates tag size according to real hash output.
Tag size can also be specified, then it warns if these values differ.
* Integritysetup now supports fixed padding for dm-integrity devices.
There was an in-kernel bug that wasted a lot of space when using metadata
areas for integrity-protected devices if a larger sector size than
512 bytes was used.
This problem affects both stand-alone dm-integrity and also LUKS2 with
authenticated encryption and larger sector size.
The new extension to dm-integrity superblock is needed, so devices
with the new optimal padding cannot be activated on older systems.
Integritysetup/Cryptsetup will use new padding automatically if it
detects the proper kernel. To create a compatible device with
the old padding, use --integrity-legacy-padding option.
* A lot of fixes to online LUKS2 reecryption.
* Add crypt_resume_by_volume_key() function to libcryptsetup.
If a user has a volume key available, the LUKS device can be resumed
directly using the provided volume key.
No keyslot derivation is needed, only the key digest is checked.
* Implement active device suspend info.
Add CRYPT_ACTIVATE_SUSPENDED bit to crypt_get_active_device() flags
that informs the caller that device is suspended (luksSuspend).
* Allow --test-passphrase for a detached header.
Before this fix, we required a data device specified on the command
line even though it was not necessary for the passphrase check.
* Allow --key-file option in legacy offline encryption.
The option was ignored for LUKS1 encryption initialization.
* Export memory safe functions.
To make developing of some extensions simpler, we now export
functions to handle memory with proper wipe on deallocation.
* Fail crypt_keyslot_get_pbkdf for inactive LUKS1 keyslot.
Libcryptsetup API extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The libcryptsetup API is backward compatible for existing symbols.
New symbols
crypt_set_compatibility
crypt_get_compatibility;
crypt_resume_by_volume_key;
crypt_activate_by_signed_key;
crypt_safe_alloc;
crypt_safe_realloc;
crypt_safe_free;
crypt_safe_memzero;
New defines introduced :
CRYPT_BITLK "BITLK" - BITLK (BitLocker-compatible mode
CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING - dm-integrity legacy padding
CRYPT_VERITY_ROOT_HASH_SIGNATURE - dm-verity root hash signature
CRYPT_ACTIVATE_SUSPENDED - device suspended info flag

45
docs/v2.3.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,45 @@
Cryptsetup 2.3.1 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.x should upgrade to this version.
Changes since version 2.3.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Support VeraCrypt 128 bytes passwords.
VeraCrypt now allows passwords of maximal length 128 bytes
(compared to legacy TrueCrypt where it was limited by 64 bytes).
* Strip extra newline from BitLocker recovery keys
There might be a trailing newline added by the text editor when
the recovery passphrase was passed using the --key-file option.
* Detect separate libiconv library.
It should fix compilation issues on distributions with iconv
implemented in a separate library.
* Various fixes and workarounds to build on old Linux distributions.
* Split lines with hexadecimal digest printing for large key-sizes.
* Do not wipe the device with no integrity profile.
With --integrity none we performed useless full device wipe.
* Workaround for dm-integrity kernel table bug.
Some kernels show an invalid dm-integrity mapping table
if superblock contains the "recalculate" bit. This causes
integritysetup to not recognize the dm-integrity device.
Integritysetup now specifies kernel options such a way that
even on unpatched kernels mapping table is correct.
* Print error message if LUKS1 keyslot cannot be processed.
If the crypto backend is missing support for hash algorithms
used in PBKDF2, the error message was not visible.
* Properly align LUKS2 keyslots area on conversion.
If the LUKS1 payload offset (data offset) is not aligned
to 4 KiB boundary, new LUKS2 keyslots area in now aligned properly.
* Validate LUKS2 earlier on conversion to not corrupt the device
if binary keyslots areas metadata are not correct.

View File

@@ -22,7 +22,8 @@ libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) \
-I $(top_srcdir)/lib/loopaes \
-I $(top_srcdir)/lib/verity \
-I $(top_srcdir)/lib/tcrypt \
-I $(top_srcdir)/lib/integrity
-I $(top_srcdir)/lib/integrity \
-I $(top_srcdir)/lib/bitlk
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
@@ -39,6 +40,7 @@ libcryptsetup_la_LIBADD = \
@LIBARGON2_LIBS@ \
@JSON_C_LIBS@ \
@BLKID_LIBS@ \
$(LTLIBICONV) \
libcrypto_backend.la \
libutils_io.la
@@ -64,6 +66,7 @@ libcryptsetup_la_SOURCES = \
lib/utils_device_locking.c \
lib/utils_device_locking.h \
lib/utils_pbkdf.c \
lib/utils_safe_memory.c \
lib/utils_storage_wrappers.c \
lib/utils_storage_wrappers.h \
lib/libdevmapper.c \
@@ -74,7 +77,7 @@ libcryptsetup_la_SOURCES = \
lib/base64.h \
lib/base64.c \
lib/integrity/integrity.h \
lib/integrity/integrity.c \
lib/integrity/integrity.c \
lib/loopaes/loopaes.h \
lib/loopaes/loopaes.c \
lib/tcrypt/tcrypt.h \
@@ -90,7 +93,7 @@ libcryptsetup_la_SOURCES = \
lib/verity/verity.h \
lib/verity/rs_encode_char.c \
lib/verity/rs_decode_char.c \
lib/verity/rs.h \
lib/verity/rs.h \
lib/luks2/luks2_disk_metadata.c \
lib/luks2/luks2_json_format.c \
lib/luks2/luks2_json_metadata.c \
@@ -107,4 +110,6 @@ libcryptsetup_la_SOURCES = \
lib/luks2/luks2_internal.h \
lib/luks2/luks2.h \
lib/utils_blkid.c \
lib/utils_blkid.h
lib/utils_blkid.h \
lib/bitlk/bitlk.h \
lib/bitlk/bitlk.c

1204
lib/bitlk/bitlk.c Normal file

File diff suppressed because it is too large Load Diff

130
lib/bitlk/bitlk.h Normal file
View File

@@ -0,0 +1,130 @@
/*
* BITLK (BitLocker-compatible) header definition
*
* Copyright (C) 2019-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2020 Milan Broz
* Copyright (C) 2019-2020 Vojtech Trefny
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _CRYPTSETUP_BITLK_H
#define _CRYPTSETUP_BITLK_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
struct crypt_device;
struct device;
#define BITLK_NONCE_SIZE 12
#define BITLK_SALT_SIZE 16
#define BITLK_VMK_MAC_TAG_SIZE 16
#define BITLK_STATE_NORMAL 0x0004
typedef enum {
BITLK_ENCRYPTION_TYPE_NORMAL = 0,
BITLK_ENCRYPTION_TYPE_EOW,
BITLK_ENCRYPTION_TYPE_UNKNOWN,
} BITLKEncryptionType;
typedef enum {
BITLK_PROTECTION_CLEAR_KEY = 0,
BITLK_PROTECTION_TPM,
BITLK_PROTECTION_STARTUP_KEY,
BITLK_PROTECTION_TPM_PIN,
BITLK_PROTECTION_RECOVERY_PASSPHRASE,
BITLK_PROTECTION_PASSPHRASE,
BITLK_PROTECTION_SMART_CARD,
BITLK_PROTECTION_UNKNOWN,
} BITLKVMKProtection;
typedef enum {
BITLK_ENTRY_TYPE_PROPERTY = 0x0000,
BITLK_ENTRY_TYPE_VMK = 0x0002,
BITLK_ENTRY_TYPE_FVEK = 0x0003,
BITLK_ENTRY_TYPE_STARTUP_KEY = 0x0006,
BITLK_ENTRY_TYPE_DESCRIPTION = 0x0007,
BITLK_ENTRY_TYPE_VOLUME_HEADER = 0x000f,
} BITLKFVEEntryType;
typedef enum {
BITLK_ENTRY_VALUE_ERASED = 0x0000,
BITLK_ENTRY_VALUE_KEY = 0x0001,
BITLK_ENTRY_VALUE_STRING = 0x0002,
BITLK_ENTRY_VALUE_STRETCH_KEY = 0x0003,
BITLK_ENTRY_VALUE_USE_KEY = 0x0004,
BITLK_ENTRY_VALUE_ENCRYPTED_KEY = 0x0005,
BITLK_ENTRY_VALUE_TPM_KEY = 0x0006,
BITLK_ENTRY_VALUE_VALIDATION = 0x0007,
BITLK_ENTRY_VALUE_VMK = 0x0008,
BITLK_ENTRY_VALUE_EXTERNAL_KEY = 0x0009,
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
} BITLKFVEEntryValue;
struct bitlk_vmk {
char *guid;
char *name;
BITLKVMKProtection protection;
uint8_t salt[BITLK_SALT_SIZE];
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
uint8_t nonce[BITLK_NONCE_SIZE];
struct volume_key *vk;
struct bitlk_vmk *next;
};
struct bitlk_fvek {
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
uint8_t nonce[BITLK_NONCE_SIZE];
struct volume_key *vk;
};
struct bitlk_metadata {
bool togo;
bool state;
BITLKEncryptionType type;
const char *cipher;
const char *cipher_mode;
uint16_t key_size;
char *guid;
uint64_t creation_time;
char *description;
uint64_t metadata_offset[3];
uint32_t metadata_version;
uint64_t volume_header_offset;
uint64_t volume_header_size;
struct bitlk_vmk *vmks;
struct bitlk_fvek *fvek;
};
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_metadata *params);
int BITLK_activate(struct crypt_device *cd,
const char *name,
const char *password,
size_t passwordLen,
const struct bitlk_metadata *params,
uint32_t flags);
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek);
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk);
void BITLK_bitlk_metadata_free(struct bitlk_metadata *params);
#endif

View File

@@ -2,8 +2,8 @@
* cryptsetup plain device helper functions
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* Argon2 PBKDF2 library wrapper
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -1,8 +1,8 @@
/*
* Cipher performance check
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2019 Milan Broz
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,6 +23,10 @@
#include <time.h>
#include "crypto_backend_internal.h"
#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
/*
* This is not simulating storage, so using disk block causes extreme overhead.
* Let's use some fixed block size where results are more reliable...

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel cipher generic utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2019 Milan Broz
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -1,8 +1,8 @@
/*
* crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -119,6 +119,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t iv_offset,
bool crypt_storage_kernel_only(struct crypt_storage *ctx);
/* Temporary Bitlk helper */
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
/* Memzero helper (memset on stack can be optimized out) */
static inline void crypt_backend_memzero(void *s, size_t n)
{

View File

@@ -1,8 +1,8 @@
/*
* crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -55,5 +55,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length);
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,6 +40,10 @@
#define SOL_ALG 279
#endif
#ifndef ALG_SET_AEAD_AUTHSIZE
#define ALG_SET_AEAD_AUTHSIZE 5
#endif
/*
* ciphers
*
@@ -49,7 +53,7 @@
*/
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
const void *key, size_t key_length,
struct sockaddr_alg *sa)
size_t tag_length, struct sockaddr_alg *sa)
{
if (!ctx)
return -EINVAL;
@@ -71,6 +75,11 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
return -EINVAL;
}
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
if (ctx->opfd < 0) {
crypt_cipher_destroy_kernel(ctx);
@@ -93,12 +102,13 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
return _crypt_cipher_init(ctx, key, key_length, &sa);
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
}
/* The in/out should be aligned to page boundary */
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *in, size_t in_length,
char *out, size_t out_length,
const char *iv, size_t iv_length,
uint32_t direction)
{
@@ -109,7 +119,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
uint32_t *type;
struct iovec iov = {
.iov_base = (void*)(uintptr_t)in,
.iov_len = length,
.iov_len = in_length,
};
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
@@ -120,7 +130,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
.msg_iovlen = 1,
};
if (!in || !out || !length)
if (!in || !out || !in_length)
return -EINVAL;
if ((!iv && iv_length) || (iv && !iv_length))
@@ -151,13 +161,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
}
len = sendmsg(ctx->opfd, &msg, 0);
if (len != (ssize_t)length) {
if (len != (ssize_t)(in_length)) {
r = -EIO;
goto bad;
}
len = read(ctx->opfd, out, length);
if (len != (ssize_t)length)
len = read(ctx->opfd, out, out_length);
if (len != (ssize_t)out_length)
r = -EIO;
bad:
crypt_backend_memzero(buffer, sizeof(buffer));
@@ -168,7 +178,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return _crypt_cipher_crypt(ctx, in, out, length,
return _crypt_cipher_crypt(ctx, in, length, out, length,
iv, iv_length, ALG_OP_ENCRYPT);
}
@@ -176,7 +186,7 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return _crypt_cipher_crypt(ctx, in, out, length,
return _crypt_cipher_crypt(ctx, in, length, out, length,
iv, iv_length, ALG_OP_DECRYPT);
}
@@ -243,13 +253,56 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
memset(key, 0xab, key_length);
*key = 0xef;
r = _crypt_cipher_init(&c, key, key_length, &sa);
r = _crypt_cipher_init(&c, key, key_length, 0, &sa);
crypt_cipher_destroy_kernel(&c);
free(key);
return r;
}
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
struct crypt_cipher_kernel c;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "aead",
.salg_name = "ccm(aes)",
};
int r;
char buffer[128], ccm_iv[16];
if (length + tag_length > sizeof(buffer))
return -EINVAL;
if (iv_length > sizeof(ccm_iv) - 2)
return -EINVAL;
r = _crypt_cipher_init(&c, key, key_length, tag_length, &sa);
if (r < 0)
return r;
memcpy(buffer, in, length);
memcpy(buffer + length, tag, tag_length);
/* CCM IV - RFC3610 */
memset(ccm_iv, 0, sizeof(ccm_iv));
ccm_iv[0] = 15 - iv_length - 1;
memcpy(ccm_iv + 1, iv, iv_length);
memset(ccm_iv + 1 + iv_length, 0, ccm_iv[0] + 1);
iv_length = sizeof(ccm_iv);
r = _crypt_cipher_crypt(&c, buffer, length + tag_length, out, length,
ccm_iv, iv_length, ALG_OP_DECRYPT);
crypt_cipher_destroy_kernel(&c);
crypt_backend_memzero(buffer, sizeof(buffer));
return r;
}
#else /* ENABLE_AF_ALG */
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length)
@@ -280,4 +333,11 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
/* Cannot check, expect success. */
return 0;
}
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return -ENOTSUP;
}
#endif

View File

@@ -1,8 +1,8 @@
/*
* GCRYPT crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -479,3 +479,43 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return ctx->use_kernel;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
#ifdef GCRY_CCM_BLOCK_LEN
gcry_cipher_hd_t hd;
uint64_t l[3];
int r = -EINVAL;
if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
return -EINVAL;
if (gcry_cipher_setkey(hd, key, key_length))
goto out;
if (gcry_cipher_setiv(hd, iv, iv_length))
goto out;
l[0] = length;
l[1] = 0;
l[2] = tag_length;
if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
goto out;
if (gcry_cipher_decrypt(hd, out, length, in, length))
goto out;
if (gcry_cipher_checktag(hd, tag, tag_length))
goto out;
r = 0;
out:
gcry_cipher_close(hd);
return r;
#else
return -ENOTSUP;
#endif
}

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel userspace API crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -392,3 +392,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* Nettle crypto backend implementation
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -433,3 +433,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* NSS crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -381,3 +381,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* OPENSSL crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -35,6 +35,8 @@
#include <openssl/rand.h>
#include "crypto_backend_internal.h"
#define CONST_CAST(x) (x)(uintptr_t)
static int crypto_backend_initialised = 0;
struct crypt_hash {
@@ -505,3 +507,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return ctx->use_kernel;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
#ifdef EVP_CTRL_CCM_SET_IVLEN
EVP_CIPHER_CTX *ctx;
int len = 0, r = -EINVAL;
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
return -EINVAL;
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
goto out;
//EVP_CIPHER_CTX_key_length(ctx)
//EVP_CIPHER_CTX_iv_length(ctx)
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
goto out;
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
goto out;
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
goto out;
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
r = 0;
out:
EVP_CIPHER_CTX_free(ctx);
return r;
#else
return -ENOTSUP;
#endif
}

View File

@@ -2,7 +2,7 @@
* Generic wrapper for storage encryption modes and Initial Vectors
* (reimplementation of some functions from Linux dm-crypt kernel)
*
* Copyright (C) 2014-2019 Milan Broz
* Copyright (C) 2014-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -4,8 +4,8 @@
* Copyright (C) 2004 Free Software Foundation
*
* cryptsetup related changes
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -1,8 +1,8 @@
/*
* PBKDF performance check
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2016-2019 Ondrej Mosnacek
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
* Copyright (C) 2016-2020 Ondrej Mosnacek
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,10 @@
#include <sys/resource.h>
#include "crypto_backend.h"
#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
#define BENCH_MIN_MS 250
#define BENCH_MIN_MS_FAST 10
#define BENCH_PERCENT_ATLEAST 95

View File

@@ -1,7 +1,7 @@
/*
* Integrity volume handling
*
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <uuid/uuid.h>
#include "integrity.h"
@@ -41,8 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
sb->version != SB_VERSION_3)) {
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_4) {
log_std(cd, "No integrity superblock detected on %s.\n",
device_path(device));
r = -EINVAL;
@@ -58,7 +56,9 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
return r;
}
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
int INTEGRITY_read_sb(struct crypt_device *cd,
struct crypt_params_integrity *params,
uint32_t *flags)
{
struct superblock sb;
int r;
@@ -70,6 +70,9 @@ int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *pa
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
params->tag_size = sb.integrity_tag_size;
if (flags)
*flags = sb.flags;
return 0;
}
@@ -92,10 +95,11 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
if (sb.version == SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector);
log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit);
log_std(cd, "flags %s%s%s\n",
log_std(cd, "flags %s%s%s%s\n",
sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "",
sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "",
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "",
sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "");
return 0;
}
@@ -137,6 +141,27 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
return -EINVAL;
}
/* Return hash or hmac(hash) size, if known */
int INTEGRITY_hash_tag_size(const char *integrity)
{
char hash[MAX_CIPHER_LEN];
int r;
if (!integrity)
return 0;
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
return 4;
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
if (r == 1)
r = crypt_hash_size(hash);
else
r = crypt_hash_size(integrity);
return r < 0 ? 0 : r;
}
int INTEGRITY_tag_size(struct crypt_device *cd,
const char *integrity,
const char *cipher,
@@ -187,7 +212,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
struct crypt_dm_active_device *dmd,
uint32_t flags)
uint32_t flags, uint32_t sb_flags)
{
int r;
@@ -198,12 +223,16 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
.flags = flags,
};
/* Workaround for kernel dm-integrity table bug */
if (sb_flags & SB_FLAG_RECALCULATING)
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
r = INTEGRITY_data_sectors(cd, crypt_metadata_device(cd),
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
if (r < 0)
return r;
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
crypt_metadata_device(cd), crypt_data_device(cd),
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
crypt_get_sector_size(cd), vk, journal_crypt_key,
@@ -213,7 +242,8 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
const char *name,
const char *type,
struct crypt_dm_active_device *dmd)
struct crypt_dm_active_device *dmd,
uint32_t sb_flags)
{
int r;
uint32_t dmi_flags;
@@ -238,7 +268,13 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
r = dm_create_device(cd, name, type, dmd);
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
log_err(cd, _("Kernel does not support dm-integrity mapping."));
return -ENOTSUP;
}
if (r < 0 && (sb_flags & SB_FLAG_FIXED_PADDING) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
!(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)) {
log_err(cd, _("Kernel does not support dm-integrity fixed metadata alignment."));
return -ENOTSUP;
}
@@ -251,15 +287,16 @@ int INTEGRITY_activate(struct crypt_device *cd,
struct volume_key *vk,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
uint32_t flags)
uint32_t flags, uint32_t sb_flags)
{
struct crypt_dm_active_device dmd = {};
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
journal_mac_key, &dmd, flags, sb_flags);
if (r < 0)
return r;
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
dm_targets_free(cd, &dmd);
return r;
}
@@ -289,7 +326,7 @@ int INTEGRITY_format(struct crypt_device *cd,
if (params && params->integrity_key_size)
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
journal_crypt_key, journal_mac_key, params);
@@ -303,7 +340,7 @@ int INTEGRITY_format(struct crypt_device *cd,
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
log_err(cd, _("Kernel does not support dm-integrity mapping."));
r = -ENOTSUP;
}
if (r) {

View File

@@ -1,7 +1,7 @@
/*
* Integrity header definition
*
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,10 +34,12 @@ struct crypt_dm_active_device;
#define SB_VERSION_1 1
#define SB_VERSION_2 2
#define SB_VERSION_3 3
#define SB_VERSION_4 4
#define SB_FLAG_HAVE_JOURNAL_MAC (1 << 0)
#define SB_FLAG_RECALCULATING (1 << 1) /* V2 only */
#define SB_FLAG_DIRTY_BITMAP (1 << 2) /* V3 only */
#define SB_FLAG_FIXED_PADDING (1 << 3) /* V4 only */
struct superblock {
uint8_t magic[8];
@@ -53,7 +55,9 @@ struct superblock {
uint64_t recalc_sector; /* V2 only */
} __attribute__ ((packed));
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
int INTEGRITY_read_sb(struct crypt_device *cd,
struct crypt_params_integrity *params,
uint32_t *flags);
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
@@ -66,6 +70,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
const char *integrity,
const char *cipher,
const char *cipher_mode);
int INTEGRITY_hash_tag_size(const char *integrity);
int INTEGRITY_format(struct crypt_device *cd,
const struct crypt_params_integrity *params,
@@ -78,7 +83,7 @@ int INTEGRITY_activate(struct crypt_device *cd,
struct volume_key *vk,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
uint32_t flags);
uint32_t flags, uint32_t sb_flags);
int INTEGRITY_create_dmd_device(struct crypt_device *cd,
const struct crypt_params_integrity *params,
@@ -86,10 +91,11 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
struct crypt_dm_active_device *dmd,
uint32_t flags);
uint32_t flags, uint32_t sb_flags);
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
const char *name,
const char *type,
struct crypt_dm_active_device *dmd);
struct crypt_dm_active_device *dmd,
uint32_t sb_flags);
#endif

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <fcntl.h>
#include "nls.h"
#include "bitops.h"
@@ -77,6 +78,10 @@
*_py = NULL; \
} while (0)
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
struct crypt_device;
struct luks2_reenc_context;

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -414,6 +414,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
#define CRYPT_TCRYPT "TCRYPT"
/** INTEGRITY dm-integrity device */
#define CRYPT_INTEGRITY "INTEGRITY"
/** BITLK (BitLocker-compatible mode) */
#define CRYPT_BITLK "BITLK"
/** LUKS any version */
#define CRYPT_LUKS NULL
@@ -505,6 +507,8 @@ struct crypt_params_verity {
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
/** Create hash - format hash device */
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
/** Root hash signature required for activation */
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
/**
*
@@ -629,6 +633,26 @@ int crypt_format(struct crypt_device *cd,
size_t volume_key_size,
void *params);
/**
* Set format compatibility flags.
*
* @param cd crypt device handle
* @param flags CRYPT_COMPATIBILITY_* flags
*/
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags);
/**
* Get compatibility flags.
*
* @param cd crypt device handle
*
* @returns compatibility flags
*/
uint32_t crypt_get_compatibility(struct crypt_device *cd);
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
/**
* Convert to new type for already existing device.
*
@@ -828,6 +852,20 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
int keyslot,
const char *keyfile,
size_t keyfile_size);
/**
* Resume crypt device using provided volume key.
*
* @param cd crypt device handle
* @param name name of device to resume
* @param volume_key provided volume key
* @param volume_key_size size of volume_key
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_resume_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size);
/** @} */
/**
@@ -1061,6 +1099,8 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
/** device is suspended (key should be wiped from memory), output only */
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
/**
* Active device runtime attributes
@@ -1252,6 +1292,31 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
size_t volume_key_size,
uint32_t flags);
/**
* Activate VERITY device using provided key and optional signature).
*
* @param cd crypt device handle
* @param name name of device to create
* @param volume_key provided volume key
* @param volume_key_size size of volume_key
* @param signature buffer with signature for the key
* @param signature_size bsize of signature buffer
* @param flags activation flags
*
* @return @e 0 on success or negative errno value otherwise.
*
* @note For VERITY the volume key means root hash required for activation.
* Because kernel dm-verity is always read only, you have to provide
* CRYPT_ACTIVATE_READONLY flag always.
*/
int crypt_activate_by_signed_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
uint32_t flags);
/**
* Activate device using passphrase stored in kernel keyring.
*
@@ -1322,6 +1387,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
*
* @note For TCRYPT cipher chain is the volume key concatenated
* for all ciphers in chain.
* @note For VERITY the volume key means root hash used for activation.
*/
int crypt_volume_key_get(struct crypt_device *cd,
int keyslot,
@@ -2251,6 +2317,53 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
struct crypt_params_reencrypt *params);
/** @} */
/**
* @defgroup crypt-memory Safe memory helpers functions
* @addtogroup crypt-memory
* @{
*/
/**
* Allocate safe memory (content is safely wiped on deallocation).
*
* @param size size of memory in bytes
*
* @return pointer to allocate memory or @e NULL.
*/
void *crypt_safe_alloc(size_t size);
/**
* Release safe memory, content is safely wiped
* The pointer must be allocated with @link crypt_safe_alloc @endlink
*
* @param data pointer to memory to be deallocated
*
* @return pointer to allocate memory or @e NULL.
*/
void crypt_safe_free(void *data);
/**
* Reallocate safe memory (content is copied and safely wiped on deallocation).
*
* @param data pointer to memory to be deallocated
* @param size new size of memory in bytes
*
* @return pointer to allocate memory or @e NULL.
*/
void *crypt_safe_realloc(void *data, size_t size);
/**
* Safe clear memory area (compile should not compile this call out).
*
* @param data pointer to memory to cleared
* @param size new size of memory in bytes
*
* @return pointer to allocate memory or @e NULL.
*/
void crypt_safe_memzero(void *data, size_t size);
/** @} */
#ifdef __cplusplus
}
#endif

View File

@@ -12,6 +12,9 @@ CRYPTSETUP_2.0 {
crypt_set_label;
crypt_set_data_device;
crypt_set_compatibility;
crypt_get_compatibility;
crypt_memory_lock;
crypt_metadata_locking;
crypt_format;
@@ -24,6 +27,7 @@ CRYPTSETUP_2.0 {
crypt_resume_by_keyfile;
crypt_resume_by_keyfile_offset;
crypt_resume_by_keyfile_device_offset;
crypt_resume_by_volume_key;
crypt_free;
crypt_keyslot_add_by_passphrase;
@@ -55,6 +59,7 @@ CRYPTSETUP_2.0 {
crypt_activate_by_keyfile_offset;
crypt_activate_by_keyfile_device_offset;
crypt_activate_by_volume_key;
crypt_activate_by_signed_key;
crypt_activate_by_keyring;
crypt_deactivate;
crypt_deactivate_by_name;
@@ -118,6 +123,11 @@ CRYPTSETUP_2.0 {
crypt_reencrypt_init_by_keyring;
crypt_reencrypt;
crypt_reencrypt_status;
crypt_safe_alloc;
crypt_safe_realloc;
crypt_safe_free;
crypt_safe_memzero;
local:
*;
};

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -27,7 +27,6 @@
#include <dirent.h>
#include <errno.h>
#include <libdevmapper.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <uuid/uuid.h>
#include <sys/stat.h>
@@ -47,6 +46,7 @@
#define DM_INTEGRITY_TARGET "integrity"
#define DM_LINEAR_TARGET "linear"
#define DM_ERROR_TARGET "error"
#define DM_ZERO_TARGET "zero"
#define RETRY_COUNT 5
/* Set if DM target versions were probed */
@@ -168,6 +168,12 @@ static void _dm_set_crypt_compat(struct crypt_device *cd,
_dm_flags |= DM_CAPI_STRING_SUPPORTED;
}
if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
_dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
_dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
_dm_crypt_checked = true;
}
@@ -196,6 +202,9 @@ static void _dm_set_verity_compat(struct crypt_device *cd,
_dm_flags |= DM_VERITY_FEC_SUPPORTED;
}
if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
_dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
_dm_verity_checked = true;
}
@@ -218,6 +227,9 @@ static void _dm_set_integrity_compat(struct crypt_device *cd,
if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
_dm_integrity_checked = true;
}
@@ -265,7 +277,7 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
(target_type == DM_VERITY && _dm_verity_checked) ||
(target_type == DM_INTEGRITY && _dm_integrity_checked) ||
(target_type == DM_LINEAR) ||
(target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
(_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
return 1;
@@ -346,7 +358,7 @@ int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
if ((target == DM_CRYPT && _dm_crypt_checked) ||
(target == DM_VERITY && _dm_verity_checked) ||
(target == DM_INTEGRITY && _dm_integrity_checked) ||
(target == DM_LINEAR)) /* nothing to check with linear */
(target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
return 0;
return -ENODEV;
@@ -667,7 +679,7 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
int max_size, r, num_options = 0;
struct crypt_params_verity *vp;
char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
char features[256], fec_features[256];
char features[256], fec_features[256], verity_verify_args[512+32];
if (!tgt || !tgt->u.verity.vp)
return NULL;
@@ -697,6 +709,13 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
} else
*fec_features = '\0';
if (tgt->u.verity.root_hash_sig_key_desc) {
num_options += 2;
snprintf(verity_verify_args, sizeof(verity_verify_args)-1,
" root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
} else
*verity_verify_args = '\0';
if (num_options)
snprintf(features, sizeof(features)-1, " %d%s%s%s%s", num_options,
(flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
@@ -722,19 +741,22 @@ static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
max_size = strlen(hexroot) + strlen(hexsalt) +
strlen(device_block_path(tgt->data_device)) +
strlen(device_block_path(tgt->u.verity.hash_device)) +
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128;
strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
strlen(verity_verify_args);
params = crypt_safe_alloc(max_size);
if (!params)
goto out;
r = snprintf(params, max_size,
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s",
"%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
vp->hash_type, device_block_path(tgt->data_device),
device_block_path(tgt->u.verity.hash_device),
vp->data_block_size, vp->hash_block_size,
vp->data_size, tgt->u.verity.hash_offset,
vp->hash_name, hexroot, hexsalt, features, fec_features);
vp->hash_name, hexroot, hexsalt, features, fec_features,
verity_verify_args);
if (r < 0 || r >= max_size) {
crypt_safe_free(params);
params = NULL;
@@ -866,6 +888,11 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
strncat(features, feature, sizeof(features) - strlen(features) - 1);
crypt_safe_free(hexkey);
}
if (tgt->u.integrity.fix_padding) {
num_options++;
snprintf(feature, sizeof(feature), "fix_padding ");
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (flags & CRYPT_ACTIVATE_RECALCULATE) {
num_options++;
@@ -922,6 +949,16 @@ static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags)
return params;
}
static char *get_dm_zero_params(const struct dm_target *tgt, uint32_t flags)
{
char *params = crypt_safe_alloc(1);
if (!params)
return NULL;
params[0] = 0;
return params;
}
/* DM helpers */
static int _dm_remove(const char *name, int udev_wait, int deferred)
{
@@ -1195,6 +1232,9 @@ static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *d
case DM_LINEAR:
target = DM_LINEAR_TARGET;
break;
case DM_ZERO:
target = DM_ZERO_TARGET;
break;
default:
return -ENOTSUP;
}
@@ -1233,6 +1273,8 @@ static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
tgt->params = get_dm_integrity_params(tgt, dmd->flags);
else if (tgt->type == DM_LINEAR)
tgt->params = get_dm_linear_params(tgt, dmd->flags);
else if (tgt->type == DM_ZERO)
tgt->params = get_dm_zero_params(tgt, dmd->flags);
else {
r = -ENOTSUP;
goto err;
@@ -1454,10 +1496,13 @@ static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target
crypt_free_verity_params(tgt->u.verity.vp);
device_free(cd, tgt->u.verity.hash_device);
free(CONST_CAST(void*)tgt->u.verity.root_hash);
free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
/* fall through */
case DM_LINEAR:
/* fall through */
case DM_ERROR:
/* fall through */
case DM_ZERO:
break;
default:
log_err(cd, _("Unknown dm target type."));
@@ -1522,7 +1567,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
/* If kernel keyring is not supported load key directly in dm-crypt */
if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
!(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
log_dbg(cd, "dm-crypt doesn't support kernel keyring");
log_dbg(cd, "dm-crypt does not support kernel keyring");
*dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
ret = 1;
}
@@ -1530,7 +1575,7 @@ static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dm
/* Drop performance options if not supported */
if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
!(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
log_dbg(cd, "dm-crypt doesn't support performance options");
log_dbg(cd, "dm-crypt does not support performance options");
*dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
ret = 1;
}
@@ -1556,7 +1601,8 @@ int dm_create_device(struct crypt_device *cd, const char *name,
if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
goto out;
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR) && check_retry(cd, &dmd->flags, dmt_flags))
if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
check_retry(cd, &dmd->flags, dmt_flags))
r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
if (r == -EINVAL &&
@@ -1669,6 +1715,7 @@ static int dm_status_dmi(const char *name, struct dm_info *dmi,
strcmp(target_type, DM_VERITY_TARGET) &&
strcmp(target_type, DM_INTEGRITY_TARGET) &&
strcmp(target_type, DM_LINEAR_TARGET) &&
strcmp(target_type, DM_ZERO_TARGET) &&
strcmp(target_type, DM_ERROR_TARGET)))
goto out;
r = 0;
@@ -1957,6 +2004,7 @@ static int _dm_target_query_verity(struct crypt_device *cd,
int r;
struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
char *root_hash_sig_key_desc = NULL;
if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
vp = crypt_zalloc(sizeof(*vp));
@@ -2140,6 +2188,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
if (vp)
vp->fec_roots = val32;
i++;
} else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
str = strsep(&params, " ");
if (!str)
goto err;
if (!root_hash_sig_key_desc)
root_hash_sig_key_desc = strdup(str);
i++;
if (vp)
vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
} else /* unknown option */
goto err;
}
@@ -2165,11 +2222,15 @@ static int _dm_target_query_verity(struct crypt_device *cd,
vp->salt = salt;
if (vp && fec_dev_str)
vp->fec_device = fec_dev_str;
if (root_hash_sig_key_desc)
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
return 0;
err:
device_free(cd, data_device);
device_free(cd, hash_device);
device_free(cd, fec_device);
free(root_hash_sig_key_desc);
free(root_hash);
free(hash_name);
free(salt);
@@ -2334,6 +2395,8 @@ static int _dm_target_query_integrity(struct crypt_device *cd,
}
} else if (!strcmp(arg, "recalculate")) {
*act_flags |= CRYPT_ACTIVATE_RECALCULATE;
} else if (!strcmp(arg, "fix_padding")) {
tgt->u.integrity.fix_padding = true;
} else /* unknown option */
goto err;
}
@@ -2416,6 +2479,14 @@ static int _dm_target_query_error(struct crypt_device *cd, struct dm_target *tgt
return 0;
}
static int _dm_target_query_zero(struct crypt_device *cd, struct dm_target *tgt)
{
tgt->type = DM_ZERO;
tgt->direction = TARGET_QUERY;
return 0;
}
/*
* on error retval has to be negative
*
@@ -2437,6 +2508,8 @@ static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const
r = _dm_target_query_linear(cd, tgt, get_flags, params);
else if (!strcmp(target_type, DM_ERROR_TARGET))
r = _dm_target_query_error(cd, tgt);
else if (!strcmp(target_type, DM_ZERO_TARGET))
r = _dm_target_query_zero(cd, tgt);
if (!r) {
tgt->offset = *start;
@@ -2519,6 +2592,9 @@ static int _dm_query_device(struct crypt_device *cd, const char *name,
if (dmi.read_only)
dmd->flags |= CRYPT_ACTIVATE_READONLY;
if (dmi.suspended)
dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
tmp_uuid = dm_task_get_uuid(dmt);
if (!tmp_uuid)
dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
@@ -2566,6 +2642,7 @@ int dm_query_device(struct crypt_device *cd, const char *name,
static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
{
#if HAVE_DECL_DM_DEVICE_GET_NAME
struct crypt_dm_active_device dmd;
char dmname[PATH_MAX];
unsigned i;
@@ -2604,6 +2681,9 @@ static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_
}
return count;
#else
return -EINVAL;
#endif
}
int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
@@ -2841,8 +2921,8 @@ err:
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *data_device, struct device *hash_device, struct device *fec_device,
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
uint64_t hash_blocks, struct crypt_params_verity *vp)
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp)
{
if (!data_device || !hash_device || !vp)
return -EINVAL;
@@ -2857,6 +2937,7 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
tgt->u.verity.fec_device = fec_device;
tgt->u.verity.root_hash = root_hash;
tgt->u.verity.root_hash_size = root_hash_size;
tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
tgt->u.verity.hash_offset = hash_offset_block;
tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
tgt->u.verity.hash_blocks = hash_blocks;
@@ -2865,16 +2946,21 @@ int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
return 0;
}
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
int dm_integrity_target_set(struct crypt_device *cd,
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *meta_device,
struct device *data_device, uint64_t tag_size, uint64_t offset,
uint32_t sector_size, struct volume_key *vk,
struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
const struct crypt_params_integrity *ip)
{
uint32_t dmi_flags;
if (!data_device)
return -EINVAL;
_dm_check_versions(cd, DM_INTEGRITY);
tgt->type = DM_INTEGRITY;
tgt->direction = TARGET_SET;
tgt->offset = seg_offset;
@@ -2890,6 +2976,11 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
tgt->u.integrity.journal_crypt_key = journal_crypt_key;
tgt->u.integrity.journal_integrity_key = journal_mac_key;
if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
tgt->u.integrity.fix_padding = true;
if (ip) {
tgt->u.integrity.journal_size = ip->journal_size;
tgt->u.integrity.journal_watermark = ip->journal_watermark;
@@ -2920,3 +3011,13 @@ int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t se
return 0;
}
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
{
tgt->type = DM_ZERO;
tgt->direction = TARGET_SET;
tgt->offset = seg_offset;
tgt->size = seg_size;
return 0;
}

View File

@@ -1,8 +1,8 @@
/*
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -81,7 +81,7 @@ static int hash_keys(struct crypt_device *cd,
const char *hash_name;
char tweak, *key_ptr;
unsigned int i;
int r;
int r = 0;
hash_name = hash_override ?: get_hash(key_len_output);
tweak = get_tweak(keys_count);
@@ -242,7 +242,7 @@ int LOOPAES_activate(struct crypt_device *cd,
if (r < 0 && !dm_flags(cd, DM_CRYPT, &dmc_flags) &&
(dmc_flags & req_flags) != req_flags) {
log_err(cd, _("Kernel doesn't support loop-AES compatible mapping."));
log_err(cd, _("Kernel does not support loop-AES compatible mapping."));
r = -ENOTSUP;
}

View File

@@ -1,8 +1,8 @@
/*
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -2,7 +2,7 @@
* AFsplitter - Anti forensic information splitter
*
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
*
* AFsplitter diffuses information over a large stripe of data,
* therefore supporting secure data destruction.

View File

@@ -2,7 +2,7 @@
* AFsplitter - Anti forensic information splitter
*
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
*
* AFsplitter diffuses information over a large stripe of data,
* therefore supporting secure data destruction.

View File

@@ -2,8 +2,8 @@
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include "luks.h"
@@ -89,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
sector, &dmd.size, &dmd.flags);
if (r < 0) {
log_err(ctx, _("Device %s doesn't exist or access denied."),
log_err(ctx, _("Device %s does not exist or access denied."),
device_path(crypt_metadata_device(ctx)));
return -EIO;
}

View File

@@ -2,8 +2,8 @@
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +23,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@@ -260,7 +259,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
r = 0;
out:
crypt_memzero(&hdr, sizeof(hdr));
crypt_safe_memzero(&hdr, sizeof(hdr));
crypt_safe_free(buffer);
return r;
}
@@ -284,7 +283,7 @@ int LUKS_hdr_restore(
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
log_err(ctx, _("Backup file does not contain valid LUKS header."));
r = -EINVAL;
goto out;
}
@@ -453,7 +452,7 @@ out:
if (r)
log_err(ctx, _("Repair failed."));
crypt_free_volume_key(vk);
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
return r;
}
@@ -692,7 +691,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
crypt_free_volume_key(empty_key);
crypt_memzero(buf, sizeof(buf));
crypt_safe_memzero(buf, sizeof(buf));
return r;
}
@@ -787,10 +786,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
return r;
assert(pbkdf->iterations);
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (PBKDF2_temp > (double)UINT32_MAX)
return -EINVAL;
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
assert(header->mkDigestIterations);
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
header->mkDigestSalt, LUKS_SALTSIZE,
@@ -982,8 +986,10 @@ static int LUKS_open_key(unsigned int keyIndex,
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
derived_key->key, hdr->keyBytes,
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
if (r < 0)
if (r < 0) {
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
goto out;
}
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
r = LUKS_decrypt_from_storage(AfKey,
@@ -1224,7 +1230,7 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
{
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
return -EINVAL;
pbkdf->type = CRYPT_KDF_PBKDF2;

View File

@@ -2,7 +2,7 @@
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -600,7 +600,8 @@ int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd,
struct crypt_params_reencrypt *params);
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock);
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock);
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic);

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, digest handling
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, PBKDF2 digest handler (LUKS1 compatible)
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -210,7 +210,7 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
}
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.",
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
return -EINVAL;
}

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +23,6 @@
#define _CRYPTSETUP_LUKS2_INTERNAL_H
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <json-c/json.h>

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,9 +1,9 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2019 Ondrej Kozina
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
* Copyright (C) 2015-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -45,11 +45,11 @@ void hexprint_base64(struct crypt_device *cd, json_object *jobj,
&buf, &buf_len))
return;
for (i = 0; i < buf_len / 2; i++)
log_std(cd, "%02hhx%s", buf[i], sep);
log_std(cd, "\n\t%s", line_sep);
for (i = buf_len / 2; i < buf_len; i++)
for (i = 0; i < buf_len; i++) {
if (i && !(i % 16))
log_std(cd, "\n\t%s", line_sep);
log_std(cd, "%02hhx%s", buf[i], sep);
}
log_std(cd, "\n");
free(buf);
}
@@ -459,12 +459,12 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
json_size = (uint64_t)strlen(json);
if (hdr_json_size != json_area_size) {
log_dbg(cd, "JSON area size doesn't match value in binary header.");
log_dbg(cd, "JSON area size does not match value in binary header.");
return 1;
}
if (json_size > json_area_size) {
log_dbg(cd, "JSON doesn't fit in the designated area.");
log_dbg(cd, "JSON does not fit in the designated area.");
return 1;
}
@@ -970,13 +970,16 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
return r;
}
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* NOTE: is called before LUKS2 validation routines */
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
}
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
{
if (hdr_cleanup_and_validate(cd, hdr))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
@@ -984,11 +987,7 @@ int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* NOTE: is called before LUKS2 validation routines */
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
if (hdr_cleanup_and_validate(cd, hdr))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
@@ -1159,7 +1158,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
device_free(cd, backup_device);
if (r < 0) {
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
log_err(cd, _("Backup file does not contain valid LUKS header."));
goto out;
}
@@ -1270,8 +1269,8 @@ out:
LUKS2_hdr_free(cd, hdr);
LUKS2_hdr_free(cd, &hdr_file);
LUKS2_hdr_free(cd, &tmp_hdr);
crypt_memzero(&hdr_file, sizeof(hdr_file));
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
crypt_safe_free(buffer);
device_sync(cd, device);
@@ -2157,7 +2156,7 @@ int LUKS2_activate(struct crypt_device *cd,
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
if (r)
return r;
@@ -2205,26 +2204,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
struct dm_target *tgt;
crypt_status_info ci;
struct crypt_dm_active_device dmdc;
char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
const char *namei = NULL;
struct crypt_lock_handle *reencrypt_lock = NULL;
if (!dmd || !dmd->uuid)
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
return -EINVAL;
/* uuid mismatch with metadata (if available) */
if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid))
return -EINVAL;
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6);
if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1))
return -EINVAL;
r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26);
if (r < 0 || (size_t)r != (sizeof(uuid) - 1))
return -EINVAL;
/* uuid mismatch with metadata (if available) */
if (hdr && strcmp(hdr->uuid, uuid))
return -EINVAL;
tgt = &dmd->segment;
/* TODO: We have LUKS2 dependencies now */
@@ -2236,7 +2230,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
goto out;
if (contains_reencryption_helper(deps)) {
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
@@ -2345,9 +2339,9 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin
reqs &= ~reqs_mask;
if (reqs_reencrypt(reqs) && !quiet)
log_err(cd, _("Offline reencryption in progress. Aborting."));
log_err(cd, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
if (reqs_reencrypt_online(reqs) && !quiet)
log_err(cd, _("Online reencryption in progress. Aborting."));
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
/* any remaining unmasked requirement fails the check */
return reqs ? -EINVAL : 0;
@@ -2400,7 +2394,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
#endif
}
/* jobj_dst must contain pointer initialised to NULL (see json-c json_object_deep_copy API) */
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
int json_object_copy(json_object *jobj_src, json_object **jobj_dst)
{
if (!jobj_src || !jobj_dst || *jobj_dst)

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, keyslot handling
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -79,19 +79,18 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
/* Check if a keyslot is assigned to specific segment */
static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
{
int keyslot_digest, segment_digest, s, count = 0;
int keyslot_digest, count = 0;
unsigned s;
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
if (keyslot_digest < 0)
return keyslot_digest;
if (segment >= 0) {
segment_digest = LUKS2_digest_by_segment(hdr, segment);
return segment_digest == keyslot_digest;
}
for (s = 0; s < 3; s++) {
segment_digest = LUKS2_digest_by_segment(hdr, s);
if (segment_digest == keyslot_digest)
if (segment >= 0)
return keyslot_digest == LUKS2_digest_by_segment(hdr, segment);
for (s = 0; s < json_segments_count(LUKS2_get_segments_jobj(hdr)); s++) {
if (keyslot_digest == LUKS2_digest_by_segment(hdr, s))
count++;
}
@@ -310,28 +309,16 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
return 0;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
static int _open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
const keyslot_handler *h,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
@@ -350,9 +337,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
*vk = NULL;
}
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
if (r) {
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
return r;
}
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -362,7 +381,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
@@ -380,29 +399,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
return r;
}
key_size = LUKS2_get_volume_key_size(hdr, segment);
if (key_size < 0)
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
*vk = crypt_alloc_volume_key(key_size, NULL);
if (!*vk)
return -ENOMEM;
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
if (r < 0)
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
else
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
if (r < 0) {
crypt_free_volume_key(*vk);
*vk = NULL;
} else
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
@@ -520,7 +517,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
size_t password_len,
struct volume_key **vks)
{
struct volume_key *vk;
struct volume_key *vk = NULL;
int digest_old, digest_new, r = -EINVAL;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
@@ -530,7 +527,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_old);
crypt_volume_key_add_next(vks, vk);
}
@@ -540,7 +536,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_new);
crypt_volume_key_add_next(vks, vk);
}
out:

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
*
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2018, Ondrej Kozina
* Copyright (C) 2016-2020, Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020, Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,9 +1,9 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Ondrej Kozina
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020 Ondrej Kozina
* Copyright (C) 2015-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -402,6 +402,7 @@ static int json_luks1_object(struct luks_phdr *hdr_v1, struct json_object **luks
json_size = LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN;
json_object_object_add(field, "json_size", json_object_new_uint64(json_size));
keyslots_size -= (keyslots_size % 4096);
json_object_object_add(field, "keyslots_size", json_object_new_uint64(keyslots_size));
*luks1_object = luks1_obj;
@@ -466,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
r = 0;
out:
device_sync(cd, device);
crypt_memzero(buf, buf_size);
crypt_safe_memzero(buf, buf_size);
free(buf);
return r;
@@ -577,6 +578,12 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
goto out;
}
/* check future LUKS2 metadata before moving keyslots area */
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
r = -EINVAL;
goto out;
}
if ((r = luks_header_in_use(cd))) {
if (r > 0)
r = -EBUSY;
@@ -586,6 +593,14 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
// move keyslots 4k -> 32k offset
buf_offset = 2 * LUKS2_HDR_16K_LEN;
buf_size = luks1_size - LUKS_ALIGN_KEYSLOTS;
/* check future LUKS2 keyslots area is at least as large as LUKS1 keyslots area */
if (buf_size > LUKS2_keyslots_size(hdr2->jobj)) {
log_err(cd, _("Unable to move keyslot area. LUKS2 keyslots area too small."));
r = -EINVAL;
goto out;
}
if ((r = move_keyslot_areas(cd, 8 * SECTOR_SIZE, buf_offset, buf_size)) < 0) {
log_err(cd, _("Unable to move keyslot area."));
goto out;

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, reencryption helpers
*
* Copyright (C) 2015-2019, Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019, Ondrej Kozina
* Copyright (C) 2015-2020, Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2020, Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -1401,12 +1401,12 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
log_dbg(cd, "Failed to read journaled data.");
r = -EIO;
/* may content plaintext */
crypt_memzero(data_buffer, rh->length);
crypt_safe_memzero(data_buffer, rh->length);
goto out;
}
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
/* may content plaintext */
crypt_memzero(data_buffer, rh->length);
crypt_safe_memzero(data_buffer, rh->length);
if (read < 0 || (size_t)read != rh->length) {
log_dbg(cd, "recovery write failed.");
r = -EINVAL;
@@ -1436,13 +1436,13 @@ static int reencrypt_recover_segment(struct crypt_device *cd,
log_dbg(cd, "Failed to read data.");
r = -EIO;
/* may content plaintext */
crypt_memzero(data_buffer, rh->length);
crypt_safe_memzero(data_buffer, rh->length);
goto out;
}
read = crypt_storage_wrapper_encrypt_write(cw2, 0, data_buffer, rh->length);
/* may content plaintext */
crypt_memzero(data_buffer, rh->length);
crypt_safe_memzero(data_buffer, rh->length);
if (read < 0 || (size_t)read != rh->length) {
log_dbg(cd, "recovery write failed.");
r = -EINVAL;
@@ -2531,7 +2531,7 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
else if (ri == CRYPT_REENCRYPT_CRASH)
r = reencrypt_load_crashed(cd, hdr, device_size, &tmp);
else if (ri == CRYPT_REENCRYPT_NONE) {
log_err(cd, _("No LUKS2 reencryption in progress."));
log_err(cd, _("Device not marked for LUKS2 reencryption."));
return -EINVAL;
} else
r = -EINVAL;
@@ -2546,21 +2546,10 @@ static int reencrypt_load(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
/* internal only */
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
static int reencrypt_lock_internal(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock)
{
int r;
char *lock_resource;
const char *tmp = crypt_get_uuid(cd);
if (!tmp && !uuid)
return -EINVAL;
if (!uuid)
uuid = tmp;
if (!tmp)
tmp = uuid;
if (strcmp(uuid, tmp))
return -EINVAL;
if (!crypt_metadata_locking_enabled()) {
*reencrypt_lock = NULL;
@@ -2582,6 +2571,36 @@ out:
return r;
}
/* internal only */
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock)
{
int r;
char hdr_uuid[37];
const char *uuid = crypt_get_uuid(cd);
if (!dm_uuid)
return -EINVAL;
if (!uuid) {
r = snprintf(hdr_uuid, sizeof(hdr_uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
dm_uuid + 6, dm_uuid + 14, dm_uuid + 18, dm_uuid + 22, dm_uuid + 26);
if (r < 0 || (size_t)r != (sizeof(hdr_uuid) - 1))
return -EINVAL;
} else if (crypt_uuid_cmp(dm_uuid, uuid))
return -EINVAL;
return reencrypt_lock_internal(cd, uuid, reencrypt_lock);
}
/* internal only */
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock)
{
if (!cd || !crypt_get_type(cd) || strcmp(crypt_get_type(cd), CRYPT_LUKS2))
return -EINVAL;
return reencrypt_lock_internal(cd, crypt_get_uuid(cd), reencrypt_lock);
}
/* internal only */
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock)
{
@@ -2605,7 +2624,7 @@ static int reencrypt_lock_and_verify(struct crypt_device *cd, struct luks2_hdr *
return -EINVAL;
}
r = crypt_reencrypt_lock(cd, NULL, &h);
r = crypt_reencrypt_lock(cd, &h);
if (r < 0) {
if (r == -EBUSY)
log_err(cd, _("Reencryption process is already running."));
@@ -2809,7 +2828,7 @@ static int reencrypt_recovery_by_passphrase(struct crypt_device *cd,
crypt_reencrypt_info ri;
struct crypt_lock_handle *reencrypt_lock;
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot perform recovery."));
@@ -2936,7 +2955,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
r = reencrypt_init_by_passphrase(cd, name, passphrase, passphrase_size, keyslot_old, keyslot_new, cipher, cipher_mode, params);
crypt_memzero(passphrase, passphrase_size);
crypt_safe_memzero(passphrase, passphrase_size);
free(passphrase);
return r;
@@ -3386,7 +3405,7 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
if (r < 0)
goto err;
vk = vk->next;
vk = crypt_volume_key_next(vk);
}
if (luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, false))

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, internal segment handling
*
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2019, Ondrej Kozina
* Copyright (C) 2018-2020, Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2020, Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, token handling
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -332,7 +332,7 @@ static void LUKS2_token_buffer_free(struct crypt_device *cd,
if (h->buffer_free)
h->buffer_free(buffer, buffer_len);
else {
crypt_memzero(buffer, buffer_len);
crypt_safe_memzero(buffer, buffer_len);
free(buffer);
}
}

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, kernel keyring token
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup kernel RNG access functions
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <sys/select.h>
@@ -28,10 +27,6 @@
#include "libcryptsetup.h"
#include "internal.h"
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
static int random_initialised = 0;
#define URANDOM_DEVICE "/dev/urandom"

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <stdarg.h>
#include <sys/utsname.h>
#include <fcntl.h>
#include <errno.h>
#include "libcryptsetup.h"
@@ -36,6 +35,7 @@
#include "verity.h"
#include "tcrypt.h"
#include "integrity.h"
#include "bitlk.h"
#include "utils_device_locking.h"
#include "internal.h"
@@ -50,6 +50,7 @@ struct crypt_device {
struct volume_key *volume_key;
int rng_type;
uint32_t compatibility;
struct crypt_pbkdf_type pbkdf;
/* global context scope settings */
@@ -95,7 +96,7 @@ struct crypt_device {
} loopaes;
struct { /* used in CRYPT_VERITY */
struct crypt_params_verity hdr;
char *root_hash;
const char *root_hash;
unsigned int root_hash_size;
char *uuid;
struct device *fec_device;
@@ -108,7 +109,12 @@ struct crypt_device {
struct crypt_params_integrity params;
struct volume_key *journal_mac_key;
struct volume_key *journal_crypt_key;
uint32_t sb_flags;
} integrity;
struct { /* used in CRYPT_BITLK */
struct bitlk_metadata params;
char *cipher_spec;
} bitlk;
struct { /* used if initialized without header by name */
char *active_name;
/* buffers, must refresh from kernel on every query */
@@ -315,6 +321,11 @@ static int isINTEGRITY(const char *type)
return (type && !strcmp(CRYPT_INTEGRITY, type));
}
static int isBITLK(const char *type)
{
return (type && !strcmp(CRYPT_BITLK, type));
}
static int _onlyLUKS(struct crypt_device *cd, uint32_t cdflags)
{
int r = 0;
@@ -572,6 +583,9 @@ int crypt_init(struct crypt_device **cd, const char *device)
return -EINVAL;
log_dbg(NULL, "Allocating context for crypt device %s.", device ?: "(none)");
#if !HAVE_DECL_O_CLOEXEC
log_dbg(NULL, "Running without O_CLOEXEC.");
#endif
if (!(h = malloc(sizeof(struct crypt_device))))
return -ENOMEM;
@@ -726,9 +740,6 @@ out:
free(type);
LUKS2_hdr_free(cd, &hdr2);
}
/* FIXME: why? */
crypt_memzero(&hdr2, sizeof(hdr2));
return r;
}
@@ -763,7 +774,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
if (isLUKS1(requested_type) || version == 1) {
if (cd->type && isLUKS2(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
@@ -803,7 +814,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
memcpy(&cd->u.luks1.hdr, &hdr, sizeof(hdr));
} else if (isLUKS2(requested_type) || version == 2 || version == 0) {
if (cd->type && isLUKS1(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
@@ -822,7 +833,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
r = -EINVAL;
}
out:
crypt_memzero(&hdr, sizeof(hdr));
crypt_safe_memzero(&hdr, sizeof(hdr));
return r;
}
@@ -886,7 +897,7 @@ static int _crypt_load_verity(struct crypt_device *cd, struct crypt_params_verit
free(CONST_CAST(void*)cd->u.verity.hdr.hash_name);
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
free(cd->u.verity.uuid);
crypt_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
crypt_safe_memzero(&cd->u.verity.hdr, sizeof(cd->u.verity.hdr));
return -ENOMEM;
}
@@ -922,7 +933,7 @@ static int _crypt_load_integrity(struct crypt_device *cd,
if (r < 0)
return r;
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params);
r = INTEGRITY_read_sb(cd, &cd->u.integrity.params, &cd->u.integrity.sb_flags);
if (r < 0)
return r;
@@ -965,6 +976,31 @@ static int _crypt_load_integrity(struct crypt_device *cd,
return 0;
}
static int _crypt_load_bitlk(struct crypt_device *cd,
struct bitlk_metadata *params)
{
int r;
r = init_crypto(cd);
if (r < 0)
return r;
r = BITLK_read_sb(cd, &cd->u.bitlk.params);
if (r < 0)
return r;
if (asprintf(&cd->u.bitlk.cipher_spec, "%s-%s",
cd->u.bitlk.params.cipher, cd->u.bitlk.params.cipher_mode) < 0) {
cd->u.bitlk.cipher_spec = NULL;
return -ENOMEM;
}
if (!cd->type && !(cd->type = strdup(CRYPT_BITLK)))
return -ENOMEM;
return 0;
}
int crypt_load(struct crypt_device *cd,
const char *requested_type,
void *params)
@@ -987,29 +1023,35 @@ int crypt_load(struct crypt_device *cd,
if (!requested_type || isLUKS1(requested_type) || isLUKS2(requested_type)) {
if (cd->type && !isLUKS1(cd->type) && !isLUKS2(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
r = _crypt_load_luks(cd, requested_type, 1, 0);
} else if (isVERITY(requested_type)) {
if (cd->type && !isVERITY(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
r = _crypt_load_verity(cd, params);
} else if (isTCRYPT(requested_type)) {
if (cd->type && !isTCRYPT(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
r = _crypt_load_tcrypt(cd, params);
} else if (isINTEGRITY(requested_type)) {
if (cd->type && !isINTEGRITY(cd->type)) {
log_dbg(cd, "Context is already initialised to type %s", cd->type);
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
r = _crypt_load_integrity(cd, params);
} else if (isBITLK(requested_type)) {
if (cd->type && !isBITLK(cd->type)) {
log_dbg(cd, "Context is already initialized to type %s", cd->type);
return -EINVAL;
}
r = _crypt_load_bitlk(cd, params);
} else
return -EINVAL;
@@ -1086,7 +1128,7 @@ static void crypt_free_type(struct crypt_device *cd)
free(CONST_CAST(void*)cd->u.verity.hdr.hash_device);
free(CONST_CAST(void*)cd->u.verity.hdr.fec_device);
free(CONST_CAST(void*)cd->u.verity.hdr.salt);
free(cd->u.verity.root_hash);
free(CONST_CAST(void*)cd->u.verity.root_hash);
free(cd->u.verity.uuid);
device_free(cd, cd->u.verity.fec_device);
} else if (isINTEGRITY(cd->type)) {
@@ -1095,6 +1137,9 @@ static void crypt_free_type(struct crypt_device *cd)
free(CONST_CAST(void*)cd->u.integrity.params.journal_crypt);
crypt_free_volume_key(cd->u.integrity.journal_crypt_key);
crypt_free_volume_key(cd->u.integrity.journal_mac_key);
} else if (isBITLK(cd->type)) {
free(cd->u.bitlk.cipher_spec);
BITLK_bitlk_metadata_free(&cd->u.bitlk.params);
} else if (!cd->type) {
free(cd->u.none.active_name);
cd->u.none.active_name = NULL;
@@ -1247,6 +1292,13 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
} else if (isTCRYPT(cd->type) && single_segment(&dmd) && tgt->type == DM_CRYPT) {
r = TCRYPT_init_by_name(cd, name, dmd.uuid, tgt, &cd->device,
&cd->u.tcrypt.params, &cd->u.tcrypt.hdr);
} else if (isBITLK(cd->type)) {
r = _crypt_load_bitlk(cd, NULL);
if (r < 0) {
log_dbg(cd, "BITLK device header not available.");
crypt_set_null_type(cd);
r = 0;
}
}
out:
dm_targets_free(cd, &dmd);
@@ -1269,6 +1321,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
r = dm_query_device(cd, name,
DM_ACTIVE_DEVICE |
DM_ACTIVE_VERITY_HASH_DEVICE |
DM_ACTIVE_VERITY_ROOT_HASH |
DM_ACTIVE_VERITY_PARAMS, &dmd);
if (r < 0)
return r;
@@ -1300,6 +1353,7 @@ static int _init_by_name_verity(struct crypt_device *cd, const char *name)
cd->u.verity.hdr.fec_roots = tgt->u.verity.vp->fec_roots;
MOVE_REF(cd->u.verity.fec_device, tgt->u.verity.fec_device);
MOVE_REF(cd->metadata_device, tgt->u.verity.hash_device);
MOVE_REF(cd->u.verity.root_hash, tgt->u.verity.root_hash);
}
out:
dm_targets_free(cd, &dmd);
@@ -1413,6 +1467,8 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
(*cd)->type = strdup(CRYPT_TCRYPT);
else if (!strncmp(CRYPT_INTEGRITY, dmd.uuid, sizeof(CRYPT_INTEGRITY)-1))
(*cd)->type = strdup(CRYPT_INTEGRITY);
else if (!strncmp(CRYPT_BITLK, dmd.uuid, sizeof(CRYPT_BITLK)-1))
(*cd)->type = strdup(CRYPT_BITLK);
else
log_dbg(NULL, "Unknown UUID set, some parameters are not set.");
} else
@@ -1424,7 +1480,7 @@ int crypt_init_by_name_and_header(struct crypt_device **cd,
goto out;
}
/* Try to initialise basic parameters from active device */
/* Try to initialize basic parameters from active device */
if (tgt->type == DM_CRYPT || tgt->type == DM_LINEAR)
r = _init_by_name_crypt(*cd, name);
@@ -2090,6 +2146,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
struct crypt_params_integrity *params)
{
int r;
uint32_t integrity_tag_size;
char *integrity = NULL, *journal_integrity = NULL, *journal_crypt = NULL;
struct volume_key *journal_crypt_key = NULL, *journal_mac_key = NULL;
@@ -2146,6 +2203,14 @@ static int _crypt_format_integrity(struct crypt_device *cd,
goto err;
}
integrity_tag_size = INTEGRITY_hash_tag_size(integrity);
if (integrity_tag_size > 0 && params->tag_size && integrity_tag_size != params->tag_size)
log_std(cd, _("WARNING: Requested tag size %d bytes differs from %s size output (%d bytes).\n"),
params->tag_size, integrity, integrity_tag_size);
if (params->tag_size)
integrity_tag_size = params->tag_size;
cd->u.integrity.journal_crypt_key = journal_crypt_key;
cd->u.integrity.journal_mac_key = journal_mac_key;
cd->u.integrity.params.journal_size = params->journal_size;
@@ -2154,7 +2219,7 @@ static int _crypt_format_integrity(struct crypt_device *cd,
cd->u.integrity.params.interleave_sectors = params->interleave_sectors;
cd->u.integrity.params.buffer_sectors = params->buffer_sectors;
cd->u.integrity.params.sector_size = params->sector_size;
cd->u.integrity.params.tag_size = params->tag_size;
cd->u.integrity.params.tag_size = integrity_tag_size;
cd->u.integrity.params.integrity = integrity;
cd->u.integrity.params.journal_integrity = journal_integrity;
cd->u.integrity.params.journal_crypt = journal_crypt;
@@ -2701,7 +2766,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
* explicit size stored in metadata (length != "dynamic")
*/
/* Device context type must be initialised */
/* Device context type must be initialized */
if (!cd || !cd->type || !name)
return -EINVAL;
@@ -2902,8 +2967,8 @@ int crypt_header_restore(struct crypt_device *cd,
else
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
crypt_memzero(&hdr1, sizeof(hdr1));
crypt_memzero(&hdr2, sizeof(hdr2));
crypt_safe_memzero(&hdr1, sizeof(hdr1));
crypt_safe_memzero(&hdr2, sizeof(hdr2));
} else if (isLUKS2(cd->type) && (!requested_type || isLUKS2(requested_type))) {
r = LUKS2_hdr_restore(cd, &cd->u.luks2.hdr, backup_file);
if (r)
@@ -2938,7 +3003,7 @@ void crypt_free(struct crypt_device *cd)
free(CONST_CAST(void*)cd->pbkdf.hash);
/* Some structures can contain keys (TCRYPT), wipe it */
crypt_memzero(cd, sizeof(*cd));
crypt_safe_memzero(cd, sizeof(*cd));
free(cd);
}
@@ -3147,7 +3212,7 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
}
r = dm_resume_and_reinstate_key(cd, name, vk);
if (r)
if (r < 0)
log_err(cd, _("Error during resuming device %s."), name);
out:
crypt_safe_free(passphrase_read);
@@ -3178,6 +3243,65 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd,
keyfile, keyfile_size, keyfile_offset);
}
int crypt_resume_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size)
{
struct volume_key *vk = NULL;
int r;
if (!name || !volume_key)
return -EINVAL;
log_dbg(cd, "Resuming volume %s by volume key.", name);
if ((r = onlyLUKS(cd)))
return r;
r = dm_status_suspended(cd, name);
if (r < 0)
return r;
if (!r) {
log_err(cd, _("Volume %s is not suspended."), name);
return -EINVAL;
}
vk = crypt_alloc_volume_key(volume_key_size, volume_key);
if (!vk)
return -ENOMEM;
if (isLUKS1(cd->type))
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
else if (isLUKS2(cd->type))
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
else
r = -EINVAL;
if (r == -EPERM || r == -ENOENT)
log_err(cd, _("Volume key does not match the volume."));
if (r < 0)
goto out;
r = 0;
if (crypt_use_keyring_for_vk(cd)) {
r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
if (!r)
r = crypt_volume_key_load_in_keyring(cd, vk);
}
if (r < 0)
goto out;
r = dm_resume_and_reinstate_key(cd, name, vk);
if (r < 0)
log_err(cd, _("Error during resuming device %s."), name);
out:
if (r < 0)
crypt_drop_keyring_key(cd, vk);
crypt_free_volume_key(vk);
return r;
}
/*
* Keyslot manipulation
*/
@@ -3621,7 +3745,7 @@ static int _create_device_with_integrity(struct crypt_device *cd,
device_check = dmd->flags & CRYPT_ACTIVATE_SHARED ? DEV_OK : DEV_EXCL;
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi);
r = INTEGRITY_activate_dmd_device(cd, iname, CRYPT_INTEGRITY, dmdi, 0);
if (r)
return r;
@@ -3643,6 +3767,27 @@ out:
return r;
}
static int kernel_keyring_support(void)
{
static unsigned _checked = 0;
if (!_checked) {
_kernel_keyring_supported = keyring_check();
_checked = 1;
}
return _kernel_keyring_supported;
}
static int dmcrypt_keyring_bug(void)
{
uint64_t kversion;
if (kernel_version(&kversion))
return 1;
return kversion < version(4,15,0,0);
}
int create_or_reload_device(struct crypt_device *cd, const char *name,
const char *type, struct crypt_dm_active_device *dmd)
{
@@ -3717,7 +3862,7 @@ static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
if (r < 0)
return r;
vk = vk->next;
vk = crypt_volume_key_next(vk);
}
return 0;
@@ -3830,7 +3975,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
if (crypt_use_keyring_for_vk(cd))
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
r = crypt_reencrypt_lock(cd, NULL, &reencrypt_lock);
r = crypt_reencrypt_lock(cd, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot activate device."));
@@ -3974,8 +4119,12 @@ static int _activate_by_passphrase(struct crypt_device *cd,
} else if (isLUKS2(cd->type)) {
r = _open_and_activate_luks2(cd, keyslot, name, passphrase, passphrase_size, flags);
keyslot = r;
} else if (isBITLK(cd->type)) {
r = BITLK_activate(cd, name, passphrase, passphrase_size,
&cd->u.bitlk.params, flags);
keyslot = 0;
} else {
log_err(cd, _("Device type is not properly initialised."));
log_err(cd, _("Device type is not properly initialized."));
r = -EINVAL;
}
out:
@@ -4114,7 +4263,6 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd,
return crypt_activate_by_keyfile_device_offset(cd, name, keyslot, keyfile,
keyfile_size, keyfile_offset, flags);
}
int crypt_activate_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
@@ -4209,25 +4357,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
if (!r && name)
r = LUKS2_activate(cd, name, vk, flags);
} else if (isVERITY(cd->type)) {
/* volume_key == root hash */
if (!volume_key || !volume_key_size) {
log_err(cd, _("Incorrect root hash specified for verity device."));
return -EINVAL;
}
r = VERITY_activate(cd, name, volume_key, volume_key_size, cd->u.verity.fec_device,
&cd->u.verity.hdr, flags|CRYPT_ACTIVATE_READONLY);
if (r == -EPERM) {
free(cd->u.verity.root_hash);
cd->u.verity.root_hash = NULL;
} if (!r) {
cd->u.verity.root_hash_size = volume_key_size;
if (!cd->u.verity.root_hash)
cd->u.verity.root_hash = malloc(volume_key_size);
if (cd->u.verity.root_hash)
memcpy(cd->u.verity.root_hash, volume_key, volume_key_size);
}
r = crypt_activate_by_signed_key(cd, name, volume_key, volume_key_size, NULL, 0, flags);
} else if (isTCRYPT(cd->type)) {
if (!name)
return 0;
@@ -4243,9 +4373,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
}
r = INTEGRITY_activate(cd, name, &cd->u.integrity.params, vk,
cd->u.integrity.journal_crypt_key,
cd->u.integrity.journal_mac_key, flags);
cd->u.integrity.journal_mac_key, flags,
cd->u.integrity.sb_flags);
} else {
log_err(cd, _("Device type is not properly initialised."));
log_err(cd, _("Device type is not properly initialized."));
r = -EINVAL;
}
@@ -4256,6 +4387,77 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
return r;
}
int crypt_activate_by_signed_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
uint32_t flags)
{
char description[512];
int r;
if (!cd || !isVERITY(cd->type))
return -EINVAL;
if (!volume_key || !volume_key_size || (!name && signature)) {
log_err(cd, _("Incorrect root hash specified for verity device."));
return -EINVAL;
}
log_dbg(cd, "%s volume %s by signed key.", name ? "Activating" : "Checking", name ?: "");
if (cd->u.verity.hdr.flags & CRYPT_VERITY_ROOT_HASH_SIGNATURE && !signature) {
log_err(cd, _("Root hash signature required."));
return -EINVAL;
}
r = _activate_check_status(cd, name, flags & CRYPT_ACTIVATE_REFRESH);
if (r < 0)
return r;
if (signature && !kernel_keyring_support()) {
log_err(cd, _("Kernel keyring missing: required for passing signature to kernel."));
return -EINVAL;
}
/* volume_key == root hash */
free(CONST_CAST(void*)cd->u.verity.root_hash);
cd->u.verity.root_hash = NULL;
if (signature) {
r = snprintf(description, sizeof(description)-1, "cryptsetup:%s%s%s",
crypt_get_uuid(cd) ?: "", crypt_get_uuid(cd) ? "-" : "", name);
if (r < 0)
return -EINVAL;
log_dbg(cd, "Adding signature into keyring %s", description);
r = keyring_add_key_in_thread_keyring(USER_KEY, description, signature, signature_size);
if (r) {
log_err(cd, _("Failed to load key in kernel keyring."));
return r;
}
}
r = VERITY_activate(cd, name, volume_key, volume_key_size,
signature ? description : NULL,
cd->u.verity.fec_device,
&cd->u.verity.hdr, flags | CRYPT_ACTIVATE_READONLY);
if (!r) {
cd->u.verity.root_hash_size = volume_key_size;
cd->u.verity.root_hash = malloc(volume_key_size);
if (cd->u.verity.root_hash)
memcpy(CONST_CAST(void*)cd->u.verity.root_hash, volume_key, volume_key_size);
}
if (signature)
crypt_drop_keyring_key_by_description(cd, description, USER_KEY);
return r;
}
int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t flags)
{
struct crypt_device *fake_cd = NULL;
@@ -4295,7 +4497,7 @@ int crypt_deactivate_by_name(struct crypt_device *cd, const char *name, uint32_t
if (isLUKS2(cd->type))
hdr2 = crypt_get_hdr(cd, CRYPT_LUKS2);
if (!strncmp(CRYPT_LUKS2, dmd.uuid ?: "", sizeof(CRYPT_LUKS2)-1) || hdr2)
if ((dmd.uuid && !strncmp(CRYPT_LUKS2, dmd.uuid, sizeof(CRYPT_LUKS2)-1)) || hdr2)
r = LUKS2_deactivate(cd, name, hdr2, &dmd, flags);
else if (isTCRYPT(cd->type))
r = TCRYPT_deactivate(cd, name, flags);
@@ -4415,7 +4617,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
struct volume_key *vk = NULL;
int key_len, r = -EINVAL;
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !passphrase))
if (!cd || !volume_key || !volume_key_size || (!isTCRYPT(cd->type) && !isVERITY(cd->type) && !passphrase))
return -EINVAL;
if (isLUKS2(cd->type) && keyslot != CRYPT_ANY_SLOT)
@@ -4445,10 +4647,18 @@ int crypt_volume_key_get(struct crypt_device *cd,
passphrase, passphrase_size, &vk);
} else if (isTCRYPT(cd->type)) {
r = TCRYPT_get_volume_key(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params, &vk);
} else if (isVERITY(cd->type)) {
/* volume_key == root hash */
if (cd->u.verity.root_hash) {
memcpy(volume_key, cd->u.verity.root_hash, cd->u.verity.root_hash_size);
*volume_key_size = cd->u.verity.root_hash_size;
r = 0;
} else
log_err(cd, _("Cannot retrieve root hash for verity device."));
} else
log_err(cd, _("This operation is not supported for %s crypt device."), cd->type ?: "(none)");
if (r >= 0) {
if (r >= 0 && vk) {
memcpy(volume_key, vk->key, vk->keylength);
*volume_key_size = vk->keylength;
}
@@ -4475,6 +4685,9 @@ int crypt_volume_key_verify(struct crypt_device *cd,
r = LUKS_verify_volume_key(&cd->u.luks1.hdr, vk);
else if (isLUKS2(cd->type))
r = LUKS2_digest_verify_by_segment(cd, &cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT, vk);
else
r = -EINVAL;
if (r == -EPERM)
log_err(cd, _("Volume key does not match the volume."));
@@ -4513,6 +4726,20 @@ int crypt_memory_lock(struct crypt_device *cd, int lock)
return lock ? crypt_memlock_inc(cd) : crypt_memlock_dec(cd);
}
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags)
{
if (cd)
cd->compatibility = flags;
}
uint32_t crypt_get_compatibility(struct crypt_device *cd)
{
if (cd)
return cd->compatibility;
return 0;
}
/*
* Reporting
*/
@@ -4632,6 +4859,8 @@ int crypt_dump(struct crypt_device *cd)
return TCRYPT_dump(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
else if (isINTEGRITY(cd->type))
return INTEGRITY_dump(cd, crypt_data_device(cd), 0);
else if (isBITLK(cd->type))
return BITLK_dump(cd, crypt_data_device(cd), &cd->u.bitlk.params);
log_err(cd, _("Dump operation is not supported for this device type."));
return -EINVAL;
@@ -4650,6 +4879,8 @@ const char *crypt_get_cipher_spec(struct crypt_device *cd)
return cd->u.plain.cipher_spec;
else if (isLOOPAES(cd->type))
return cd->u.loopaes.cipher_spec;
else if (isBITLK(cd->type))
return cd->u.bitlk.cipher_spec;
else if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.cipher_spec;
@@ -4680,6 +4911,9 @@ const char *crypt_get_cipher(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.cipher;
if (isBITLK(cd->type))
return cd->u.bitlk.params.cipher;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.cipher;
@@ -4710,6 +4944,9 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.mode;
if (isBITLK(cd->type))
return cd->u.bitlk.params.cipher_mode;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.cipher_mode;
@@ -4784,6 +5021,9 @@ const char *crypt_get_uuid(struct crypt_device *cd)
if (isVERITY(cd->type))
return cd->u.verity.uuid;
if (isBITLK(cd->type))
return cd->u.bitlk.params.guid;
return NULL;
}
@@ -4844,6 +5084,9 @@ int crypt_get_volume_key_size(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return cd->u.tcrypt.params.key_size;
if (isBITLK(cd->type))
return cd->u.bitlk.params.key_size / 8;
if (!cd->type && !_init_by_name_crypt_none(cd))
return cd->u.none.key_size;
@@ -5025,6 +5268,9 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd)
if (isTCRYPT(cd->type))
return TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
if (isBITLK(cd->type))
return cd->u.bitlk.params.volume_header_size / SECTOR_SIZE;
return cd->data_offset;
}
@@ -5144,7 +5390,7 @@ int crypt_get_verity_info(struct crypt_device *cd,
vp->data_size = cd->u.verity.hdr.data_size;
vp->hash_area_offset = cd->u.verity.hdr.hash_area_offset;
vp->hash_type = cd->u.verity.hdr.hash_type;
vp->flags = cd->u.verity.hdr.flags & CRYPT_VERITY_NO_HEADER;
vp->flags = cd->u.verity.hdr.flags & (CRYPT_VERITY_NO_HEADER | CRYPT_VERITY_ROOT_HASH_SIGNATURE);
return 0;
}
@@ -5596,7 +5842,7 @@ int crypt_keyslot_add_by_key(struct crypt_device *cd,
r = LUKS2_keyslot_params_default(cd, &cd->u.luks2.hdr, &params);
if (r < 0) {
log_err(cd, _("Failed to initialise default LUKS2 keyslot parameters."));
log_err(cd, _("Failed to initialize default LUKS2 keyslot parameters."));
goto out;
}
@@ -5624,32 +5870,11 @@ out:
* Keyring handling
*/
static int kernel_keyring_support(void)
{
static unsigned _checked = 0;
if (!_checked) {
_kernel_keyring_supported = keyring_check();
_checked = 1;
}
return _kernel_keyring_supported;
}
static int dmcrypt_keyring_bug(void)
{
uint64_t kversion;
if (kernel_version(&kversion))
return 1;
return kversion < version(4,15,0,0);
}
int crypt_use_keyring_for_vk(struct crypt_device *cd)
{
uint32_t dmc_flags;
/* dm backend must be initialised */
/* dm backend must be initialized */
if (!cd || !isLUKS2(cd->type))
return 0;
@@ -5770,7 +5995,7 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
r = _activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
crypt_memzero(passphrase, passphrase_size);
crypt_safe_memzero(passphrase, passphrase_size);
free(passphrase);
return r;

View File

@@ -1,8 +1,8 @@
/*
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include "libcryptsetup.h"
@@ -301,8 +300,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
}
crypt_cipher_destroy(cipher);
crypt_memzero(iv, bs);
crypt_memzero(iv_old, bs);
crypt_safe_memzero(iv, bs);
crypt_safe_memzero(iv_old, bs);
return r;
}
@@ -369,8 +368,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
crypt_cipher_destroy(cipher);
}
crypt_memzero(backend_key, sizeof(backend_key));
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
crypt_safe_memzero(backend_key, sizeof(backend_key));
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
return r;
}
@@ -420,8 +419,8 @@ out:
if (cipher[j])
crypt_cipher_destroy(cipher[j]);
crypt_memzero(iv, bs);
crypt_memzero(iv_old, bs);
crypt_safe_memzero(iv, bs);
crypt_safe_memzero(iv_old, bs);
return r;
}
@@ -474,13 +473,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
r = -EPERM;
}
crypt_memzero(&hdr2, sizeof(hdr2));
crypt_safe_memzero(&hdr2, sizeof(hdr2));
return r;
}
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
unsigned char pool[TCRYPT_KEY_POOL_LEN],
const char *keyfile)
unsigned char pool[VCRYPT_KEY_POOL_LEN],
const char *keyfile, int keyfiles_pool_length)
{
unsigned char *data;
int i, j, fd, data_size, r = -EIO;
@@ -512,12 +511,12 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
pool[j++] += (unsigned char)(crc >> 16);
pool[j++] += (unsigned char)(crc >> 8);
pool[j++] += (unsigned char)(crc);
j %= TCRYPT_KEY_POOL_LEN;
j %= keyfiles_pool_length;
}
r = 0;
out:
crypt_memzero(&crc, sizeof(crc));
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
crypt_safe_memzero(&crc, sizeof(crc));
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
free(data);
return r;
@@ -527,29 +526,41 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
struct tcrypt_phdr *hdr,
struct crypt_params_tcrypt *params)
{
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
size_t passphrase_size;
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
size_t passphrase_size, max_passphrase_size;
char *key;
unsigned int i, skipped = 0, iterations;
int r = -EPERM;
int r = -EPERM, keyfiles_pool_length;
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
return -ENOMEM;
if (params->flags & CRYPT_TCRYPT_VERA_MODES) {
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN)
keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
else
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
} else {
max_passphrase_size = TCRYPT_KEY_POOL_LEN;
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
}
if (params->keyfiles_count)
passphrase_size = TCRYPT_KEY_POOL_LEN;
passphrase_size = max_passphrase_size;
else
passphrase_size = params->passphrase_size;
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
TCRYPT_KEY_POOL_LEN);
if (params->passphrase_size > max_passphrase_size) {
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
max_passphrase_size);
goto out;
}
/* Calculate pool content from keyfiles */
for (i = 0; i < params->keyfiles_count; i++) {
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
if (r < 0)
goto out;
}
@@ -619,9 +630,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
params->cipher, params->mode, params->key_size);
}
out:
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
if (key)
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
free(key);
return r;
}
@@ -747,7 +758,7 @@ int TCRYPT_activate(struct crypt_device *cd,
}
if (strstr(params->mode, "-tcrypt")) {
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
return -ENOTSUP;
}
@@ -859,7 +870,7 @@ int TCRYPT_activate(struct crypt_device *cd,
if (r < 0 &&
(dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
r = -ENOTSUP;
}

View File

@@ -1,8 +1,8 @@
/*
* TCRYPT (TrueCrypt-compatible) header definition
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -42,6 +42,7 @@
#define TCRYPT_LRW_IKEY_LEN 16
#define TCRYPT_KEY_POOL_LEN 64
#define VCRYPT_KEY_POOL_LEN 128
#define TCRYPT_KEYFILE_LEN 1048576
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
@@ -130,7 +129,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
if (errno == EINTR)
continue;
crypt_memzero(tmp, sizeof(tmp));
crypt_safe_memzero(tmp, sizeof(tmp));
/* read error */
return -1;
}
@@ -142,7 +141,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
bytes -= bytes_r;
}
crypt_memzero(tmp, sizeof(tmp));
crypt_safe_memzero(tmp, sizeof(tmp));
return bytes == 0 ? 0 : -1;
}
@@ -181,7 +180,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
unlimited_read = 1;
/* use 4k for buffer (page divisor but avoid huge pages) */
buflen = 4096 - sizeof(struct safe_allocation);
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
} else
buflen = key_size;

View File

@@ -1,8 +1,8 @@
/*
* libcryptsetup - cryptsetup library, cipher benchmark
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -72,7 +72,7 @@ int crypt_benchmark(struct crypt_device *cd,
if (r == -ERANGE)
log_dbg(cd, "Measured cipher runtime is too low.");
else if (r == -ENOTSUP || r == -ENOENT)
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
log_dbg(cd, "Cannot initialize cipher %s, mode %s.", cipher, cipher_mode);
out:
free(buffer);

View File

@@ -1,7 +1,7 @@
/*
* blkid probe utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -310,9 +310,9 @@ int blk_supported(void)
off_t blk_get_offset(struct blkid_handle *h)
{
const char *offset;
off_t offset_value = -1;
#ifdef HAVE_BLKID
const char *offset;
if (blk_is_superblock(h)) {
if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
offset_value = strtoll(offset, NULL, 10);

View File

@@ -1,7 +1,7 @@
/*
* blkid probe utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -2,8 +2,8 @@
* utils_crypt - cipher utilities for cryptsetup
*
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -149,79 +149,6 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
return 0;
}
/*
* Replacement for memset(s, 0, n) on stack that can be optimized out
* Also used in safe allocations for explicit memory wipe.
*/
void crypt_memzero(void *s, size_t n)
{
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(s, n);
#else
volatile uint8_t *p = (volatile uint8_t *)s;
while(n--)
*p++ = 0;
#endif
}
/* safe allocations */
void *crypt_safe_alloc(size_t size)
{
struct safe_allocation *alloc;
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
return NULL;
alloc = malloc(size + offsetof(struct safe_allocation, data));
if (!alloc)
return NULL;
alloc->size = size;
crypt_memzero(&alloc->data, size);
/* coverity[leaked_storage] */
return &alloc->data;
}
void crypt_safe_free(void *data)
{
struct safe_allocation *alloc;
if (!data)
return;
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
crypt_memzero(data, alloc->size);
alloc->size = 0x55aa55aa;
free(alloc);
}
void *crypt_safe_realloc(void *data, size_t size)
{
struct safe_allocation *alloc;
void *new_data;
new_data = crypt_safe_alloc(size);
if (new_data && data) {
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
if (size > alloc->size)
size = alloc->size;
memcpy(new_data, data, size);
}
crypt_safe_free(data);
return new_data;
}
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
{
char buf[3] = "xx\0", *endp, *bytes;

View File

@@ -2,8 +2,8 @@
* utils_crypt - cipher utilities for cryptsetup
*
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -29,14 +29,6 @@
#define MAX_CIPHER_LEN_STR "31"
#define MAX_KEYFILES 32
struct crypt_device;
/* Not to be used directly */
struct safe_allocation {
size_t size;
char data[0];
};
int crypt_parse_name_and_mode(const char *s, char *cipher,
int *key_nums, char *cipher_mode);
int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
@@ -44,12 +36,6 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
int *integrity_key_size);
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
void *crypt_safe_alloc(size_t size);
void crypt_safe_free(void *data);
void *crypt_safe_realloc(void *data, size_t size);
void crypt_memzero(void *s, size_t n);
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
#endif /* _UTILS_CRYPT_H */

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -24,7 +24,6 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -145,7 +144,7 @@ static int device_read_test(int devfd)
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
r = 0;
crypt_memzero(buffer, sizeof(buffer));
crypt_safe_memzero(buffer, sizeof(buffer));
return r;
}
@@ -185,7 +184,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
}
if (devfd < 0) {
log_err(cd, _("Device %s doesn't exist or access denied."),
log_err(cd, _("Device %s does not exist or access denied."),
device_path(device));
return -EINVAL;
}

View File

@@ -1,8 +1,8 @@
/*
* Metadata on-disk locking for processes serialization
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -20,7 +20,6 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,8 +1,8 @@
/*
* Metadata on-disk locking for processes serialization
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,7 +26,6 @@
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -64,8 +64,12 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_INTEGRITY_RECALC_SUPPORTED (1 << 16) /* dm-integrity automatic recalculation supported */
#define DM_INTEGRITY_BITMAP_SUPPORTED (1 << 17) /* dm-integrity bitmap mode supported */
#define DM_GET_TARGET_VERSION_SUPPORTED (1 << 18) /* dm DM_GET_TARGET version ioctl supported */
#define DM_INTEGRITY_FIX_PADDING_SUPPORTED (1 << 19) /* supports the parameter fix_padding that fixes a bug that caused excessive padding */
#define DM_BITLK_EBOIV_SUPPORTED (1 << 20) /* EBOIV for BITLK supported */
#define DM_BITLK_ELEPHANT_SUPPORTED (1 << 21) /* Elephant diffuser for BITLK supported */
#define DM_VERITY_SIGNATURE_SUPPORTED (1 << 22) /* Verity option root_hash_sig_key_desc supported */
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_UNKNOWN } dm_target_type;
typedef enum { DM_CRYPT = 0, DM_VERITY, DM_INTEGRITY, DM_LINEAR, DM_ERROR, DM_ZERO, DM_UNKNOWN } dm_target_type;
enum tdirection { TARGET_SET = 1, TARGET_QUERY };
int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags);
@@ -110,6 +114,7 @@ struct dm_target {
const char *root_hash;
uint32_t root_hash_size;
const char *root_hash_sig_key_desc;
uint64_t hash_offset; /* hash offset in blocks (not header) */
uint64_t hash_blocks; /* size of hash device (in hash blocks) */
@@ -138,10 +143,14 @@ struct dm_target {
struct volume_key *journal_crypt_key;
struct device *meta_device;
bool fix_padding;
} integrity;
struct {
uint64_t offset;
} linear;
struct {
} zero;
} u;
char *params;
@@ -175,9 +184,10 @@ int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg
uint32_t tag_size, uint32_t sector_size);
int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *data_device, struct device *hash_device, struct device *fec_device,
const char *root_hash, uint32_t root_hash_size, uint64_t hash_offset_block,
uint64_t hash_blocks, struct crypt_params_verity *vp);
int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
const char *root_hash, uint32_t root_hash_size, const char *root_hash_sig_key_desc,
uint64_t hash_offset_block, uint64_t hash_blocks, struct crypt_params_verity *vp);
int dm_integrity_target_set(struct crypt_device *cd,
struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *meta_device,
struct device *data_device, uint64_t tag_size, uint64_t offset, uint32_t sector_size,
struct volume_key *vk,
@@ -185,6 +195,7 @@ int dm_integrity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t
const struct crypt_params_integrity *ip);
int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
struct device *data_device, uint64_t data_offset);
int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size);
int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags);
int dm_status_device(struct crypt_device *cd, const char *name);

View File

@@ -1,7 +1,7 @@
/*
* FIPS mode utilities
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,7 +1,7 @@
/*
* FIPS mode utilities
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* kernel keyring utilities
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,15 +25,14 @@
#include <unistd.h>
#include <sys/syscall.h>
#include "libcryptsetup.h"
#include "utils_keyring.h"
#ifndef HAVE_KEY_SERIAL_T
#define HAVE_KEY_SERIAL_T
#include <stdint.h>
typedef int32_t key_serial_t;
#endif
#include "utils_crypt.h"
#include "utils_keyring.h"
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
@@ -178,7 +177,7 @@ int keyring_get_passphrase(const char *key_desc,
if (ret < 0) {
err = errno;
if (buf)
crypt_memzero(buf, len);
crypt_safe_memzero(buf, len);
free(buf);
return -err;
}

View File

@@ -1,8 +1,8 @@
/*
* kernel keyring syscall wrappers
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2020 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* loopback block device utilities
*
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* loopback block device utilities
*
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@@ -1,8 +1,8 @@
/*
* utils_pbkdf - PBKDF settings for libcryptsetup
*
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

102
lib/utils_safe_memory.c Normal file
View File

@@ -0,0 +1,102 @@
/*
* utils_safe_memory - safe memory helpers
*
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdlib.h>
#include <string.h>
#include "libcryptsetup.h"
struct safe_allocation {
size_t size;
char data[0];
};
/*
* Replacement for memset(s, 0, n) on stack that can be optimized out
* Also used in safe allocations for explicit memory wipe.
*/
void crypt_safe_memzero(void *data, size_t size)
{
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(data, size);
#else
volatile uint8_t *p = (volatile uint8_t *)data;
while(size--)
*p++ = 0;
#endif
}
/* safe allocations */
void *crypt_safe_alloc(size_t size)
{
struct safe_allocation *alloc;
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
return NULL;
alloc = malloc(size + offsetof(struct safe_allocation, data));
if (!alloc)
return NULL;
alloc->size = size;
crypt_safe_memzero(&alloc->data, size);
/* coverity[leaked_storage] */
return &alloc->data;
}
void crypt_safe_free(void *data)
{
struct safe_allocation *alloc;
if (!data)
return;
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
crypt_safe_memzero(data, alloc->size);
alloc->size = 0x55aa55aa;
free(alloc);
}
void *crypt_safe_realloc(void *data, size_t size)
{
struct safe_allocation *alloc;
void *new_data;
new_data = crypt_safe_alloc(size);
if (new_data && data) {
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
if (size > alloc->size)
size = alloc->size;
memcpy(new_data, data, size);
}
crypt_safe_free(data);
return new_data;
}

View File

@@ -2,7 +2,7 @@
* Generic wrapper for storage functions
* (experimental only)
*
* Copyright (C) 2018, Ondrej Kozina
* Copyright (C) 2018-2020, Ondrej Kozina
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,6 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
@@ -108,7 +107,7 @@ static int crypt_storage_dmcrypt_init(
r = device_block_adjust(cd, device, DEV_OK,
device_offset, &dmd.size, &dmd.flags);
if (r < 0) {
log_err(cd, _("Device %s doesn't exist or access denied."),
log_err(cd, _("Device %s does not exist or access denied."),
device_path(device));
return -EIO;
}

View File

@@ -2,7 +2,7 @@
* Generic wrapper for storage functions
* (experimental only)
*
* Copyright (C) 2018, Ondrej Kozina
* Copyright (C) 2018-2020, Ondrej Kozina
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -2,8 +2,8 @@
* utils_wipe - wipe a device
*
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2020 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,7 +22,6 @@
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include "internal.h"
/*
@@ -56,7 +55,7 @@ static int crypt_wipe_special(struct crypt_device *cd, int fd, size_t bsize,
size_t alignment, char *buffer,
uint64_t offset, size_t size)
{
int r;
int r = 0;
unsigned int i;
ssize_t written;

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Phil Karn, KA9Q
* libcryptsetup modifications
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Phil Karn, KA9Q
* libcryptsetup modifications
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -3,7 +3,7 @@
*
* Copyright (C) 2002, Phil Karn, KA9Q
* libcryptsetup modifications
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public

View File

@@ -1,7 +1,7 @@
/*
* dm-verity volume handling
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,7 +25,6 @@
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <uuid/uuid.h>
@@ -66,7 +65,7 @@ int VERITY_read_sb(struct crypt_device *cd,
sizeof(struct verity_sb), device_path(device), sb_offset);
if (params->flags & CRYPT_VERITY_NO_HEADER) {
log_err(cd, _("Verity device %s doesn't use on-disk header."),
log_err(cd, _("Verity device %s does not use on-disk header."),
device_path(device));
return -EINVAL;
}
@@ -169,7 +168,7 @@ int VERITY_write_sb(struct crypt_device *cd,
}
if (params->flags & CRYPT_VERITY_NO_HEADER) {
log_err(cd, _("Verity device %s doesn't use on-disk header."),
log_err(cd, _("Verity device %s does not use on-disk header."),
device_path(device));
return -EINVAL;
}
@@ -235,6 +234,7 @@ int VERITY_activate(struct crypt_device *cd,
const char *name,
const char *root_hash,
size_t root_hash_size,
const char *signature_description,
struct device *fec_device,
struct crypt_params_verity *verity_hdr,
uint32_t activation_flags)
@@ -252,6 +252,11 @@ int VERITY_activate(struct crypt_device *cd,
name ?: "[none]", verity_hdr->hash_name);
if (verity_hdr->flags & CRYPT_VERITY_CHECK_HASH) {
if (signature_description) {
log_err(cd, _("Root hash signature verification is not supported."));
return -EINVAL;
}
log_dbg(cd, "Verification of data in userspace required.");
r = VERITY_verify(cd, verity_hdr, root_hash, root_hash_size);
@@ -291,7 +296,8 @@ int VERITY_activate(struct crypt_device *cd,
r = dm_verity_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
crypt_metadata_device(cd), fec_device, root_hash,
root_hash_size, VERITY_hash_offset_block(verity_hdr),
root_hash_size, signature_description,
VERITY_hash_offset_block(verity_hdr),
VERITY_hash_blocks(cd, verity_hdr), verity_hdr);
if (r)
@@ -299,7 +305,11 @@ int VERITY_activate(struct crypt_device *cd,
r = dm_create_device(cd, name, CRYPT_VERITY, &dmd);
if (r < 0 && (dm_flags(cd, DM_VERITY, &dmv_flags) || !(dmv_flags & DM_VERITY_SUPPORTED))) {
log_err(cd, _("Kernel doesn't support dm-verity mapping."));
log_err(cd, _("Kernel does not support dm-verity mapping."));
r = -ENOTSUP;
}
if (r < 0 && signature_description && !(dmv_flags & DM_VERITY_SIGNATURE_SUPPORTED)) {
log_err(cd, _("Kernel does not support dm-verity signature option."));
r = -ENOTSUP;
}
if (r < 0)

View File

@@ -1,7 +1,7 @@
/*
* dm-verity volume handling
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -46,6 +46,7 @@ int VERITY_activate(struct crypt_device *cd,
const char *name,
const char *root_hash,
size_t root_hash_size,
const char *signature_description,
struct device *fec_device,
struct crypt_params_verity *verity_hdr,
uint32_t activation_flags);
@@ -57,7 +58,7 @@ int VERITY_verify(struct crypt_device *cd,
int VERITY_create(struct crypt_device *cd,
struct crypt_params_verity *verity_hdr,
char *root_hash,
const char *root_hash,
size_t root_hash_size);
int VERITY_FEC_process(struct crypt_device *cd,

View File

@@ -2,7 +2,7 @@
* dm-verity Forward Error Correction (FEC) support
*
* Copyright (C) 2015 Google, Inc. All rights reserved.
* Copyright (C) 2017-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2017-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,7 +20,6 @@
*/
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include "verity.h"

View File

@@ -1,7 +1,7 @@
/*
* dm-verity volume handling
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2020 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -102,7 +102,7 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
off_t *hash_level_block, off_t *hash_level_size)
{
size_t hash_per_block_bits;
off_t s;
off_t s, s_shift;
int i;
if (!digest_size)
@@ -124,7 +124,10 @@ static int hash_levels(size_t hash_block_size, size_t digest_size,
if (hash_level_block)
hash_level_block[i] = *hash_position;
// verity position of block data_file_blocks at level i
s = (data_file_blocks + ((off_t)1 << ((i + 1) * hash_per_block_bits)) - 1) >> ((i + 1) * hash_per_block_bits);
s_shift = (i + 1) * hash_per_block_bits;
if (s_shift > 63)
return -EINVAL;
s = (data_file_blocks + ((off_t)1 << s_shift) - 1) >> ((i + 1) * hash_per_block_bits);
if (hash_level_size)
hash_level_size[i] = s;
if ((*hash_position + s) < *hash_position ||
@@ -418,7 +421,7 @@ int VERITY_verify(struct crypt_device *cd,
/* Create verity hash */
int VERITY_create(struct crypt_device *cd,
struct crypt_params_verity *verity_hdr,
char *root_hash,
const char *root_hash,
size_t root_hash_size)
{
unsigned pgsize = (unsigned)crypt_getpagesize();
@@ -439,7 +442,7 @@ int VERITY_create(struct crypt_device *cd,
verity_hdr->data_block_size,
verity_hdr->data_size,
VERITY_hash_offset_block(verity_hdr),
root_hash,
CONST_CAST(char*)root_hash,
root_hash_size,
verity_hdr->salt,
verity_hdr->salt_size);

View File

@@ -2,7 +2,7 @@
* cryptsetup volume key implementation
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2020 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -47,7 +47,7 @@ struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key)
if (key)
memcpy(&vk->key, key, keylength);
else
crypt_memzero(&vk->key, keylength);
crypt_safe_memzero(&vk->key, keylength);
}
return vk;
@@ -120,7 +120,7 @@ void crypt_free_volume_key(struct volume_key *vk)
struct volume_key *vk_next;
while (vk) {
crypt_memzero(vk->key, vk->keylength);
crypt_safe_memzero(vk->key, vk->keylength);
vk->keylength = 0;
free(CONST_CAST(void*)vk->key_description);
vk_next = vk->next;

View File

@@ -285,9 +285,9 @@ Please attach the output of the failed command with the
.SH AUTHORS
Cryptsetup-reencrypt was written by Milan Broz <gmazyland@gmail.com>.
.SH COPYRIGHT
Copyright \(co 2012-2019 Milan Broz
Copyright \(co 2012-2020 Milan Broz
.br
Copyright \(co 2012-2019 Red Hat, Inc.
Copyright \(co 2012-2020 Red Hat, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -12,7 +12,7 @@ and can hence offer more features than plain dm-crypt. On the other
hand, the header is visible and vulnerable to damage.
In addition, cryptsetup provides limited support for the use of
loop-AES volumes and for TrueCrypt compatible volumes.
loop-AES volumes, TrueCrypt, VeraCrypt and BitLocker compatible volumes.
.SH PLAIN DM-CRYPT OR LUKS?
.PP
@@ -84,6 +84,8 @@ For backward compatibility there are \fBopen\fR command aliases:
\fBloopaesOpen\fR: open \-\-type loopaes
.br
\fBtcryptOpen\fR: open \-\-type tcrypt
.br
\fBbitlkOpen\fR: open \-\-type bitlk
\fB<options>\fR are type specific and are described below
for individual device types. For \fBcreate\fR, the order of the <name>
@@ -743,6 +745,47 @@ TrueCrypt.
Please note that cryptsetup does not use TrueCrypt code, please report
all problems related to this compatibility extension to the cryptsetup project.
.SH BITLK (Windows BitLocker-compatible) EXTENSION (EXPERIMENTAL)
cryptsetup supports mapping of BitLocker and BitLocker to Go encrypted partition
using a native Linux kernel API.
Header formatting and BITLK header changes are not supported, cryptsetup
never changes BITLK header on-device.
\fBWARNING:\fR This extension is EXPERIMENTAL.
BITLK extension requires kernel userspace crypto API to be available
(for details see TCRYPT section).
Cryptsetup should recognize all BITLK header variants, except legacy
header used in Windows Vista systems and partially decrypted BitLocker devices.
Activation of legacy devices encrypted in CBC mode requires at least
Linux kernel version 5.3 and for devices using Elephant diffuser kernel 5.6.
The \fBbitlkDump\fR command should work for all recognized BITLK devices
and doesn't require superuser privilege.
For unlocking with the \fBopen\fR a password or a recovery passphrase must
be provided. Other unlocking methods (TPM, SmartCard) are not supported.
.PP
\fIopen\fR \-\-type bitlk <device> <name>
.br
\fIbitlkOpen\fR <device> <name> (\fBold syntax\fR)
.IP
Opens the BITLK (a BitLocker-compatible) <device> and sets up
a mapping <name>.
\fB<options>\fR can be [\-\-key\-file, \-\-readonly, \-\-test\-passphrase,
\-\-allow-discards].
.PP
\fIbitlkDump\fR <device>
.IP
Dump the header information of a BITLK device.
Please note that cryptsetup does not use any Windows BitLocker code, please report
all problems related to this compatibility extension to the cryptsetup project.
.SH MISCELLANEOUS
.PP
\fIrepair\fR <device>
@@ -1128,6 +1171,7 @@ e.g. 12345678-1234-1234-1234-123456789abc.
.B "\-\-allow\-discards\fR"
Allow the use of discard (TRIM) requests for the device.
This option is only relevant for \fIopen\fR action.
This is also not supported for LUKS2 devices with data integrity protection.
\fBWARNING:\fR This command can have a negative security impact
because it can make filesystem-level operations visible on
@@ -1576,6 +1620,9 @@ for integrity protected devices.
If you want to format LUKS2 device with data integrity protection,
use \fI\-\-integrity\fR option.
Since dm-integrity doesn't support discards (TRIM), dm-crypt device on top of it
inherits this, so integrity protection mode doesn't support discards either.
Some integrity modes requires two independent keys (key for encryption
and for authentication). Both these keys are stored in one LUKS keyslot.
@@ -1636,9 +1683,9 @@ Copyright \(co 2004-2006 Clemens Fruhwirth
.br
Copyright \(co 2012-2014 Arno Wagner
.br
Copyright \(co 2009-2019 Red Hat, Inc.
Copyright \(co 2009-2020 Red Hat, Inc.
.br
Copyright \(co 2009-2019 Milan Broz
Copyright \(co 2009-2020 Milan Broz
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -165,8 +165,8 @@ The file with the integrity key.
.TP
.B "\-\-journal\-crypt ALGORITHM"
Encryption algorithm for journal data area.
You can use a block cipher here such as cbc(aes) or
a stream cipher, for example, chacha20 or ctr(aes).
You can use a block cipher here such as cbc-aes or
a stream cipher, for example, chacha20 or ctr-aes.
.TP
.B "\-\-journal\-crypt\-key\-size BYTES"
The size of the journal encryption key.
@@ -223,9 +223,9 @@ Please attach the output of the failed command with the
The integritysetup tool is written by Milan Broz <gmazyland@gmail.com>
and is part of the cryptsetup project.
.SH COPYRIGHT
Copyright \(co 2016-2019 Red Hat, Inc.
Copyright \(co 2016-2020 Red Hat, Inc.
.br
Copyright \(co 2016-2019 Milan Broz
Copyright \(co 2016-2020 Milan Broz
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -40,7 +40,7 @@ The <root_hash> is a hexadecimal string.
\fB<options>\fR can be [\-\-hash-offset, \-\-no-superblock,
\-\-ignore-corruption or \-\-restart-on-corruption, \-\-ignore-zero-blocks,
\-\-check-at-most-once]
\-\-check-at-most-once, \-\-root-hash-signature]
If option \-\-no-superblock is used, you have to use as the same options
as in initial format operation.
@@ -165,6 +165,10 @@ This is the offset, in bytes, from the start of the FEC device to the beginning
Number of generator roots. This equals to the number of parity bytes in the encoding data.
In RS(M, N) encoding, the number of roots is M-N. M is 255 and M-N is between 2 and 24 (including).
.TP
.B "\-\-root-hash-signature=FILE"
Path to roothash signature file used to verify the root hash (in kernel).
This feature requires Linux kernel version 5.4 or more recent.
.TP
.SH RETURN CODES
Veritysetup returns 0 on success and a non-zero value on error.
@@ -215,9 +219,9 @@ The first implementation of veritysetup was written by Chrome OS authors.
This version is based on verification code written by Mikulas Patocka <mpatocka@redhat.com>
and rewritten for libcryptsetup by Milan Broz <gmazyland@gmail.com>.
.SH COPYRIGHT
Copyright \(co 2012-2019 Red Hat, Inc.
Copyright \(co 2012-2020 Red Hat, Inc.
.br
Copyright \(co 2012-2019 Milan Broz
Copyright \(co 2012-2020 Milan Broz
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@@ -1,7 +1,7 @@
/*
* Example of LUKS2 kesylot handler (EXAMPLE)
*
* Copyright (C) 2016-2019 Milan Broz <gmazyland@gmail.com>
* Copyright (C) 2016-2020 Milan Broz <gmazyland@gmail.com>
*
* Use:
* - generate LUKS device

View File

@@ -1,7 +1,7 @@
/*
* Example of LUKS2 token storing third party metadata (EXAMPLE)
*
* Copyright (C) 2016-2019 Milan Broz <gmazyland@gmail.com>
* Copyright (C) 2016-2020 Milan Broz <gmazyland@gmail.com>
*
* Use:
* - generate LUKS device

View File

@@ -22,6 +22,7 @@ lib/luks1/keyencryption.c
lib/luks1/keymanage.c
lib/loopaes/loopaes.c
lib/tcrypt/tcrypt.c
lib/bitlk/bitlk.c
lib/verity/verity.c
lib/verity/verity_hash.c
lib/verity/verity_fec.c

File diff suppressed because it is too large Load Diff

1790
po/cs.po

File diff suppressed because it is too large Load Diff

2412
po/da.po

File diff suppressed because it is too large Load Diff

1785
po/de.po

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More