Compare commits

..

125 Commits

Author SHA1 Message Date
Milan Broz
b4e9252270 Redirect lib API docs. 2018-12-19 11:57:40 +01:00
Milan Broz
21c4d1507a Update README.md. 2018-12-03 10:36:39 +01:00
Milan Broz
3e763e1cd2 Update LUKS2 docs. 2018-12-03 09:34:35 +01:00
Milan Broz
060c807bc8 Add 2.0.6 release notes. 2018-12-03 09:34:27 +01:00
Milan Broz
0f82f90e14 Update po files. 2018-12-02 19:00:56 +01:00
Ondrej Kozina
66b6808cb8 Add validation tests for non-default metadata. 2018-12-02 18:58:36 +01:00
Ondrej Kozina
99b3a69e52 Update LUKS2 test images.
- update test images for validation fixes
  from previous commits

- erase leftover json data in between secondary
  header and keyslot areas.
2018-11-28 17:05:34 +01:00
Ondrej Kozina
1a940a49cb Remove redundant check in keyslot areas validation.
Due to previous fix it's no longer needed to add
all keyslot area lengths and check if result sum
is lower than keyslots_size.

(We already check lower limit, upper limit and
overlapping areas)
2018-11-28 17:05:02 +01:00
Ondrej Kozina
645c8b6026 Fix keyslot areas validation.
This commit fixes two problems:

a) Replace hardcoded 16KiB metadata variant as lower limit
   for keyslot area offset with current value set in config
   section (already validated).

b) Replace segment offset (if not zero) as upper limit for
   keyslot area offset + size with value calculated as
   2 * metadata size + keyslots_size as acquired from
   config section (also already validated)
2018-11-28 17:03:34 +01:00
Ondrej Kozina
00fc4beac1 Reshuffle config and keyslots areas validation code.
Swap config and keyslot areas validation code order.

Also split original keyslots_size validation code in
between config and keyslot areas routines for furhter
changes in the code later. This commit has no funtional
impact.
2018-11-28 17:00:55 +01:00
Ondrej Kozina
b220bef821 Do not validate keyslot areas so frantically.
Keyslot areas were validated from each keyslot
validation routine and later one more time
in general header validation routine. The call
from header validation routine is good enough.
2018-11-28 16:55:20 +01:00
Ondrej Kozina
d1cfdc7fd7 Test cryptsetup can handle all LUKS2 metadata variants.
following tests:

add keyslot
test passphrase
unlock device
store token in metadata
read token from metadata
2018-11-27 22:35:00 +01:00
Ondrej Kozina
ccfbd302bd Add LUKS2 metadata test images.
Test archive contains images with all supported
LUKS2 metadata size configurations. There's
one active keyslot 0 in every image that can be
unlocked with following passphrase (ignore
quotation marks): "Qx3qn46vq0v"
2018-11-27 22:34:51 +01:00
Ondrej Kozina
0dda2b0e33 Add validation tests for non-default json area size.
Test both primary and secondary header validation tests
with non-default LUKS2 json area size.

Check validation rejects config.keyslots_size with zero value.

Check validation rejects mismatching values for metadata size
set in binary header and in config json section.
2018-11-27 22:34:35 +01:00
Ondrej Kozina
4e70b9ce16 Extend baseline LUKS2 validation image to 16 MiBs. 2018-11-27 22:34:10 +01:00
Ondrej Kozina
7d8a62b7d5 Move some validation tests in new section. 2018-11-27 22:33:56 +01:00
Ondrej Kozina
b383e11372 Drop needless size restriction on keyslots size. 2018-11-27 11:54:35 +01:00
Milan Broz
a6e9399f7b Update POTFILES. 2018-11-25 16:03:40 +01:00
Milan Broz
e4fd2fafed Fix signed/unsigned comparison warning. 2018-11-25 15:12:22 +01:00
Milan Broz
e31b20d8d8 Set 2.0.6 version. 2018-11-25 15:04:24 +01:00
Milan Broz
838c91fef3 Update po file. 2018-11-25 15:03:23 +01:00
Milan Broz
be8c39749f Fix setting of integrity persistent flags (no-journal).
We have to query and set flags also for underlying dm-integrity device,
otherwise activation flags applied there are ignored.
2018-11-25 15:01:29 +01:00
Milan Broz
cec5f8a8bf Check for algorithms string lengths in crypt_cipher_check().
The kernel check will fail anyway if string is truncated, but this
make some compilers more happy.
2018-11-25 15:01:14 +01:00
Milan Broz
f6dde0f39e Fix LUKS2_hdr_validate funtion definition. 2018-11-25 15:00:58 +01:00
Milan Broz
2f265f81e7 Properly handle interrupt in cryptsetup-reencrypt and remove log.
Fixes #419.
2018-11-25 15:00:43 +01:00
Milan Broz
9da865e685 Fix sector-size tests for older kernels. 2018-11-25 15:00:28 +01:00
Milan Broz
8d4e794d39 Check for device size and sector size misalignment.
Kernel prevents activation of device that is not aligned
to requested sector size.

Add early check to plain and LUKS2 formats to disallow
creation of such a device.
(Activation will fail in kernel later anyway.)

Fixes #390.
2018-11-25 15:00:12 +01:00
Milan Broz
018486cea0 Add support for Adiantum cipher mode. 2018-11-25 14:57:25 +01:00
Milan Broz
96a3dc0a66 Try to check if AEAD cipher is available through kernel crypto API. 2018-11-25 14:42:50 +01:00
Milan Broz
efeada291a Fix unsigned return value. 2018-11-25 14:29:09 +01:00
Milan Broz
fb6935385c Properly propagate error from AF diffuse function. 2018-11-25 14:28:31 +01:00
Milan Broz
599748bc9f Check hash value in pbkdf setting early. 2018-11-25 14:27:59 +01:00
Milan Broz
d0d507e325 Fallback to default keyslot algorithm if backend does not know the cipher. 2018-11-25 14:27:37 +01:00
Ondrej Kozina
7d8f64fe21 Remove unused crypt_dm_active_device member. 2018-11-25 14:27:11 +01:00
Ondrej Kozina
a52dbc43d3 Secondary header offset must match header size. 2018-11-25 14:26:53 +01:00
Ondrej Kozina
7df458b74e Check json size matches value from binary LUKS2 header.
We have max json area length parameter stored twice. In
LUKS2 binary header and in json metadata. Those two values
must match.
2018-11-25 14:26:38 +01:00
Ondrej Kozina
bcd7527938 Change max json area length type to unsigned.
We use uint64_t for max json length everywhere else
including config.json_size field in LUKS2 metadata.

Also renames some misleading parameter names.
2018-11-25 14:26:23 +01:00
Ondrej Kozina
e7141383e3 Enable all supported metadata sizes in LUKS2 validation code.
LUKS2 specification allows various size of LUKS2 metadata.
The single metadata instance is composed of LUKS2 binary header
(4096 bytes) and immediately following json area. The resulting
assembled metadata size have to be one of following values,
all in KiB:

16, 32, 64, 128, 256, 512, 1024, 2048 or 4096
2018-11-25 14:25:59 +01:00
Milan Broz
cd968551d6 Add workaround for benchmarking Adiantum cipher. 2018-11-25 14:24:37 +01:00
Milan Broz
6a3e585141 Fix ext4 image to work without CONFIG_LBDAF. 2018-11-25 14:24:02 +01:00
Milan Broz
6f48bdf9e5 Add branch v2_0_x to Travis. 2018-11-19 13:26:41 +01:00
Milan Broz
517b5da67a Version 2.0.5. 2018-10-28 15:30:25 +01:00
Milan Broz
98460af44f Update LUKS2 docs. 2018-10-28 15:27:55 +01:00
Milan Broz
7213d5a76b Fix verbose message about key removal in luksKillSlot,luksErase and luksKremoveKey.
The crypt_keyslot_destroy() does not return keyslot number,
so return value 0 was always used as a keyslot reference.
2018-10-27 17:44:38 +02:00
Ondrej Kozina
bb29c5b322 Update man section describing convert command.
Fixes #414.
2018-10-26 10:07:41 +02:00
Milan Broz
58ad7bae48 Add 2.0.5 release notes. 2018-10-22 12:23:54 +02:00
Milan Broz
82a3480b12 Update po files. 2018-10-21 12:30:34 +02:00
Ondrej Kozina
c00811a846 Run LUKS2 validation code before header areas wiping.
Also drops redundant checks peformed in general validation code.
2018-10-18 08:48:48 +02:00
Milan Broz
27eaf46c8a Fix issues found by Coverity scan.
- possible overflow of data offset calculation in wipe and
- dereferencing of pointer in a keyring error path.
2018-10-14 21:50:06 +02:00
Milan Broz
202aeece3c Fix test module inclusion in tarball. 2018-10-14 20:54:06 +02:00
Milan Broz
825fc895dc Fix some signed/unsigned comparison warnings. 2018-10-14 20:36:45 +02:00
Milan Broz
a74aecedf1 Set devel version. 2018-10-14 20:24:34 +02:00
Milan Broz
fa1f63bcd0 Update po files. 2018-10-14 20:23:32 +02:00
Milan Broz
c2bce3e93e Wipe full header areas (including unused) during LUKS format.
All previous version of cryptsetup wiped only first 4k for LUKS1
and both JSON areas for LUKS2 (first 32k) and the allocated
keyslot area (as it contained the generated key).

Remaining areas (unused keyslots, padding, and alignment) were
not wiped and could contain some previous data.

Since this commit, the whole area up to the data offset is zeroed,
and subsequently, all keyslots areas are wiped with random data.

Only exceptions are
 - padding/alignment areas for detached header
   if the data offset is set to 0
 - bogus LUKS1 keyslot areas (upstream code never
   created such keyslots but someone could use that).

This operation could slow down luksFormat on some devices, but
it guarantees that after this operation LUKS header does not
contain any foreign data.
2018-10-14 13:11:50 +02:00
Milan Broz
a46733e701 Reintroduce error message if LUKS device is not detected.
Older cryptsetup printed this message through library,
later it disappeared even in cryptsetup binary.
2018-10-13 10:13:29 +02:00
Milan Broz
8f350f9b9f Print error message if crypt_load() detects unsupported version of LUKS. 2018-10-12 12:34:43 +02:00
Milan Broz
484692aacd Do not ask wiping questions in format if we just created the file. 2018-10-12 12:24:42 +02:00
Milan Broz
7f0df99511 Properly parse errno to error message for devices. 2018-10-12 12:03:56 +02:00
Milan Broz
bebd2fe7e7 Do not print error for used device twice. 2018-10-12 12:03:54 +02:00
Milan Broz
36e8839675 Do not fail if device is smaller than requested wipe size. 2018-10-11 21:20:34 +02:00
Ondrej Kozina
61305a50c1 Add delay=0 parameter to scsi_debug in all tests.
Speed up tests significantly.
2018-10-11 16:21:36 +02:00
Milan Broz
1d7749a40f Show better errors if kesylot decryption fails.
This happens also in cipher check where the old message was
very confusing.
2018-10-11 15:41:35 +02:00
Milan Broz
f01d044618 Print file name size instead of a loop device in error messages. 2018-10-11 15:40:22 +02:00
Milan Broz
31532adf86 Do not copy buffer if read fails. 2018-10-11 15:39:31 +02:00
Milan Broz
879e06db39 Wiping empty device should not fail. 2018-10-11 15:38:56 +02:00
Milan Broz
4beb0f702a Do not allow device activation if data area overlaps with LUKS header. 2018-10-11 11:55:45 +02:00
Ondrej Kozina
a771460dbd Add validation tests for optional segment flags section. 2018-10-11 11:55:26 +02:00
Ondrej Kozina
f849f83d84 Add validation code for option flags section of segment. 2018-10-11 11:55:22 +02:00
Ondrej Kozina
1d084a41ad Add support for optional flags section in LUKS2 segments dump. 2018-10-11 11:55:18 +02:00
Ondrej Kozina
c4198986f1 Sort LUKS2 segments by keys in crypt_dump output. 2018-10-11 11:55:13 +02:00
Milan Broz
7514786b20 Add an error message if device is unusable. 2018-10-04 20:00:12 +02:00
Milan Broz
9df042c0b8 Use explicit_bzero if available. 2018-10-04 15:21:01 +02:00
Ondrej Kozina
37e0150f70 Do not use fallocate in blockwise tests.
fs driver may skip some sanity checks if it's aware the content
of file is uninitialized.

Fixes warnings for xfs in kernel 4.19+
2018-10-04 11:20:03 +02:00
Milan Broz
294e4cbcb7 Fix tcrypt test on very old distros. 2018-10-02 13:56:57 +02:00
Milan Broz
952716afe1 Report versions in test run. 2018-10-02 13:46:03 +02:00
Milan Broz
24aba9a514 tcrypt: Support additional Veracrypt modes.
Add support for Camellia and Kuznyechik ciphers and Streebog hash functions,
introduced in recent Veracrypt.

Note, that Kuznyechik requires out-of-tree kernel module and Streebog
hash function is available only with gcrypt backend.
2018-10-02 10:47:38 +02:00
Milan Broz
905993751c Fix integritysetup build. 2018-09-29 18:28:10 +02:00
Milan Broz
0b10d877b0 Some more gcc warnings fixes. 2018-09-29 17:32:33 +02:00
Milan Broz
874fa5810d Do not use local libutils. 2018-09-29 10:42:05 +02:00
Milan Broz
5be31bbce6 More warnings fixes. 2018-09-27 20:54:06 +02:00
Milan Broz
a6e3a31690 Workaround for some gcc8 warnings.
Some new string length checks are too clever now...
2018-09-27 13:25:52 +02:00
Milan Broz
506f3f7b57 Decrease memory limit for pbkdf test. 2018-09-26 10:48:31 +02:00
Ondrej Kozina
cd1c36ef94 Allow passphrase change for unbound keyslots.
Also fixes small typo in API.

Fixes #409.
2018-09-25 13:13:31 +02:00
Ondrej Kozina
ee689d88b4 Add blkid scan when attemting to open plain device.
Warn user about existing device signatures on candidate ciphertext
device and prompt for action confirmation.

Fixes #411.
2018-09-25 13:13:18 +02:00
Ondrej Kozina
b93b676336 Move blkid scan after device context initialization.
Fixes bug with misleading error message when target device
does not exist.
2018-09-25 08:55:24 +02:00
Ondrej Kozina
1c6d66fccc Emit error message for converting inactive keyslot.
Fixes: #416.
2018-09-25 08:53:48 +02:00
Ondrej Kozina
114356ad2e Properly load new device context after header restore. 2018-09-25 08:53:26 +02:00
Ondrej Kozina
7ab419701c Rename get_key_size_strlen() to int_log10().
because that's what the function does
2018-09-25 08:52:29 +02:00
Ondrej Kozina
d41b1a7560 Unify checks for misaligned values. 2018-09-25 08:51:51 +02:00
Ondrej Kozina
622943529e Wipe LUKS header if luksFormat fails to add first keyslot. 2018-09-25 08:45:03 +02:00
Ondrej Kozina
9d7cc152f9 Do not enforce iv_tweak alignment in LUKS2 validation.
1) iv_tweak is not in 'bytes'
2) it may be arbitrary number
3) there's no reason to enforce alignment to encryption sector size

Fixes #406.
2018-09-25 08:44:31 +02:00
Milan Broz
3f73d448f3 Retry temporary device removal in align test. 2018-09-10 15:53:27 +02:00
Milan Broz
a1b606803f Fix HMAC vector test exit value. 2018-09-05 14:38:16 +02:00
Michal Virgovič
b2c7b40568 Add test vectors for HMAC - sha1, sha256, sha512. 2018-09-05 14:17:25 +02:00
Milan Broz
0cbe09d43a Rephrase LUKS info. 2018-09-03 15:16:31 +02:00
Milan Broz
f1d5b94762 Run API tests without verbose flag by default.
And rename some tests.
2018-08-10 12:36:15 +02:00
Ondrej Kozina
6fc2e7c774 Skip pbkdf benchmark in align-test (test speedup). 2018-08-10 08:20:00 +02:00
Ondrej Kozina
3b39c1d1ef Fix data alignment test in compat-test2.
Alignment should not expected failure when --align-payload is not
aligned to encryption sector size.
2018-08-10 08:19:49 +02:00
Ondrej Kozina
5a3e4abf71 Add basic LUKS2 align test. 2018-08-10 08:19:38 +02:00
Ondrej Kozina
48e9362186 Do not enforce encryption sector size alignment on data offset.
crypt segment data offset has nothing to do with encryption sector
size. The device may hint alignment offset which is completely
unrelated and LUKS2 validation blocks it.
2018-08-10 08:19:17 +02:00
Ondrej Kozina
03a74b74e5 Revert "Fix data alignment calculations with custom encryption sector size."
This reverts commit 71dd149ca2.

Enforcing data alignment to be encryption sector size aligned
is completelly wrong. The underlying data device alignment
has nothing to do with dm-crypt internal encryption sector size.

The restriction is however valid for dm-crypt segment size.
2018-08-10 08:19:02 +02:00
Ondrej Kozina
248f99cad3 Data alignment is always 512B sectors count. 2018-08-10 08:18:18 +02:00
Ondrej Kozina
d2f0773eb8 Remove useless division followed by multiplication by same base. 2018-08-10 08:16:27 +02:00
Ondrej Kozina
dd36d56d47 Fix miscalculation of device alignment offset.
device_topology_alignment routine already returns alignment offset
in bytes. There's no need to divide it by sector size, since LUKS2
format have all offsets and sizes stored in bytes.
2018-08-10 08:15:01 +02:00
Milan Broz
0270fc66a1 Fix align test.
Seems that the forced alignment value was never properly used...
2018-08-09 13:53:48 +02:00
Milan Broz
69a844c654 Remove O_SYNC from device open and use fsync().
This speed up wipe operation considerably.
2018-08-09 12:01:20 +02:00
Ondrej Kozina
5b5a64361f Update blockwise-compat test.
Issue warning in case of failure with file-systems based
tests.

Mute the test so that it prints out messages only for 'warning'
and 'fail' results.
2018-08-08 21:48:10 +02:00
Milan Broz
26f6d1cb10 Create --master-key-file in luksDump and fail if file already exists.
For some reason the volume key file have to exists.

Let's change the logic to the same as for luksBackupHeader
(a file is created and operation fails if it already exists).
2018-08-08 14:32:15 +02:00
Ondrej Kozina
f87eb1668a Allow compat-test2 to run with larger LUKS2 header size. 2018-08-08 12:55:29 +02:00
Milan Broz
3114abfd55 Remove not needed -Z option from diff that is not present on older systems. 2018-08-08 10:43:03 +02:00
Ondrej Kozina
5a94cff91e Do not fail device-test with larger LUKS2 header. 2018-08-08 10:13:40 +02:00
Ondrej Kozina
d704e87ee4 No need to lock data device in crypt_format. 2018-08-08 08:54:42 +02:00
Ondrej Kozina
c8ce996872 Wipe data device in crypt_format with auth. encryption.
crypt_wipe_device was called incorrectly on metadata device even
though integrity header is always on data device from cryptsetup
pov. During LUKS2 crypt_format with detached header scenario we
would wiped first 8 sectors of metadata device instead of data
device.
2018-08-08 08:52:44 +02:00
Milan Broz
0e7b068061 Add sector-size & payload align test. 2018-08-08 08:45:26 +02:00
Ondrej Kozina
71dd149ca2 Fix data alignment calculations with custom encryption sector size. 2018-08-08 08:01:45 +02:00
Ondrej Kozina
b30ba41d6a Fix typo in blockwise-compat test. 2018-08-08 07:44:07 +02:00
Ondrej Kozina
a0bf790892 Fix FAST_PBKDF typos in LUKS2 reencrypt tests. 2018-08-08 07:43:56 +02:00
Ondrej Kozina
caefc4eb8e Add basic test for token import and export. 2018-08-08 07:42:58 +02:00
Milan Broz
31364c17d6 Fix configure typo in previous patch. 2018-08-07 15:28:43 +02:00
Milan Broz
5e56966e72 Make tests for strings in configure more consistent.
Intead of
  test x$enable_xyz = xyes;
use
  test "$enable_xyz" = "xyes"; then
2018-08-07 09:29:51 +02:00
Milan Broz
1f951ed7ec Use AC_ARG_ENABLE consistently.
AC_ARG_ENABLE(feature, ...) -> AC_ARG_ENABLE([feature], ...
2018-08-07 08:37:55 +02:00
joerichey@google.com
ecd82f1fc9 Fix configure.ac formatting
Currently, AC_ARG_[ENABLE|WITH] are used in multiple different ways.
This change makes all their uses the same by following the style of
the GNU manual:
  - AC_ARG_ENABLE(foo) should only define $enable_foo
  - Use the 2 argument form with a --enable_foo flag
  - Use the 4 argument form with a --disable_foo flag
  - Format all uses the same way
  - Always compare using: test "x$enable_foo" = "xyes"

This makes the easier to debug, more readable, and shorter.

This formatting fix also revealed a bug (fix submitted seperately).
2018-08-07 08:21:25 +02:00
Milan Broz
7aaf1eeb1b Fix bz2->xz untar api-test option. 2018-08-06 15:16:39 +02:00
Milan Broz
e53fe70668 Use only xz archives in tests.
Bzip2 is sometimesmissing and we use xz already.

Seems xz produces slightly larger archives (despite the best mode)
but it is not worth to keep bz2 here.
2018-08-06 13:48:54 +02:00
Milan Broz
9e2e0a4a2d Update Readme.md 2018-08-03 12:51:22 +02:00
126 changed files with 11320 additions and 6083 deletions

View File

@@ -44,13 +44,6 @@ function check_nonroot
$MAKE || return
sudo modprobe dm-crypt
sudo modprobe dm-verity
sudo modprobe dm-integrity
uname -a
sudo dmsetup version
sudo dmsetup targets
make check
}
@@ -69,13 +62,6 @@ function check_root
$MAKE || return
sudo modprobe dm-crypt
sudo modprobe dm-verity
sudo modprobe dm-integrity
uname -a
sudo dmsetup version
sudo dmsetup targets
# FIXME: we should use -E option here
sudo make check
}

View File

@@ -14,6 +14,7 @@ branches:
only:
- master
- wip-luks2
- v2_0_x
before_install:
- uname -a

View File

@@ -18,8 +18,7 @@ LUKS Design
-----------
**LUKS** is the standard for Linux hard disk encryption. By providing a standard on-disk-format, it does not
only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
In contrast to existing solution, LUKS stores all setup necessary setup information in the partition header,
enabling the user to transport or migrate his data seamlessly.
LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.
Last version of the LUKS format specification is
[available here](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
@@ -42,13 +41,22 @@ 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.0.3**
* [cryptsetup-2.0.3.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz)
* Signature [cryptsetup-2.0.3.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign)
**The latest cryptsetup version is 2.0.6**
* [cryptsetup-2.0.6.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz)
* Signature [cryptsetup-2.0.6.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.0.3 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
* [Cryptsetup 2.0.6 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
Previous versions
* [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).
@@ -82,7 +90,7 @@ Source and API docs
For development version code, please refer to [source](https://gitlab.com/cryptsetup/cryptsetup/tree/master) page,
mirror on [kernel.org](https://git.kernel.org/cgit/utils/cryptsetup/cryptsetup.git/) or [GitHub](https://github.com/mbroz/cryptsetup).
For libcryptsetup documentation see [libcryptsetup API](https://gitlab.com/cryptsetup/cryptsetup/wikis/API/index.html) page.
For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeople.org/libcryptsetup_API/) page.
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).

View File

@@ -1,5 +1,5 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.0.4])
AC_INIT([cryptsetup],[2.0.6])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
@@ -63,7 +63,9 @@ AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
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.])])
AC_ARG_ENABLE(keyring, AS_HELP_STRING([--disable-keyring],[disable kernel keyring support and builtin kernel keyring token]),[], [enable_keyring=yes])
AC_ARG_ENABLE([keyring],
AS_HELP_STRING([--disable-keyring], [disable kernel keyring support and builtin kernel keyring token]),
[], [enable_keyring=yes])
if test "x$enable_keyring" = "xyes"; then
AC_CHECK_HEADERS(linux/keyctl.h,,[AC_MSG_ERROR([You need Linux kernel headers with kernel keyring service compiled.])])
@@ -84,7 +86,7 @@ if test "x$enable_keyring" = "xyes"; then
AC_DEFINE(KERNEL_KEYRING, 1, [Enable kernel keyring service support])
fi
AM_CONDITIONAL(KERNEL_KEYRING, test x$enable_keyring = xyes)
AM_CONDITIONAL(KERNEL_KEYRING, test "x$enable_keyring" = "xyes")
saved_LIBS=$LIBS
AC_CHECK_LIB(uuid, uuid_clear, ,[AC_MSG_ERROR([You need the uuid library.])])
@@ -92,9 +94,9 @@ AC_SUBST(UUID_LIBS, $LIBS)
LIBS=$saved_LIBS
AC_SEARCH_LIBS([clock_gettime],[rt posix4])
AC_CHECK_FUNCS([posix_memalign clock_gettime posix_fallocate])
AC_CHECK_FUNCS([posix_memalign clock_gettime posix_fallocate explicit_bzero])
if test "x$enable_largefile" = "xno" ; then
if test "x$enable_largefile" = "xno"; then
AC_MSG_ERROR([Building with --disable-largefile is not supported, it can cause data corruption.])
fi
@@ -120,12 +122,10 @@ AC_SUBST(POPT_LIBS, $LIBS)
LIBS=$saved_LIBS
dnl ==========================================================================
dnl FIPS extensions (only for RHEL)
AC_ARG_ENABLE([fips], AS_HELP_STRING([--enable-fips],[enable FIPS mode restrictions]),
[with_fips=$enableval],
[with_fips=no])
if test "x$with_fips" = "xyes"; then
dnl FIPS extensions
AC_ARG_ENABLE([fips],
AS_HELP_STRING([--enable-fips], [enable FIPS mode restrictions]))
if test "x$enable_fips" = "xyes"; then
AC_DEFINE(ENABLE_FIPS, 1, [Enable FIPS mode restrictions])
if test "x$enable_static" = "xyes" -o "x$enable_static_cryptsetup" = "xyes" ; then
@@ -134,7 +134,7 @@ if test "x$with_fips" = "xyes"; then
fi
AC_DEFUN([NO_FIPS], [
if test "x$with_fips" = "xyes"; then
if test "x$enable_fips" = "xyes"; then
AC_MSG_ERROR([This option is not compatible with FIPS.])
fi
])
@@ -142,12 +142,9 @@ AC_DEFUN([NO_FIPS], [
dnl ==========================================================================
dnl pwquality library (cryptsetup CLI only)
AC_ARG_ENABLE([pwquality],
AS_HELP_STRING([--enable-pwquality],
[enable password quality checking using pwquality library]),
[with_pwquality=$enableval],
[with_pwquality=no])
AS_HELP_STRING([--enable-pwquality], [enable password quality checking using pwquality library]))
if test "x$with_pwquality" = "xyes"; then
if test "x$enable_pwquality" = "xyes"; then
AC_DEFINE(ENABLE_PWQUALITY, 1, [Enable password quality checking using pwquality library])
PKG_CHECK_MODULES([PWQUALITY], [pwquality >= 1.0.0],,
AC_MSG_ERROR([You need pwquality library.]))
@@ -159,13 +156,11 @@ fi
dnl ==========================================================================
dnl passwdqc library (cryptsetup CLI only)
AC_ARG_ENABLE([passwdqc],
AS_HELP_STRING([--enable-passwdqc@<:@=CONFIG_PATH@:>@],
[enable password quality checking using passwdqc library (optionally with CONFIG_PATH)]),
[enable_passwdqc=$enableval],
[enable_passwdqc=no])
AS_HELP_STRING([--enable-passwdqc@<:@=CONFIG_PATH@:>@],
[enable password quality checking using passwdqc library (optionally with CONFIG_PATH)]))
case "$enable_passwdqc" in
yes|no) use_passwdqc_config="" ;;
""|yes|no) use_passwdqc_config="" ;;
/*) use_passwdqc_config="$enable_passwdqc"; enable_passwdqc=yes ;;
*) AC_MSG_ERROR([Unrecognized --enable-passwdqc parameter.]) ;;
esac
@@ -177,7 +172,7 @@ if test "x$enable_passwdqc" = "xyes"; then
PASSWDQC_LIBS="-lpasswdqc"
fi
if test "x$with_pwquality$enable_passwdqc" = "xyesyes"; then
if test "x$enable_pwquality$enable_passwdqc" = "xyesyes"; then
AC_MSG_ERROR([--enable-pwquality and --enable-passwdqc are mutually incompatible.])
fi
@@ -185,13 +180,14 @@ dnl ==========================================================================
dnl Crypto backend functions
AC_DEFUN([CONFIGURE_GCRYPT], [
if test "x$with_fips" = "xyes"; then
if test "x$enable_fips" = "xyes"; then
GCRYPT_REQ_VERSION=1.4.5
else
GCRYPT_REQ_VERSION=1.1.42
fi
dnl Check if we can use gcrypt PBKDF2 (1.6.0 supports empty password)
AC_ARG_ENABLE([gcrypt-pbkdf2], AS_HELP_STRING([--enable-gcrypt-pbkdf2],[force enable internal gcrypt PBKDF2]),
AC_ARG_ENABLE([gcrypt-pbkdf2],
AS_HELP_STRING([--enable-gcrypt-pbkdf2], [force enable internal gcrypt PBKDF2]),
if test "x$enableval" = "xyes"; then
[use_internal_pbkdf2=0]
else
@@ -208,7 +204,7 @@ AC_DEFUN([CONFIGURE_GCRYPT], [
NO_FIPS([])
fi
if test x$enable_static_cryptsetup = xyes; then
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_LIBS=$LIBS
LIBS="$saved_LIBS $LIBGCRYPT_LIBS -static"
AC_CHECK_LIB(gcrypt, gcry_check_version,,
@@ -232,7 +228,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
CRYPTO_LIBS=$OPENSSL_LIBS
use_internal_pbkdf2=0
if test x$enable_static_cryptsetup = xyes; then
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
PKG_CHECK_MODULES([OPENSSL_STATIC], [openssl])
@@ -242,7 +238,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
])
AC_DEFUN([CONFIGURE_NSS], [
if test x$enable_static_cryptsetup = xyes; then
if test "x$enable_static_cryptsetup" = "xyes"; then
AC_MSG_ERROR([Static build of cryptsetup is not supported with NSS.])
fi
@@ -291,43 +287,42 @@ dnl ==========================================================================
saved_LIBS=$LIBS
AC_ARG_ENABLE([static-cryptsetup],
AS_HELP_STRING([--enable-static-cryptsetup],
[enable build of static version of tools]))
if test x$enable_static_cryptsetup = xyes; then
if test x$enable_static = xno; then
AS_HELP_STRING([--enable-static-cryptsetup], [enable build of static version of tools]))
if test "x$enable_static_cryptsetup" = "xyes"; then
if test "x$enable_static" = "xno"; then
AC_MSG_WARN([Requested static cryptsetup build, enabling static library.])
enable_static=yes
fi
fi
AM_CONDITIONAL(STATIC_TOOLS, test x$enable_static_cryptsetup = xyes)
AM_CONDITIONAL(STATIC_TOOLS, test "x$enable_static_cryptsetup" = "xyes")
AC_ARG_ENABLE(cryptsetup,
AS_HELP_STRING([--disable-cryptsetup],
[disable cryptsetup support]),[], [enable_cryptsetup=yes])
AM_CONDITIONAL(CRYPTSETUP, test x$enable_cryptsetup = xyes)
AC_ARG_ENABLE([cryptsetup],
AS_HELP_STRING([--disable-cryptsetup], [disable cryptsetup support]),
[], [enable_cryptsetup=yes])
AM_CONDITIONAL(CRYPTSETUP, test "x$enable_cryptsetup" = "xyes")
AC_ARG_ENABLE(veritysetup,
AS_HELP_STRING([--disable-veritysetup],
[disable veritysetup support]),[], [enable_veritysetup=yes])
AM_CONDITIONAL(VERITYSETUP, test x$enable_veritysetup = xyes)
AC_ARG_ENABLE([veritysetup],
AS_HELP_STRING([--disable-veritysetup], [disable veritysetup support]),
[], [enable_veritysetup=yes])
AM_CONDITIONAL(VERITYSETUP, test "x$enable_veritysetup" = "xyes")
AC_ARG_ENABLE([cryptsetup-reencrypt],
AS_HELP_STRING([--disable-cryptsetup-reencrypt],
[disable cryptsetup-reencrypt tool]),[], [enable_cryptsetup_reencrypt=yes])
AM_CONDITIONAL(REENCRYPT, test x$enable_cryptsetup_reencrypt = xyes)
AS_HELP_STRING([--disable-cryptsetup-reencrypt], [disable cryptsetup-reencrypt tool]),
[], [enable_cryptsetup_reencrypt=yes])
AM_CONDITIONAL(REENCRYPT, test "x$enable_cryptsetup_reencrypt" = "xyes")
AC_ARG_ENABLE(integritysetup,
AS_HELP_STRING([--disable-integritysetup],
[disable integritysetup support]),[], [enable_integritysetup=yes])
AM_CONDITIONAL(INTEGRITYSETUP, test x$enable_integritysetup = xyes)
AC_ARG_ENABLE([integritysetup],
AS_HELP_STRING([--disable-integritysetup], [disable integritysetup support]),
[], [enable_integritysetup=yes])
AM_CONDITIONAL(INTEGRITYSETUP, test "x$enable_integritysetup" = "xyes")
AC_ARG_ENABLE(selinux,
AS_HELP_STRING([--disable-selinux],
[disable selinux support [default=auto]]),[], [])
AC_ARG_ENABLE([selinux],
AS_HELP_STRING([--disable-selinux], [disable selinux support [default=auto]]),
[], [enable_selinux=yes])
AC_ARG_ENABLE([udev],
AS_HELP_STRING([--disable-udev],
[disable udev support]),[], enable_udev=yes)
AS_HELP_STRING([--disable-udev], [disable udev support]),
[], [enable_udev=yes])
dnl Try to use pkg-config for devmapper, but fallback to old detection
PKG_CHECK_MODULES([DEVMAPPER], [devmapper >= 1.02.03],, [
@@ -361,16 +356,14 @@ PKG_CHECK_MODULES([JSON_C], [json-c])
dnl Crypto backend configuration.
AC_ARG_WITH([crypto_backend],
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [gcrypt]]),
[], with_crypto_backend=gcrypt
)
[], [with_crypto_backend=gcrypt])
dnl Kernel crypto API backend needed for benchmark and tcrypt
AC_ARG_ENABLE([kernel_crypto], AS_HELP_STRING([--disable-kernel_crypto],
[disable kernel userspace crypto (no benchmark and tcrypt)]),
[with_kernel_crypto=$enableval],
[with_kernel_crypto=yes])
AC_ARG_ENABLE([kernel_crypto],
AS_HELP_STRING([--disable-kernel_crypto], [disable kernel userspace crypto (no benchmark and tcrypt)]),
[], [enable_kernel_crypto=yes])
if test "x$with_kernel_crypto" = "xyes"; then
if test "x$enable_kernel_crypto" = "xyes"; then
AC_CHECK_HEADERS(linux/if_alg.h,,
[AC_MSG_ERROR([You need Linux kernel headers with userspace crypto interface. (Or use --disable-kernel_crypto.)])])
AC_DEFINE(ENABLE_AF_ALG, 1, [Enable using of kernel userspace crypto])
@@ -384,23 +377,24 @@ case $with_crypto_backend in
nettle) CONFIGURE_NETTLE([]) ;;
*) AC_MSG_ERROR([Unknown crypto backend.]) ;;
esac
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test $with_crypto_backend = gcrypt)
AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test $with_crypto_backend = openssl)
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test $with_crypto_backend = nss)
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test $with_crypto_backend = kernel)
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test $with_crypto_backend = nettle)
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test "$with_crypto_backend" = "gcrypt")
AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test "$with_crypto_backend" = "openssl")
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test "$with_crypto_backend" = "nss")
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test "$with_crypto_backend" = "kernel")
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test "$with_crypto_backend" = "nettle")
AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1)
AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2])
dnl Argon2 implementation
AC_ARG_ENABLE(internal-argon2, AS_HELP_STRING([--disable-internal-argon2],
[disable internal implementation of Argon2 PBKDF]),[], [enable_internal_argon2=yes])
AC_ARG_ENABLE([internal-argon2],
AS_HELP_STRING([--disable-internal-argon2], [disable internal implementation of Argon2 PBKDF]),
[], [enable_internal_argon2=yes])
AC_ARG_ENABLE([libargon2], AS_HELP_STRING([--enable-libargon2],
[enable external libargon2 (PHC) library (disables internal bundled version) ]),[], [enable_libargon2=no])
AC_ARG_ENABLE([libargon2],
AS_HELP_STRING([--enable-libargon2], [enable external libargon2 (PHC) library (disables internal bundled version)]))
if test x$enable_libargon2 = xyes ; then
if test "x$enable_libargon2" = "xyes" ; then
AC_CHECK_HEADERS(argon2.h,,
[AC_MSG_ERROR([You need libargon2 development library installed.])])
AC_CHECK_DECL(Argon2_id,,[AC_MSG_ERROR([You need more recent Argon2 library with support for Argon2id.])], [#include <argon2.h>])
@@ -409,10 +403,10 @@ if test x$enable_libargon2 = xyes ; then
else
AC_MSG_WARN([Argon2 bundled (slow) reference implementation will be used, please consider to use system library with --enable-libargon2.])
AC_ARG_ENABLE(internal-sse-argon2, AS_HELP_STRING([--enable-internal-sse-argon2],
[enable internal SSE implementation of Argon2 PBKDF]),[], [enable_internal_sse_argon2=no])
AC_ARG_ENABLE([internal-sse-argon2],
AS_HELP_STRING([--enable-internal-sse-argon2], [enable internal SSE implementation of Argon2 PBKDF]))
if test x$enable_internal_sse_argon2 = xyes ; then
if test "x$enable_internal_sse_argon2" = "xyes"; then
AC_MSG_CHECKING(if Argon2 SSE optimization can be used)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <emmintrin.h>
@@ -424,17 +418,18 @@ else
fi
fi
if test x$enable_internal_argon2 = xyes ; then
if test "x$enable_internal_argon2" = "xyes"; then
AC_DEFINE(USE_INTERNAL_ARGON2, 1, [Use internal Argon2])
fi
AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test x$enable_internal_argon2 = xyes)
AM_CONDITIONAL(CRYPTO_INTERNAL_SSE_ARGON2, test x$enable_internal_sse_argon2 = xyes)
AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test "x$enable_internal_argon2" = "xyes")
AM_CONDITIONAL(CRYPTO_INTERNAL_SSE_ARGON2, test "x$enable_internal_sse_argon2" = "xyes")
dnl Link with blkid to check for other device types
AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid],
[disable use of blkid for device signature detection and wiping.]), [], [enable_blkid=yes])
AC_ARG_ENABLE([blkid],
AS_HELP_STRING([--disable-blkid], [disable use of blkid for device signature detection and wiping]),
[], [enable_blkid=yes])
if test x$enable_blkid = xyes ; then
if test "x$enable_blkid" = "xyes"; then
PKG_CHECK_MODULES([BLKID], [blkid],[AC_DEFINE([HAVE_BLKID], 1, [Define to 1 to use blkid for detection of disk signatures.])],[LIBBLKID_LIBS="-lblkid"])
AC_CHECK_HEADERS(blkid/blkid.h,,[AC_MSG_ERROR([You need blkid development library installed.])])
@@ -458,12 +453,12 @@ if test x$enable_blkid = xyes ; then
[AC_MSG_ERROR([Can not compile with blkid support, disable it by --disable-blkid.])],
[#include <blkid/blkid.h>])
fi
AM_CONDITIONAL(HAVE_BLKID, test x$enable_blkid = xyes)
AM_CONDITIONAL(HAVE_BLKID_WIPE, test x$enable_blkid_wipe = xyes)
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test x$enable_blkid_step_back = xyes)
AM_CONDITIONAL(HAVE_BLKID, test "x$enable_blkid" = "xyes")
AM_CONDITIONAL(HAVE_BLKID_WIPE, test "x$enable_blkid_wipe" = "xyes")
AM_CONDITIONAL(HAVE_BLKID_STEP_BACK, test "x$enable_blkid_step_back" = "xyes")
dnl Magic for cryptsetup.static build.
if test x$enable_static_cryptsetup = xyes; then
if test "x$enable_static_cryptsetup" = "xyes"; then
saved_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --static"
@@ -475,7 +470,7 @@ if test x$enable_static_cryptsetup = xyes; then
LIBS="$saved_LIBS -static"
PKG_CHECK_MODULES([DEVMAPPER_STATIC], [devmapper >= 1.02.27],,[
DEVMAPPER_STATIC_LIBS=$DEVMAPPER_LIBS
if test "x$enable_selinux" != xno; then
if test "x$enable_selinux" = "xyes"; then
AC_CHECK_LIB(sepol, sepol_bool_set)
AC_CHECK_LIB(selinux, is_selinux_enabled)
DEVMAPPER_STATIC_LIBS="$DEVMAPPER_STATIC_LIBS $LIBS"
@@ -553,15 +548,14 @@ AC_DEFUN([CS_ABSPATH], [
dnl ==========================================================================
dnl Python bindings
AC_ARG_ENABLE([python], AS_HELP_STRING([--enable-python],[enable Python bindings]),
[with_python=$enableval],
[with_python=no])
AC_ARG_ENABLE([python],
AS_HELP_STRING([--enable-python], [enable Python bindings]))
AC_ARG_WITH([python_version],
AS_HELP_STRING([--with-python_version=VERSION], [required Python version [2.6]]),
[PYTHON_VERSION=$withval], [PYTHON_VERSION=2.6])
if test "x$with_python" = "xyes"; then
if test "x$enable_python" = "xyes"; then
AM_PATH_PYTHON([$PYTHON_VERSION])
AC_PATH_PROGS([PYTHON_CONFIG], [python${PYTHON_VERSION}-config python-config], [no])
@@ -579,7 +573,7 @@ if test "x$with_python" = "xyes"; then
AC_MSG_RESULT($PYTHON_LIBS)
AC_SUBST(PYTHON_LIBS)
fi
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$with_python" = "xyes"])
AM_CONDITIONAL([PYTHON_CRYPTSETUP], [test "x$enable_python" = "xyes"])
dnl ==========================================================================
CS_STR_WITH([plain-hash], [password hashing function for plain mode], [ripemd160])
@@ -633,8 +627,7 @@ AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS)
dnl Override default LUKS format version (for cryptsetup or cryptsetup-reencrypt format actions only).
AC_ARG_WITH([default_luks_format],
AS_HELP_STRING([--with-default-luks-format=FORMAT], [default LUKS format version (LUKS1/LUKS2) [LUKS1]]),
[], with_default_luks_format=LUKS1
)
[], [with_default_luks_format=LUKS1])
case $with_default_luks_format in
LUKS1) default_luks=CRYPT_LUKS1 ;;

Binary file not shown.

102
docs/v2.0.5-ReleaseNotes Normal file
View File

@@ -0,0 +1,102 @@
Cryptsetup 2.0.5 Release Notes
==============================
Stable bug-fix release with new features.
Cryptsetup 2.x version introduces a new on-disk LUKS2 format.
The legacy LUKS (referenced as LUKS1) will be fully supported
forever as well as a traditional and fully backward compatible format.
Please note that authenticated disk encryption, non-cryptographic
data integrity protection (dm-integrity), use of Argon2 Password-Based
Key Derivation Function and the LUKS2 on-disk format itself are new
features and can contain some bugs.
Please do not use LUKS2 without properly configured backup or in
production systems that need to be compatible with older systems.
Changes since version 2.0.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Wipe full header areas (including unused) during LUKS format.
Since this version, the whole area up to the data offset is zeroed,
and subsequently, all keyslots areas are wiped with random data.
This ensures that no remaining old data remains in the LUKS header
areas, but it could slow down format operation on some devices.
Previously only first 4k (or 32k for LUKS2) and the used keyslot
was overwritten in the format operation.
* Several fixes to error messages that were unintentionally replaced
in previous versions with a silent exit code.
More descriptive error messages were added, including error
messages if
- a device is unusable (not a block device, no access, etc.),
- a LUKS device is not detected,
- LUKS header load code detects unsupported version,
- a keyslot decryption fails (also happens in the cipher check),
- converting an inactive keyslot.
* Device activation fails if data area overlaps with LUKS header.
* Code now uses explicit_bzero to wipe memory if available
(instead of own implementation).
* Additional VeraCrypt modes are now supported, including Camellia
and Kuznyechik symmetric ciphers (and cipher chains) and Streebog
hash function. These were introduced in a recent VeraCrypt upstream.
Note that Kuznyechik requires out-of-tree kernel module and
Streebog hash function is available only with the gcrypt cryptographic
backend for now.
* Fixes static build for integritysetup if the pwquality library is used.
* Allows passphrase change for unbound keyslots.
* Fixes removed keyslot number in verbose message for luksKillSlot,
luksRemoveKey and erase command.
* Adds blkid scan when attempting to open a plain device and warn the user
about existing device signatures in a ciphertext device.
* Remove LUKS header signature if luksFormat fails to add the first keyslot.
* Remove O_SYNC from device open and use fsync() to speed up
wipe operation considerably.
* Create --master-key-file in luksDump and fail if the file already exists.
* Fixes a bug when LUKS2 authenticated encryption with a detached header
wiped the header device instead of dm-integrity data device area (causing
unnecessary LUKS2 header auto recovery).
Unfinished things & TODO for next releases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Authenticated encryption should use new algorithms from CAESAR competition
https://competitions.cr.yp.to/caesar-submissions.html.
AEGIS and MORUS are already available in kernel 4.18.
For more info about LUKS2 authenticated encryption, please see our paper
https://arxiv.org/abs/1807.00309
Please note that authenticated encryption is still an experimental feature
and can have performance problems for hish-speed devices and device
with larger IO blocks (like RAID).
* Authenticated encryption do not set encryption for a dm-integrity journal.
While it does not influence data confidentiality or integrity protection,
an attacker can get some more information from data journal or cause that
system will corrupt sectors after journal replay. (That corruption will be
detected though.)
* There are examples of user-defined tokens inside misc/luks2_keyslot_example
directory (like a simple external program that uses libssh to unlock LUKS2
using remote keyfile).
* The python binding (pycryptsetup) contains only basic functionality for LUKS1
(it is not updated for new features) and will be REMOVED in version 2.1
in favor of python bindings to the libblockdev library.
See https://github.com/storaged-project/libblockdev/releases that
already supports LUKS2 and VeraCrypt devices handling through libcryptsetup.

97
docs/v2.0.6-ReleaseNotes Normal file
View File

@@ -0,0 +1,97 @@
Cryptsetup 2.0.6 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.0.x should upgrade to this version.
Cryptsetup 2.x version introduces a new on-disk LUKS2 format.
The legacy LUKS (referenced as LUKS1) will be fully supported
forever as well as a traditional and fully backward compatible format.
Please note that authenticated disk encryption, non-cryptographic
data integrity protection (dm-integrity), use of Argon2 Password-Based
Key Derivation Function and the LUKS2 on-disk format itself are new
features and can contain some bugs.
Please do not use LUKS2 without properly configured backup or in
production systems that need to be compatible with older systems.
Changes since version 2.0.5
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix support of larger metadata areas in LUKS2 header.
This release properly supports all specified metadata areas, as documented
in LUKS2 format description (see docs/on-disk-format-luks2.pdf in archive).
Currently, only default metadata area size is used (in format or convert).
Later cryptsetup versions will allow increasing this metadata area size.
* If AEAD (authenticated encryption) is used, cryptsetup now tries to check
if the requested AEAD algorithm with specified key size is available
in kernel crypto API.
This change avoids formatting a device that cannot be later activated.
For this function, the kernel must be compiled with the
CONFIG_CRYPTO_USER_API_AEAD option enabled.
Note that kernel user crypto API options (CONFIG_CRYPTO_USER_API and
CONFIG_CRYPTO_USER_API_SKCIPHER) are already mandatory for LUKS2.
* Fix setting of integrity no-journal flag.
Now you can store this flag to metadata using --persistent option.
* Fix cryptsetup-reencrypt to not keep temporary reencryption headers
if interrupted during initial password prompt.
* Adds early check to plain and LUKS2 formats to disallow device format
if device size is not aligned to requested sector size.
Previously it was possible, and the device was rejected to activate by
kernel later.
* Fix checking of hash algorithms availability for PBKDF early.
Previously LUKS2 format allowed non-existent hash algorithm with
invalid keyslot preventing the device from activation.
* Allow Adiantum cipher construction (a non-authenticated length-preserving
fast encryption scheme), so it can be used both for data encryption and
keyslot encryption in LUKS1/2 devices.
For benchmark, use:
# cryptsetup benchmark -c xchacha12,aes-adiantum
# cryptsetup benchmark -c xchacha20,aes-adiantum
For LUKS format:
# cryptsetup luksFormat -c xchacha20,aes-adiantum-plain64 -s 256 <device>
The support for Adiantum will be merged in Linux kernel 4.21.
For more info see the paper https://eprint.iacr.org/2018/720.
Unfinished things & TODO for next releases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Authenticated encryption should use new algorithms from CAESAR competition
https://competitions.cr.yp.to/caesar-submissions.html.
AEGIS and MORUS are already available in kernel 4.18.
For more info about LUKS2 authenticated encryption, please see our paper
https://arxiv.org/abs/1807.00309
Please note that authenticated encryption is still an experimental feature
and can have performance problems for high-speed devices and device
with larger IO blocks (like RAID).
* Authenticated encryption do not set encryption for a dm-integrity journal.
While it does not influence data confidentiality or integrity protection,
an attacker can get some more information from data journal or cause that
system will corrupt sectors after journal replay. (That corruption will be
detected though.)
* There are examples of user-defined tokens inside misc/luks2_keyslot_example
directory (like a simple external program that uses libssh to unlock LUKS2
using remote keyfile).
* The python binding (pycryptsetup) contains only basic functionality for LUKS1
(it is not updated for new features) and will be REMOVED in version 2.1
in favor of python bindings to the libblockdev library.
See https://github.com/storaged-project/libblockdev/releases that
already supports LUKS2 and VeraCrypt devices handling through libcryptsetup.

View File

@@ -26,53 +26,58 @@
struct cipher_alg {
const char *name;
const char *mode;
int blocksize;
bool wrapped_key;
};
/* FIXME: Getting block size should be dynamic from cipher backend. */
static const struct cipher_alg cipher_algs[] = {
{ "cipher_null", 16, false },
{ "aes", 16, false },
{ "serpent", 16, false },
{ "twofish", 16, false },
{ "anubis", 16, false },
{ "blowfish", 8, false },
{ "camellia", 16, false },
{ "cast5", 8, false },
{ "cast6", 16, false },
{ "des", 8, false },
{ "des3_ede", 8, false },
{ "khazad", 8, false },
{ "seed", 16, false },
{ "tea", 8, false },
{ "xtea", 8, false },
{ "paes", 16, true }, /* protected AES, s390 wrapped key scheme */
{ NULL, 0, false }
{ "cipher_null", NULL, 16, false },
{ "aes", NULL, 16, false },
{ "serpent", NULL, 16, false },
{ "twofish", NULL, 16, false },
{ "anubis", NULL, 16, false },
{ "blowfish", NULL, 8, false },
{ "camellia", NULL, 16, false },
{ "cast5", NULL, 8, false },
{ "cast6", NULL, 16, false },
{ "des", NULL, 8, false },
{ "des3_ede", NULL, 8, false },
{ "khazad", NULL, 8, false },
{ "seed", NULL, 16, false },
{ "tea", NULL, 8, false },
{ "xtea", NULL, 8, false },
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
{ "xchacha12,aes", "adiantum", 32, false },
{ "xchacha20,aes", "adiantum", 32, false },
{ NULL, NULL, 0, false }
};
static const struct cipher_alg *_get_alg(const char *name)
static const struct cipher_alg *_get_alg(const char *name, const char *mode)
{
int i = 0;
while (name && cipher_algs[i].name) {
if (!strcasecmp(name, cipher_algs[i].name))
return &cipher_algs[i];
if (!mode || !cipher_algs[i].mode ||
!strncasecmp(mode, cipher_algs[i].mode, strlen(cipher_algs[i].mode)))
return &cipher_algs[i];
i++;
}
return NULL;
}
int crypt_cipher_blocksize(const char *name)
int crypt_cipher_ivsize(const char *name, const char *mode)
{
const struct cipher_alg *ca = _get_alg(name);
const struct cipher_alg *ca = _get_alg(name, mode);
return ca ? ca->blocksize : -EINVAL;
}
int crypt_cipher_wrapped_key(const char *name)
int crypt_cipher_wrapped_key(const char *name, const char *mode)
{
const struct cipher_alg *ca = _get_alg(name);
const struct cipher_alg *ca = _get_alg(name, mode);
return ca ? (int)ca->wrapped_key : 0;
}

View File

@@ -99,8 +99,8 @@ int argon2(const char *type, const char *password, size_t password_length,
uint32_t crypt_crc32(uint32_t seed, const unsigned char *buf, size_t len);
/* ciphers */
int crypt_cipher_blocksize(const char *name);
int crypt_cipher_wrapped_key(const char *name);
int crypt_cipher_ivsize(const char *name, const char *mode);
int crypt_cipher_wrapped_key(const char *name, const char *mode);
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length);
void crypt_cipher_destroy(struct crypt_cipher *ctx);
@@ -111,6 +111,10 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length);
/* Check availability of a cipher */
int crypt_cipher_check(const char *name, const char *mode,
const char *integrity, size_t key_length);
/* storage encryption wrappers */
int crypt_storage_init(struct crypt_storage **ctx, uint64_t sector_start,
const char *cipher, const char *cipher_mode,
@@ -124,8 +128,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t sector,
/* Memzero helper (memset on stack can be optimized out) */
static inline void crypt_backend_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
}
#endif /* _CRYPTO_BACKEND_H */

View File

@@ -22,6 +22,7 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
@@ -51,22 +52,16 @@ struct crypt_cipher {
* ENOTSUP - AF_ALG family not available
* (but cannot check specifically for skcipher API)
*/
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length)
static int _crypt_cipher_init(struct crypt_cipher **ctx,
const void *key, size_t key_length,
struct sockaddr_alg *sa)
{
struct crypt_cipher *h;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher",
};
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
"%s(%s)", mode, name);
h->opfd = -1;
h->tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (h->tfmfd < 0) {
@@ -74,14 +69,11 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
return -ENOTSUP;
}
if (bind(h->tfmfd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
if (bind(h->tfmfd, (struct sockaddr *)sa, sizeof(*sa)) < 0) {
crypt_cipher_destroy(h);
return -ENOENT;
}
if (!strcmp(name, "cipher_null"))
key_length = 0;
if (setsockopt(h->tfmfd, SOL_ALG, ALG_SET_KEY, key, key_length) < 0) {
crypt_cipher_destroy(h);
return -EINVAL;
@@ -97,6 +89,22 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
return 0;
}
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length)
{
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher",
};
if (!strcmp(name, "cipher_null"))
key_length = 0;
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
return _crypt_cipher_init(ctx, key, key_length, &sa);
}
/* The in/out should be aligned to page boundary */
static int crypt_cipher_crypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length,
@@ -191,6 +199,68 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx)
free(ctx);
}
int crypt_cipher_check(const char *name, const char *mode,
const char *integrity, size_t key_length)
{
struct crypt_cipher *c = NULL;
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
const char *salg_type;
bool aead;
int r;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
};
aead = integrity && strcmp(integrity, "none");
/* Remove IV if present */
if (mode) {
strncpy(mode_name, mode, sizeof(mode_name));
mode_name[sizeof(mode_name) - 1] = 0;
cipher_iv = strchr(mode_name, '-');
if (cipher_iv) {
*cipher_iv = '\0';
real_mode = mode_name;
}
}
salg_type = aead ? "aead" : "skcipher";
snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type);
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
/* FIXME: this is duplicating a part of devmapper backend */
if (aead && !strcmp(integrity, "poly1305"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
else if (!real_mode)
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
else if (aead && !strcmp(real_mode, "ccm"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
else
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
if (r <= 0 || r > (int)(sizeof(sa.salg_name) - 1))
return -EINVAL;
memcpy(sa.salg_name, tmp_salg_name, sizeof(sa.salg_name));
key = malloc(key_length);
if (!key)
return -ENOMEM;
r = crypt_backend_rng(key, key_length, CRYPT_RND_NORMAL, 0);
if (r < 0) {
free (key);
return r;
}
r = _crypt_cipher_init(&c, key, key_length, &sa);
if (c)
crypt_cipher_destroy(c);
free(key);
return r;
}
#else /* ENABLE_AF_ALG */
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *buffer, size_t length)
@@ -215,4 +285,9 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
{
return -EINVAL;
}
int crypt_cipher_check(const char *name, const char *mode,
const char *integrity, size_t key_length)
{
return 0;
}
#endif

View File

@@ -60,7 +60,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
{
memset(ctx, 0, sizeof(*ctx));
ctx->iv_size = crypt_cipher_blocksize(cipher_name);
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
if (ctx->iv_size < 8)
return -ENOENT;

View File

@@ -48,7 +48,7 @@ int crypt_pbkdf_get_limits(const char *kdf, struct crypt_pbkdf_limits *limits)
limits->min_parallel = 0; /* N/A */
limits->max_parallel = 0; /* N/A */
return 0;
} else if (!strncmp(kdf, "argon2", 6)) {
} else if (!strcmp(kdf, "argon2i") || !strcmp(kdf, "argon2id")) {
limits->min_iterations = 4;
limits->max_iterations = UINT32_MAX;
limits->min_memory = 32;

View File

@@ -46,6 +46,7 @@
/* to silent gcc -Wcast-qual for const cast */
#define CONST_CAST(x) (x)(uintptr_t)
#define SHIFT_4K 12
#define SECTOR_SHIFT 9
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
#define MAX_SECTOR_SIZE 4096 /* min page size among all platforms */
@@ -55,6 +56,11 @@
#define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
#define MISALIGNED(a, b) ((a) & ((b) - 1))
#define MISALIGNED_4K(a) MISALIGNED((a), 1 << SHIFT_4K)
#define MISALIGNED_512(a) MISALIGNED((a), 1 << SECTOR_SHIFT)
#define NOTPOW2(a) MISALIGNED((a), (a))
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
@@ -104,6 +110,7 @@ int device_is_rotational(struct device *device);
size_t device_alignment(struct device *device);
int device_direct_io(const struct device *device);
int device_fallocate(struct device *device, uint64_t size);
void device_sync(struct device *device, int devfd);
int device_open_locked(struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device);

View File

@@ -368,7 +368,7 @@ struct crypt_params_plain {
*/
struct crypt_params_luks1 {
const char *hash; /**< hash used in LUKS header */
size_t data_alignment; /**< data alignment in sectors, data offset is multiple of this */
size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */
const char *data_device; /**< detached encrypted data device or @e NULL */
};
@@ -490,7 +490,7 @@ struct crypt_params_luks2 {
const struct crypt_pbkdf_type *pbkdf; /**< PBKDF (and hash) parameters or @e NULL*/
const char *integrity; /**< integrity algorithm or @e NULL */
const struct crypt_params_integrity *integrity_params; /**< Data integrity parameters or @e NULL*/
size_t data_alignment; /**< data alignment in sectors, data offset is multiple of this */
size_t data_alignment; /**< data area alignment in 512B sectors, data offset is multiple of this */
const char *data_device; /**< detached encrypted data device or @e NULL */
uint32_t sector_size; /**< encryption sector size */
const char *label; /**< header label or @e NULL*/
@@ -958,7 +958,7 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_IGNORE_PERSISTENT (1 << 14)
/** dm-verity: check_at_most_once - check data blocks only the first time */
#define CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE (1 << 15)
/** allow activation check including unbound keyslots (kesylots without segments) */
/** allow activation check including unbound keyslots (keyslots without segments) */
#define CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY (1 << 16)
/**

View File

@@ -376,15 +376,12 @@ static void hex_key(char *hexkey, size_t key_size, const char *key)
sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
}
/* get string length for key_size written in decimal system */
static size_t get_key_size_strlen(size_t key_size)
static size_t int_log10(size_t x)
{
size_t ret = 1;
while ((key_size /= 10))
ret++;
return ret;
size_t r = 0;
for (x /= 10; x > 0; x /= 10)
r++;
return r;
}
#define CLEN 64 /* 2*MAX_CIPHER_LEN */
@@ -397,7 +394,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
char *i_dm, int i_dm_size)
{
int c_size = 0, i_size = 0, i;
char cipher[CLEN], mode[CLEN], iv[CLEN], tmp[CLEN];
char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
char capi[CAPIL];
if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
@@ -410,7 +407,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
if (i == 1) {
memset(iv, 0, sizeof(iv));
strncpy(iv, mode, sizeof(iv) - 1);
strncpy(iv, mode, sizeof(iv)-1);
*mode = '\0';
if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
return -EINVAL;
@@ -457,7 +454,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
{
char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
char tmp[CAPIL*2], capi[CAPIL];
char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
size_t len;
int i;
@@ -500,16 +497,16 @@ static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char
} else
*org_i = NULL;
memset(capi, 0, sizeof(capi));
strncpy(capi, tmp, sizeof(capi) - 1);
strncpy(capi, tmp, sizeof(capi)-1);
}
i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
if (i == 2)
snprintf(tmp, sizeof(tmp), "%s-%s-%s", cipher, mode, iv);
snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
else
snprintf(tmp, sizeof(tmp), "%s-%s", capi, iv);
snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
if (!(*org_c = strdup(tmp))) {
if (!(*org_c = strdup(dmcrypt_tmp))) {
free(*org_i);
*org_i = NULL;
return -ENOMEM;
@@ -561,7 +558,7 @@ static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd, uint32_t fl
null_cipher = 1;
if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
keystr_len = strlen(dmd->u.crypt.vk->key_description) + get_key_size_strlen(dmd->u.crypt.vk->keylength) + 9;
keystr_len = strlen(dmd->u.crypt.vk->key_description) + int_log10(dmd->u.crypt.vk->keylength) + 10;
hexkey = crypt_safe_alloc(keystr_len);
} else
hexkey = crypt_safe_alloc(null_cipher ? 2 : (dmd->u.crypt.vk->keylength * 2 + 1));
@@ -687,7 +684,7 @@ static char *get_dm_integrity_params(struct crypt_dm_active_device *dmd, uint32_
{
int r, max_size, num_options = 0;
char *params, *hexkey, mode;
char features[256], feature[256];
char features[512], feature[256];
if (!dmd)
return NULL;
@@ -2131,7 +2128,7 @@ int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
goto out;
if (vk->key_description)
msg_size = strlen(vk->key_description) + get_key_size_strlen(vk->keylength) + 17;
msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
else
msg_size = vk->keylength * 2 + 10; // key set <key>

View File

@@ -64,31 +64,34 @@ out:
/* diffuse: Information spreading over the whole dataset with
* the help of hash function.
*/
static int diffuse(char *src, char *dst, size_t size, const char *hash_name)
{
int hash_size = crypt_hash_size(hash_name);
int r, hash_size = crypt_hash_size(hash_name);
unsigned int digest_size;
unsigned int i, blocks, padding;
if (hash_size <= 0)
return 1;
return -EINVAL;
digest_size = hash_size;
blocks = size / digest_size;
padding = size % digest_size;
for (i = 0; i < blocks; i++)
if(hash_buf(src + digest_size * i,
for (i = 0; i < blocks; i++) {
r = hash_buf(src + digest_size * i,
dst + digest_size * i,
i, (size_t)digest_size, hash_name))
return 1;
i, (size_t)digest_size, hash_name);
if (r < 0)
return r;
}
if(padding)
if(hash_buf(src + digest_size * i,
if (padding) {
r = hash_buf(src + digest_size * i,
dst + digest_size * i,
i, (size_t)padding, hash_name))
return 1;
i, (size_t)padding, hash_name);
if (r < 0)
return r;
}
return 0;
}
@@ -104,17 +107,19 @@ int AF_split(const char *src, char *dst, size_t blocksize,
{
unsigned int i;
char *bufblock;
int r = -EINVAL;
int r;
if((bufblock = calloc(blocksize, 1)) == NULL) return -ENOMEM;
/* process everything except the last block */
for(i=0; i<blocknumbers-1; i++) {
r = crypt_random_get(NULL, dst+(blocksize*i), blocksize, CRYPT_RND_NORMAL);
if(r < 0) goto out;
if (r < 0)
goto out;
XORblock(dst+(blocksize*i),bufblock,bufblock,blocksize);
if(diffuse(bufblock, bufblock, blocksize, hash))
r = diffuse(bufblock, bufblock, blocksize, hash);
if (r < 0)
goto out;
}
/* the last block is computed */
@@ -130,7 +135,7 @@ int AF_merge(const char *src, char *dst, size_t blocksize,
{
unsigned int i;
char *bufblock;
int r = -EINVAL;
int r;
if((bufblock = calloc(blocksize, 1)) == NULL)
return -ENOMEM;
@@ -138,7 +143,8 @@ int AF_merge(const char *src, char *dst, size_t blocksize,
memset(bufblock,0,blocksize);
for(i=0; i<blocknumbers-1; i++) {
XORblock(src+(blocksize*i),bufblock,bufblock,blocksize);
if(diffuse(bufblock, bufblock, blocksize, hash))
r = diffuse(bufblock, bufblock, blocksize, hash);
if (r < 0)
goto out;
}
XORblock(src + blocksize * i, bufblock, dst, blocksize);

View File

@@ -24,6 +24,7 @@
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include "luks.h"
#include "af.h"
#include "internal.h"
@@ -150,7 +151,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
int devfd = -1, r = 0;
/* Only whole sector writes supported */
if (srcLength % SECTOR_SIZE)
if (MISALIGNED_512(srcLength))
return -EINVAL;
/* Encrypt buffer */
@@ -193,8 +194,10 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
r = 0;
out:
if (devfd >= 0)
if (devfd >= 0) {
device_sync(device, devfd);
close(devfd);
}
if (r)
log_err(ctx, _("IO error while encrypting keyslot."));
@@ -210,10 +213,11 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
{
struct device *device = crypt_metadata_device(ctx);
struct crypt_storage *s;
struct stat st;
int devfd = -1, r = 0;
/* Only whole sector reads supported */
if (dstLength % SECTOR_SIZE)
if (MISALIGNED_512(dstLength))
return -EINVAL;
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);
@@ -235,17 +239,26 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
log_dbg("Using userspace crypto wrapper to access keyslot area.");
r = -EIO;
/* Read buffer from device */
devfd = device_open(device, O_RDONLY);
if (devfd < 0)
goto bad;
if (devfd < 0) {
log_err(ctx, _("Cannot open device %s."), device_path(device));
crypt_storage_destroy(s);
return -EIO;
}
if (read_lseek_blockwise(devfd, device_block_size(device),
device_alignment(device), dst, dstLength,
sector * SECTOR_SIZE) < 0)
goto bad;
sector * SECTOR_SIZE) < 0) {
if (!fstat(devfd, &st) && (st.st_size < (off_t)dstLength))
log_err(ctx, _("Device %s is too small."), device_path(device));
else
log_err(ctx, _("IO error while decrypting keyslot."));
close(devfd);
crypt_storage_destroy(s);
return -EIO;
}
close(devfd);
@@ -253,13 +266,5 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
r = crypt_storage_decrypt(s, 0, dstLength / SECTOR_SIZE, dst);
crypt_storage_destroy(s);
return r;
bad:
if (devfd >= 0)
close(devfd);
log_err(ctx, _("IO error while decrypting keyslot."));
crypt_storage_destroy(s);
return r;
}

View File

@@ -378,8 +378,10 @@ int LUKS_hdr_restore(
/* Be sure to reload new data */
r = LUKS_read_phdr(hdr, 1, 0, ctx);
out:
if (devfd >= 0)
if (devfd >= 0) {
device_sync(device, devfd);
close(devfd);
}
crypt_safe_free(buffer);
return r;
}
@@ -681,6 +683,8 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
&convHdr, hdr_size) < hdr_size ? -EIO : 0;
if (r)
log_err(ctx, _("Error during update of LUKS header on device %s."), device_path(device));
device_sync(device, devfd);
close(devfd);
/* Re-read header from disk to be sure that in-memory and on-disk data are the same. */
@@ -1206,3 +1210,56 @@ int LUKS1_activate(struct crypt_device *cd,
free(dm_cipher);
return r;
}
int LUKS_wipe_header_areas(struct luks_phdr *hdr,
struct crypt_device *ctx)
{
int i, r;
uint64_t offset, length;
size_t wipe_block;
/* Wipe complete header, keyslots and padding areas with zeroes. */
offset = 0;
length = (uint64_t)hdr->payloadOffset * SECTOR_SIZE;
wipe_block = 1024 * 1024;
/* On detached header or bogus header, wipe at least the first 4k */
if (length == 0 || length > (LUKS_MAX_KEYSLOT_SIZE * LUKS_NUMKEYS)) {
length = 4096;
wipe_block = 4096;
}
log_dbg("Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
offset, length + offset);
r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_ZERO,
offset, length, wipe_block, NULL, NULL);
if (r < 0)
return r;
/* Wipe keyslots areas */
wipe_block = 1024 * 1024;
for (i = 0; i < LUKS_NUMKEYS; i++) {
r = LUKS_keyslot_area(hdr, i, &offset, &length);
if (r < 0)
return r;
/* Ignore too big LUKS1 keyslots here */
if (length > LUKS_MAX_KEYSLOT_SIZE ||
offset > (LUKS_MAX_KEYSLOT_SIZE - length))
continue;
if (length == 0 || offset < 4096)
return -EINVAL;
log_dbg("Wiping keyslot %i area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
i, offset, length + offset);
r = crypt_wipe_device(ctx, crypt_metadata_device(ctx), CRYPT_WIPE_RANDOM,
offset, length, wipe_block, NULL, NULL);
if (r < 0)
return r;
}
return r;
}

View File

@@ -61,6 +61,9 @@
/* Offset to keyslot area [in bytes] */
#define LUKS_ALIGN_KEYSLOTS 4096
/* Maximal LUKS header size, for wipe [in bytes] */
#define LUKS_MAX_KEYSLOT_SIZE 0x1000000 /* 16 MB, up to 32768 bits key */
/* Any integer values are stored in network byte order on disk and must be
converted */
@@ -168,6 +171,9 @@ int LUKS_del_key(
struct luks_phdr *hdr,
struct crypt_device *ctx);
int LUKS_wipe_header_areas(struct luks_phdr *hdr,
struct crypt_device *ctx);
crypt_keyslot_info LUKS_keyslot_info(struct luks_phdr *hdr, int keyslot);
int LUKS_keyslot_find_empty(struct luks_phdr *hdr);
int LUKS_keyslot_active_count(struct luks_phdr *hdr);

View File

@@ -35,6 +35,7 @@
#define LUKS2_KEYSLOTS_MAX 32
#define LUKS2_TOKENS_MAX 32
#define LUKS2_SEGMENT_MAX 32
#define LUKS2_BUILTIN_TOKEN_PREFIX "luks2-"
#define LUKS2_BUILTIN_TOKEN_PREFIX_LEN 6
@@ -330,6 +331,12 @@ int LUKS2_generate_hdr(
unsigned int alignOffset,
int detached_metadata_device);
int LUKS2_check_metadata_area_size(uint64_t metadata_size);
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);
int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr);
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
int LUKS2_get_sector_size(struct luks2_hdr *hdr);
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);

View File

@@ -26,12 +26,13 @@
/*
* Helper functions
*/
json_object *parse_json_len(const char *json_area, int length, int *end_offset)
json_object *parse_json_len(const char *json_area, uint64_t max_length, int *json_len)
{
json_object *jobj;
struct json_tokener *jtok;
if (!json_area || length <= 0)
/* INT32_MAX is internal (json-c) json_tokener_parse_ex() limit */
if (!json_area || max_length > INT32_MAX)
return NULL;
jtok = json_tokener_new();
@@ -40,13 +41,13 @@ json_object *parse_json_len(const char *json_area, int length, int *end_offset)
return NULL;
}
jobj = json_tokener_parse_ex(jtok, json_area, length);
jobj = json_tokener_parse_ex(jtok, json_area, max_length);
if (!jobj)
log_dbg("ERROR: Failed to parse json data (%d): %s",
json_tokener_get_error(jtok),
json_tokener_error_desc(json_tokener_get_error(jtok)));
else
*end_offset = jtok->char_offset;
*json_len = jtok->char_offset;
json_tokener_free(jtok);
@@ -204,6 +205,12 @@ static int hdr_disk_sanity_check_pre(struct luks2_hdr_disk *hdr,
return -EINVAL;
}
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
log_dbg("LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
return -EINVAL;
}
/* FIXME: sanity check checksum alg. */
log_dbg("LUKS2 header version %u of size %u bytes, checksum %s.",
@@ -341,6 +348,7 @@ static int hdr_write_disk(struct device *device, struct luks2_hdr *hdr,
LUKS2_HDR_BIN_LEN, offset) < (ssize_t)LUKS2_HDR_BIN_LEN)
r = -EIO;
device_sync(device, devfd);
close(devfd);
return r;
}
@@ -387,11 +395,6 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
return -EINVAL;
}
if (hdr->hdr_size != LUKS2_HDR_16K_LEN) {
log_dbg("Unsupported LUKS2 header size (%zu).", hdr->hdr_size);
return -EINVAL;
}
r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
if (r)
return r;
@@ -448,7 +451,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
return r;
}
static int validate_json_area(const char *json_area, int start, int length)
static int validate_json_area(const char *json_area, uint64_t json_len, uint64_t max_length)
{
char c;
@@ -458,7 +461,7 @@ static int validate_json_area(const char *json_area, int start, int length)
return -EINVAL;
}
if (start >= length) {
if (json_len >= max_length) {
log_dbg("ERROR: Missing trailing null byte beyond parsed json data string.");
return -EINVAL;
}
@@ -466,22 +469,22 @@ static int validate_json_area(const char *json_area, int start, int length)
/*
* TODO:
* validate there are legal json format characters between
* 'json_area' and 'json_area + start'
* 'json_area' and 'json_area + json_len'
*/
do {
c = *(json_area + start);
c = *(json_area + json_len);
if (c != '\0') {
log_dbg("ERROR: Forbidden ascii code 0x%02hhx found beyond json data string at offset %d.",
c, start);
log_dbg("ERROR: Forbidden ascii code 0x%02hhx found beyond json data string at offset %" PRIu64,
c, json_len);
return -EINVAL;
}
} while (++start < length);
} while (++json_len < max_length);
return 0;
}
static int validate_luks2_json_object(json_object *jobj_hdr)
static int validate_luks2_json_object(json_object *jobj_hdr, uint64_t length)
{
int r;
@@ -492,14 +495,14 @@ static int validate_luks2_json_object(json_object *jobj_hdr)
return r;
}
r = LUKS2_hdr_validate(jobj_hdr);
r = LUKS2_hdr_validate(jobj_hdr, length);
if (r) {
log_dbg("Repairing JSON metadata.");
/* try to correct known glitches */
LUKS2_hdr_repair(jobj_hdr);
/* run validation again */
r = LUKS2_hdr_validate(jobj_hdr);
r = LUKS2_hdr_validate(jobj_hdr, length);
}
if (r)
@@ -508,20 +511,20 @@ static int validate_luks2_json_object(json_object *jobj_hdr)
return r;
}
static json_object *parse_and_validate_json(const char *json_area, int length)
static json_object *parse_and_validate_json(const char *json_area, uint64_t max_length)
{
int offset, r;
json_object *jobj = parse_json_len(json_area, length, &offset);
int json_len, r;
json_object *jobj = parse_json_len(json_area, max_length, &json_len);
if (!jobj)
return NULL;
/* successful parse_json_len must not return offset <= 0 */
assert(offset > 0);
assert(json_len > 0);
r = validate_json_area(json_area, offset, length);
r = validate_json_area(json_area, json_len, max_length);
if (!r)
r = validate_luks2_json_object(jobj);
r = validate_luks2_json_object(jobj, max_length);
if (r) {
json_object_put(jobj);

View File

@@ -58,7 +58,7 @@ json_object *LUKS2_get_tokens_jobj(struct luks2_hdr *hdr);
void hexprint_base64(struct crypt_device *cd, json_object *jobj,
const char *sep, const char *line_sep);
json_object *parse_json_len(const char *json_area, int length, int *end_offset);
json_object *parse_json_len(const char *json_area, uint64_t max_length, int *json_len);
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);
@@ -73,7 +73,7 @@ void JSON_DBG(json_object *jobj, const char *desc);
json_object *json_contains(json_object *jobj, const char *name, const char *section,
const char *key, json_type type);
int LUKS2_hdr_validate(json_object *hdr_jobj);
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size);
int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key);
int LUKS2_check_json_size(const struct luks2_hdr *hdr);
int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const char *key);

View File

@@ -114,6 +114,22 @@ int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
return 0;
}
int LUKS2_check_metadata_area_size(uint64_t metadata_size)
{
/* see LUKS2_HDR2_OFFSETS */
return (metadata_size != 0x004000 &&
metadata_size != 0x008000 && metadata_size != 0x010000 &&
metadata_size != 0x020000 && metadata_size != 0x040000 &&
metadata_size != 0x080000 && metadata_size != 0x100000 &&
metadata_size != 0x200000 && metadata_size != 0x400000);
}
int LUKS2_check_keyslots_area_size(uint64_t keyslots_size)
{
return (MISALIGNED_4K(keyslots_size) ||
keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE);
}
int LUKS2_generate_hdr(
struct crypt_device *cd,
struct luks2_hdr *hdr,
@@ -122,9 +138,9 @@ int LUKS2_generate_hdr(
const char *cipherMode,
const char *integrity,
const char *uuid,
unsigned int sector_size,
unsigned int alignPayload,
unsigned int alignOffset,
unsigned int sector_size, /* in bytes */
unsigned int alignPayload, /* in bytes */
unsigned int alignOffset, /* in bytes */
int detached_metadata_device)
{
struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
@@ -182,11 +198,11 @@ int LUKS2_generate_hdr(
jobj_segment = json_object_new_object();
json_object_object_add(jobj_segment, "type", json_object_new_string("crypt"));
if (detached_metadata_device)
offset = (uint64_t)alignPayload * sector_size;
offset = (uint64_t)alignPayload;
else {
//FIXME
//offset = size_round_up(areas[7].offset + areas[7].length, alignPayload * SECTOR_SIZE);
offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload * sector_size);
offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload);
offset += alignOffset;
}
@@ -229,3 +245,44 @@ int LUKS2_generate_hdr(
JSON_DBG(hdr->jobj, "Header JSON");
return 0;
}
int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr)
{
int r;
uint64_t offset, length;
size_t wipe_block;
/* Wipe complete header, keyslots and padding areas with zeroes. */
offset = 0;
length = LUKS2_get_data_offset(hdr) * SECTOR_SIZE;
wipe_block = 1024 * 1024;
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL;
/* On detached header wipe at least the first 4k */
if (length == 0) {
length = 4096;
wipe_block = 4096;
}
log_dbg("Wiping LUKS areas (0x%06" PRIx64 " - 0x%06" PRIx64") with zeroes.",
offset, length + offset);
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
offset, length, wipe_block, NULL, NULL);
if (r < 0)
return r;
/* Wipe keyslot area */
wipe_block = 1024 * 1024;
offset = get_min_offset(hdr);
length = LUKS2_keyslots_size(hdr->jobj);
log_dbg("Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
offset, length + offset);
return crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_RANDOM,
offset, length, wipe_block, NULL, NULL);
}

View File

@@ -363,12 +363,13 @@ static json_bool segment_has_digest(const char *segment_name, json_object *jobj_
return FALSE;
}
static json_bool validate_intervals(int length, const struct interval *ix, uint64_t *data_offset)
static json_bool validate_intervals(int length, const struct interval *ix,
uint64_t metadata_size, uint64_t keyslots_area_end)
{
int j, i = 0;
while (i < length) {
if (ix[i].offset < 2 * LUKS2_HDR_16K_LEN) {
if (ix[i].offset < 2 * metadata_size) {
log_dbg("Illegal area offset: %" PRIu64 ".", ix[i].offset);
return FALSE;
}
@@ -378,10 +379,9 @@ static json_bool validate_intervals(int length, const struct interval *ix, uint6
return FALSE;
}
/* first segment at offset 0 means we have detached header. Do not check then. */
if (*data_offset && (ix[i].offset + ix[i].length) > *data_offset) {
log_dbg("Area [%" PRIu64 ", %" PRIu64 "] intersects with segment starting at offset: %" PRIu64,
ix[i].offset, ix[i].offset + ix[i].length, *data_offset);
if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
log_dbg("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;
}
@@ -402,7 +402,6 @@ static json_bool validate_intervals(int length, const struct interval *ix, uint6
return TRUE;
}
static int hdr_validate_areas(json_object *hdr_jobj);
int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
{
json_object *jobj_key_size;
@@ -419,9 +418,6 @@ int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, cons
return 1;
}
if (hdr_validate_areas(hdr_jobj))
return 1;
return 0;
}
@@ -446,7 +442,7 @@ int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const c
return 0;
}
static int hdr_validate_json_size(json_object *hdr_jobj)
static int hdr_validate_json_size(json_object *hdr_jobj, uint64_t hdr_json_size)
{
json_object *jobj, *jobj1;
const char *json;
@@ -460,12 +456,22 @@ static int hdr_validate_json_size(json_object *hdr_jobj)
json_area_size = json_object_get_uint64(jobj1);
json_size = (uint64_t)strlen(json);
return json_size > json_area_size ? 1 : 0;
if (hdr_json_size != json_area_size) {
log_dbg("JSON area size doesn't match value in binary header.");
return 1;
}
if (json_size > json_area_size) {
log_dbg("JSON doesn't fit in the designated area.");
return 1;
}
return 0;
}
int LUKS2_check_json_size(const struct luks2_hdr *hdr)
{
return hdr_validate_json_size(hdr->jobj);
return hdr_validate_json_size(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
}
static int hdr_validate_keyslots(json_object *hdr_jobj)
@@ -535,22 +541,14 @@ static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_o
}
sector_size = json_object_get_uint32(jobj_sector_size);
if (!sector_size || sector_size % SECTOR_SIZE) {
if (!sector_size || MISALIGNED_512(sector_size)) {
log_dbg("Illegal sector size: %" PRIu32, sector_size);
return 1;
}
if (!numbered("iv_tweak", json_object_get_string(jobj_ivoffset)) ||
!json_str_to_uint64(jobj_ivoffset, &ivoffset))
return 1;
if (offset % sector_size) {
log_dbg("Offset field has to be aligned to sector size: %" PRIu32, sector_size);
return 1;
}
if (ivoffset % sector_size) {
log_dbg("IV offset field has to be aligned to sector size: %" PRIu32, sector_size);
!json_str_to_uint64(jobj_ivoffset, &ivoffset)) {
log_dbg("Illegal iv_tweak value.");
return 1;
}
@@ -564,7 +562,8 @@ static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_o
static int hdr_validate_segments(json_object *hdr_jobj)
{
json_object *jobj, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type;
json_object *jobj, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags;
int i;
uint64_t offset, size;
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj)) {
@@ -604,15 +603,24 @@ static int hdr_validate_segments(json_object *hdr_jobj)
size = 0;
/* all device-mapper devices are aligned to 512 sector size */
if (offset % SECTOR_SIZE) {
if (MISALIGNED_512(offset)) {
log_dbg("Offset field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
return 1;
}
if (size % SECTOR_SIZE) {
if (MISALIGNED_512(size)) {
log_dbg("Size field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
return 1;
}
/* flags array is optional and must contain strings */
if (json_object_object_get_ex(val, "flags", NULL)) {
if (!(jobj_flags = json_contains(val, key, "Segment", "flags", json_type_array)))
return 1;
for (i = 0; i < (int) json_object_array_length(jobj_flags); i++)
if (!json_object_is_type(json_object_array_get_idx(jobj_flags, i), json_type_string))
return 1;
}
/* crypt */
if (!strcmp(json_object_get_string(jobj_type), "crypt") &&
hdr_validate_crypt_segment(val, key, jobj_digests, offset, size))
@@ -622,12 +630,24 @@ static int hdr_validate_segments(json_object *hdr_jobj)
return 0;
}
static uint64_t LUKS2_metadata_size(json_object *jobj)
{
json_object *jobj1, *jobj2;
uint64_t json_size;
json_object_object_get_ex(jobj, "config", &jobj1);
json_object_object_get_ex(jobj1, "json_size", &jobj2);
json_str_to_uint64(jobj2, &json_size);
return json_size + LUKS2_HDR_BIN_LEN;
}
static int hdr_validate_areas(json_object *hdr_jobj)
{
struct interval *intervals;
json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area;
int length, ret, i = 0;
uint64_t first_offset;
uint64_t metadata_size;
if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
return 1;
@@ -636,6 +656,9 @@ static int hdr_validate_areas(json_object *hdr_jobj)
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
return 1;
/* config is already validated */
metadata_size = LUKS2_metadata_size(hdr_jobj);
length = json_object_object_length(jobj_keyslots);
/* Empty section */
@@ -679,9 +702,7 @@ static int hdr_validate_areas(json_object *hdr_jobj)
return 1;
}
first_offset = get_first_data_offset(jobj_segments, NULL);
ret = validate_intervals(length, intervals, &first_offset) ? 0 : 1;
ret = validate_intervals(length, intervals, metadata_size, LUKS2_hdr_and_areas_size(hdr_jobj)) ? 0 : 1;
free(intervals);
@@ -723,56 +744,11 @@ static int hdr_validate_digests(json_object *hdr_jobj)
return 0;
}
/* requires keyslots and segments sections being already validated */
static int validate_keyslots_size(json_object *hdr_jobj, json_object *jobj_keyslots_size)
{
json_object *jobj_keyslots, *jobj, *jobj1;
uint64_t keyslots_size, segment_offset, keyslots_area_sum = 0;
if (!json_str_to_uint64(jobj_keyslots_size, &keyslots_size))
return 1;
if (keyslots_size % 4096) {
log_dbg("keyslots_size is not 4 KiB aligned");
return 1;
}
if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE) {
log_dbg("keyslots_size is too large. The cap is %" PRIu64 " bytes", (uint64_t) LUKS2_MAX_KEYSLOTS_SIZE);
return 1;
}
json_object_object_get_ex(hdr_jobj, "segments", &jobj);
segment_offset = get_first_data_offset(jobj, "crypt");
if (segment_offset &&
(segment_offset < keyslots_size ||
(segment_offset - keyslots_size) < (2 * LUKS2_HDR_16K_LEN))) {
log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64 ", keyslots offset: %d", keyslots_size, segment_offset, 2 * LUKS2_HDR_16K_LEN);
return 1;
}
json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots);
json_object_object_foreach(jobj_keyslots, key, val) {
UNUSED(key);
json_object_object_get_ex(val, "area", &jobj);
json_object_object_get_ex(jobj, "size", &jobj1);
keyslots_area_sum += json_object_get_uint64(jobj1);
}
if (keyslots_area_sum > keyslots_size) {
log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %" PRIu64, keyslots_area_sum, keyslots_size);
return 1;
}
return 0;
}
static int hdr_validate_config(json_object *hdr_jobj)
{
json_object *jobj_config, *jobj, *jobj1;
int i;
uint64_t json_size;
uint64_t keyslots_size, metadata_size, segment_offset;
if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
log_dbg("Missing config section.");
@@ -780,25 +756,40 @@ static int hdr_validate_config(json_object *hdr_jobj)
}
if (!(jobj = json_contains(jobj_config, "section", "Config", "json_size", json_type_string)) ||
!json_str_to_uint64(jobj, &json_size))
!json_str_to_uint64(jobj, &metadata_size))
return 1;
/* currently it's hardcoded */
if (json_size != (LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN)) {
log_dbg("Invalid json_size %" PRIu64, json_size);
/* single metadata instance is assembled from json area size plus
* binary header size */
metadata_size += LUKS2_HDR_BIN_LEN;
if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)) ||
!json_str_to_uint64(jobj, &keyslots_size))
return 1;
if (LUKS2_check_metadata_area_size(metadata_size)) {
log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", metadata_size);
return 1;
}
if (json_size % 4096) {
log_dbg("Json area is not properly aligned to 4 KiB.");
if (LUKS2_check_keyslots_area_size(keyslots_size)) {
log_dbg("Unsupported LUKS2 keyslots size (%" PRIu64 ").", keyslots_size);
return 1;
}
if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)))
return 1;
if (validate_keyslots_size(hdr_jobj, jobj))
/*
* validate keyslots_size fits in between (2 * metadata_size) and first
* segment_offset (except detached header)
*/
json_object_object_get_ex(hdr_jobj, "segments", &jobj);
segment_offset = get_first_data_offset(jobj, "crypt");
if (segment_offset &&
(segment_offset < keyslots_size ||
(segment_offset - keyslots_size) < (2 * metadata_size))) {
log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64
", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size);
return 1;
}
/* Flags array is optional */
if (json_object_object_get_ex(jobj_config, "flags", &jobj)) {
@@ -831,7 +822,7 @@ static int hdr_validate_config(json_object *hdr_jobj)
return 0;
}
int LUKS2_hdr_validate(json_object *hdr_jobj)
int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size)
{
struct {
int (*validate)(json_object *);
@@ -840,8 +831,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
{ hdr_validate_digests },
{ hdr_validate_segments },
{ hdr_validate_keyslots },
{ hdr_validate_areas },
{ hdr_validate_config },
{ hdr_validate_areas },
{ NULL }
};
int i;
@@ -853,10 +844,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
if (checks[i].validate && checks[i].validate(hdr_jobj))
return 1;
if (hdr_validate_json_size(hdr_jobj)) {
log_dbg("Json header is too large.");
if (hdr_validate_json_size(hdr_jobj, json_size))
return 1;
}
/* validate keyslot implementations */
if (LUKS2_keyslots_validate(hdr_jobj))
@@ -904,7 +893,7 @@ int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(hdr->jobj))
if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd));
@@ -964,14 +953,7 @@ uint64_t LUKS2_keyslots_size(json_object *jobj)
uint64_t LUKS2_hdr_and_areas_size(json_object *jobj)
{
json_object *jobj1, *jobj2;
uint64_t json_size;
json_object_object_get_ex(jobj, "config", &jobj1);
json_object_object_get_ex(jobj1, "json_size", &jobj2);
json_str_to_uint64(jobj2, &json_size);
return 2 * (json_size + LUKS2_HDR_BIN_LEN) + LUKS2_keyslots_size(jobj);
return 2 * LUKS2_metadata_size(jobj) + LUKS2_keyslots_size(jobj);
}
int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
@@ -1189,20 +1171,19 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
/* end of TODO */
out:
LUKS2_hdr_free(hdr);
LUKS2_hdr_free(&hdr_file);
LUKS2_hdr_free(&tmp_hdr);
crypt_memzero(&hdr_file, sizeof(hdr_file));
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
crypt_safe_free(buffer);
if (devfd >= 0)
if (devfd >= 0) {
device_sync(device, devfd);
close(devfd);
if (!r) {
LUKS2_hdr_free(hdr);
r = LUKS2_hdr_read(cd, hdr, 1);
}
return r;
}
@@ -1265,9 +1246,11 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3
jobj_flags = json_object_new_array();
for (i = 0; persistent_flags[i].description; i++) {
if (flags & persistent_flags[i].flag)
if (flags & persistent_flags[i].flag) {
log_dbg("Setting persistent flag: %s.", persistent_flags[i].description);
json_object_array_add(jobj_flags,
json_object_new_string(persistent_flags[i].description));
}
}
/* Replace or add new flags array */
@@ -1539,40 +1522,56 @@ static void hdr_dump_tokens(struct crypt_device *cd, json_object *hdr_jobj)
}
}
/* FIXME: sort segments when more segments available later */
static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj)
{
json_object *jobj1, *jobj2, *jobj3;
char segment[16];
json_object *jobj_segments, *jobj_segment, *jobj1, *jobj2;
int i, j, flags;
uint64_t value;
log_std(cd, "Data segments:\n");
json_object_object_get_ex(hdr_jobj, "segments", &jobj1);
json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments);
json_object_object_foreach(jobj1, key, val) {
json_object_object_get_ex(val, "type", &jobj2);
log_std(cd, " %s: %s\n", key, json_object_get_string(jobj2));
for (i = 0; i < LUKS2_SEGMENT_MAX; i++) {
(void) snprintf(segment, sizeof(segment), "%i", i);
if (!json_object_object_get_ex(jobj_segments, segment, &jobj_segment))
continue;
json_object_object_get_ex(val, "offset", &jobj3);
json_str_to_uint64(jobj3, &value);
json_object_object_get_ex(jobj_segment, "type", &jobj1);
log_std(cd, " %s: %s\n", segment, json_object_get_string(jobj1));
json_object_object_get_ex(jobj_segment, "offset", &jobj1);
json_str_to_uint64(jobj1, &value);
log_std(cd, "\toffset: %" PRIu64 " [bytes]\n", value);
json_object_object_get_ex(val, "size", &jobj3);
if (!(strcmp(json_object_get_string(jobj3), "dynamic")))
json_object_object_get_ex(jobj_segment, "size", &jobj1);
if (!(strcmp(json_object_get_string(jobj1), "dynamic")))
log_std(cd, "\tlength: (whole device)\n");
else {
json_str_to_uint64(jobj3, &value);
json_str_to_uint64(jobj1, &value);
log_std(cd, "\tlength: %" PRIu64 " [bytes]\n", value);
}
if (json_object_object_get_ex(val, "encryption", &jobj3))
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj3));
if (json_object_object_get_ex(jobj_segment, "encryption", &jobj1))
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj1));
if (json_object_object_get_ex(val, "sector_size", &jobj3))
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj3));
if (json_object_object_get_ex(jobj_segment, "sector_size", &jobj1))
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj1));
if (json_object_object_get_ex(val, "integrity", &jobj2) &&
json_object_object_get_ex(jobj2, "type", &jobj3))
log_std(cd, "\tintegrity: %s\n", json_object_get_string(jobj3));
if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) &&
json_object_object_get_ex(jobj1, "type", &jobj2))
log_std(cd, "\tintegrity: %s\n", json_object_get_string(jobj2));
if (json_object_object_get_ex(jobj_segment, "flags", &jobj1) &&
(flags = (int)json_object_array_length(jobj1)) > 0) {
jobj2 = json_object_array_get_idx(jobj1, 0);
log_std(cd, "\tflags : %s", json_object_get_string(jobj2));
for (j = 1; j < flags; j++) {
jobj2 = json_object_array_get_idx(jobj1, j);
log_std(cd, ", %s", json_object_get_string(jobj2));
}
log_std(cd, "\n");
}
log_std(cd, "\n");
}
@@ -1898,7 +1897,7 @@ int LUKS2_activate(struct crypt_device *cd,
}
snprintf(dm_int_name, sizeof(dm_int_name), "%s_dif", name);
r = INTEGRITY_activate(cd, dm_int_name, NULL, NULL, NULL, NULL, flags);
r = INTEGRITY_activate(cd, dm_int_name, NULL, NULL, NULL, NULL, dmd.flags);
if (r)
return r;

View File

@@ -114,13 +114,18 @@ int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment)
int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd)
{
const char *cipher = crypt_get_cipher(cd);
const char *cipher_mode = crypt_get_cipher_mode(cd);
/* Keyslot is already authenticated; we cannot use integrity tags here */
if (crypt_get_integrity_tag_size(cd) || !cipher)
return 1;
/* Wrapped key schemes cannot be used for keyslot encryption */
if (crypt_cipher_wrapped_key(cipher))
if (crypt_cipher_wrapped_key(cipher, cipher_mode))
return 1;
/* Check if crypto backend can use the cipher */
if (crypt_cipher_ivsize(cipher, cipher_mode) < 0)
return 1;
return 0;

View File

@@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
int devfd = -1, r;
/* Only whole sector writes supported */
if (srcLength % SECTOR_SIZE)
if (MISALIGNED_512(srcLength))
return -EINVAL;
/* Encrypt buffer */
@@ -79,6 +79,8 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
r = -EIO;
else
r = 0;
device_sync(device, devfd);
close(devfd);
} else
r = -EIO;
@@ -111,7 +113,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
int devfd = -1, r;
/* Only whole sector writes supported */
if (dstLength % SECTOR_SIZE)
if (MISALIGNED_512(dstLength))
return -EINVAL;
r = crypt_storage_init(&s, 0, cipher, cipher_mode, vk->key, vk->keylength);

View File

@@ -461,6 +461,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
r = 0;
out:
device_sync(device, devfd);
close(devfd);
crypt_memzero(buf, buf_size);
free(buf);
@@ -644,7 +645,7 @@ static int keyslot_LUKS1_compatible(struct luks2_hdr *hdr, int keyslot, uint32_t
int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct luks_phdr *hdr1)
{
size_t buf_size, buf_offset;
char cipher[LUKS_CIPHERNAME_L], cipher_mode[LUKS_CIPHERMODE_L];
char cipher[LUKS_CIPHERNAME_L-1], cipher_mode[LUKS_CIPHERMODE_L-1];
char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE];
size_t len;
json_object *jobj_keyslot, *jobj_digest, *jobj_segment, *jobj_kdf, *jobj_area, *jobj1, *jobj2;
@@ -673,7 +674,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (r < 0)
return r;
if (crypt_cipher_wrapped_key(cipher)) {
if (crypt_cipher_wrapped_key(cipher, cipher_mode)) {
log_err(cd, _("Cannot convert to LUKS1 format - device uses wrapped key cipher %s."), cipher);
return -EINVAL;
}
@@ -828,7 +829,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
/* FIXME: LUKS1 requires offset == 0 || offset >= luks1_hdr_size */
hdr1->payloadOffset = offset;
strncpy(hdr1->uuid, hdr2->uuid, UUID_STRING_L - 1); /* max 36 chars */
strncpy(hdr1->uuid, hdr2->uuid, UUID_STRING_L); /* max 36 chars */
hdr1->uuid[UUID_STRING_L-1] = '\0';
memcpy(hdr1->magic, luksMagic, LUKS_MAGIC_L);

View File

@@ -182,6 +182,11 @@ static const char *mdata_device_path(struct crypt_device *cd)
return device_path(cd->metadata_device ?: cd->device);
}
static const char *data_device_path(struct crypt_device *cd)
{
return device_path(cd->device);
}
/* internal only */
struct device *crypt_metadata_device(struct crypt_device *cd)
{
@@ -777,8 +782,11 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
* perform repair.
*/
r = _crypt_load_luks2(cd, cd->type != NULL, repair);
} else
} else {
if (version > 2)
log_err(cd, _("Unsupported LUKS version %d."), version);
r = -EINVAL;
}
out:
crypt_memzero(&hdr, sizeof(hdr));
@@ -1340,6 +1348,7 @@ static int _crypt_format_plain(struct crypt_device *cd,
struct crypt_params_plain *params)
{
unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE;
uint64_t dev_size;
if (!cipher || !cipher_mode) {
log_err(cd, _("Invalid plain crypt parameters."));
@@ -1361,11 +1370,20 @@ static int _crypt_format_plain(struct crypt_device *cd,
sector_size = SECTOR_SIZE;
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
(sector_size & (sector_size - 1))) {
NOTPOW2(sector_size)) {
log_err(cd, _("Unsupported encryption sector size."));
return -EINVAL;
}
if (sector_size > SECTOR_SIZE && !device_size(cd->device, &dev_size)) {
if (params && params->offset)
dev_size -= (params->offset * SECTOR_SIZE);
if (dev_size % sector_size) {
log_err(cd, _("Device size is not aligned to requested sector size."));
return -EINVAL;
}
}
if (!(cd->type = strdup(CRYPT_PLAIN)))
return -ENOMEM;
@@ -1466,9 +1484,7 @@ static int _crypt_format_luks1(struct crypt_device *cd,
if (r < 0)
return r;
/* Wipe first 8 sectors - fs magic numbers etc. */
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO, 0,
8 * SECTOR_SIZE, 8 * SECTOR_SIZE, NULL, NULL);
r = LUKS_wipe_header_areas(&cd->u.luks1.hdr, cd);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
@@ -1493,6 +1509,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
unsigned long alignment_offset = 0;
unsigned int sector_size = params ? params->sector_size : SECTOR_SIZE;
const char *integrity = params ? params->integrity : NULL;
uint64_t dev_size;
cd->u.luks2.hdr.jobj = NULL;
@@ -1505,7 +1522,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
}
if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE ||
(sector_size & (sector_size - 1))) {
NOTPOW2(sector_size)) {
log_err(cd, _("Unsupported encryption sector size."));
return -EINVAL;
}
@@ -1535,12 +1552,8 @@ static int _crypt_format_luks2(struct crypt_device *cd,
}
r = device_check_access(cd, crypt_metadata_device(cd), DEV_EXCL);
if (r < 0) {
log_err(cd, _("Cannot use device %s which is in use "
"(already mapped or mounted)."),
device_path(crypt_metadata_device(cd)));
if (r < 0)
return r;
}
if (!(cd->type = strdup(CRYPT_LUKS2)))
return -ENOMEM;
@@ -1567,9 +1580,9 @@ static int _crypt_format_luks2(struct crypt_device *cd,
cd->device = NULL;
if (device_alloc(&cd->device, params->data_device) < 0)
return -ENOMEM;
required_alignment = params->data_alignment * sector_size;
required_alignment = params->data_alignment * SECTOR_SIZE;
} else if (params && params->data_alignment) {
required_alignment = params->data_alignment * sector_size;
required_alignment = params->data_alignment * SECTOR_SIZE;
} else
device_topology_alignment(cd->device,
&required_alignment,
@@ -1583,8 +1596,16 @@ static int _crypt_format_luks2(struct crypt_device *cd,
goto out;
}
/* FIXME: we have no way how to check AEAD ciphers,
* only length preserving mode or authenc() composed modes */
/* FIXME: allow this later also for normal ciphers (check AF_ALG availability. */
if (integrity && !integrity_key_size) {
r = crypt_cipher_check(cipher, cipher_mode, integrity, volume_key_size);
if (r < 0) {
log_err(cd, _("Cipher %s-%s (key size %zd bits) is not available."),
cipher, cipher_mode, volume_key_size * 8);
goto out;
}
}
if ((!integrity || integrity_key_size) && !LUKS2_keyslot_cipher_incompatible(cd)) {
r = LUKS_check_cipher(cd, volume_key_size - integrity_key_size,
cipher, cipher_mode);
@@ -1596,12 +1617,21 @@ static int _crypt_format_luks2(struct crypt_device *cd,
cipher, cipher_mode,
integrity, uuid,
sector_size,
required_alignment / sector_size,
alignment_offset / sector_size,
required_alignment,
alignment_offset,
cd->metadata_device ? 1 : 0);
if (r < 0)
goto out;
if (!integrity && sector_size > SECTOR_SIZE && !device_size(crypt_data_device(cd), &dev_size)) {
dev_size -= (crypt_get_data_offset(cd) * SECTOR_SIZE);
if (dev_size % sector_size) {
log_err(cd, _("Device size is not aligned to requested sector size."));
r = -EINVAL;
goto out;
}
}
if (params && (params->label || params->subsystem)) {
r = LUKS2_hdr_labels(cd, &cd->u.luks2.hdr,
params->label, params->subsystem, 0);
@@ -1609,41 +1639,37 @@ static int _crypt_format_luks2(struct crypt_device *cd,
goto out;
}
r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
goto out;
}
/* Wipe integrity superblock and create integrity superblock */
if (crypt_get_integrity_tag_size(cd)) {
/* FIXME: this should be locked. */
r = crypt_wipe_device(cd, crypt_metadata_device(cd), CRYPT_WIPE_ZERO,
r = crypt_wipe_device(cd, crypt_data_device(cd), CRYPT_WIPE_ZERO,
crypt_get_data_offset(cd) * SECTOR_SIZE,
8 * SECTOR_SIZE, 8 * SECTOR_SIZE, NULL, NULL);
if (r < 0) {
if (r == -EBUSY)
log_err(cd, _("Cannot format device %s which is still in use."),
mdata_device_path(cd));
data_device_path(cd));
else if (r == -EACCES) {
log_err(cd, _("Cannot format device %s, permission denied."),
mdata_device_path(cd));
data_device_path(cd));
r = -EINVAL;
} else
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
data_device_path(cd));
goto out;
}
r = device_write_lock(cd, crypt_metadata_device(cd));
if (r) {
log_err(cd, _("Failed to acquire write lock on device %s."),
mdata_device_path(cd));
r = -EINVAL;
goto out;
}
r = INTEGRITY_format(cd, params ? params->integrity_params : NULL, NULL, NULL);
if (r)
log_err(cd, _("Cannot format integrity for device %s."),
mdata_device_path(cd));
device_write_unlock(crypt_metadata_device(cd));
data_device_path(cd));
}
if (r < 0)
@@ -1740,12 +1766,12 @@ static int _crypt_format_verity(struct crypt_device *cd,
return -EINVAL;
}
if (params->hash_area_offset % 512) {
if (MISALIGNED_512(params->hash_area_offset)) {
log_err(cd, _("Unsupported VERITY hash offset."));
return -EINVAL;
}
if (params->fec_area_offset % 512) {
if (MISALIGNED_512(params->fec_area_offset)) {
log_err(cd, _("Unsupported VERITY FEC offset."));
return -EINVAL;
}
@@ -2112,7 +2138,7 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
if (r)
goto out;
if (new_size & ((dmd.u.crypt.sector_size >> SECTOR_SHIFT) - 1)) {
if (MISALIGNED(new_size, dmd.u.crypt.sector_size >> SECTOR_SHIFT)) {
log_err(cd, _("Device %s size is not aligned to requested sector size (%u bytes)."),
crypt_get_device_name(cd), (unsigned)dmd.u.crypt.sector_size);
r = -EINVAL;
@@ -2255,17 +2281,20 @@ int crypt_header_restore(struct crypt_device *cd,
else
r = LUKS2_hdr_restore(cd, &hdr2, backup_file);
LUKS2_hdr_free(&hdr2);
crypt_memzero(&hdr1, sizeof(hdr1));
crypt_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);
/* FIXME: if (r != 0) context may be lost */
} else if (isLUKS1(cd->type) && (!requested_type || isLUKS1(requested_type))) {
if (r)
_luks2_reload(cd);
} else if (isLUKS1(cd->type) && (!requested_type || isLUKS1(requested_type)))
r = LUKS_hdr_restore(backup_file, &cd->u.luks1.hdr, cd);
} else
else
r = -EINVAL;
if (!r)
r = _crypt_load_luks(cd, version == 1 ? CRYPT_LUKS1 : CRYPT_LUKS2, 1, 1);
return r;
}
@@ -2359,7 +2388,7 @@ int crypt_suspend(struct crypt_device *cd,
key_desc = crypt_get_device_key_description(name);
/* we can't simply wipe wrapped keys */
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd)))
if (crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd)))
r = dm_suspend_device(cd, name);
else
r = dm_suspend_and_wipe_key(cd, name);
@@ -2907,6 +2936,23 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot)
return LUKS2_keyslot_wipe(cd, &cd->u.luks2.hdr, keyslot, 0);
}
static int _check_header_data_overlap(struct crypt_device *cd, const char *name)
{
if (!name || !isLUKS(cd->type))
return 0;
if (!device_is_identical(crypt_data_device(cd), crypt_metadata_device(cd)))
return 0;
/* FIXME: check real header size */
if (crypt_get_data_offset(cd) == 0) {
log_err(cd, _("Device header overlaps with data area."));
return -EINVAL;
}
return 0;
}
/*
* Activation/deactivation of a device
*/
@@ -2926,6 +2972,10 @@ static int _activate_by_passphrase(struct crypt_device *cd,
if ((flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) && name)
return -EINVAL;
r = _check_header_data_overlap(cd, name);
if (r < 0)
return r;
/* plain, use hashed passphrase */
if (isPLAIN(cd->type)) {
if (!name)
@@ -3126,6 +3176,10 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
if (r < 0)
return r;
r = _check_header_data_overlap(cd, name);
if (r < 0)
return r;
/* use key directly, no hash */
if (isPLAIN(cd->type)) {
if (!name)
@@ -3322,13 +3376,14 @@ int crypt_deactivate(struct crypt_device *cd, const char *name)
int crypt_get_active_device(struct crypt_device *cd, const char *name,
struct crypt_active_device *cad)
{
struct crypt_dm_active_device dmd;
struct crypt_dm_active_device dmd = {}, dmdi = {};
const char *namei = NULL;
int r;
if (!cd || !name || !cad)
return -EINVAL;
r = dm_query_device(cd, name, 0, &dmd);
r = dm_query_device(cd, name, DM_ACTIVE_DEVICE, &dmd);
if (r < 0)
return r;
@@ -3337,6 +3392,14 @@ int crypt_get_active_device(struct crypt_device *cd, const char *name,
dmd.target != DM_INTEGRITY)
return -ENOTSUP;
/* For LUKS2 with integrity we need flags from underlying dm-integrity */
if (isLUKS2(cd->type) && crypt_get_integrity_tag_size(cd)) {
namei = device_dm_name(dmd.data_device);
if (namei && dm_query_device(cd, namei, 0, &dmdi) >= 0)
dmd.flags |= dmdi.flags;
}
device_free(dmd.data_device);
if (cd && isTCRYPT(cd->type)) {
cad->offset = TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
cad->iv_offset = TCRYPT_get_iv_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params);
@@ -3386,7 +3449,8 @@ int crypt_volume_key_get(struct crypt_device *cd,
return -EINVAL;
/* wrapped keys or unbound keys may be exported */
if (crypt_fips_mode() && !crypt_cipher_wrapped_key(crypt_get_cipher(cd))) {
if (crypt_fips_mode() &&
!crypt_cipher_wrapped_key(crypt_get_cipher(cd), crypt_get_cipher_mode(cd))) {
if (!isLUKS2(cd->type) || keyslot == CRYPT_ANY_SLOT ||
!LUKS2_keyslot_for_segment(&cd->u.luks2.hdr, keyslot, CRYPT_DEFAULT_SEGMENT)) {
log_err(cd, _("Function not available in FIPS mode."));

View File

@@ -51,6 +51,8 @@ static const struct {
{ 0, 1, "pbkdf2", "sha256", 200000, 0, 2048 }, // boot only
{ 0, 1, "pbkdf2", "ripemd160", 655331, 15000, 1000 },
{ 0, 1, "pbkdf2", "ripemd160", 327661, 0, 2048 }, // boot only
{ 0, 1, "pbkdf2", "stribog512",500000, 15000, 1000 },
// { 0, 1, "pbkdf2", "stribog512",200000, 0, 2048 }, // boot only
{ 0, 0, NULL, NULL, 0, 0, 0 }
};
@@ -98,6 +100,26 @@ static struct tcrypt_algs tcrypt_cipher[] = {
{0,2,128,"serpent-twofish","xts-plain64",
{{"serpent",64,16, 0,64,0},
{"twofish",64,16,32,96,0}}},
{0,1,64,"camellia","xts-plain64",
{{"camellia", 64,16,0,32,0}}},
{0,1,64,"kuznyechik","xts-plain64",
{{"kuznyechik", 64,16,0,32,0}}},
{0,2,128,"kuznyechik-camellia","xts-plain64",
{{"kuznyechik",64,16, 0,64,0},
{"camellia", 64,16,32,96,0}}},
{0,2,128,"twofish-kuznyechik","xts-plain64",
{{"twofish", 64,16, 0,64,0},
{"kuznyechik",64,16,32,96,0}}},
{0,2,128,"serpent-camellia","xts-plain64",
{{"serpent", 64,16, 0,64,0},
{"camellia", 64,16,32,96,0}}},
{0,2,128,"aes-kuznyechik","xts-plain64",
{{"aes", 64,16, 0,64,0},
{"kuznyechik",64,16,32,96,0}}},
{0,3,192,"camellia-serpent-kuznyechik","xts-plain64",
{{"camellia", 64,16, 0, 96,0},
{"serpent", 64,16,32,128,0},
{"kuznyechik",64,16,64,160,0}}},
/* LRW mode */
{0,1,48,"aes","lrw-benbi",

View File

@@ -155,10 +155,14 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
*/
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 */

View File

@@ -190,6 +190,12 @@ static int device_ready(struct device *device)
r = -EINVAL;
else if (!S_ISBLK(st.st_mode))
r = S_ISREG(st.st_mode) ? -ENOTBLK : -EINVAL;
if (r == -EINVAL) {
log_err(NULL, _("Device %s is not compatible."),
device_path(device));
close(devfd);
return r;
}
/* Allow only increase (loop device) */
tmp_size = device_alignment_fd(devfd);
@@ -229,6 +235,16 @@ static int _open_locked(struct device *device, int flags)
return fd;
}
/*
* Common wrapper for device sync.
* FIXME: file descriptor will be in struct later.
*/
void device_sync(struct device *device, int devfd)
{
if (fsync(devfd) == -1)
log_dbg("Cannot sync device %s.", device_path(device));
}
/*
* in non-locked mode returns always fd or -1
*
@@ -242,7 +258,6 @@ static int device_open_internal(struct device *device, int flags)
{
int devfd;
flags |= O_SYNC;
if (device->o_direct)
flags |= O_DIRECT;
@@ -561,7 +576,7 @@ static int device_info(struct crypt_device *cd,
}
if (fd == -1) {
r = -EINVAL;
r = errno ? -errno : -EINVAL;
goto out;
}
@@ -597,13 +612,14 @@ out:
break;
case -EBUSY:
log_err(cd, _("Cannot use device %s which is in use "
"(already mapped or mounted)."), device->path);
"(already mapped or mounted)."), device_path(device));
break;
case -EACCES:
log_err(cd, _("Cannot use device %s, permission denied."), device->path);
log_err(cd, _("Cannot use device %s, permission denied."), device_path(device));
break;
default:
log_err(cd, _("Cannot get info about device %s."), device->path);
log_err(cd, _("Cannot get info about device %s."), device_path(device));
r = -EINVAL;
}
return r;
@@ -682,14 +698,14 @@ int device_block_adjust(struct crypt_device *cd,
if (device_offset >= real_size) {
log_err(cd, _("Requested offset is beyond real size of device %s."),
device->path);
device_path(device));
return -EINVAL;
}
if (size && !*size) {
*size = real_size;
if (!*size) {
log_err(cd, _("Device %s has zero size."), device->path);
log_err(cd, _("Device %s has zero size."), device_path(device));
return -ENOTBLK;
}
*size -= device_offset;
@@ -700,7 +716,7 @@ int device_block_adjust(struct crypt_device *cd,
log_dbg("Device %s: offset = %" PRIu64 " requested size = %" PRIu64
", backing device size = %" PRIu64,
device->path, device_offset, *size, real_size);
log_err(cd, _("Device %s is too small."), device->path);
log_err(cd, _("Device %s is too small."), device_path(device));
return -EINVAL;
}

View File

@@ -79,7 +79,6 @@ struct crypt_dm_active_device {
struct {
const char *cipher;
const char *integrity;
char *key_description;
/* Active key for device */
struct volume_key *vk;

View File

@@ -184,7 +184,8 @@ ssize_t read_blockwise(int fd, size_t bsize, size_t alignment,
out:
free(hangover_buf);
if (buf != orig_buf) {
memcpy(orig_buf, buf, length);
if (ret != -1)
memcpy(orig_buf, buf, length);
free(buf);
}
return ret;

View File

@@ -133,7 +133,8 @@ int keyring_get_passphrase(const char *key_desc,
if (ret < 0) {
err = errno;
crypt_memzero(buf, len);
if (buf)
crypt_memzero(buf, len);
free(buf);
return -err;
}

View File

@@ -63,7 +63,11 @@ int verify_pbkdf_params(struct crypt_device *cd,
{
struct crypt_pbkdf_limits pbkdf_limits;
const char *pbkdf_type;
int r = 0;
int r;
r = init_crypto(cd);
if (r < 0)
return r;
if (!pbkdf->type ||
(!pbkdf->hash && !strcmp(pbkdf->type, "pbkdf2")))
@@ -74,13 +78,17 @@ int verify_pbkdf_params(struct crypt_device *cd,
return -EINVAL;
}
/* TODO: initialise crypto and check the hash and pbkdf are both available */
r = crypt_parse_pbkdf(pbkdf->type, &pbkdf_type);
if (r < 0) {
log_err(cd, _("Unknown PBKDF type %s."), pbkdf->type);
return r;
}
if (pbkdf->hash && crypt_hash_size(pbkdf->hash) < 0) {
log_err(cd, _("Requested hash %s is not supported."), pbkdf->hash);
return -EINVAL;
}
r = crypt_pbkdf_get_limits(pbkdf->type, &pbkdf_limits);
if (r < 0)
return r;
@@ -161,11 +169,6 @@ int init_pbkdf_type(struct crypt_device *cd,
if (r < 0)
return r;
/*
* Crypto backend may be not initialized here,
* cannot check if algorithms are really available.
* It will fail later anyway :-)
*/
type = strdup(pbkdf->type);
hash = pbkdf->hash ? strdup(pbkdf->hash) : NULL;

View File

@@ -153,7 +153,7 @@ int crypt_wipe_device(struct crypt_device *cd,
/* FIXME: if wipe_block_size < bsize, then a wipe is highly ineffective */
/* Everything must be aligned to SECTOR_SIZE */
if ((offset % SECTOR_SIZE) || (length % SECTOR_SIZE) || (wipe_block_size % SECTOR_SIZE))
if (MISALIGNED_512(offset) || MISALIGNED_512(length) || MISALIGNED_512(wipe_block_size))
return -EINVAL;
devfd = device_open(device, O_RDWR);
@@ -161,9 +161,12 @@ int crypt_wipe_device(struct crypt_device *cd,
return errno ? -errno : -EINVAL;
r = device_size(device, &dev_size);
if (r)
if (r || dev_size == 0)
goto out;
if (dev_size < length)
length = 0;
if (length) {
if ((dev_size <= offset) || (dev_size - offset) < length) {
r = -EINVAL;
@@ -213,7 +216,7 @@ int crypt_wipe_device(struct crypt_device *cd,
}
}
fsync(devfd);
device_sync(device, devfd);
out:
close(devfd);
free(sf);

View File

@@ -71,7 +71,7 @@ int VERITY_read_sb(struct crypt_device *cd,
return -EINVAL;
}
if (sb_offset % 512) {
if (MISALIGNED_512(sb_offset)) {
log_err(cd, _("Unsupported VERITY hash offset."));
return -EINVAL;
}
@@ -201,6 +201,8 @@ int VERITY_write_sb(struct crypt_device *cd,
if (r)
log_err(cd, _("Error during update of verity header on device %s."),
device_path(device));
device_sync(device, devfd);
close(devfd);
return r;

View File

@@ -487,10 +487,15 @@ to standard output.
.PP
\fIconvert\fR <device> \-\-type <format>
.IP
Converts the device between LUKS and LUKS2 format (if possible).
The conversion will not be performed if there is an additional LUKS2 feature or LUKS has
Converts the device between LUKS1 and LUKS2 format (if possible).
The conversion will not be performed if there is an additional LUKS2 feature or LUKS1 has
unsupported header size.
Conversion (both directions) must be performed on inactive device. There must not be active
dm-crypt mapping established for LUKS header requested for conversion.
\fB\-\-type\fR option is mandatory with following accepted values: \fIluks1\fR or \fIluks2\fR.
\fBWARNING:\fR The \fIconvert\fR action can destroy the LUKS header in the case of a crash
during conversion or if a media error occurs.
Always create a header backup before performing this operation!
@@ -1171,6 +1176,9 @@ Specify integrity algorithm to be used for authenticated disk encryption in LUKS
\fBWARNING: This extension is EXPERIMENTAL\fR and requires dm-integrity
kernel target (available since kernel version 4.12).
For native AEAD modes, also enable "User-space interface for AEAD cipher algorithms"
in "Cryptographic API" section (CONFIG_CRYPTO_USER_API_AEAD .config option).
For more info, see \fIAUTHENTICATED DISK ENCRYPTION\fR section.
.TP
.B "\-\-integrity\-no\-journal"

View File

@@ -14,6 +14,8 @@ lib/utils_benchmark.c
lib/utils_device_locking.c
lib/utils_wipe.c
lib/utils_keyring.c
lib/utils_blkid.c
lib/utils_io.c
lib/luks1/af.c
lib/luks1/keyencryption.c
lib/luks1/keymanage.c
@@ -39,3 +41,4 @@ src/integritysetup.c
src/cryptsetup_reencrypt.c
src/utils_tools.c
src/utils_password.c
src/utils_luks2.c

1252
po/cs.po

File diff suppressed because it is too large Load Diff

3161
po/da.po

File diff suppressed because it is too large Load Diff

1073
po/de.po

File diff suppressed because it is too large Load Diff

1396
po/es.po

File diff suppressed because it is too large Load Diff

1399
po/fr.po

File diff suppressed because it is too large Load Diff

1252
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1252
po/uk.po

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,24 @@
noinst_LTLIBRARIES += libutils_tools.la
libutils_tools_la_SOURCES = \
src/utils_tools.c \
src/utils_password.c \
lib/utils_io.c \
lib/utils_blkid.c \
src/cryptsetup.h
libutils_tools_la_CFLAGS = $(AM_CFLAGS)
libutils_tools_la_LIBADD = -lm @BLKID_LIBS@ @PWQUALITY_LIBS@ @PASSWDQC_LIBS@
# cryptsetup
if CRYPTSETUP
cryptsetup_SOURCES = \
lib/utils_crypt.c \
lib/utils_loop.c \
lib/utils_io.c \
lib/utils_blkid.c \
src/utils_tools.c \
src/utils_password.c \
src/utils_luks2.c \
src/cryptsetup.c \
src/cryptsetup.h
cryptsetup_LDADD = \
cryptsetup_LDADD = -lm \
libcryptsetup.la \
libutils_tools.la \
@POPT_LIBS@ \
@UUID_LIBS@
@PWQUALITY_LIBS@ \
@PASSWDQC_LIBS@ \
@UUID_LIBS@ \
@BLKID_LIBS@
sbin_PROGRAMS += cryptsetup
@@ -46,13 +40,16 @@ if VERITYSETUP
veritysetup_SOURCES = \
lib/utils_crypt.c \
lib/utils_loop.c \
lib/utils_io.c \
lib/utils_blkid.c \
src/utils_tools.c \
src/veritysetup.c \
src/cryptsetup.h
veritysetup_LDADD = \
veritysetup_LDADD = -lm \
libcryptsetup.la \
libutils_tools.la \
@POPT_LIBS@
@POPT_LIBS@ \
@BLKID_LIBS@
sbin_PROGRAMS += veritysetup
@@ -74,14 +71,17 @@ if INTEGRITYSETUP
integritysetup_SOURCES = \
lib/utils_crypt.c \
lib/utils_loop.c \
lib/utils_io.c \
lib/utils_blkid.c \
src/utils_tools.c \
src/integritysetup.c \
src/cryptsetup.h
integritysetup_LDADD = \
integritysetup_LDADD = -lm \
libcryptsetup.la \
libutils_tools.la \
@POPT_LIBS@ \
@UUID_LIBS@
@UUID_LIBS@ \
@BLKID_LIBS@
sbin_PROGRAMS += integritysetup
@@ -101,14 +101,20 @@ endif
if REENCRYPT
cryptsetup_reencrypt_SOURCES = \
lib/utils_crypt.c \
lib/utils_io.c \
lib/utils_blkid.c \
src/utils_tools.c \
src/utils_password.c \
src/cryptsetup_reencrypt.c \
src/cryptsetup.h
cryptsetup_reencrypt_LDADD = \
cryptsetup_reencrypt_LDADD = -lm \
libcryptsetup.la \
libutils_tools.la \
@POPT_LIBS@ \
@UUID_LIBS@
@PWQUALITY_LIBS@ \
@PASSWDQC_LIBS@ \
@UUID_LIBS@ \
@BLKID_LIBS@
sbin_PROGRAMS += cryptsetup-reencrypt

View File

@@ -166,7 +166,7 @@ static void _set_activation_flags(uint32_t *flags)
static int action_open_plain(void)
{
struct crypt_device *cd = NULL;
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
char *msg, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
struct crypt_params_plain params = {
.hash = opt_hash ?: DEFAULT_PLAIN_HASH,
.skip = opt_skip,
@@ -175,8 +175,8 @@ static int action_open_plain(void)
.sector_size = opt_sector_size,
};
char *password = NULL;
size_t passwordLen, key_size_max;
size_t key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
size_t passwordLen, key_size_max, signatures = 0,
key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
uint32_t activate_flags = 0;
int r;
@@ -205,6 +205,27 @@ static int action_open_plain(void)
if ((r = crypt_init(&cd, action_argv[0])))
goto out;
/* Skip blkid scan when activating plain device with offset */
if (!opt_offset) {
/* Print all present signatures in read-only mode */
r = tools_detect_signatures(action_argv[0], 0, &signatures);
if (r < 0)
goto out;
}
if (signatures) {
r = asprintf(&msg, _("Detected device signature(s) on %s. Proceeding further may damage existing data."), action_argv[0]);
if (r == -1) {
r = -ENOMEM;
goto out;
}
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg);
if (r < 0)
goto out;
}
r = crypt_format(cd, CRYPT_PLAIN,
cipher, cipher_mode,
NULL, NULL,
@@ -748,7 +769,7 @@ static int action_benchmark(void)
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
double enc_mbr = 0, dec_mbr = 0;
int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
int iv_size = 16, skipped = 0;
int iv_size = 16, skipped = 0, width;
char *c;
int i, r;
@@ -775,13 +796,19 @@ static int action_benchmark(void)
if (!strcmp(cipher_mode, "ecb"))
iv_size = 0;
if (!strcmp(cipher_mode, "adiantum"))
iv_size = 32;
r = benchmark_cipher_loop(cipher, cipher_mode,
key_size, iv_size,
&enc_mbr, &dec_mbr);
if (!r) {
width = strlen(cipher) + strlen(cipher_mode) + 1;
if (width < 11)
width = 11;
/* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */
log_std(_("# Algorithm | Key | Encryption | Decryption\n"));
log_std("%11s-%s %9db %10.1f MiB/s %10.1f MiB/s\n",
log_std(_("#%*s Algorithm | Key | Encryption | Decryption\n"), width - 11, "");
log_std("%*s-%s %9db %10.1f MiB/s %10.1f MiB/s\n", width - (int)strlen(cipher_mode) - 1,
cipher, cipher_mode, key_size*8, enc_mbr, dec_mbr);
} else if (r == -ENOENT)
log_err(_("Cipher %s is not available."), opt_cipher);
@@ -923,7 +950,7 @@ static int _wipe_data_device(struct crypt_device *cd)
static int action_luksFormat(void)
{
int r = -EINVAL, keysize, integrity_keysize = 0, fd;
int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
struct stat st;
const char *header_device, *type;
char *msg = NULL, *key = NULL, *password = NULL;
@@ -977,8 +1004,10 @@ static int action_luksFormat(void)
fd = open(opt_header_device, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
if (fd == -1 || posix_fallocate(fd, 0, 4096))
log_err(_("Cannot create header file %s."), opt_header_device);
else
else {
r = 0;
created = 1;
}
if (fd != -1)
close(fd);
if (r < 0)
@@ -987,20 +1016,6 @@ static int action_luksFormat(void)
header_device = opt_header_device ?: action_argv[0];
/* Print all present signatures in read-only mode */
r = tools_detect_signatures(header_device, 0, &signatures);
if (r < 0)
return r;
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
if (r == -1)
return -ENOMEM;
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg);
if (r < 0)
return r;
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
cipher, NULL, cipher_mode);
if (r < 0) {
@@ -1028,6 +1043,24 @@ static int action_luksFormat(void)
return r;
}
/* Print all present signatures in read-only mode */
r = tools_detect_signatures(header_device, 0, &signatures);
if (r < 0)
goto out;
if (!created) {
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
if (r == -1) {
r = -ENOMEM;
goto out;
}
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg);
if (r < 0)
goto out;
}
keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8 + integrity_keysize;
if (opt_random)
@@ -1066,8 +1099,10 @@ static int action_luksFormat(void)
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
key, keysize,
password, passwordLen);
if (r < 0) /* FIXME: call wipe signatures again */
if (r < 0) {
(void) tools_wipe_all_signatures(header_device);
goto out;
}
tools_keyslot_msg(r, CREATED);
if (opt_integrity && !opt_integrity_no_wipe)
@@ -1098,8 +1133,11 @@ static int action_open_luks(void)
if ((r = crypt_init(&cd, header_device)))
goto out;
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
header_device);
goto out;
}
if (data_device &&
(r = crypt_set_data_device(cd, data_device)))
@@ -1217,8 +1255,11 @@ static int action_luksKillSlot(void)
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
ki = crypt_keyslot_status(cd, opt_key_slot);
switch (ki) {
@@ -1253,7 +1294,7 @@ static int action_luksKillSlot(void)
}
r = crypt_keyslot_destroy(cd, opt_key_slot);
tools_keyslot_msg(r, REMOVED);
tools_keyslot_msg(opt_key_slot, REMOVED);
out:
crypt_free(cd);
return r;
@@ -1271,8 +1312,11 @@ static int action_luksRemoveKey(void)
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
r = tools_get_key(_("Enter passphrase to be deleted: "),
&password, &passwordLen,
@@ -1303,7 +1347,7 @@ static int action_luksRemoveKey(void)
}
r = crypt_keyslot_destroy(cd, opt_key_slot);
tools_keyslot_msg(r, REMOVED);
tools_keyslot_msg(opt_key_slot, REMOVED);
out:
crypt_safe_free(password);
crypt_free(cd);
@@ -1324,8 +1368,11 @@ static int luksAddUnboundKey(void)
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
/* Never call pwquality if using null cipher */
if (tools_is_cipher_null(crypt_get_cipher(cd)))
@@ -1384,8 +1431,11 @@ static int action_luksAddKey(void)
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
/* Never call pwquality if using null cipher */
if (tools_is_cipher_null(crypt_get_cipher(cd)))
@@ -1473,8 +1523,11 @@ static int action_luksChangeKey(void)
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out;
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
/* Never call pwquality if using null cipher */
if (tools_is_cipher_null(crypt_get_cipher(cd)))
@@ -1495,7 +1548,7 @@ static int action_luksChangeKey(void)
/* Check password before asking for new one */
r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot,
password, password_size, 0);
password, password_size, CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY);
tools_passphrase_msg(r);
check_signal(&r);
if (r < 0)
@@ -1530,8 +1583,17 @@ static int action_luksConvertKey(void)
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out;
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
if (crypt_keyslot_status(cd, opt_key_slot) == CRYPT_SLOT_INACTIVE) {
r = -EINVAL;
log_err(_("Keyslot %d is not active."), opt_key_slot);
goto out;
}
r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) {
@@ -1677,8 +1739,11 @@ static int action_luksDump(void)
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out;
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
if (opt_dump_master_key)
r = luksDump_with_volume_key(cd);
@@ -1823,8 +1888,11 @@ static int action_luksErase(void)
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(opt_type), NULL)))
if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
if(asprintf(&msg, _("This operation will erase all keyslots on device %s.\n"
"Device will become unusable after this operation."),
@@ -1849,7 +1917,7 @@ static int action_luksErase(void)
r = crypt_keyslot_destroy(cd, i);
if (r < 0)
goto out;
tools_keyslot_msg(r, REMOVED);
tools_keyslot_msg(i, REMOVED);
}
}
out:
@@ -1881,6 +1949,8 @@ static int action_luksConvert(void)
if ((r = crypt_load(cd, CRYPT_LUKS, NULL)) ||
!(from_type = crypt_get_type(cd))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
crypt_free(cd);
return r;
}
@@ -1944,8 +2014,11 @@ static int action_luksConfig(void)
if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
return r;
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL));
goto out;
}
if (opt_priority && (r = _config_priority(cd)))
goto out;
@@ -2106,6 +2179,8 @@ static int action_token(void)
return r;
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device(opt_header_device ?: action_argv[1]));
crypt_free(cd);
return r;
}

View File

@@ -588,8 +588,9 @@ static int create_new_header(struct reenc_ctx *rc, struct crypt_device *cd_old,
goto out;
}
if ((r = crypt_format(cd_new, type, cipher, cipher_mode,
uuid, key, key_size, params)))
r = crypt_format(cd_new, type, cipher, cipher_mode, uuid, key, key_size, params);
check_signal(&r);
if (r < 0)
goto out;
log_verbose(_("New LUKS header for device %s created."), rc->device);
@@ -598,6 +599,7 @@ static int create_new_header(struct reenc_ctx *rc, struct crypt_device *cd_old,
continue;
r = create_new_keyslot(rc, i, cd_old, cd_new);
check_signal(&r);
if (r < 0)
goto out;
tools_keyslot_msg(r, CREATED);
@@ -835,11 +837,13 @@ static int backup_fake_header(struct reenc_ctx *rc)
r = crypt_format(cd_new, CRYPT_LUKS1, "cipher_null", "ecb",
NO_UUID, NULL, opt_key_size / 8, &params);
check_signal(&r);
if (r < 0)
goto out;
r = crypt_keyslot_add_by_volume_key(cd_new, rc->keyslot, NULL, 0,
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
check_signal(&r);
if (r < 0)
goto out;
@@ -1535,6 +1539,8 @@ static int run_reencrypt(const char *device)
.stained = 1
};
set_int_handler(0);
if (initialize_context(&rc, device))
goto out;
@@ -1654,8 +1660,6 @@ int main(int argc, const char **argv)
crypt_set_log_callback(NULL, tool_log, NULL);
set_int_block(1);
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);

View File

@@ -209,19 +209,6 @@ static int action_format(int arg)
params.journal_crypt = journal_crypt;
}
r = tools_detect_signatures(action_argv[0], 0, &signatures);
if (r < 0)
return r;
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]);
if (r == -1)
return -ENOMEM;
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg);
if (r < 0)
return r;
r = _read_keys(&integrity_key, &params);
if (r)
goto out;
@@ -230,6 +217,21 @@ static int action_format(int arg)
if (r < 0)
goto out;
r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), action_argv[0]);
if (r == -1) {
r = -ENOMEM;
goto out;
}
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg);
if (r < 0)
goto out;
r = tools_detect_signatures(action_argv[0], 0, &signatures);
if (r < 0)
goto out;
/* Signature candidates found */
if (signatures && ((r = tools_wipe_all_signatures(action_argv[0])) < 0))
goto out;

139
src/utils_luks2.c Normal file
View File

@@ -0,0 +1,139 @@
/*
* Helper utilities for LUKS2 features
*
* Copyright (C) 2018, Red Hat, Inc. All rights reserved.
* Copyright (C) 2018, Milan Broz
* Copyright (C) 2018, Ondrej Kozina
*
* 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 "cryptsetup.h"
/*
* FIXME: 4MiBs is max LUKS2 mda length (including binary header).
* In future, read max allowed JSON size from config section.
*/
#define LUKS2_MAX_MDA_SIZE 0x400000
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size)
{
ssize_t ret;
int fd, block, r;
void *buf = NULL;
block = tools_signals_blocked();
if (block)
set_int_block(0);
if (tools_is_stdin(file)) {
fd = STDIN_FILENO;
log_dbg("STDIN descriptor JSON read requested.");
} else {
log_dbg("File descriptor JSON read requested.");
fd = open(file, O_RDONLY);
if (fd < 0) {
log_err(_("Failed to open file %s in read-only mode."), file);
r = -EINVAL;
goto out;
}
}
buf = malloc(LUKS2_MAX_MDA_SIZE);
if (!buf) {
r = -ENOMEM;
goto out;
}
if (isatty(fd) && !opt_batch_mode)
log_std(_("Provide valid LUKS2 token JSON:\n"));
/* we expect JSON (string) */
r = 0;
ret = read_buffer_intr(fd, buf, LUKS2_MAX_MDA_SIZE - 1, &quit);
if (ret < 0) {
r = -EIO;
log_err(_("Failed to read JSON file."));
goto out;
}
check_signal(&r);
if (r) {
log_err(_("\nRead interrupted."));
goto out;
}
*json_size = (size_t)ret;
*json = buf;
*(*json + ret) = '\0';
out:
if (block && !quit)
set_int_block(1);
if (fd >= 0 && fd != STDIN_FILENO)
close(fd);
if (r && buf) {
memset(buf, 0, LUKS2_MAX_MDA_SIZE);
free(buf);
}
return r;
}
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json)
{
int block, fd, r;
size_t json_len;
ssize_t ret;
if (!json || !(json_len = strlen(json)) || json_len >= LUKS2_MAX_MDA_SIZE)
return -EINVAL;
block = tools_signals_blocked();
if (block)
set_int_block(0);
if (tools_is_stdin(file)) {
fd = STDOUT_FILENO;
log_dbg("STDOUT descriptor JSON write requested.");
} else {
log_dbg("File descriptor JSON write requested.");
fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
}
if (fd < 0) {
log_err(_("Failed to open file %s in write mode."), file ?: "");
r = -EINVAL;
goto out;
}
r = 0;
ret = write_buffer_intr(fd, json, json_len, &quit);
check_signal(&r);
if (r) {
log_err(_("\nWrite interrupted."));
goto out;
}
if (ret < 0 || (size_t)ret != json_len) {
log_err(_("Failed to write JSON file."));
r = -EIO;
goto out;
}
if (isatty(fd))
(void) write_buffer_intr(fd, "\n", 1, &quit);
out:
if (block && !quit)
set_int_block(1);
if (fd >=0 && fd != STDOUT_FILENO)
close(fd);
return r;
}

View File

@@ -94,25 +94,6 @@ static int tools_check_pwquality(const char *password)
}
#endif /* ENABLE_PWQUALITY || ENABLE_PASSWDQC */
int tools_is_cipher_null(const char *cipher)
{
if (!cipher)
return 0;
return !strcmp(cipher, "cipher_null") ? 1 : 0;
}
/*
* Keyfile - is standard input treated as a binary file (no EOL handling).
*/
int tools_is_stdin(const char *key_file)
{
if (!key_file)
return 1;
return strcmp(key_file, "-") ? 0 : 1;
}
/* Password reading helpers */
static int untimed_read(int fd, char *pass, size_t maxlen)
{
@@ -334,7 +315,7 @@ int tools_write_mk(const char *file, const char *key, int keysize)
{
int fd, r = -EINVAL;
fd = open(file, O_WRONLY);
fd = open(file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR);
if (fd < 0) {
log_err(_("Cannot open keyfile %s for write."), file);
return r;

View File

@@ -583,118 +583,21 @@ out:
return r;
}
int tools_is_cipher_null(const char *cipher)
{
if (!cipher)
return 0;
return !strcmp(cipher, "cipher_null") ? 1 : 0;
}
/*
* FIXME: 4MiBs is max LUKS2 mda length (including binary header).
* In future, read max allowed JSON size from config section.
* Keyfile - is standard input treated as a binary file (no EOL handling).
*/
#define LUKS2_MAX_MDA_SIZE 0x400000
int tools_read_json_file(struct crypt_device *cd, const char *file, char **json, size_t *json_size)
int tools_is_stdin(const char *key_file)
{
ssize_t ret;
int fd, block, r;
void *buf = NULL;
if (!key_file)
return 1;
block = tools_signals_blocked();
if (block)
set_int_block(0);
if (tools_is_stdin(file)) {
fd = STDIN_FILENO;
log_dbg("STDIN descriptor JSON read requested.");
} else {
log_dbg("File descriptor JSON read requested.");
fd = open(file, O_RDONLY);
if (fd < 0) {
log_err(_("Failed to open file %s in read-only mode."), file);
r = -EINVAL;
goto out;
}
}
buf = malloc(LUKS2_MAX_MDA_SIZE);
if (!buf) {
r = -ENOMEM;
goto out;
}
if (isatty(fd) && !opt_batch_mode)
log_std(_("Provide valid LUKS2 token JSON:\n"));
/* we expect JSON (string) */
r = 0;
ret = read_buffer_intr(fd, buf, LUKS2_MAX_MDA_SIZE - 1, &quit);
if (ret < 0) {
r = -EIO;
log_err(_("Failed to read JSON file."));
goto out;
}
check_signal(&r);
if (r) {
log_err(_("\nRead interrupted."));
goto out;
}
*json_size = (size_t)ret;
*json = buf;
*(*json + ret) = '\0';
out:
if (block && !quit)
set_int_block(1);
if (fd >= 0 && fd != STDIN_FILENO)
close(fd);
if (r && buf) {
memset(buf, 0, LUKS2_MAX_MDA_SIZE);
free(buf);
}
return r;
}
int tools_write_json_file(struct crypt_device *cd, const char *file, const char *json)
{
int block, fd, r;
size_t json_len;
ssize_t ret;
if (!json || !(json_len = strlen(json)) || json_len >= LUKS2_MAX_MDA_SIZE)
return -EINVAL;
block = tools_signals_blocked();
if (block)
set_int_block(0);
if (tools_is_stdin(file)) {
fd = STDOUT_FILENO;
log_dbg("STDOUT descriptor JSON write requested.");
} else {
log_dbg("File descriptor JSON write requested.");
fd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
}
if (fd < 0) {
log_err(_("Failed to open file %s in write mode."), file ?: "");
r = -EINVAL;
goto out;
}
r = 0;
ret = write_buffer_intr(fd, json, json_len, &quit);
check_signal(&r);
if (r) {
log_err(_("\nWrite interrupted."));
goto out;
}
if (ret < 0 || (size_t)ret != json_len) {
log_err(_("Failed to write JSON file."));
r = -EIO;
goto out;
}
if (isatty(fd))
(void) write_buffer_intr(fd, "\n", 1, &quit);
out:
if (block && !quit)
set_int_block(1);
if (fd >=0 && fd != STDOUT_FILENO)
close(fd);
return r;
return strcmp(key_file, "-") ? 0 : 1;
}

28
tests/00modules-test Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
echo "Cryptsetup test environment ($(date))"
uname -a
if [ -f /etc/os-release ] ; then
source /etc/os-release
echo "$PRETTY_NAME ($NAME) $VERSION"
fi
[ -x ../cryptsetup ] && ../cryptsetup --version
[ -x ../veritysetup ] && ../veritysetup --version
[ -x ../integritysetup ] && ../integritysetup --version
[ -x ../cryptsetup-reencrypt ] && ../cryptsetup-reencrypt --version
[ $(id -u) != 0 ] && exit 77
modprobe dm-crypt >/dev/null 2>&1
modprobe dm-verity >/dev/null 2>&1
modprobe dm-integrity >/dev/null 2>&1
modprobe dm-zero >/dev/null 2>&1
dmsetup version
echo "Device mapper targets:"
dmsetup targets
exit 0

View File

@@ -1,9 +1,11 @@
TESTS = api-test \
TESTS = 00modules-test \
api-test \
api-test-2 \
compat-test \
compat-test2 \
loopaes-test \
align-test \
align-test2 \
discards-test \
mode-test \
password-hash-test \
@@ -30,26 +32,28 @@ if INTEGRITYSETUP
TESTS += integrity-compat-test
endif
EXTRA_DIST = compatimage.img.bz2 compatv10image.img.bz2 \
EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \
compatimage2.img.xz \
conversion_imgs.tar.xz \
luks2_keyslot_unassigned.img.xz \
img_fs_ext4.img.bz2 img_fs_vfat.img.bz2 img_fs_xfs.img.bz2 \
valid_header_file.bz2 \
img_fs_ext4.img.xz img_fs_vfat.img.xz img_fs_xfs.img.xz \
valid_header_file.xz \
luks2_valid_hdr.img.xz \
luks2_header_requirements.xz \
luks2_header_requirements_free.xz \
evil_hdr-payload_overwrite.bz2 \
evil_hdr-stripes_payload_dmg.bz2 \
evil_hdr-luks_hdr_damage.bz2 \
evil_hdr-small_luks_device.bz2 \
evil_hdr-keyslot_overlap.bz2 \
tcrypt-images.tar.bz2 \
luks1-images.tar.bz2 \
luks2_mda_images.tar.xz \
evil_hdr-payload_overwrite.xz \
evil_hdr-stripes_payload_dmg.xz \
evil_hdr-luks_hdr_damage.xz \
evil_hdr-small_luks_device.xz \
evil_hdr-keyslot_overlap.xz \
tcrypt-images.tar.xz \
luks1-images.tar.xz \
00modules-test \
compat-test \
compat-test2 \
loopaes-test align-test discards-test mode-test password-hash-test \
verity-compat-test \
align-test2 verity-compat-test \
reencryption-compat-test \
reencryption-compat-test2 \
tcrypt-compat-test \
@@ -101,7 +105,7 @@ conversion_imgs:
@tar xJf conversion_imgs.tar.xz
compatimage.img:
@bzip2 -k -d compatimage.img.bz2
@xz -k -d compatimage.img.xz
valgrind-check: api-test api-test-2 differ
@VALG=1 ./compat-test

View File

@@ -3,9 +3,11 @@
CRYPTSETUP="../cryptsetup"
DEV=""
DEV_STACKED="luks0xbabe"
DEV_NAME="dummyalign"
MNT_DIR="./mnt_luks"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
FAST_PBKDF="--pbkdf-force-iterations 1000"
cleanup() {
udevadm settle >/dev/null 2>&1
@@ -13,7 +15,8 @@ cleanup() {
umount -f $MNT_DIR 2>/dev/null
rmdir $MNT_DIR 2>/dev/null
fi
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove $DEV_STACKED >/dev/null 2>&1
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1
# FIXME scsi_debug sometimes in-use here
sleep 1
rmmod scsi_debug 2>/dev/null
@@ -34,8 +37,31 @@ skip()
exit 0
}
function dm_crypt_features()
{
VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
[ $VER_MAJ -lt 1 ] && return
[ $VER_MAJ -gt 1 ] && {
DM_PERF_CPU=1
DM_SECTOR_SIZE=1
return
}
[ $VER_MIN -lt 14 ] && return
DM_PERF_CPU=1
if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then
DM_SECTOR_SIZE=1
fi
}
add_device() {
modprobe scsi_debug $@
modprobe scsi_debug $@ delay=0
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 77
@@ -58,12 +84,16 @@ format() # key_bits expected [forced]
{
if [ -z "$3" ] ; then
echo -n "Formatting using topology info ($1 bits key)..."
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c aes-cbc-essiv:sha256 -s $1
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c aes-cbc-essiv:sha256 -s $1 || fail
else
echo -n "Formatting using forced sector alignment $3 ($1 bits key)..."
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -s $1 -c aes-cbc-essiv:sha256 --align-payload=$2
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -s $1 -c aes-cbc-essiv:sha256 --align-payload=$3 ||fail
fi
# check the device can be activated
echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
ALIGN=$($CRYPTSETUP luksDump $DEV |grep "Payload offset" | sed -e s/.*\\t//)
#echo "ALIGN = $ALIGN"
@@ -71,7 +101,7 @@ format() # key_bits expected [forced]
[ $ALIGN -ne $2 ] && fail "Expected alignment differs: expected $2 != detected $ALIGN"
# test some operation, just in case
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV -i1 --key-slot 1
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1
[ $? -ne 0 ] && fail "Keyslot add failed."
$CRYPTSETUP -q luksKillSlot $DEV 1
@@ -89,18 +119,22 @@ format_null()
{
if [ $3 -eq 0 ] ; then
echo -n "Formatting using topology info ($1 bits key) [slot 0"
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c null -s $1
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 || fail
else
echo -n "Formatting using forced sector alignment $3 ($1 bits key) [slot 0"
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q -i1 -c null -s $1 --align-payload=$3
echo | $CRYPTSETUP luksFormat --type luks1 $DEV -q $FAST_PBKDF -c null -s $1 --align-payload=$3 || fail
fi
# check the device can be activated
echo | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
POFF=$(get_offsets "Payload offset")
[ -z "$POFF" ] && fail
[ $POFF != $2 ] && fail "Expected data offset differs: expected $2 != detected $POFF"
if [ -n "$4" ] ; then
for j in 1 2 3 4 5 6 7 ; do
echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q -i1 --key-slot $j -c null $PARAMS
echo -e "\n" | $CRYPTSETUP luksAddKey $DEV -q $FAST_PBKDF --key-slot $j -c null $PARAMS
echo -n $j
[ $? -ne 0 ] && fail
done
@@ -113,11 +147,35 @@ format_null()
echo "]...PASSED"
}
format_plain() # sector size
{
echo -n "Formatting plain device (sector size $1)..."
if [ -n "$DM_SECTOR_SIZE" ] ; then
echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
echo "PASSED"
else
echo "N/A"
fi
}
format_plain_fail() # sector size
{
echo -n "Formatting plain device (sector size $1, must fail)..."
if [ -n "$DM_SECTOR_SIZE" ] ; then
echo $PWD1 | $CRYPTSETUP open --type plain --sector-size $1 $DEV $DEV_NAME >/dev/null 2>&1 && fail
echo "PASSED"
else
echo "N/A"
fi
}
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run this test, test skipped."
exit 77
fi
dm_crypt_features
modprobe --dry-run scsi_debug || exit 77
cleanup
@@ -125,9 +183,9 @@ echo "# Create desktop-class 4K drive"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1
format 256 4096
format 256 2112 8
format 256 2056 8
format 128 2048
format 128 1088 8
format 128 1032 8
format 256 8192 8192
format 128 8192 8192
cleanup
@@ -136,9 +194,9 @@ echo "# Create desktop-class 4K drive with misaligned opt-io (some bad USB enclo
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0, opt-io=1025)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1 opt_blks=1025
format 256 4096
format 256 2112 8
format 256 2056 8
format 128 2048
format 128 1088 8
format 128 1032 8
format 256 8192 8192
format 128 8192 8192
cleanup
@@ -147,18 +205,18 @@ echo "# Create desktop-class 4K drive w/ 63-sector DOS partition compensation"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=3584)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=7 num_tgts=1
format 256 4103
format 256 2119 8
format 256 2056 8
format 128 2055
format 128 1095 8
format 128 1032 8
cleanup
echo "# Create enterprise-class 4K drive"
echo "# (logical_block_size=4096, physical_block_size=4096, alignment_offset=0)"
add_device dev_size_mb=16 sector_size=4096 num_tgts=1 opt_blks=64
format 256 4096
format 256 2560 8
format 256 2056 8
format 128 2048
format 128 1536 8
format 128 1032 8
cleanup
echo "# Create classic 512B drive and stack dm-linear"
@@ -168,12 +226,32 @@ DEV2=$DEV
DEV=/dev/mapper/$DEV_STACKED
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
format 256 4096
format 256 2112 8
format 256 2056 8
format 128 2048
format 128 1088 8
format 128 1032 8
format 128 8192 8192
cleanup
echo "# Create classic 512B drive and stack dm-linear (plain mode)"
add_device dev_size_mb=16 sector_size=512 num_tgts=1
DEV2=$DEV
DEV=/dev/mapper/$DEV_STACKED
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
format_plain 512
format_plain 1024
format_plain 2048
format_plain 4096
format_plain_fail 1111
format_plain_fail 8192
echo "# Create classic 512B drive, unaligned to 4096 and stack dm-linear (plain mode)"
dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
dmsetup create $DEV_STACKED --table "0 32762 linear $DEV2 0"
format_plain 512
format_plain 1024
format_plain_fail 2048
format_plain_fail 4096
cleanup
echo "# Offset check: 512B sector drive"
add_device dev_size_mb=16 sector_size=512 num_tgts=1
# |k| expO reqO expected slot offsets
@@ -227,13 +305,13 @@ echo "# Create enterprise-class 4K drive with fs and LUKS images."
# loop device here presents 512 block but images have 4k block
# cryptsetup should properly use 4k block on direct-io
add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64
for file in $(ls img_fs_*.img.bz2) ; do
for file in $(ls img_fs_*.img.xz) ; do
echo "Format using fs image $file."
bzip2 -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
mount $DEV $MNT_DIR || skip "Mounting image is not available."
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 -i 1 $MNT_DIR/luks.img || fail
echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 -i 1 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF $MNT_DIR/luks.img || fail
echo $PWD2 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
umount $MNT_DIR
done
cleanup

334
tests/align-test2 Executable file
View File

@@ -0,0 +1,334 @@
#!/bin/bash
CRYPTSETUP="../cryptsetup"
DEV=""
DEV_STACKED="luks0xbabe"
DEV_NAME="dummyalign"
MNT_DIR="./mnt_luks"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
FAST_PBKDF="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
EXPCT=8192
cleanup() {
udevadm settle >/dev/null 2>&1
if [ -d "$MNT_DIR" ] ; then
umount -f $MNT_DIR 2>/dev/null
rmdir $MNT_DIR 2>/dev/null
fi
[ -b /dev/mapper/$DEV_STACKED ] && dmsetup remove --retry $DEV_STACKED >/dev/null 2>&1
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME >/dev/null 2>&1
# FIXME scsi_debug sometimes in-use here
sleep 1
rmmod scsi_debug 2>/dev/null
sleep 1
}
fail()
{
if [ -n "$1" ] ; then echo "FAIL $1" ; fi
echo "FAILED at line $(caller)"
cleanup
exit 100
}
skip()
{
echo "TEST SKIPPED: $1"
cleanup
exit 0
}
function dm_crypt_features()
{
VER_STR=$(dmsetup targets | grep crypt | cut -f2 -dv)
[ -z "$VER_STR" ] && fail "Failed to parse dm-crypt version."
VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
VER_PTC=$(echo $VER_STR | cut -f 3 -d.)
[ $VER_MAJ -lt 1 ] && return
[ $VER_MAJ -gt 1 ] && {
DM_PERF_CPU=1
DM_SECTOR_SIZE=1
return
}
[ $VER_MIN -lt 14 ] && return
DM_PERF_CPU=1
if [ $VER_MIN -ge 17 -o \( $VER_MIN -eq 14 -a $VER_PTC -ge 5 \) ]; then
DM_SECTOR_SIZE=1
fi
}
add_device() {
modprobe scsi_debug $@ delay=0
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 77
fi
sleep 2
DEV=$(grep -l -e scsi_debug /sys/block/*/device/model | cut -f4 -d /)
if [ ! -e /sys/block/$DEV/alignment_offset ] ; then
echo "This kernel seems to not support topology info, test skipped."
cleanup
exit 77
fi
DEV="/dev/$DEV"
[ -b $DEV ] || fail "Cannot find $DEV."
}
format() # expected [forced] [encryption_sector_size]
{
local _sec_size=512
local _exp=$1
if [ "${2:0:1}" = "s" ]; then
_sec_size=${2:1}
shift
fi
test "${3:0:1}" = "s" && _sec_size=${3:1}
test $_sec_size -eq 512 || local _smsg=" (encryption sector size $_sec_size)"
if [ -z "$2" ] ; then
echo -n "Formatting using topology info$_smsg..."
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size || fail
else
echo -n "Formatting using forced sector alignment $2$_smsg..."
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size || fail
fi
# check the device can be activated
if [ -n "$DM_SECTOR_SIZE" ] ; then
echo $PWD1 | $CRYPTSETUP luksOpen $DEV $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
fi
ALIGN=$($CRYPTSETUP luksDump $DEV | tee /tmp/last_dump | grep -A1 "0: crypt" | grep "offset:" | cut -d ' ' -f2)
# echo "ALIGN = $ALIGN"
[ -z "$ALIGN" ] && fail
ALIGN=$((ALIGN/512))
[ $ALIGN -ne $_exp ] && fail "Expected alignment differs: expected $_exp != detected $ALIGN"
# test some operation, just in case
echo -e "$PWD1\n$PWD2" | $CRYPTSETUP luksAddKey $DEV $FAST_PBKDF --key-slot 1
[ $? -ne 0 ] && fail "Keyslot add failed."
$CRYPTSETUP -q luksKillSlot $DEV 1
[ $? -ne 0 ] && fail "Keyslot removal failed."
echo "PASSED"
}
format_fail() # expected [forced] [encryption_sector_size]
{
local _sec_size=512
local _exp=$1
if [ "${2:0:1}" = "s" ]; then
_sec_size=${2:1}
shift
fi
test "${3:0:1}" = "s" && _sec_size=${3:1}
test $_sec_size -eq 512 || local _smsg=" (encryption sector size $_sec_size)"
if [ -z "$2" ] ; then
echo -n "Formatting using topology info$_smsg (must fail)..."
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --sector-size $_sec_size >/dev/null 2>&1 && fail
else
echo -n "Formatting using forced sector alignment $2$_smsg (must fail)..."
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $DEV -q -c aes-cbc-essiv:sha256 --align-payload=$2 --sector-size $_sec_size >/dev/null 2>&1 && fail
fi
echo "PASSED"
}
if [ $(id -u) != 0 ]; then
echo "WARNING: You must be root to run this test, test skipped."
exit 77
fi
dm_crypt_features
modprobe --dry-run scsi_debug || exit 77
cleanup
echo "# Create desktop-class 4K drive"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1
format $EXPCT
format $EXPCT s1024
format $EXPCT s2048
format $EXPCT s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create desktop-class 4K drive with misaligned opt-io (some bad USB enclosures)"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=0, opt-io=1025)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 num_tgts=1 opt_blks=1025
format $EXPCT
format $EXPCT s1024
format $EXPCT s2048
format $EXPCT s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create desktop-class 4K drive w/ 1-sector shift (original bug report)"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=512)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=1 num_tgts=1
format $((EXPCT+1))
format_fail $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create desktop-class 4K drive w/ 63-sector DOS partition compensation"
echo "# (logical_block_size=512, physical_block_size=4096, alignment_offset=3584)"
add_device dev_size_mb=16 sector_size=512 physblk_exp=3 lowest_aligned=7 num_tgts=1
format $((EXPCT+7))
format_fail $((EXPCT+7)) s1024
format_fail $((EXPCT+7)) s2048
format_fail $((EXPCT+7)) s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create enterprise-class 4K drive"
echo "# (logical_block_size=4096, physical_block_size=4096, alignment_offset=0)"
add_device dev_size_mb=16 sector_size=4096 num_tgts=1 opt_blks=64
format $EXPCT
format $EXPCT s1024
format $EXPCT s2048
format $EXPCT s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
#FIXME: kernel limits issue?
##format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create classic 512B drive and stack dm-linear"
echo "# (logical_block_size=512, physical_block_size=512, alignment_offset=0)"
add_device dev_size_mb=16 sector_size=512 num_tgts=1
DEV2=$DEV
DEV=/dev/mapper/$DEV_STACKED
dmsetup create $DEV_STACKED --table "0 32768 linear $DEV2 0"
format $EXPCT
format $EXPCT s1024
format $EXPCT s2048
format $EXPCT s4096
format $EXPCT 1
format $EXPCT 1 s1024
format $EXPCT 1 s2048
format $EXPCT 1 s4096
format $EXPCT 8
format $EXPCT 8 s1024
format $EXPCT 8 s2048
format $EXPCT 8 s4096
format $((EXPCT+1)) $((EXPCT+1))
format_fail $((EXPCT+1)) $((EXPCT+1)) s1024
format_fail $((EXPCT+1)) $((EXPCT+1)) s2048
format_fail $((EXPCT+1)) $((EXPCT+1)) s4096
format $EXPCT $EXPCT
format $EXPCT $EXPCT s1024
format $EXPCT $EXPCT s2048
format $EXPCT $EXPCT s4096
cleanup
echo "# Create enterprise-class 4K drive with fs and LUKS images."
# loop device here presents 512 block but images have 4k block
# cryptsetup should properly use 4k block on direct-io
add_device dev_size_mb=32 sector_size=4096 physblk_exp=0 num_tgts=1 opt_blks=64
for file in $(ls img_fs_*.img.xz) ; do
echo "Format using fs image $file."
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
mount $DEV $MNT_DIR || skip "Mounting image is not available."
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img || fail
echo $PWD2 | $CRYPTSETUP luksFormat $FAST_PBKDF --type luks2 $MNT_DIR/luks.img --header $MNT_DIR/luks_header.img || fail
umount $MNT_DIR
done
cleanup

View File

@@ -354,7 +354,7 @@ static int _setup(void)
fd = loop_attach(&DEVICE_6, IMAGE_PV_LUKS2_SEC, 0, 0, &ro);
close(fd);
_system(" [ ! -d " CONV_DIR " ] && tar xJf " CONV_DIR ".tar.xz", 1);
_system(" [ ! -d " CONV_DIR " ] && tar xJf " CONV_DIR ".tar.xz 2>/dev/null", 1);
if (_system("modprobe dm-crypt", 1))
return 1;
@@ -426,13 +426,11 @@ static int test_open(struct crypt_device *cd,
void *usrptr)
{
const char *str = (const char *)usrptr;
char *buf = malloc(strlen(str));
if (!buf)
return -ENOMEM;
strncpy(buf, str, strlen(str));
*buffer = buf;
*buffer_len = strlen(str);
*buffer = strdup(str);
if (!*buffer)
return -ENOMEM;
*buffer_len = strlen(*buffer);
return 0;
}
@@ -868,6 +866,7 @@ static void UseTempVolumes(void)
static void Luks2HeaderRestore(void)
{
char key[128];
struct crypt_device *cd;
struct crypt_pbkdf_type pbkdf = {
.type = CRYPT_KDF_ARGON2I,
@@ -890,7 +889,7 @@ static void Luks2HeaderRestore(void)
struct crypt_params_luks1 luks1 = {
.data_alignment = 8192, // 4M offset to pass alignment test
};
char key[128];
uint32_t flags = 0;
const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
size_t key_size = strlen(mk_hex) / 2;
@@ -945,6 +944,22 @@ static void Luks2HeaderRestore(void)
FAIL_(crypt_header_restore(cd, CRYPT_LUKS2, NO_REQS_LUKS2_HEADER), "LUKS1 format detected");
crypt_free(cd);
/* check crypt_header_restore() properly loads crypt_device context */
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
OK_(crypt_header_restore(cd, CRYPT_LUKS2, NO_REQS_LUKS2_HEADER));
/* check LUKS2 specific API call returns non-error code */
OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags));
EQ_(flags, 0);
/* same test, any LUKS */
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
OK_(crypt_header_restore(cd, CRYPT_LUKS, NO_REQS_LUKS2_HEADER));
/* check LUKS2 specific API call returns non-error code */
OK_(crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &flags));
EQ_(flags, 0);
crypt_free(cd);
_cleanup_dmdevices();
}
@@ -2254,9 +2269,8 @@ static void Pbkdf(void)
bad.type = NULL;
bad.hash = DEFAULT_LUKS1_HASH;
FAIL_(crypt_set_pbkdf_type(cd, &bad), "Pbkdf type member is empty");
// following test fails atm
// bad.hash = "hamster_hash";
// FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Unknown hash member");
bad.hash = "hamster_hash";
FAIL_(crypt_set_pbkdf_type(cd, &pbkdf2), "Unknown hash member");
crypt_free(cd);
// test whether crypt_get_pbkdf_type() behaves accordingly after second crypt_load() call
OK_(crypt_init(&cd, DEVICE_1));
@@ -2974,23 +2988,23 @@ int main(int argc, char *argv[])
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
RUN_(AddDeviceLuks2, "Format and use LUKS2 device");
RUN_(Luks2HeaderLoad, "test header load");
RUN_(Luks2HeaderRestore, "test LUKS2 header restore");
RUN_(Luks2HeaderBackup, "test LUKS2 header backup");
RUN_(ResizeDeviceLuks2, "Luks device resize tests");
RUN_(Luks2HeaderLoad, "LUKS2 header load");
RUN_(Luks2HeaderRestore, "LUKS2 header restore");
RUN_(Luks2HeaderBackup, "LUKS2 header backup");
RUN_(ResizeDeviceLuks2, "LUKS2 device resize tests");
RUN_(UseLuks2Device, "Use pre-formated LUKS2 device");
RUN_(SuspendDevice, "Suspend/Resume test");
RUN_(SuspendDevice, "LUKS2 Suspend/Resume");
RUN_(UseTempVolumes, "Format and use temporary encrypted device");
RUN_(Tokens, "General tokens API tests");
RUN_(TokenActivationByKeyring, "Builtin kernel keyring token tests");
RUN_(LuksConvert, "Test LUKS1 <-> LUKS2 conversions");
RUN_(Pbkdf, "Exercice default pbkdf manipulation routines");
RUN_(Luks2KeyslotAdd, "Add new keyslot by unused key");
RUN_(Luks2ActivateByKeyring, "Test LUKS2 activation by passphrase in keyring");
RUN_(Luks2Requirements, "Test LUKS2 requirements flags");
RUN_(Luks2Integrity, "Test LUKS2 with data integrity");
RUN_(Luks2Flags, "Test LUKS2 persistent flags");
RUN_(Luks2Repair, "Test LUKS2 repair"); // test disables metadata locking. Run alwas last!
RUN_(Tokens, "General tokens API");
RUN_(TokenActivationByKeyring, "Builtin kernel keyring token");
RUN_(LuksConvert, "LUKS1 <-> LUKS2 conversions");
RUN_(Pbkdf, "Default PBKDF manipulation routines");
RUN_(Luks2KeyslotAdd, "Add a new keyslot by unused key");
RUN_(Luks2ActivateByKeyring, "LUKS2 activation by passphrase in keyring");
RUN_(Luks2Requirements, "LUKS2 requirements flags");
RUN_(Luks2Integrity, "LUKS2 with data integrity");
RUN_(Luks2Flags, "LUKS2 persistent flags");
RUN_(Luks2Repair, "LUKS2 repair"); // test disables metadata locking. Run always last!
out:
_cleanup();
return 0;

View File

@@ -100,14 +100,18 @@ static int get_luks_offsets(int metadata_device,
uint64_t current_sector;
uint32_t sectors_per_stripes_set;
if (!keylength)
if (!keylength) {
if (r_header_size)
*r_header_size = 0;
if (r_payload_offset)
*r_payload_offset = 0;
return -1;
}
sectors_per_stripes_set = DIV_ROUND_UP(keylength*LUKS_STRIPES, SECTOR_SIZE);
printf("sectors_per_stripes %" PRIu32 "\n", sectors_per_stripes_set);
current_sector = DIV_ROUND_UP_MODULO(DIV_ROUND_UP(LUKS_PHDR_SIZE_B, SECTOR_SIZE),
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
for(i=0;i < (LUKS_NUMKEYS - 1);i++)
for (i=0; i < (LUKS_NUMKEYS - 1); i++)
current_sector = DIV_ROUND_UP_MODULO(current_sector + sectors_per_stripes_set,
LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE);
if (r_header_size)
@@ -255,7 +259,7 @@ static int _setup(void)
_system("dmsetup create " DEVICE_EMPTY_name " --table \"0 10000 zero\"", 1);
_system("dmsetup create " DEVICE_ERROR_name " --table \"0 10000 error\"", 1);
_system(" [ ! -e " IMAGE1 " ] && bzip2 -dk " IMAGE1 ".bz2", 1);
_system(" [ ! -e " IMAGE1 " ] && xz -dk " IMAGE1 ".xz", 1);
fd = loop_attach(&DEVICE_1, IMAGE1, 0, 0, &ro);
close(fd);
@@ -264,22 +268,22 @@ static int _setup(void)
close(fd);
/* Keymaterial offset is less than 8 sectors */
_system(" [ ! -e " EVL_HEADER_1 " ] && bzip2 -dk " EVL_HEADER_1 ".bz2", 1);
_system(" [ ! -e " EVL_HEADER_1 " ] && xz -dk " EVL_HEADER_1 ".xz", 1);
/* keymaterial offset aims into payload area */
_system(" [ ! -e " EVL_HEADER_2 " ] && bzip2 -dk " EVL_HEADER_2 ".bz2", 1);
_system(" [ ! -e " EVL_HEADER_2 " ] && xz -dk " EVL_HEADER_2 ".xz", 1);
/* keymaterial offset is valid, number of stripes causes payload area to be overwritten */
_system(" [ ! -e " EVL_HEADER_3 " ] && bzip2 -dk " EVL_HEADER_3 ".bz2", 1);
_system(" [ ! -e " EVL_HEADER_3 " ] && xz -dk " EVL_HEADER_3 ".xz", 1);
/* luks device header for data and header on same device. payloadOffset is greater than
* device size (crypt_load() test) */
_system(" [ ! -e " EVL_HEADER_4 " ] && bzip2 -dk " EVL_HEADER_4 ".bz2", 1);
_system(" [ ! -e " EVL_HEADER_4 " ] && xz -dk " EVL_HEADER_4 ".xz", 1);
/* two keyslots with same offset (overlapping keyslots) */
_system(" [ ! -e " EVL_HEADER_5 " ] && bzip2 -dk " EVL_HEADER_5 ".bz2", 1);
_system(" [ ! -e " EVL_HEADER_5 " ] && xz -dk " EVL_HEADER_5 ".xz", 1);
/* valid header: payloadOffset=4096, key_size=32,
* volume_key = bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a */
_system(" [ ! -e " VALID_HEADER " ] && bzip2 -dk " VALID_HEADER ".bz2", 1);
_system(" [ ! -e " VALID_HEADER " ] && xz -dk " VALID_HEADER ".xz", 1);
/* Prepare tcrypt images */
_system(" [ ! -d tcrypt-images ] && tar xjf tcrypt-images.tar.bz2 2>/dev/null", 1);
_system(" [ ! -d tcrypt-images ] && tar xJf tcrypt-images.tar.xz 2>/dev/null", 1);
_system("modprobe dm-crypt", 0);
_system("modprobe dm-verity", 0);
@@ -1072,6 +1076,18 @@ static void LuksHeaderRestore(void)
//_system("dmsetup table;sleep 1",1);
crypt_free(cd);
/* check crypt_header_restore() properly loads crypt_device context */
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
OK_(crypt_header_restore(cd, CRYPT_LUKS1, VALID_HEADER));
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
/* same test, any LUKS */
OK_(crypt_wipe(cd, NULL, CRYPT_WIPE_ZERO, 0, 1*1024*1024, 1*1024*1024, 0, NULL, NULL));
OK_(crypt_header_restore(cd, CRYPT_LUKS, VALID_HEADER));
OK_(crypt_activate_by_volume_key(cd, NULL, key, key_size, 0));
crypt_free(cd);
_cleanup_dmdevices();
}
@@ -1762,20 +1778,20 @@ int main(int argc, char *argv[])
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
RUN_(NonFIPSAlg, "Crypto is properly initialised in format"); //must be the first!
RUN_(AddDevicePlain, "plain device API creation exercise");
RUN_(HashDevicePlain, "plain device API hash test");
RUN_(AddDevicePlain, "A plain device API creation");
RUN_(HashDevicePlain, "A plain device API hash");
RUN_(AddDeviceLuks, "Format and use LUKS device");
RUN_(LuksHeaderLoad, "test header load");
RUN_(LuksHeaderRestore, "test LUKS header restore");
RUN_(LuksHeaderBackup, "test LUKS header backup");
RUN_(ResizeDeviceLuks, "Luks device resize tests");
RUN_(LuksHeaderLoad, "Header load");
RUN_(LuksHeaderRestore, "LUKS header restore");
RUN_(LuksHeaderBackup, "LUKS header backup");
RUN_(ResizeDeviceLuks, "LUKS device resize");
RUN_(UseLuksDevice, "Use pre-formated LUKS device");
RUN_(SuspendDevice, "Suspend/Resume test");
RUN_(SuspendDevice, "Suspend/Resume");
RUN_(UseTempVolumes, "Format and use temporary encrypted device");
RUN_(CallbacksTest, "API callbacks test");
RUN_(VerityTest, "DM verity test");
RUN_(TcryptTest, "Tcrypt API test");
RUN_(IntegrityTest, "Integrity API test");
RUN_(CallbacksTest, "API callbacks");
RUN_(VerityTest, "DM verity");
RUN_(TcryptTest, "Tcrypt API");
RUN_(IntegrityTest, "Integrity API");
out:
_cleanup();
return 0;

View File

@@ -7,7 +7,7 @@
BW_UNIT=./unit-utils-io
STRACE=strace
MNT_DIR=./mnt_bwunit
LOCAL_FILE=./blocwise_localfile
LOCAL_FILE=./blockwise_localfile
# $1 path to scsi debug bdev
scsi_debug_teardown() {
@@ -42,10 +42,16 @@ fail()
fail_count()
{
echo "[WRONG]"
echo "$MSG[FAIL]"
FAILS=$((FAILS+1))
}
warn_count()
{
echo "$MSG[WARNING]"
WARNS=$((WARNS+1))
}
skip()
{
echo "TEST SKIPPED: $1"
@@ -54,7 +60,7 @@ skip()
}
add_device() {
modprobe scsi_debug $@
modprobe scsi_debug $@ delay=0
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 77
@@ -65,15 +71,19 @@ add_device() {
}
falloc() {
fallocate -l"$1"m $2 2>/dev/null || dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
dd if=/dev/zero of=$2 bs=1M count=$1 2> /dev/null
}
run_all_in_fs() {
for file in $(ls img_fs_*.img.bz2) ; do
for file in $(ls img_fs_*.img.xz) ; do
echo "Run tests in $file put on top block device."
bzip2 -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
xz -d -c $file | dd of=$DEV bs=1M 2>/dev/null || fail "bad image"
[ ! -d $MNT_DIR ] && mkdir $MNT_DIR
mount $DEV $MNT_DIR || skip "Mounting image $file failed."
mount $DEV $MNT_DIR
if [ $? -ne 0 ]; then
echo "Mounting image $file failed, skipped."
continue;
fi
rm -rf $MNT_DIR/* 2>/dev/null
local tfile=$MNT_DIR/bwunit_tstfile
falloc $DEVSIZEMB $tfile || fail "enospc?"
@@ -108,25 +118,33 @@ RUN() {
case "$_res" in
P)
echo -n "Testing $_fn on $_type with params $@ [should PASS]..."
MSG="Testing $_fn on $_type with params $@ [expecting TRUE]..."
$BW_UNIT $_dev $_fn $@
if [ $? -ne 0 ]; then
fail_count
if [ $_type = "file" ]; then
warn_count
else
fail_count
fi
trunc_file $_fsize $_dev
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-pass.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
else
echo "[OK]"
MSG="$MSG[OK]"
fi
;;
F)
echo -n "Testing $_fn on $_type with params $@ [should FAIL]..."
MSG="Testing $_fn on $_type with params $@ [expecting FALSE]..."
$BW_UNIT $_dev $_fn $@ 2> /dev/null
if [ $? -eq 0 ]; then
fail_count
if [ $_type = "file" ]; then
warn_count
else
fail_count
fi
trunc_file $_fsize $_dev
test -z "$STRACE" || $STRACE -o ./$BW_UNIT-fail-$FAILS-should-fail.log $BW_UNIT $_dev $_fn $@ 2> /dev/null
else
echo "[OK]"
MSG="$MSG[OK]"
fi
;;
*)
@@ -290,6 +308,7 @@ which $STRACE > /dev/null 2>&1 || unset STRACE
test -x $BW_UNIT || skip "Run \"make `basename $BW_UNIT`\" first"
FAILS=0
WARNS=0
DEVSIZEMB=2
DEVSIZE=$((DEVSIZEMB*1024*1024))
@@ -299,16 +318,12 @@ echo "System PAGE_SIZE=$PAGE_SIZE"
echo "Run tests in local filesystem"
falloc $DEVSIZEMB $LOCAL_FILE || fail "Failed to create file in local filesystem."
BSIZE=$(stat -c "%o" $LOCAL_FILE)
if [ $BSIZE -gt $PAGE_SIZE ]; then
if [ $BSIZE -gt $((512*1024)) ]; then
echo "Detected file block size: $BSIZE bytes"
if [ -n "$_FORCE_LOCAL" ]; then
run_all $LOCAL_FILE
else
echo "Nfs? I'm not going to run blockwise tests on this."
fi
else
run_all $LOCAL_FILE
echo "Tuning it down to system page size ($PAGE_SIZE bytes)"
BSIZE=$PAGE_SIZE
fi
run_all $LOCAL_FILE
[ $(id -u) -eq 0 ] || {
echo "WARNING: You must be root to run remaining tests."
@@ -356,4 +371,5 @@ add_device dev_size_mb=$DEVSIZEMBIMG sector_size=$DEVBSIZE physblk_exp=$EXP num_
run_all_in_fs
cleanup
test $WARNS -eq 0 || echo "(WARNING: $WARNS suspicious result(s) in total)"
test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"

View File

@@ -104,19 +104,19 @@ function prepare()
;;
new)
remove_mapping
bzip2 -cd compatimage.img.bz2 > $IMG
xz -cd compatimage.img.xz > $IMG
# FIXME: switch to internal loop (no losetup at all)
echo "bad" | $CRYPTSETUP luksOpen --key-slot 0 --test-passphrase $IMG 2>&1 | \
grep "autoclear flag" && skip "WARNING: Too old kernel, test skipped."
losetup $LOOPDEV $IMG
bzip2 -cd compatv10image.img.bz2 > $IMG10
xz -cd compatv10image.img.xz > $IMG10
;;
reuse | *)
if [ ! -e $IMG ]; then
bzip2 -cd compatimage.img.bz2 > $IMG
xz -cd compatimage.img.xz > $IMG
losetup $LOOPDEV $IMG
fi
[ ! -e $IMG10 ] && bzip2 -cd compatv10image.img.bz2 > $IMG10
[ ! -e $IMG10 ] && xz -cd compatv10image.img.xz > $IMG10
;;
esac
@@ -138,10 +138,6 @@ function prepare()
touch $KEYE
fi
if [ ! -e $VK_FILE ]; then
touch $VK_FILE
fi
cp $IMG $ORIG_IMG
[ -n "$1" ] && echo "CASE: $1"
}
@@ -241,8 +237,8 @@ $CRYPTSETUP luksDump $IMG | grep -q $TEST_UUID || fail
echo $PWDW | $CRYPTSETUP luksDump $IMG --dump-master-key 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksDump $IMG --dump-master-key | grep -q "MK dump:" || can_fail_fips
$CRYPTSETUP luksDump -q $IMG --dump-master-key -d $KEY1 | grep -q "MK dump:" || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file missing-file 2> /dev/null && fail
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE > /dev/null || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE >/dev/null || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $IMG --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail
fips_mode || {
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $IMG || fail
}
@@ -853,7 +849,7 @@ prepare "[37] Interactive add key." new
expect - >/dev/null <<EOF
proc abort {} { send_error "Timeout. "; exit 2 }
set timeout 10
eval spawn $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -v $LOOPDEV
eval spawn $CRYPTSETUP luksAddKey -S 2 $FAST_PBKDF_OPT -v $LOOPDEV
expect timeout abort "Enter any existing passphrase:"
sleep 0.1
send "$PWD0\n"
@@ -871,6 +867,15 @@ sleep 0.1
send "$PWD1\n"
expect timeout abort "Command successful."
expect timeout abort eof
eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 1
expect timeout abort "Keyslot 1 is not active."
expect timeout abort eof
eval spawn $CRYPTSETUP luksKillSlot -v $LOOPDEV 2
expect timeout abort "Enter any remaining passphrase:"
sleep 0.1
send "$PWD0\n"
expect timeout abort "Key slot 2 removed."
expect timeout abort eof
exit
EOF
[ $? -eq 0 ] || fail "Expect script failed."

View File

@@ -23,11 +23,15 @@ PWD0="compatkey"
PWD1="93R4P4pIqAH8"
PWD2="mymJeD8ivEhE"
PWD3="ocMakf3fAcQO"
PWD4="Qx3qn46vq0v"
PWDW="rUkL4RUryBom"
TEST_KEYRING_NAME="compattest2_keyring"
TEST_TOKEN0="compattest2_desc0"
TEST_TOKEN1="compattest2_desc1"
VK_FILE="compattest2_vkfile"
IMPORT_TOKEN="{\"type\":\"some_type\",\"keyslots\":[],\"base64_data\":\"zxI7vKB1Qwl4VPB4D-N-OgcC14hPCG0IDu8O7eCqaQ\"}"
TOKEN_FILE0=test-token-file0
TOKEN_FILE1=test-token-file1
FAST_PBKDF_OPT="--pbkdf pbkdf2 --pbkdf-force-iterations 1000"
@@ -47,7 +51,7 @@ function remove_mapping()
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
losetup -d $LOOPDEV >/dev/null 2>&1
rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE $HEADER_LUKS2_PV missing-file >/dev/null 2>&1
rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE $HEADER_LUKS2_PV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* >/dev/null 2>&1
# unlink whole test keyring
[ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
@@ -93,26 +97,26 @@ function prepare()
case "$2" in
wipe)
remove_mapping
dd if=/dev/zero of=$IMG bs=1k count=10000 >/dev/null 2>&1
dd if=/dev/zero of=$IMG bs=4096 count=5000 >/dev/null 2>&1
sync
losetup $LOOPDEV $IMG
;;
new)
remove_mapping
bzip2 -cd compatimage.img.bz2 > $IMG
xz -cd compatimage.img.xz > $IMG
xz -dk $HEADER_KEYU.xz
# FIXME: switch to internal loop (no losetup at all)
echo "bad" | $CRYPTSETUP luksOpen --key-slot 0 --test-passphrase $IMG 2>&1 | \
grep "autoclear flag" && skip "WARNING: Too old kernel, test skipped."
losetup $LOOPDEV $IMG
bzip2 -cd compatv10image.img.bz2 > $IMG10
xz -cd compatv10image.img.xz > $IMG10
;;
reuse | *)
if [ ! -e $IMG ]; then
bzip2 -cd compatimage.img.bz2 > $IMG
xz -cd compatimage.img.xz > $IMG
losetup $LOOPDEV $IMG
fi
[ ! -e $IMG10 ] && bzip2 -cd compatv10image.img.bz2 > $IMG10
[ ! -e $IMG10 ] && xz -cd compatv10image.img.xz > $IMG10
;;
esac
@@ -134,10 +138,6 @@ function prepare()
touch $KEYE
fi
if [ ! -e $VK_FILE ]; then
touch $VK_FILE
fi
cp $IMG $ORIG_IMG
[ -n "$1" ] && echo "CASE: $1"
}
@@ -209,7 +209,21 @@ export LANG=C
[ -z "$LOOPDEV" ] && skip "WARNING: Cannot find free loop device, test skipped."
[ -d "$LOCK_DIR" ] || skip "WARNING: LUKS2 locking directory ($LOCK_DIR) is missing, test skipped."
# LUKS tests
prepare "[2] Sector size and old payload alignment" wipe
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 511 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 256 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 8192 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 512 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --align-payload 5 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 512 --align-payload 5 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 --align-payload 32 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 4096 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 --align-payload 32768 || fail
$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 32768)) \[bytes\]" || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 2048 || fail
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -q --sector-size 4096 --align-payload 32768 || fail
$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "offset: $((512 * 32768)) \[bytes\]" || fail
prepare "[3] format" new
echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256 -s 128 luksFormat --type luks2 $LOOPDEV || fail
prepare "[4] format using hash sha512" wipe
@@ -398,7 +412,7 @@ $CRYPTSETUP -q status $DEV_NAME | grep "mode:" | grep -q "readonly" || fail
$CRYPTSETUP -q resize $DEV_NAME --size 100 || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "100 sectors" || fail
$CRYPTSETUP -q resize $DEV_NAME || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "19997 sectors" || fail
$CRYPTSETUP -q status $DEV_NAME | grep "size:" | grep -q "39997 sectors" || fail
# Resize underlying loop device as well
truncate -s 16M $IMG || fail
$CRYPTSETUP -q resize $DEV_NAME || fail
@@ -460,18 +474,18 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail
echo $PWDW | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP luksDump $LOOPDEV --dump-master-key | grep -q "MK dump:" || can_fail_fips
$CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file missing-file 2> /dev/null && fail
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE > /dev/null || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE >/dev/null || can_fail_fips
echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail
fips_mode || {
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $LOOPDEV || fail
}
prepare "[22] remove disappeared device" wipe
dmsetup create $DEV_NAME --table "0 10000 linear $LOOPDEV 2" || fail
dmsetup create $DEV_NAME --table "0 39998 linear $LOOPDEV 2" || fail
echo $PWD1 | $CRYPTSETUP -q $FAST_PBKDF_OPT luksFormat --type luks2 /dev/mapper/$DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP -q luksOpen /dev/mapper/$DEV_NAME $DEV_NAME2 || fail
# underlying device now returns error but node is still present
dmsetup load $DEV_NAME --table "0 10000 error" || fail
dmsetup load $DEV_NAME --table "0 40000 error" || fail
dmsetup resume $DEV_NAME || fail
$CRYPTSETUP -q luksClose $DEV_NAME2 || fail
dmsetup remove $DEV_NAME || fail
@@ -673,7 +687,7 @@ if dm_crypt_keyring_flawed; then
fi
if dm_crypt_keyring_support; then
prepare "[32b] LUKS2 key in keyring" wipe
prepare "[32] LUKS2 key in keyring" wipe
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail
# check keyring support detection works as expected
rmmod dm-crypt > /dev/null 2>&1 || true
@@ -699,12 +713,12 @@ if dm_crypt_keyring_support; then
fi
# FIXME: candidate for non-root tests
prepare "[33] tokens" wipe
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
if [ $HAVE_KEYRING -gt 0 ]; then
prepare "[33] tokens" wipe
test_and_prepare_keyring
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV || fail
$CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN0 --token-id 3 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q -e "3: luks2-keyring" || fail
# keyslot 5 is inactive
@@ -727,6 +741,18 @@ if [ $HAVE_KEYRING -gt 0 ]; then
$CRYPTSETUP token add $LOOPDEV --key-description $TEST_TOKEN1 --key-slot 4 || fail
$CRYPTSETUP -q luksKillSlot $LOOPDEV 4 || fail
fi
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 10 || fail
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 11 --json-file - || fail
echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0
$CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 || fail
$CRYPTSETUP token import $LOOPDEV --token-id 12 --json-file $TOKEN_FILE0 2>/dev/null && fail
$CRYPTSETUP token export $LOOPDEV --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail
$CRYPTSETUP token export $LOOPDEV --token-id 11 | diff --from-file - $TOKEN_FILE0 || fail
$CRYPTSETUP token export $LOOPDEV --token-id 12 | diff --from-file - $TOKEN_FILE0 || fail
$CRYPTSETUP token export $LOOPDEV --token-id 12 --json-file $TOKEN_FILE1 || fail
diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
$CRYPTSETUP token export $LOOPDEV --token-id 12 > $TOKEN_FILE1 || fail
diff $TOKEN_FILE0 $TOKEN_FILE1 || fail
prepare "[34] LUKS keyslot priority" wipe
echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV -S 1 || fail
@@ -763,7 +789,7 @@ echo $PWD1 | $CRYPTSETUP luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 --pbkdf-force-iterations 1234 $LOOPDEV || fail
$CRYPTSETUP luksDump $LOOPDEV | grep "Iterations:" | grep -q "1234" || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 3 $LOOPDEV 2>/dev/null && fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 4 $LOOPDEV || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 100000 $LOOPDEV || fail
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "argon2id" || fail
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf argon2i --pbkdf-force-iterations 4 \
--pbkdf-memory 1234 --pbkdf-parallel 1 $LOOPDEV || fail
@@ -780,7 +806,7 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 --pbkdf pbkdf2 -i 500 $LOOPD
prepare "[37] LUKS Keyslot convert" wipe
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV $KEY5 --key-slot 5 || fail
$CRYPTSETUP -q luksConvertKey $LOOPDEV --key-file $KEY5 && fail
$CRYPTSETUP -q luksConvertKey $LOOPDEV --key-file $KEY5 2>/dev/null && fail
$CRYPTSETUP -q convert --type luks2 $LOOPDEV || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "5: luks2" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
@@ -792,6 +818,8 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail
$CRYPTSETUP luksDump $LOOPDEV | grep "PBKDF:" | grep -q "pbkdf2" || fail
echo $PWD1 | $CRYPTSETUP -q luksConvertKey $LOOPDEV -S 1 --pbkdf argon2i -i1 --pbkdf-memory 32 || fail
$CRYPTSETUP luksDump $LOOPDEV | grep -q "1: luks2" || fail
echo $PWD3 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT -S 21 --unbound -s 16 $LOOPDEV || fail
echo $PWD3 | $CRYPTSETUP luksConvertKey --pbkdf-force-iterations 1001 --pbkdf pbkdf2 -S 21 $LOOPDEV || fail
prepare "[38] luksAddKey unbound tests" wipe
$CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV $KEY5 --key-slot 5 || fail
@@ -812,8 +840,12 @@ echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV $DEV_NAME 2> /dev/null && fail
echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV --test-passphrase || fail
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail
echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail
# check we're able to change passphrase for unbound keyslot
echo -e "$PWD2\n$PWD3" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail
echo $PWD3 | $CRYPTSETUP open --test-passphrase $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail
echo $PWD3 | $CRYPTSETUP -q open -S 2 $LOOPDEV $DEV_NAME 2> /dev/null && fail
# do not allow adding keyslot by unbound keyslot
echo -e "$PWD2\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail
echo -e "$PWD3\n$PWD1" | $CRYPTSETUP -q luksAddKey $LOOPDEV 2> /dev/null && fail
# check adding keyslot works when there's unbound keyslot
echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV --key-file $KEY5 -S8 || fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
@@ -823,5 +855,21 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q "2: luks2 (unbound)" && fail
$CRYPTSETUP luksKillSlot -q $LOOPDEV 3
$CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" && fail
prepare "[39] LUKS2 metadata variants" wipe
tar xJf luks2_mda_images.tar.xz
echo -n "$IMPORT_TOKEN" > $TOKEN_FILE0
for mda in 16 32 64 128 256 512 1024 2048 4096 ; do
echo -n "[$mda KiB]"
echo $PWD4 | $CRYPTSETUP open test_image_$mda $DEV_NAME || fail
$CRYPTSETUP close $DEV_NAME || fail
echo -e "$PWD4\n$PWD3" | $CRYPTSETUP luksAddKey -S9 $FAST_PBKDF_OPT test_image_$mda || fail
echo $PWD4 | $CRYPTSETUP open --test-passphrase test_image_$mda || fail
echo $PWD3 | $CRYPTSETUP open -S9 --test-passphrase test_image_$mda || fail
echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import test_image_$mda --token-id 10 || fail
$CRYPTSETUP token export test_image_$mda --token-id 10 | diff --from-file - $TOKEN_FILE0 || fail
echo -n "[OK]"
done
echo
remove_mapping
exit 0

Binary file not shown.

BIN
tests/compatimage.img.xz Normal file

Binary file not shown.

Binary file not shown.

BIN
tests/compatv10image.img.xz Normal file

Binary file not shown.

View File

@@ -25,6 +25,8 @@
#include "crypto_backend.h"
#define MAX_BLOCK_SIZE 128
static void printhex(const char *s, const char *buf, size_t len)
{
size_t i;
@@ -237,6 +239,10 @@ struct kdf_test_vector kdf_test_vectors[] = {
}
};
/*
* Hash tests
*/
struct hash_alg {
const char *name;
int length;
@@ -333,6 +339,69 @@ struct hash_out hash_outputs[] = {
}
};
/*
* HMAC tests
*/
// RFC 4231 - HMAC test vectors for SHA-256, SHA-512
// RFC 2202 - HMAC test vectors for SHA-1
struct hmac_test_vector {
const char *key;
unsigned int key_length;
const char *data;
unsigned int data_length;
const char *hmac_sha_1;
const char *hmac_sha_256;
const char *hmac_sha_512;
};
struct hmac_test_vector hmac_test_vectors[] = {
{
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20,
"\x48\x69\x20\x54\x68\x65\x72\x65", 8, // "Hi There"
"\xb6\x17\x31\x86\x55\x05\x72\x64\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1\x46\xbe\x00",
"\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7",
"\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54"
},
{
"\x4a\x65\x66\x65", 4, // "Jefe"
"\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f", 28, // "what do ya want for nothing?"
"\xef\xfc\xdf\x6a\xe5\xeb\x2f\xa2\xd2\x74\x16\xd5\xf1\x84\xdf\x9c\x25\x9a\x7c\x79",
"\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43",
"\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37"
},
{
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20,
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50,
"\x12\x5d\x73\x42\xb9\xac\x11\xcd\x91\xa3\x9a\xf4\x8a\xa1\x7b\x4f\x63\xf1\x75\xd3",
"\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe",
"\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb"
},
{
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd", 50,
"\x4c\x90\x07\xf4\x02\x62\x50\xc6\xbc\x84\x14\xf9\xbf\x50\xc8\x6c\x2d\x72\x35\xda",
"\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b",
"\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd"
},
{
// Long key
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131,
"\x54\x65\x73\x74\x20\x55\x73\x69\x6e\x67\x20\x4c\x61\x72\x67\x65\x72\x20\x54\x68\x61\x6e\x20\x42\x6c\x6f\x63\x6b\x2d\x53\x69\x7a\x65\x20\x4b\x65\x79\x20\x2d\x20\x48\x61\x73\x68\x20\x4b\x65\x79\x20\x46\x69\x72\x73\x74", 54, // "Test Using Larger Than Block-Size Key - Hash Key First"
"\x90\xd0\xda\xce\x1c\x1b\xdc\x95\x73\x39\x30\x78\x03\x16\x03\x35\xbd\xe6\xdf\x2b",
"\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54",
"\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98"
},
{
// Long key and long data
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 131,
"\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68\x6d\x2e", 152,
"\x21\x7e\x44\xbb\x08\xb6\xe0\x6a\x2d\x6c\x30\xf3\xcb\x9f\x53\x7f\x97\xc6\x33\x56",
"\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2",
"\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58"
}
};
static int pbkdf_test_vectors(void)
{
char result[256];
@@ -447,6 +516,96 @@ static int hash_test(void)
return 0;
}
const char* get_hmac_res(struct hmac_test_vector* out, int i)
{
switch (i) {
case 0:
return out->hmac_sha_1;
case 1:
return out->hmac_sha_256;
case 2:
return out->hmac_sha_512;
}
return NULL;
}
static int hmac_test(void)
{
struct crypt_hmac *hmac;
struct hmac_test_vector *vector;
struct crypt_hash *h;
unsigned int hmac_length;
int i, j, r;
char result[64];
char key[MAX_BLOCK_SIZE];
for (i = 0; i < (sizeof(hmac_test_vectors) / sizeof(*hmac_test_vectors)); i++) {
vector = &hmac_test_vectors[i];
printf("HMAC vector %02d: ", i);
for(j = 0; j < 3; j++) {
struct hash_alg* hash = &hash_algs[j];
hmac_length = crypt_hmac_size(hash->name);
if (hmac_length != hash->length) {
if (hmac_length < 0) {
printf("[%s N/A]", hash->name);
continue;
}
return -EINVAL;
}
printf("[%s]", hash->name);
int key_length = vector->key_length;
// hash key first if key size is greater than max block size
if (key_length > MAX_BLOCK_SIZE) {
if (crypt_hash_init(&h, hash->name))
return -EINVAL;
r = crypt_hash_write(h, vector->key, vector->key_length);
if (!r)
r = crypt_hash_final(h, key, hash->length);
crypt_hash_destroy(h);
if (r)
return r;
key_length = hash->length;
} else {
memcpy(key, vector->key, vector->key_length);
}
if (crypt_hmac_init(&hmac, hash->name, key, key_length))
return -EINVAL;
r = crypt_hmac_write(hmac, vector->data, vector->data_length);
if (!r)
r = crypt_hmac_final(hmac, result, hmac_length);
crypt_hmac_destroy(hmac);
if (r)
return r;
if (memcmp(result, get_hmac_res(vector, j), hash->length)) {
printf("expected output [FAILED].\n");
printhex(" got", result, hash->length);
printhex("want", get_hmac_res(vector, j), hash->length);
return -EINVAL;
}
}
printf("\n");
}
return 0;
}
int main(int argc, char *argv[])
{
if (crypt_backend_init(NULL)) {
@@ -461,6 +620,9 @@ int main(int argc, char *argv[])
if (hash_test())
exit(EXIT_FAILURE);
if (hmac_test())
exit(EXIT_FAILURE);
crypt_backend_destroy();
exit(EXIT_SUCCESS);
}

View File

@@ -57,7 +57,7 @@ function dm_crypt_features()
format() # format
{
dd if=/dev/zero of=$DEV bs=1M count=5 >/dev/null 2>&1
dd if=/dev/zero of=$DEV bs=1M count=9 >/dev/null 2>&1
echo $PWD1 | $CRYPTSETUP luksFormat --type $1 $DEV -q $FAST_PBKDF_OPT -c aes-cbc-essiv:sha256
[ $? -ne 0 ] && fail "Format failed."
@@ -97,11 +97,11 @@ if [ -z "$DM_PERF_CPU" ]; then
SKIP_COUNT=$((SKIP_COUNT+1))
else
# plain
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --perf-submit_from_crypt_cpus || fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
$CRYPTSETUP status $DEV_NAME | grep -q submit_from_crypt_cpus || fail
$CRYPTSETUP close $DEV_NAME || fail
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --perf-same_cpu_crypt --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep -q same_cpu_crypt || fail
$CRYPTSETUP status $DEV_NAME | grep -q discards || fail
$CRYPTSETUP close $DEV_NAME || fail
@@ -152,7 +152,7 @@ else
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size 1234 >/dev/null 2>&1 && fail
for S in 512 1024 2048 4096; do
echo -n "[$S]"
echo -e "$PWD1" | $CRYPTSETUP open --type plain $DEV $DEV_NAME --sector-size $S || fail
echo -e "$PWD1" | $CRYPTSETUP open -q --type plain $DEV $DEV_NAME --sector-size $S || fail
check_sector_size $S
$CRYPTSETUP close $DEV_NAME || fail
done

View File

@@ -20,7 +20,7 @@ fail()
}
add_device() {
modprobe scsi_debug $@
modprobe scsi_debug $@ delay=0
if [ $? -ne 0 ] ; then
echo "This kernel seems to not support proper scsi_debug module, test skipped."
exit 77
@@ -74,7 +74,7 @@ dmsetup table $DEV_NAME | grep allow_discards >/dev/null || fail
$CRYPTSETUP luksClose $DEV_NAME || fail
echo "[2] Allowing discards for plain device"
echo $PWD1 | $CRYPTSETUP create $DEV_NAME $DEV --hash sha1 --allow-discards || fail
echo $PWD1 | $CRYPTSETUP create -q $DEV_NAME $DEV --hash sha1 --allow-discards || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail
$CRYPTSETUP resize $DEV_NAME --size 100 || fail
$CRYPTSETUP status $DEV_NAME | grep flags | grep discards >/dev/null || fail

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,85 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary header with config json size mismatching
# value in binary header
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512))
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
json_str=$(jq -c '.' $TMPDIR/json0)
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0
local str_res1=$(head -c 4 $TMPDIR/hdr_res0)
test "$str_res1" = "LUKS" || exit 2
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 4 $TMPDIR/hdr_res1)
test "$str_res1" = "SKUL" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
jq -c --arg js $JS 'if .config.json_size != ( $js | tostring )
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 128 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 128KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 16 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 1 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 1 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 256 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 256KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,96 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 2 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 2 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 32 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary header with non-default metadata json_size.
# There's only limited set of values allowed as json size in
# config section of LUKS2 metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 32KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,96 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 4 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 4 MiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 512 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size. There's only limited
# set of values allowed as json size in config section of LUKS2
# metadata
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 512KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,94 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary header with non-default metadata json_size
# and keyslots area trespassing in json area.
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 64KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024-1))
# overlap in json area by exactly one byte
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024-1))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,96 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary header with non-default metadata json_size
# and keyslot area overflowing out of keyslots area.
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 64KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
--arg mda $((2*TEST_MDA_SIZE_BYTES)) \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.keyslots."7".area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring ) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
# .keyslots.7.area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots.7.area.size | tonumber) + 1) | tostring ) |
jq -c --arg mda $((2*TEST_MDA_SIZE_BYTES)) --arg jsize $JSON_SIZE \
'if (.keyslots."7".area.offset != ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring )) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,96 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate primary with predefined json_size where keyslots size
# overflows in data area (segment offset)
#
# secondary header is corrupted on purpose as well
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 64KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
--arg mda $((2*TEST_MDA_SIZE_BYTES)) \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.config.keyslots_size = (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ) |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area1
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
test "$str_res1" = "VACUUM" || exit 2
read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE --arg off $DATA_OFFSET --arg mda $((2*TEST_MDA_SIZE_BYTES)) \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize) or
(.config.keyslots_size != (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ))
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

View File

@@ -0,0 +1,97 @@
#!/bin/bash
. lib.sh
#
# *** Description ***
#
# generate secondary header with one of allowed json area
# size values. Test wheter auto-recovery code is able
# to validate secondary header with non-default json area
# size.
#
# primary header is corrupted on purpose.
#
# $1 full target dir
# $2 full source luks2 image
function prepare()
{
cp $SRC_IMG $TGT_IMG
test -d $TMPDIR || mkdir $TMPDIR
read_luks2_json0 $TGT_IMG $TMPDIR/json0
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
}
function generate()
{
# 64 KiB metadata
TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
JSON_SIZE=$((TEST_JSN_SIZE*512))
DATA_OFFSET=16777216
json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
'.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
.config.json_size = $jsize |
.segments."0".offset = $off' $TMPDIR/json0)
test -n "$json_str" || exit 2
test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
erase_checksum $TMPDIR/area0
chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
write_checksum $chks0 $TMPDIR/area0
erase_checksum $TMPDIR/area1
chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
write_checksum $chks0 $TMPDIR/area1
kill_bin_hdr $TMPDIR/area0
write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
}
function check()
{
read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
test "$str_res0" = "VACUUM" || exit 2
read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
(.config.json_size != $jsize)
then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
}
function cleanup()
{
rm -f $TMPDIR/*
rm -fd $TMPDIR
}
test $# -eq 2 || exit 1
TGT_IMG=$1/$(test_img_name $0)
SRC_IMG=$2
prepare
generate
check
cleanup

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