Compare commits

..

224 Commits

Author SHA1 Message Date
Milan Broz
780ebb4680 Version 2.3.2. 2020-04-30 16:56:53 +02:00
Yuri Chornoivan
02a579af59 po: update uk.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Yuri Kozlov
9bcf1c4b8d po: update ru.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Jakub Bogusz
dec9b4f7c7 po: update pl.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Hiroshi Takekawa
4701842829 po: update ja.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Frédéric Marchal
488b4bdbe8 po: update fr.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Antonio Ceballos
c8d886b422 po: update es.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Roland Illig
a83bbd2e92 po: update de.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Petr Pisar
c3a47cb72f po: update cs.po (from translationproject.org) 2020-04-29 08:49:39 +02:00
Ondrej Kozina
0971e55d4d Fix gcc warning in unbound key dump. 2020-04-29 08:49:25 +02:00
Ondrej Kozina
6f45c7a8ac Drop duplicit check on --refresh option. 2020-04-29 08:49:04 +02:00
Arno Wagner
c567d852a5 Sync to wiki (added 10.9) 2020-04-28 15:28:49 +02:00
Arno Wagner
0b38128e21 sync to Wiki 2020-04-27 16:27:50 +02:00
Arno Wagner
b9daa8b2ee Fixes to 6.10, should state situation with LUKS2
accurately now.
2020-04-26 18:56:28 +02:00
Arno Wagner
878c7173c3 typo 2020-04-26 18:34:59 +02:00
Arno Wagner
f69b980dcf Sync to Wiki Version.
Rework to differentiate LUKS1 from LUKS2 and
info for LUKS2 added.
2020-04-26 18:22:25 +02:00
Milan Broz
33378792ca Prepare rc0 for version 2.3.2. 2020-04-17 10:48:04 +02:00
Milan Broz
c7a2b4d5e3 Fix a line break in veritysetup man page. 2020-04-16 15:33:25 +02:00
Milan Broz
4a077fc2c9 Rephrase warning a little bit. 2020-04-16 15:30:35 +02:00
Ondrej Kozina
f309ec21d7 Allow dump of LUKS2 unbound keyslot.
Adds option to dump content of LUKS2 unbound keyslot
in to a file:

'cryptsetup luksDump --unbound --master-key-file /file -S 12 /dev/luks2'

or to terminal:

'cryptsetup luksDump --unbound -S 12 /dev/luks2'

Parameters -S (specific keyslot) is mandatory with --unbound.

Fixes: #549
2020-04-16 15:29:24 +02:00
Milan Broz
e261cf7481 Add issue templates.
(Note: default is in project setting as a copy of Bug.md)
2020-04-15 18:06:07 +02:00
Milan Broz
fa8390b23e Remove redundant EOL in some usage messages.
With recent changes in log wrapper these messages were forgotten to fix.
2020-04-15 13:14:13 +02:00
Milan Broz
af89858d47 Use fsync explicitly for the device check in cryptsetup-reencrypt.
With direct-io removal in previous patch we should ensure the header
change hits the real device immediatelly.
2020-04-15 13:10:36 +02:00
Ondrej Kozina
e6a3569743 Avoid name clash with newer json-c library.
This is partial revert of previous commit and also
fixes wrong decision to name our internal helpers with
json_object prefix.
2020-04-14 17:24:57 +02:00
Björn Esser
604abec333 Add support for upcoming json-c 0.14.0.
* TRUE/FALSE are not defined anymore.  1 and 0 are used instead.
  * json_object_get_uint64() and json_object_new_uint64() are part
    of the upstream API now.
2020-04-13 14:25:18 +02:00
Milan Broz
790666ffb0 Add support for allow_discrads for dm-integrity.
Kernel 5.7 adds support for optional discard/TRIM operation
for dm-integrity (available only for internal hash, not for LUKS2
with integrity).

This patch adds support for the new option.
2020-04-09 00:03:42 +02:00
Milan Broz
c9f6ccff9f Ignore not relevant TOCTOU warning in previous commit. 2020-04-03 13:30:54 +02:00
Milan Broz
02b3f42500 Fix open flags in cryptsetup-reencrypt header access check.
We should not use O_DIRECT, it does not work tin in-memory fs.

Also never use O_EXCL on regular files, it is undedfined according
to open() documentation.

Fixes: #529.
2020-04-03 12:59:50 +02:00
Vojtěch Trefný
e10724accb bitlk: Correctly free memory in passphrase_to_utf16
Fixes: #547
2020-04-01 08:02:09 +02:00
Milan Broz
5b68dec43a Adjust IV size in cipher benchmark.
The IV size for benchmark can be autodetected (for known ciphers).
For other algorithms user still can specify own values.
2020-03-23 18:46:59 +01:00
Milan Broz
9d13da0050 Set devel version. 2020-03-23 18:46:28 +01:00
Ondrej Kozina
1e94425279 Remove unused parameter from crypto_backend_init. 2020-03-20 11:32:57 +01:00
Milan Broz
fc48f9bc08 Workaround for verity FEC test.
Threre asre some situatiuoins when randomized image is nor repairable
by FEC data. Let's use completely deterministic image creation (fixed salt and uuid).

FIXME: The FEC Reed-Solomon code is doing something strange here, this
kind of erasure should be always repairable.
2020-03-19 10:14:45 +01:00
Milan Broz
2eb25910a1 Fix Veracrypt compatible support for longer passphrases.
Previous fix for longer passhphrases increased maximal
passphrase length even if it was not needed, for example
if used with SHA256 hash in combination with keyfiles.

This patch tries to fix the problem, so some older volumes
can be opened again.

Also some test images are added for regression testing.

Fixes: #542.
2020-03-16 17:09:41 +01:00
Milan Broz
1dab341b33 Update Readme.md. 2020-03-12 09:59:00 +01:00
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
Milan Broz
c82728f04d Version 2.2.2. 2019-11-01 09:02:46 +01:00
Milan Broz
cc0d33bca7 Fix DM_DEVICE_GET_TARGET_VERSION detection.
Stable libdevampper used changed name for dm task, let's fix it.
2019-10-31 20:35:46 +01:00
Milan Broz
3933ec7dce Add Ondra to authors. 2019-10-31 20:02:51 +01:00
Petr Pisar
f8c9507612 po: update cs.po (from translationproject.org) 2019-10-31 20:01:51 +01:00
Yuri Kozlov
7c5c9ae8fd po: update ru.po (from translationproject.org) 2019-10-31 12:10:04 +01:00
Frédéric Marchal
cd00792fe9 po: update fr.po (from translationproject.org) 2019-10-31 12:10:04 +01:00
Ondrej Kozina
df390509b2 Hotfix missing new line character in translated string.
Without this fix the message gets immediately overwritten with
reencryption progress bar.
2019-10-31 12:02:55 +01:00
Ondrej Kozina
dd6abe9375 Add luks2-reencryption-test to valgrind checks. 2019-10-22 15:07:57 +02:00
Milan Broz
a3f199d0a3 po: update pot file 2019-10-20 10:40:12 +02:00
Yuri Chornoivan
8e3b85ee12 po: update uk.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Jakub Bogusz
e60fbfc865 po: update pl.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Hiroshi Takekawa
a512488fd7 po: update ja.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Antonio Ceballos
1981d909cf po: update es.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Roland Illig
ea14f2c98c po: update de.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Milan Broz
c81becf10d Prepare version tag, and sync po files.
(For some reason I unsynced all po files again,
this patch reverts them to the translationproject versions...)
2019-10-18 10:52:33 +02:00
dofrupisla
1433d040ae Fix luksHeaderRestore occuring twice 2019-10-17 11:07:32 +02:00
Milan Broz
206b70c837 Explicitly print error message if keyslot open failed.
The only quiet message now is EPERM (wrong password) that is
processed by the caller.

Fixes #488.
2019-10-11 14:06:49 +02:00
Ondrej Kozina
bb857dcef2 Silence reencryption compat test. 2019-10-11 12:40:14 +02:00
Ondrej Kozina
5568a780a9 Add missing error message to translation. 2019-10-11 12:40:09 +02:00
Ondrej Kozina
7c2086967b Add various units for progress speed reporting.
The progress function remained silent unless the speed was higher
than minimal delta for double type in MiB/s. That could confuse
users that progress got stucked, but it in fact it was only slow.

Now wipe and reencryption progess functions can report speeds
in B/s up to GiB/s.
2019-10-11 12:40:03 +02:00
Ondrej Kozina
f7fbf4d38c Fix bogus speed reports after resuming tracked operation.
When resuming reencryption operation (both LUKS2 and legacy offline
code) speeds were incorectly calculated from whole progress including
range already reencrypted in previous runs. Now we track speed only
for currently running session.
2019-10-11 12:39:59 +02:00
Ondrej Kozina
0c8cf5c1e0 Switch cryptsetup-reencrypt to use tools_reencrypt_progress. 2019-10-11 12:39:51 +02:00
Milan Broz
33f2af1c09 Change --version option handling and support -V short option.
Fixes #480.
2019-10-10 10:51:04 +02:00
Ondrej Kozina
c9a7e6e4ec Add blkid wipe report messages to translations. 2019-10-08 15:31:57 +02:00
Ondrej Kozina
86bb4ea8f2 Report offsets when wiping device signatures.
Fixes: #489.
2019-10-08 15:31:57 +02:00
Milan Broz
99c4e83994 Properly support LTLIBINTL setting in Makefiles.
Fixes #479.
2019-10-08 15:26:13 +02:00
Milan Broz
ca2f5a8160 Fix tests in previous commits. 2019-10-08 14:58:07 +02:00
Milan Broz
7af304251e Fix activation message during encryption process. 2019-10-08 14:57:15 +02:00
Milan Broz
15f5126296 Support new DM_GET_TARGET_VERSION ioctl.
This way we can load kernel device-mapper target module before
table create ioctl.

Target version is available since kernel 5.4.
2019-10-08 14:05:30 +02:00
Ondrej Kozina
21edd66892 Allow LUKS2 reencryption to run on systems w/o kernel keyring service. 2019-10-07 14:08:41 +02:00
Ondrej Kozina
3e9d6b6960 Temporarily disable test failing due to deferred remove after decryption. 2019-10-04 13:46:13 +02:00
Ondrej Kozina
62b580904b Move check for loop device inside crypt_loop_backing_file.
It also fixes minor regression where we return backing file
for partition on top of loop device when prompting for passphrase.
Partition on loop has different major number so it should not be
considered loop device at all.
2019-10-04 13:46:13 +02:00
Ondrej Kozina
c4c4f9d159 Mark active device for deferred remove after decryption gets finished. 2019-10-04 12:20:34 +02:00
Ondrej Kozina
67a5ec1567 Abort reencryption initialization sooner on error. 2019-10-04 12:20:29 +02:00
Ondrej Kozina
c646832bfe Add hard and soft memory limit to reencrypt hotzone size.
Currently hard memory limit is 1 GiB. Soft limit is
1/4 of system memory.

Note that --hotzone-size cryptsetup parameter can only further
lower hard and soft memory limit on hotzone size and not bypass
it.
2019-10-04 12:20:22 +02:00
Ondrej Kozina
539d4756f2 Do not flush and freeze fs while swapping in/out overlay device. 2019-10-04 12:20:16 +02:00
Ondrej Kozina
8714e115ad Remove unused parameter from reencrypt_swap_backing_device.
It always loads dm-linear mapping in original device that maps 1:1
to helper overlay device (holding original table).
2019-10-04 12:20:12 +02:00
Ondrej Kozina
9c38e09ad3 Retain activation flags during and after online reencryption. 2019-10-04 12:20:06 +02:00
Ondrej Kozina
5628d7d8b5 Drop duplicite flag in LUKS2 device reload after reencryption.
Reload operation implicictly requires shared flag anyway and it's
added later.
2019-10-04 12:19:39 +02:00
Ondrej Kozina
5f2e8d6062 Allow LUKS2 device activation after encryption initialization.
It may be useful to activate device right after LUKS2 encryption
is initialized:

device is ready to use immediately even if data encryption runs in
the background for a long time

It simplifies encryption initialization during reboot.
2019-10-04 12:19:34 +02:00
Ondrej Kozina
630e336ea0 Do not allocate data device when identical with metadata device.
we do not need to allocate separate data device if it's equal
to metadata device during initialization.
2019-10-04 12:19:14 +02:00
Ondrej Kozina
430852736d Cleanup crypt_init_data_device.
data_device can not be NULL
2019-10-04 12:19:09 +02:00
Milan Broz
4eeb741358 Report kernel FIPS mode in module version test. 2019-10-03 14:01:27 +02:00
Ondrej Kozina
bb1ce4a069 Check plain crypt device is properly aligned on activation. 2019-10-02 13:40:10 +02:00
Ondrej Kozina
5e3e4a225e Check resize operation is aligned to device logical size.
Fixes #486.
2019-10-01 12:41:43 +02:00
Ondrej Kozina
583d05e32a Fix upconversion to LUKS2 with detached header.
The check for enough space before moving keyslots data did not expect real
detached header size to be less than aligned LUKS1 header size.

Also if detached header is placed in regular file we can grow so that
moved keyslots area fit the file.

Fixes #445.
2019-09-09 19:01:01 +02:00
Ondrej Kozina
2c0914b2ba Fix LUKS2 reencryption recovery test.
Fix corner case when head or tail of test device is remapped
to error target for writes.
2019-09-09 14:07:30 +02:00
Milan Broz
3ebedfe7b0 Update readme.md. 2019-09-06 13:13:44 +02:00
145 changed files with 20943 additions and 12817 deletions

View File

@@ -0,0 +1,15 @@
### Issue description
<!-- Please, shortly describe the issue here. -->
### Steps for reproducing the issue
<!-- How it can be reproduced? Include all important steps. -->
### Additional info
<!-- Please mention what distribution you are using. -->
### Debug log
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
```
Output with --debug option:
```

View File

@@ -0,0 +1,5 @@
### Documentation issue
<!-- Please, shortly describe the issue in documentation here. -->
### Additional info
<!-- Please mention what cryptsetup version you are using. -->

View File

@@ -0,0 +1,5 @@
### New feature description
<!-- Please, shortly describe the requested feature here. -->
### Additional info
<!-- Please mention what distribution and cryptsetup version you are using. -->

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

@@ -1,3 +1,4 @@
Jana Saout <jana@saout.de>
Clemens Fruhwirth <clemens@endorphin.org>
Milan Broz <gmazyland@gmail.com>
Ondrej Kozina <okozina@redhat.com>

3052
FAQ

File diff suppressed because it is too large Load Diff

View File

@@ -15,6 +15,8 @@ AM_CPPFLAGS = \
AM_CFLAGS = -Wall
AM_LDFLAGS =
LDADD = $(LTLIBINTL) -lm
tmpfilesddir = @DEFAULT_TMPFILESDIR@
noinst_LTLIBRARIES =

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,55 +44,25 @@ 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.0**
* [cryptsetup-2.2.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.xz)
* Signature [cryptsetup-2.2.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0.tar.sign)
**The latest stable cryptsetup version is 2.3.1**
* [cryptsetup-2.3.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.xz)
* Signature [cryptsetup-2.3.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.1.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.2.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-ReleaseNotes).
* [Cryptsetup 2.3.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.1-ReleaseNotes).
Previous versions
* [Version 2.1.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/v2.1.0-ReleaseNotes).
* [Version 2.3.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.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).
* [Version 2.0.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.5-ReleaseNotes).
* [Version 2.0.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.4-ReleaseNotes).
* [Version 2.0.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
* [Version 2.0.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.2-ReleaseNotes).
* [Version 2.0.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.1-ReleaseNotes).
* [Version 2.0.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.0-ReleaseNotes).
* [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes).
* [Version 1.7.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.4-ReleaseNotes).
* [Version 1.7.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.3-ReleaseNotes).
* [Version 1.7.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.2-ReleaseNotes).
* [Version 1.7.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.1-ReleaseNotes).
* [Version 1.7.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes).
Source and API docs
-------------------

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.2.1])
AC_INIT([cryptsetup],[2.3.2])
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,8 @@ 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
if test "x$have_cookie" = xno; 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

56
docs/v2.2.2-ReleaseNotes Normal file
View File

@@ -0,0 +1,56 @@
Cryptsetup 2.2.2 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.1 and 2.2 should upgrade to this version.
Changes since version 2.2.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Print error message if a keyslot open failed for a different reason
than wrong passwords (for example there is not enough memory).
Only an exit code was present in this case.
* The progress function switches unit sizes (B/s to GiB/s) according
to the actual speed. Also, it properly calculates speed in the case
of a resumed reencryption operation.
* The --version now supports short -V short option and better handles
common option priorities.
* If cryptsetup wipes signatures during format actions through blkid,
it also prints signature device offsets.
* Compilation now properly uses LTLIBINTL gettext setting in Makefiles.
* Device-mapper backend now supports new DM_GET_TARGET_VERSION ioctl
(available since Linux kernel 5.4).
This should help to detect some kernel/userspace incompatibilities
earlier later after a failed device activation.
* Fixes LUKS2 reencryption on systems without kernel keyring.
* Fixes unlocking prompt for partitions mapped through loop devices
(to properly show the backing device).
* For LUKS2 decryption, a device is now marked for deferred removal
to be automatically deactivated.
* Reencryption now limits hotzone size to be maximal 1 GiB or 1/4
system memory (if lower).
* Reencryption now retains activation flags during online reencryption.
* Reencryption now allows LUKS2 device to activate device right after
LUKS2 encryption is initialized through optional active device name
for cryptsetup reencrypt --encrypt command.
This could help with automated encryption during boot.
NOTE: It means that part of the device is still not encrypted during
activation. Use with care!
* Fixes failure in resize and plain format activation if activated device
size was not aligned to underlying logical device size.
* Fixes conversion to LUKS2 format with detached header if a detached
header size was smaller than the expected aligned LUKS1 header size.

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.

42
docs/v2.3.2-ReleaseNotes Normal file
View File

@@ -0,0 +1,42 @@
Cryptsetup 2.3.2 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.x should upgrade to this version.
Changes since version 2.3.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Support compilation with json-c library version 0.14.
* Update FAQ document for some LUKS2 specific information.
* Add option to dump content of LUKS2 unbound keyslot:
cryptsetup luksDump --unbound -S <slot> <device>
or optionally with --master-key-file option.
The slot number --key-slot (-S) option is mandatory here.
An unbound keyslot store a key is that is not assigned to data
area on disk (LUKS2 allows to store arbitrary keys).
* Rephrase some error messages and remove redundant end-of-lines.
* Add support for discards (TRIM) for standalone dm-integrity devices.
Linux kernel 5.7 adds support for optional discard/TRIM operation
over dm-integrity devices.
It is now supported through --allow-discards integritysetup option.
Note you need to add this flag in all activation calls.
Note that this option cannot be used for LUKS2 authenticated encryption
(that uses dm-integrity for storing additional per-sector metadata).
* Fix cryptsetup-reencrypt to work on devices that do not allow
direct-io device access.
* Fix a crash in the BitLocker-compatible code error path.
* Fix Veracrypt compatible support for longer (>64 bytes) passphrases.
It allows some older images to be correctly opened again.
The issue was introduced in version 2.3.1.

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
@@ -51,6 +51,7 @@ static const struct cipher_alg cipher_algs[] = {
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
{ "xchacha12,aes", "adiantum", 32, false },
{ "xchacha20,aes", "adiantum", 32, false },
{ "sm4", NULL, 16, false },
{ NULL, NULL, 0, false }
};
@@ -72,7 +73,13 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
{
const struct cipher_alg *ca = _get_alg(name, mode);
return ca ? ca->blocksize : -EINVAL;
if (!ca)
return -EINVAL;
if (mode && !strcasecmp(mode, "ecb"))
return 0;
return ca->blocksize;
}
int crypt_cipher_wrapped_key(const char *name, const char *mode)

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
@@ -26,13 +26,12 @@
#include <stddef.h>
#include <string.h>
struct crypt_device;
struct crypt_hash;
struct crypt_hmac;
struct crypt_cipher;
struct crypt_storage;
int crypt_backend_init(struct crypt_device *ctx);
int crypt_backend_init(void);
void crypt_backend_destroy(void);
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
@@ -119,6 +118,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
@@ -89,7 +89,7 @@ static void crypt_hash_test_whirlpool_bug(void)
crypto_backend_whirlpool_bug = 1;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
if (crypto_backend_initialised)
return 0;
@@ -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
@@ -110,7 +110,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
return 0;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
struct utsname uts;
struct sockaddr_alg sa = {
@@ -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
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
return 0;
}
@@ -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
@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
if (crypto_backend_initialised)
return 0;
@@ -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 {
@@ -119,7 +121,7 @@ static const char *openssl_backend_version(void)
}
#endif
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
if (crypto_backend_initialised)
return 0;
@@ -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,9 +227,48 @@ 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;
if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
_dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
_dm_integrity_checked = true;
}
/* We use this for loading target module */
static void _dm_check_target(dm_target_type target_type)
{
#if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
struct dm_task *dmt;
const char *target_name = NULL;
if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
return;
if (target_type == DM_CRYPT)
target_name = DM_CRYPT_TARGET;
else if (target_type == DM_VERITY)
target_name = DM_VERITY_TARGET;
else if (target_type == DM_INTEGRITY)
target_name = DM_INTEGRITY_TARGET;
else
return;
if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
goto out;
if (!dm_task_set_name(dmt, target_name))
goto out;
if (!dm_task_run(dmt))
goto out;
out:
if (dmt)
dm_task_destroy(dmt);
#endif
}
static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
{
struct dm_task *dmt;
@@ -232,13 +280,15 @@ 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;
/* Shut up DM while checking */
_quiet_log = 1;
_dm_check_target(target_type);
/* FIXME: add support to DM so it forces crypt target module load here */
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
goto out;
@@ -259,6 +309,10 @@ static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_typ
#if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
_dm_flags |= DM_DEFERRED_SUPPORTED;
#endif
#if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
_dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
#endif
}
@@ -307,7 +361,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;
@@ -628,7 +682,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;
@@ -658,6 +712,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" : "",
@@ -683,19 +744,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;
@@ -827,6 +891,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++;
@@ -834,6 +903,12 @@ static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
num_options++;
snprintf(feature, sizeof(feature), "allow_discards ");
strncat(features, feature, sizeof(features) - strlen(features) - 1);
}
if (tgt->u.integrity.meta_device) {
num_options++;
snprintf(feature, sizeof(feature), "meta_device:%s ",
@@ -883,6 +958,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)
{
@@ -1156,6 +1241,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;
}
@@ -1194,6 +1282,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;
@@ -1415,10 +1505,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."));
@@ -1483,7 +1576,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;
}
@@ -1491,7 +1584,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;
}
@@ -1517,7 +1610,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 &&
@@ -1547,6 +1641,10 @@ int dm_create_device(struct crypt_device *cd, const char *name,
!(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
!(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
@@ -1579,6 +1677,9 @@ int dm_reload_device(struct crypt_device *cd, const char *name,
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
!dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
log_err(cd, _("Discard/TRIM is not supported."));
}
if (!r && resume)
@@ -1630,6 +1731,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;
@@ -1918,6 +2020,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));
@@ -2101,6 +2204,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;
}
@@ -2126,11 +2238,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);
@@ -2295,6 +2411,10 @@ 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 if (!strcmp(arg, "allow_discards")) {
*act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
} else /* unknown option */
goto err;
}
@@ -2377,6 +2497,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
*
@@ -2398,6 +2526,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;
@@ -2480,6 +2610,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;
@@ -2527,6 +2660,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;
@@ -2565,6 +2699,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)
@@ -2802,8 +2939,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;
@@ -2818,6 +2955,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;
@@ -2826,16 +2964,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;
@@ -2851,6 +2994,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;
@@ -2881,3 +3029,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
@@ -55,6 +55,9 @@
/* 20 MiBs */
#define LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH 0x1400000
/* 1 GiB */
#define LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH 0x40000000
struct device;
/*
@@ -162,6 +165,7 @@ struct luks2_reenc_context {
char *device_name;
char *hotzone_name;
char *overlay_name;
uint32_t flags;
/* reencryption window persistence attributes */
struct reenc_protection rp;
@@ -596,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>
@@ -59,9 +58,9 @@ json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr);
void hexprint_base64(struct crypt_device *cd, json_object *jobj,
const char *sep, const char *line_sep);
uint64_t json_object_get_uint64(json_object *jobj);
uint32_t json_object_get_uint32(json_object *jobj);
json_object *json_object_new_uint64(uint64_t value);
uint64_t crypt_jobj_get_uint64(json_object *jobj);
uint32_t crypt_jobj_get_uint32(json_object *jobj);
json_object *crypt_jobj_new_uint64(uint64_t value);
int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val);
void json_object_object_del_by_uint(json_object *jobj, unsigned key);

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
@@ -325,8 +325,8 @@ int LUKS2_generate_hdr(
json_object_object_add_by_uint(jobj_segments, 0, jobj_segment);
json_object_object_add(jobj_config, "json_size", json_object_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(jobj_config, "json_size", crypt_jobj_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
JSON_DBG(cd, hdr->jobj, "Header JSON:");
return 0;
@@ -400,6 +400,6 @@ int LUKS2_set_keyslots_size(struct crypt_device *cd,
if (!json_object_object_get_ex(hdr->jobj, "config", &jobj_config))
return 1;
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
return 0;
}

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);
}
@@ -219,7 +219,7 @@ int LUKS2_get_default_segment(struct luks2_hdr *hdr)
* json_type_int needs to be validated first.
* See validate_json_uint32()
*/
uint32_t json_object_get_uint32(json_object *jobj)
uint32_t crypt_jobj_get_uint32(json_object *jobj)
{
return json_object_get_int64(jobj);
}
@@ -234,21 +234,21 @@ static json_bool json_str_to_uint64(json_object *jobj, uint64_t *value)
tmp = strtoull(json_object_get_string(jobj), &endptr, 10);
if (*endptr || errno) {
*value = 0;
return FALSE;
return 0;
}
*value = tmp;
return TRUE;
return 1;
}
uint64_t json_object_get_uint64(json_object *jobj)
uint64_t crypt_jobj_get_uint64(json_object *jobj)
{
uint64_t r;
json_str_to_uint64(jobj, &r);
return r;
}
json_object *json_object_new_uint64(uint64_t value)
json_object *crypt_jobj_new_uint64(uint64_t value)
{
/* 18446744073709551615 */
char num[21];
@@ -273,9 +273,9 @@ static json_bool numbered(struct crypt_device *cd, const char *name, const char
for (i = 0; key[i]; i++)
if (!isdigit(key[i])) {
log_dbg(cd, "%s \"%s\" is not in numbered form.", name, key);
return FALSE;
return 0;
}
return TRUE;
return 1;
}
json_object *json_contains(struct crypt_device *cd, json_object *jobj, const char *name,
@@ -300,7 +300,7 @@ json_bool validate_json_uint32(json_object *jobj)
errno = 0;
tmp = json_object_get_int64(jobj);
return (errno || tmp < 0 || tmp > UINT32_MAX) ? FALSE : TRUE;
return (errno || tmp < 0 || tmp > UINT32_MAX) ? 0 : 1;
}
static json_bool validate_keyslots_array(struct crypt_device *cd,
@@ -313,17 +313,17 @@ static json_bool validate_keyslots_array(struct crypt_device *cd,
jobj = json_object_array_get_idx(jarr, i);
if (!json_object_is_type(jobj, json_type_string)) {
log_dbg(cd, "Illegal value type in keyslots array at index %d.", i);
return FALSE;
return 0;
}
if (!json_contains(cd, jobj_keys, "", "Keyslots section",
json_object_get_string(jobj), json_type_object))
return FALSE;
return 0;
i++;
}
return TRUE;
return 1;
}
static json_bool validate_segments_array(struct crypt_device *cd,
@@ -336,17 +336,17 @@ static json_bool validate_segments_array(struct crypt_device *cd,
jobj = json_object_array_get_idx(jarr, i);
if (!json_object_is_type(jobj, json_type_string)) {
log_dbg(cd, "Illegal value type in segments array at index %d.", i);
return FALSE;
return 0;
}
if (!json_contains(cd, jobj_segments, "", "Segments section",
json_object_get_string(jobj), json_type_object))
return FALSE;
return 0;
i++;
}
return TRUE;
return 1;
}
static json_bool segment_has_digest(const char *segment_name, json_object *jobj_digests)
@@ -357,10 +357,10 @@ static json_bool segment_has_digest(const char *segment_name, json_object *jobj_
UNUSED(key);
json_object_object_get_ex(val, "segments", &jobj_segments);
if (LUKS2_array_jobj(jobj_segments, segment_name))
return TRUE;
return 1;
}
return FALSE;
return 0;
}
static json_bool validate_intervals(struct crypt_device *cd,
@@ -372,18 +372,18 @@ static json_bool validate_intervals(struct crypt_device *cd,
while (i < length) {
if (ix[i].offset < 2 * metadata_size) {
log_dbg(cd, "Illegal area offset: %" PRIu64 ".", ix[i].offset);
return FALSE;
return 0;
}
if (!ix[i].length) {
log_dbg(cd, "Area length must be greater than zero.");
return FALSE;
return 0;
}
if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
log_dbg(cd, "Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
return FALSE;
return 0;
}
for (j = 0; j < length; j++) {
@@ -393,14 +393,14 @@ static json_bool validate_intervals(struct crypt_device *cd,
log_dbg(cd, "Overlapping areas [%" PRIu64 ",%" PRIu64 "] and [%" PRIu64 ",%" PRIu64 "].",
ix[i].offset, ix[i].offset + ix[i].length,
ix[j].offset, ix[j].offset + ix[j].length);
return FALSE;
return 0;
}
}
i++;
}
return TRUE;
return 1;
}
static int LUKS2_keyslot_validate(struct crypt_device *cd, json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
@@ -455,16 +455,16 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
json = json_object_to_json_string_ext(hdr_jobj,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
json_area_size = json_object_get_uint64(jobj1);
json_area_size = crypt_jobj_get_uint64(jobj1);
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;
}
@@ -543,7 +543,7 @@ static int hdr_validate_crypt_segment(struct crypt_device *cd,
return 1;
}
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (!sector_size || MISALIGNED_512(sector_size)) {
log_dbg(cd, "Illegal sector size: %" PRIu32, sector_size);
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);
@@ -1567,7 +1566,7 @@ static void hdr_dump_keyslots(struct crypt_device *cd, json_object *hdr_jobj)
log_std(cd, " %s: %s%s\n", slot, tmps, r == -ENOENT ? " (unbound)" : "");
if (json_object_object_get_ex(val, "key_size", &jobj2))
log_std(cd, "\tKey: %u bits\n", json_object_get_uint32(jobj2) * 8);
log_std(cd, "\tKey: %u bits\n", crypt_jobj_get_uint32(jobj2) * 8);
log_std(cd, "\tPriority: %s\n", get_priority_desc(val));
@@ -1650,7 +1649,7 @@ static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj)
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj1));
if (json_object_object_get_ex(jobj_segment, "sector_size", &jobj1))
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj1));
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", crypt_jobj_get_uint32(jobj1));
if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) &&
json_object_object_get_ex(jobj1, "type", &jobj2))
@@ -1747,7 +1746,7 @@ int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic)
return 0;
}
tmp += json_object_get_uint64(jobj_size);
tmp += crypt_jobj_get_uint64(jobj_size);
}
/* impossible, real device size must not be zero */
@@ -2157,7 +2156,12 @@ int LUKS2_activate(struct crypt_device *cd,
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
log_err(cd, _("Discard/TRIM is not supported."));
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
if (r)
return r;
@@ -2205,26 +2209,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 +2235,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 +2344,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 +2399,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++;
}
@@ -301,37 +300,25 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj))
return -EINVAL;
*offset = json_object_get_uint64(jobj);
*offset = crypt_jobj_get_uint64(jobj);
if (!json_object_object_get_ex(jobj_area, "size", &jobj))
return -EINVAL;
*length = json_object_get_uint64(jobj);
*length = crypt_jobj_get_uint64(jobj);
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,13 +536,17 @@ 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:
if (r < 0) {
crypt_free_volume_key(*vks);
*vks = NULL;
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -579,6 +579,13 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
} else
r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk);
if (r < 0) {
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -828,8 +835,8 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);

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
@@ -220,7 +220,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
return -EINVAL;
area_offset = json_object_get_uint64(jobj2);
area_offset = crypt_jobj_get_uint64(jobj2);
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL;
@@ -313,7 +313,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
return -EINVAL;
area_offset = json_object_get_uint64(jobj2);
area_offset = crypt_jobj_get_uint64(jobj2);
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL;
@@ -494,8 +494,8 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
@@ -607,7 +607,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tCipher: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "key_size", &jobj1);
log_std(cd, "\tCipher key: %u bits\n", json_object_get_uint32(jobj1) * 8);
log_std(cd, "\tCipher key: %u bits\n", crypt_jobj_get_uint32(jobj1) * 8);
json_object_object_get_ex(jobj_kdf, "type", &jobj1);
log_std(cd, "\tPBKDF: %s\n", json_object_get_string(jobj1));
@@ -617,7 +617,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tHash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_kdf, "iterations", &jobj1);
log_std(cd, "\tIterations: %" PRIu64 "\n", json_object_get_uint64(jobj1));
log_std(cd, "\tIterations: %" PRIu64 "\n", crypt_jobj_get_uint64(jobj1));
} else {
json_object_object_get_ex(jobj_kdf, "time", &jobj1);
log_std(cd, "\tTime cost: %" PRIu64 "\n", json_object_get_int64(jobj1));
@@ -640,10 +640,10 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tAF hash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "offset", &jobj1);
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
json_object_object_get_ex(jobj_area, "size", &jobj1);
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
return 0;
}

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
@@ -67,13 +67,13 @@ int reenc_keyslot_alloc(struct crypt_device *cd,
if (params->data_shift) {
json_object_object_add(jobj_area, "type", json_object_new_string("datashift"));
json_object_object_add(jobj_area, "shift_size", json_object_new_uint64(params->data_shift << SECTOR_SHIFT));
json_object_object_add(jobj_area, "shift_size", crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
} else
/* except data shift protection, initial setting is irrelevant. Type can be changed during reencryption */
json_object_object_add(jobj_area, "type", json_object_new_string("none"));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "type", json_object_new_string("reencrypt"));
json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(1)); /* useless but mandatory */
@@ -113,8 +113,8 @@ static int reenc_keyslot_store_data(struct crypt_device *cd,
!json_object_object_get_ex(jobj_area, "size", &jobj_length))
return -EINVAL;
area_offset = json_object_get_uint64(jobj_offset);
area_length = json_object_get_uint64(jobj_length);
area_offset = crypt_jobj_get_uint64(jobj_offset);
area_length = crypt_jobj_get_uint64(jobj_length);
if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
return -EINVAL;
@@ -242,14 +242,14 @@ static int reenc_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\t%-12s%d [bytes]\n", "Hash data:", json_object_get_int(jobj1));
} else if (!strcmp(json_object_get_string(jobj_resilience), "datashift")) {
json_object_object_get_ex(jobj_area, "shift_size", &jobj1);
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", json_object_get_uint64(jobj1));
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", crypt_jobj_get_uint64(jobj1));
}
json_object_object_get_ex(jobj_area, "offset", &jobj1);
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
json_object_object_get_ex(jobj_area, "size", &jobj1);
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
return 0;
}
@@ -304,7 +304,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
return -EINVAL;
if (!validate_json_uint32(jobj_sector_size))
return -EINVAL;
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (sector_size < SECTOR_SIZE || NOTPOW2(sector_size)) {
log_dbg(cd, "Invalid sector_size (%" PRIu32 ") for checksum resilience mode.", sector_size);
return -EINVAL;
@@ -313,7 +313,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
if (!(jobj_shift_size = json_contains(cd, jobj_area, "type:datashift", "Keyslot area", "shift_size", json_type_string)))
return -EINVAL;
shift_size = json_object_get_uint64(jobj_shift_size);
shift_size = crypt_jobj_get_uint64(jobj_shift_size);
if (!shift_size)
return -EINVAL;

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
@@ -91,8 +91,8 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
}
area_size = offs_b - offs_a;
json_object_object_add(jobj_area, "key_size", json_object_new_int(hdr_v1->keyBytes));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_size));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_size));
json_object_object_add(keyslot_obj, "area", jobj_area);
*keyslot_object = keyslot_obj;
@@ -145,7 +145,7 @@ static int json_luks1_segment(const struct luks_phdr *hdr_v1, struct json_object
/* offset field */
number = (uint64_t)hdr_v1->payloadOffset * SECTOR_SIZE;
field = json_object_new_uint64(number);
field = crypt_jobj_new_uint64(number);
if (!field) {
json_object_put(segment_obj);
return -ENOMEM;
@@ -401,8 +401,9 @@ static int json_luks1_object(struct luks_phdr *hdr_v1, struct json_object **luks
json_object_object_add(luks1_obj, "config", field);
json_size = LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN;
json_object_object_add(field, "json_size", json_object_new_uint64(json_size));
json_object_object_add(field, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(field, "json_size", crypt_jobj_new_uint64(json_size));
keyslots_size -= (keyslots_size % 4096);
json_object_object_add(field, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
*luks1_object = luks1_obj;
return 0;
@@ -418,8 +419,8 @@ static void move_keyslot_offset(json_object *jobj, int offset_add)
UNUSED(key);
json_object_object_get_ex(val, "area", &jobj_area);
json_object_object_get_ex(jobj_area, "offset", &jobj2);
offset = json_object_get_uint64(jobj2) + offset_add;
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
offset = crypt_jobj_get_uint64(jobj2) + offset_add;
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
}
}
@@ -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;
@@ -518,7 +519,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
int r;
json_object *jobj = NULL;
size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS;
uint64_t max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
/* for detached headers max size == device size */
if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size)))
@@ -539,11 +540,18 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
log_dbg(cd, "Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu",
max_size, luks1_size, luks1_shift);
if ((max_size - luks1_size) < luks1_shift) {
required_size = luks1_size + luks1_shift;
if ((max_size < required_size) &&
device_fallocate(crypt_metadata_device(cd), required_size)) {
log_err(cd, _("Unable to move keyslot area. Not enough space."));
return -EINVAL;
}
if (max_size < required_size)
max_size = required_size;
r = json_luks1_object(hdr1, &jobj, max_size - 2 * LUKS2_HDR_16K_LEN);
if (r < 0)
return r;
@@ -570,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;
@@ -579,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;
@@ -742,7 +764,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
return -EINVAL;
if (!json_object_object_get_ex(jobj_area, "offset", &jobj1))
return -EINVAL;
offset = json_object_get_uint64(jobj1);
offset = crypt_jobj_get_uint64(jobj1);
} else {
if (LUKS2_find_area_gap(cd, hdr2, key_size, &offset, &area_length))
return -EINVAL;
@@ -774,7 +796,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_kdf, "iterations", &jobj1))
continue;
hdr1->keyblock[i].passwordIterations = json_object_get_uint32(jobj1);
hdr1->keyblock[i].passwordIterations = crypt_jobj_get_uint32(jobj1);
if (!json_object_object_get_ex(jobj_kdf, "salt", &jobj1))
continue;
@@ -815,7 +837,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_digest, "iterations", &jobj1))
return -EINVAL;
hdr1->mkDigestIterations = json_object_get_uint32(jobj1);
hdr1->mkDigestIterations = crypt_jobj_get_uint32(jobj1);
if (!json_object_object_get_ex(jobj_digest, "digest", &jobj1))
return -EINVAL;
@@ -840,7 +862,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_segment, "offset", &jobj1))
return -EINVAL;
offset = json_object_get_uint64(jobj1) / SECTOR_SIZE;
offset = crypt_jobj_get_uint64(jobj1) / SECTOR_SIZE;
if (offset > UINT32_MAX)
return -EINVAL;
/* FIXME: LUKS1 requires offset == 0 || offset >= luks1_hdr_size */

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
@@ -165,7 +165,7 @@ static uint32_t reencrypt_alignment(struct luks2_hdr *hdr)
if (!json_object_object_get_ex(jobj_area, "sector_size", &jobj_sector_size))
return 0;
return json_object_get_uint32(jobj_sector_size);
return crypt_jobj_get_uint32(jobj_sector_size);
}
static json_object *_enc_create_segments_shift_after(struct crypt_device *cd,
@@ -200,13 +200,13 @@ static json_object *_enc_create_segments_shift_after(struct crypt_device *cd,
json_segment_remove_flag(jobj_seg_new, "in-reencryption");
tmp = rh->length;
} else {
json_object_object_add(jobj_seg_new, "offset", json_object_new_uint64(rh->offset + data_offset));
json_object_object_add(jobj_seg_new, "iv_tweak", json_object_new_uint64(rh->offset >> SECTOR_SHIFT));
json_object_object_add(jobj_seg_new, "offset", crypt_jobj_new_uint64(rh->offset + data_offset));
json_object_object_add(jobj_seg_new, "iv_tweak", crypt_jobj_new_uint64(rh->offset >> SECTOR_SHIFT));
tmp = json_segment_get_size(jobj_seg_new, 0) + rh->length;
}
/* alter size of new segment, reenc_seg == 0 we're finished */
json_object_object_add(jobj_seg_new, "size", reenc_seg > 0 ? json_object_new_uint64(tmp) : json_object_new_string("dynamic"));
json_object_object_add(jobj_seg_new, "size", reenc_seg > 0 ? crypt_jobj_new_uint64(tmp) : json_object_new_string("dynamic"));
json_object_object_add_by_uint(jobj_segs_post, reenc_seg, jobj_seg_new);
return jobj_segs_post;
@@ -256,7 +256,7 @@ static json_object *reencrypt_make_hot_segments_encrypt_shift(struct crypt_devic
jobj_seg_shrunk = NULL;
if (json_object_copy(LUKS2_get_segment_jobj(hdr, sg), &jobj_seg_shrunk))
goto err;
json_object_object_add(jobj_seg_shrunk, "size", json_object_new_uint64(segment_size - rh->length));
json_object_object_add(jobj_seg_shrunk, "size", crypt_jobj_new_uint64(segment_size - rh->length));
json_object_object_add_by_uint(jobj_segs_hot, sg++, jobj_seg_shrunk);
}
@@ -336,7 +336,7 @@ static json_object *reencrypt_make_post_segments_forward(struct crypt_device *cd
goto err;
jobj_old_seg = jobj_old_seg_copy;
fixed_length = rh->device_size - fixed_length;
json_object_object_add(jobj_old_seg, "size", json_object_new_uint64(fixed_length));
json_object_object_add(jobj_old_seg, "size", crypt_jobj_new_uint64(fixed_length));
} else
json_object_get(jobj_old_seg);
json_object_object_add_by_uint(jobj_segs_post, 1, jobj_old_seg);
@@ -491,7 +491,7 @@ static json_object *reencrypt_make_hot_segments_backward(struct crypt_device *cd
if (rh->offset) {
if (json_object_copy(LUKS2_get_segment_jobj(hdr, 0), &jobj_old_seg))
goto err;
json_object_object_add(jobj_old_seg, "size", json_object_new_uint64(rh->offset));
json_object_object_add(jobj_old_seg, "size", crypt_jobj_new_uint64(rh->offset));
json_object_object_add_by_uint(jobj_segs_hot, sg++, jobj_old_seg);
}
@@ -575,7 +575,7 @@ static uint64_t reencrypt_data_shift(struct luks2_hdr *hdr)
if (!json_object_object_get_ex(jobj_area, "shift_size", &jobj_data_shift))
return 0;
return json_object_get_uint64(jobj_data_shift);
return crypt_jobj_get_uint64(jobj_data_shift);
}
static crypt_reencrypt_mode_info reencrypt_mode(struct luks2_hdr *hdr)
@@ -824,7 +824,7 @@ static uint64_t reencrypt_length(struct crypt_device *cd,
uint64_t length_max)
{
unsigned long dummy, optimal_alignment;
uint64_t length;
uint64_t length, soft_mem_limit;
if (rh->rp.type == REENC_PROTECTION_NONE)
length = length_max ?: LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH;
@@ -835,6 +835,16 @@ static uint64_t reencrypt_length(struct crypt_device *cd,
else
length = keyslot_area_length;
/* hard limit */
if (length > LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH)
length = LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH;
/* soft limit is 1/4 of system memory */
soft_mem_limit = crypt_getphysmemory_kb() << 8; /* multiply by (1024/4) */
if (soft_mem_limit && length > soft_mem_limit)
length = soft_mem_limit;
if (length_max && length > length_max)
length = length_max;
@@ -940,6 +950,11 @@ static int reencrypt_context_init(struct crypt_device *cd, struct luks2_hdr *hdr
rh->fixed_length = false;
rh->length = reencrypt_length(cd, hdr, rh, area_length, params->max_hotzone_size << SECTOR_SHIFT);
if (!rh->length) {
log_dbg(cd, "Invalid reencryption length.");
return -EINVAL;
}
if (reencrypt_offset(hdr, rh->direction, device_size, &rh->length, &rh->offset)) {
log_dbg(cd, "Failed to get reencryption offset.");
return -EINVAL;
@@ -1386,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;
@@ -1421,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;
@@ -1777,14 +1792,15 @@ out:
* 2) can't we derive hotzone device name from crypt context? (unlocked name, device uuid, etc?)
*/
static int reencrypt_load_overlay_device(struct crypt_device *cd, struct luks2_hdr *hdr,
const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size)
const char *overlay, const char *hotzone, struct volume_key *vks, uint64_t size,
uint32_t flags)
{
char hz_path[PATH_MAX];
int r;
struct device *hz_dev = NULL;
struct crypt_dm_active_device dmd = {
.flags = CRYPT_ACTIVATE_KEYRING_KEY,
.flags = flags,
};
log_dbg(cd, "Loading new table for overlay device %s.", overlay);
@@ -1868,15 +1884,12 @@ err:
}
static int reencrypt_swap_backing_device(struct crypt_device *cd, const char *name,
const char *new_backend_name, uint32_t flags)
const char *new_backend_name)
{
int r;
struct device *overlay_dev = NULL;
char overlay_path[PATH_MAX] = { 0 };
struct crypt_dm_active_device dmd = {
.flags = flags,
};
struct crypt_dm_active_device dmd = {};
log_dbg(cd, "Redirecting %s mapping to new backing device: %s.", name, new_backend_name);
@@ -1902,7 +1915,7 @@ static int reencrypt_swap_backing_device(struct crypt_device *cd, const char *na
r = dm_reload_device(cd, name, &dmd, 0, 0);
if (!r) {
log_dbg(cd, "Resuming device %s", name);
r = dm_resume_device(cd, name, dmd.flags);
r = dm_resume_device(cd, name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
}
out:
@@ -1971,7 +1984,7 @@ static int reencrypt_init_device_stack(struct crypt_device *cd,
}
/* swap origin mapping to overlay device */
r = reencrypt_swap_backing_device(cd, rh->device_name, rh->overlay_name, CRYPT_ACTIVATE_KEYRING_KEY);
r = reencrypt_swap_backing_device(cd, rh->device_name, rh->overlay_name);
if (r) {
log_err(cd, _("Failed to load new mapping for device %s."), rh->device_name);
goto err;
@@ -2033,9 +2046,10 @@ static int reencrypt_refresh_overlay_devices(struct crypt_device *cd,
const char *overlay,
const char *hotzone,
struct volume_key *vks,
uint64_t device_size)
uint64_t device_size,
uint32_t flags)
{
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size);
int r = reencrypt_load_overlay_device(cd, hdr, overlay, hotzone, vks, device_size, flags);
if (r) {
log_err(cd, _("Failed to reload device %s."), overlay);
return REENC_ERR;
@@ -2223,8 +2237,9 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
else {
if (LUKS2_digest_verify_by_digest(cd, hdr, digest_new, vk) != digest_new)
return -EINVAL;
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
if (r)
if (crypt_use_keyring_for_vk(cd) &&
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
return r;
}
}
@@ -2239,8 +2254,8 @@ static int reencrypt_verify_and_upload_keys(struct crypt_device *cd, struct luks
r = -EINVAL;
goto err;
}
r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
if (r)
if (crypt_use_keyring_for_vk(cd) &&
(r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk))))
goto err;
}
}
@@ -2516,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;
@@ -2531,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;
@@ -2567,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)
{
@@ -2590,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."));
@@ -2637,6 +2671,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
uint64_t minimal_size, device_size, mapping_size = 0, required_size = 0;
bool dynamic;
struct crypt_params_reencrypt rparams = {};
uint32_t flags = 0;
if (params) {
rparams = *params;
@@ -2693,6 +2728,7 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
DM_ACTIVE_CRYPT_CIPHER, &dmd_target);
if (r < 0)
goto err;
flags = dmd_target.flags;
r = LUKS2_assembly_multisegment_dmd(cd, hdr, *vks, LUKS2_get_segments_jobj(hdr), &dmd_source);
if (!r) {
@@ -2767,6 +2803,8 @@ static int reencrypt_load_by_passphrase(struct crypt_device *cd,
}
}
rh->flags = flags;
MOVE_REF(rh->vks, *vks);
MOVE_REF(rh->reenc_lock, reencrypt_lock);
@@ -2790,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."));
@@ -2917,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;
@@ -2968,7 +3006,7 @@ static reenc_status_t reencrypt_step(struct crypt_device *cd,
}
if (online) {
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size);
r = reencrypt_refresh_overlay_devices(cd, hdr, rh->overlay_name, rh->hotzone_name, rh->vks, rh->device_size, rh->flags);
/* Teardown overlay devices with dm-error. None bio shall pass! */
if (r != REENC_OK)
return r;
@@ -3092,6 +3130,7 @@ static int reencrypt_wipe_moved_segment(struct crypt_device *cd, struct luks2_hd
static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr, struct luks2_reenc_context *rh)
{
int i, r;
uint32_t dmt_flags;
bool finished = !(rh->device_size > rh->progress);
if (rh->rp.type == REENC_PROTECTION_NONE &&
@@ -3101,16 +3140,20 @@ static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr,
}
if (rh->online) {
r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, CRYPT_ACTIVATE_KEYRING_KEY | CRYPT_ACTIVATE_SHARED);
r = LUKS2_reload(cd, rh->device_name, rh->vks, rh->device_size, rh->flags);
if (r)
log_err(cd, _("Failed to reload device %s."), rh->device_name);
if (!r) {
r = dm_resume_device(cd, rh->device_name, 0);
r = dm_resume_device(cd, rh->device_name, DM_SUSPEND_SKIP_LOCKFS | DM_SUSPEND_NOFLUSH);
if (r)
log_err(cd, _("Failed to resume device %s."), rh->device_name);
}
dm_remove_device(cd, rh->overlay_name, 0);
dm_remove_device(cd, rh->hotzone_name, 0);
if (!r && finished && rh->mode == CRYPT_REENCRYPT_DECRYPT &&
!dm_flags(cd, DM_LINEAR, &dmt_flags) && (dmt_flags & DM_DEFERRED_SUPPORTED))
dm_remove_device(cd, rh->device_name, CRYPT_DEACTIVATE_DEFERRED);
}
if (finished) {
@@ -3342,7 +3385,7 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
uint64_t minimal_size, device_size;
int keyslot, r = -EINVAL;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
struct volume_key *vk, *_vks = NULL;
struct volume_key *vk = NULL, *_vks = NULL;
log_dbg(cd, "Entering reencryption crash recovery.");
@@ -3355,12 +3398,14 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
goto err;
keyslot = r;
vk = _vks;
if (crypt_use_keyring_for_vk(cd))
vk = _vks;
while (vk) {
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
@@ -55,7 +55,7 @@ uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise)
!json_object_object_get_ex(jobj_segment, "offset", &jobj))
return 0;
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
}
const char *json_segment_type(json_object *jobj_segment)
@@ -77,7 +77,7 @@ uint64_t json_segment_get_iv_offset(json_object *jobj_segment)
!json_object_object_get_ex(jobj_segment, "iv_tweak", &jobj))
return 0;
return json_object_get_uint64(jobj);
return crypt_jobj_get_uint64(jobj);
}
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
@@ -88,7 +88,7 @@ uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
!json_object_object_get_ex(jobj_segment, "size", &jobj))
return 0;
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
}
const char *json_segment_get_cipher(json_object *jobj_segment)
@@ -229,8 +229,8 @@ static json_object *_segment_create_generic(const char *type, uint64_t offset, c
return NULL;
json_object_object_add(jobj, "type", json_object_new_string(type));
json_object_object_add(jobj, "offset", json_object_new_uint64(offset));
json_object_object_add(jobj, "size", length ? json_object_new_uint64(*length) : json_object_new_string("dynamic"));
json_object_object_add(jobj, "offset", crypt_jobj_new_uint64(offset));
json_object_object_add(jobj, "size", length ? crypt_jobj_new_uint64(*length) : json_object_new_string("dynamic"));
return jobj;
}
@@ -252,7 +252,7 @@ json_object *json_segment_create_crypt(uint64_t offset,
if (!jobj)
return NULL;
json_object_object_add(jobj, "iv_tweak", json_object_new_uint64(iv_offset));
json_object_object_add(jobj, "iv_tweak", crypt_jobj_new_uint64(iv_offset));
json_object_object_add(jobj, "encryption", json_object_new_string(cipher));
json_object_object_add(jobj, "sector_size", json_object_new_int(sector_size));
if (reencryption)

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 */
@@ -224,7 +230,7 @@ int init_crypto(struct crypt_device *ctx)
return r;
}
r = crypt_backend_init(ctx);
r = crypt_backend_init();
if (r < 0)
log_err(ctx, _("Cannot initialize crypto backend."));
@@ -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;
@@ -510,6 +521,11 @@ int PLAIN_activate(struct crypt_device *cd,
log_dbg(cd, "Trying to activate PLAIN device %s using cipher %s.",
name, crypt_get_cipher_spec(cd));
if (MISALIGNED(size, device_block_size(cd, crypt_data_device(cd)) >> SECTOR_SHIFT)) {
log_err(cd, _("Device size is not aligned to device logical block size."));
return -EINVAL;
}
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd),
crypt_get_data_offset(cd), crypt_get_integrity(cd),
@@ -567,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;
@@ -659,10 +678,10 @@ int crypt_init_data_device(struct crypt_device **cd, const char *device, const c
return -EINVAL;
r = crypt_init(cd, device);
if (r || !data_device)
if (r || !data_device || !strcmp(device, data_device))
return r;
log_dbg(NULL, "Setting ciphertext data device to %s.", data_device ?: "(none)");
log_dbg(NULL, "Setting ciphertext data device to %s.", data_device);
r = _crypt_set_data_device(*cd, data_device);
if (r) {
crypt_free(*cd);
@@ -721,9 +740,6 @@ out:
free(type);
LUKS2_hdr_free(cd, &hdr2);
}
/* FIXME: why? */
crypt_memzero(&hdr2, sizeof(hdr2));
return r;
}
@@ -758,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;
}
@@ -798,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;
}
@@ -817,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;
}
@@ -881,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;
}
@@ -917,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;
@@ -960,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)
@@ -982,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;
@@ -1081,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)) {
@@ -1090,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;
@@ -1242,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);
@@ -1264,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;
@@ -1295,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);
@@ -1408,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
@@ -1419,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);
@@ -2085,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;
@@ -2141,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;
@@ -2149,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;
@@ -2696,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;
@@ -2750,6 +2820,12 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
goto out;
}
if (MISALIGNED(new_size, device_block_size(cd, crypt_data_device(cd)) >> SECTOR_SHIFT)) {
log_err(cd, _("Device size is not aligned to device logical block size."));
r = -EINVAL;
goto out;
}
dmd.uuid = crypt_get_uuid(cd);
dmd.size = new_size;
dmd.flags = dmdq.flags | CRYPT_ACTIVATE_REFRESH;
@@ -2891,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)
@@ -2927,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);
}
@@ -3136,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);
@@ -3167,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
*/
@@ -3610,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;
@@ -3632,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)
{
@@ -3706,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;
@@ -3819,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."));
@@ -3963,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:
@@ -4103,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,
@@ -4198,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;
@@ -4232,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;
}
@@ -4245,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;
@@ -4284,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);
@@ -4404,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)
@@ -4434,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;
}
@@ -4464,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."));
@@ -4502,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
*/
@@ -4621,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;
@@ -4639,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;
@@ -4669,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;
@@ -4699,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;
@@ -4773,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;
}
@@ -4833,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;
@@ -5014,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;
}
@@ -5133,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;
}
@@ -5585,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;
}
@@ -5613,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;
@@ -5759,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,39 @@ 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 &&
params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
keyfiles_pool_length = VCRYPT_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 +628,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 +756,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 +868,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
@@ -48,6 +48,12 @@ int crypt_benchmark(struct crypt_device *cd,
if (posix_memalign(&buffer, crypt_getpagesize(), buffer_size))
goto out;
r = crypt_cipher_ivsize(cipher, cipher_mode);
if (r >= 0 && iv_size != (size_t)r) {
log_dbg(cd, "IV length for benchmark adjusted to %i bytes (requested %zu).", r, iv_size);
iv_size = r;
}
if (iv_size) {
iv = malloc(iv_size);
if (!iv)
@@ -71,9 +77,9 @@ 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);
else if (r)
log_dbg(cd, "Cannot initialize cipher %s, mode %s, key size %zu, IV size %zu.",
cipher, cipher_mode, volume_key_size, iv_size);
out:
free(buffer);
free(key);

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
@@ -307,3 +307,17 @@ int blk_supported(void)
#endif
return r;
}
off_t blk_get_offset(struct blkid_handle *h)
{
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);
} else if (blk_is_partition(h) && !blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
offset_value = strtoll(offset, NULL, 10);
#endif
return offset_value;
}

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
@@ -59,4 +59,6 @@ int blk_do_wipe(struct blkid_handle *h);
int blk_supported(void);
off_t blk_get_offset(struct blkid_handle *h);
#endif

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
@@ -63,8 +63,14 @@ static inline uint32_t act2dmflags(uint32_t act_flags)
#define DM_DEFERRED_SUPPORTED (1 << 15) /* deferred removal of device */
#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 */
#define DM_INTEGRITY_DISCARDS_SUPPORTED (1 << 23) /* dm-integrity discards/TRIM option is 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);
@@ -109,6 +115,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) */
@@ -137,10 +144,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;
@@ -174,9 +185,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,
@@ -184,6 +196,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
@@ -252,7 +252,12 @@ static char *_sysfs_backing_file(const char *loop)
char *crypt_loop_backing_file(const char *loop)
{
char *bf = _sysfs_backing_file(loop);
char *bf;
if (!crypt_loop_device(loop))
return NULL;
bf = _sysfs_backing_file(loop);
return bf ?: _ioctl_backing_file(loop);
}

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>
@@ -161,7 +163,7 @@ above in LUKS2 metadata (only after successful refresh operation).
in dm-crypt driver.
.PP
\fIreencrypt\fR <device> or --active-name <name>
\fIreencrypt\fR <device> or --active-name <name> [<new_name>]
.IP
Run resilient reencryption (LUKS2 device only).
@@ -191,6 +193,10 @@ If the reencryption process was interrupted abruptly (reencryption process crash
it may require recovery. The recovery is currently run automatically on next activation (action \fIopen\fR)
when needed.
Optional parameter <new_name> takes effect only with \-\-encrypt option and it activates device <new_name>
immediately after encryption initialization gets finished. That's useful when device needs to be ready
as soon as possible and mounted (used) before full data area encryption is completed.
Action supports following additional \fB<options>\fR [\-\-encrypt, \-\-decrypt, \-\-device\-size,
\-\-resilience, \-\-resilience-hash, \-\-hotzone-size, \-\-init\-only, \-\-resume\-only,
\-\-reduce\-device\-size].
@@ -484,14 +490,18 @@ master key is dumped to a file instead of standard output. Beware that the
master key cannot be changed without reencryption and can be used to decrypt
the data stored in the LUKS container without a passphrase and even without the
LUKS header. This means that if the master key is compromised, the whole device
has to be erased to prevent further access. Use this option carefully.
has to be erased or reencrypted to prevent further access. Use this option carefully.
To dump the master key, a passphrase has to be supplied,
either interactively or via \-\-key\-file.
To dump unbound key (LUKS2 format only), \-\-unbound parameter, specific \-\-key-slot
id and proper passphrase has to be supplied, either interactively or via \-\-key\-file.
Optional \-\-master\-key\-file parameter enables unbound keyslot dump to a file.
\fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
\-\-keyfile\-offset, \-\-keyfile\-size, \-\-header, \-\-disable\-locks,
\-\-master\-key\-file, \-\-type].
\-\-master\-key\-file, \-\-type, \-\-unbound, \-\-key-slot].
\fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
and the argument to \-\-key\-file is '-', no validation question
@@ -739,6 +749,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>
@@ -1124,6 +1175,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
@@ -1189,7 +1241,7 @@ with the \-\-header option. Use with care.
.TP
.B "\-\-header\-backup\-file <file>"
Specify file with header backup for \fIluksHeaderBackup\fR or
\fIluksHeaderBackup\fR actions.
\fIluksHeaderRestore\fR actions.
.TP
.B "\-\-force\-password"
Do not use password quality checking for new LUKS passwords.
@@ -1320,8 +1372,9 @@ integrity tag.
.TP
.B "\-\-unbound"
Creates new LUKS2 unbound keyslot. See \fIluksAddKey\fR action for more
details.
Creates new or dumps existing LUKS2 unbound keyslot. See \fIluksAddKey\fR or
\fIluksDump\fR actions for more details.
.TP
.B "\-\-tcrypt\-hidden"
.B "\-\-tcrypt\-system"
@@ -1572,6 +1625,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.
@@ -1632,9 +1688,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

@@ -33,7 +33,7 @@ Open a mapping with <name> backed by device <device>.
\fB<options>\fR can be [\-\-data\-device, \-\-batch\-mode, \-\-journal\-watermark,
\-\-journal\-commit\-time, \-\-buffer\-sectors, \-\-integrity, \-\-integrity\-key\-size,
\-\-integrity\-key\-file, \-\-integrity\-no\-journal, \-\-integrity\-recalculate,
\-\-integrity\-recovery\-mode]
\-\-integrity\-recovery\-mode, \-\-allow\-discards]
.PP
\fIclose\fR <name>
@@ -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.
@@ -174,6 +174,10 @@ The size of the journal encryption key.
.B "\-\-journal\-crypt\-key\-file FILE"
The file with the journal encryption key.
.TP
.B "\-\-allow\-discards\fR"
Allow the use of discard (TRIM) requests for the device.
This option is available since the Linux kernel version 5.7.
.TP
The dm-integrity target is available since Linux kernel version 4.12.
.TP
\fBNOTE:\fR
@@ -223,9 +227,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.

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