Compare commits

...

828 Commits

Author SHA1 Message Date
Milan Broz
ff51d5a8fa Version 2.4.2. 2021-11-18 11:35:45 +01:00
Jakub Bogusz
949ed8c9e2 po: update pl.po (from translationproject.org) 2021-11-18 10:57:02 +01:00
Milan Broz
31698f8388 LUKS convert: also check sysfs for device activity.
On some "broken" systems, udev directory (where we try to check
if device is active) is present, but the symlink is missing.

Let's fallback in this case on sysfs scanning also, otherwise
possible conversion of an active device can cause data corruption.
2021-11-18 08:15:09 +00:00
Milan Broz
c400a84987 Add 2.4.2 release notes. 2021-11-17 13:11:26 +01:00
Yuri Chornoivan
ce52bb2f5a po: update uk.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Yuri Kozlov
bf374ca9e6 po: update ru.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Hiroshi Takekawa
17ca463767 po: update ja.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Frédéric Marchal
aa8d8ec0ae po: update fr.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Roland Illig
1b08d47045 po: update de.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Petr Pisar
0f656105e2 po: update cs.po (from translationproject.org) 2021-11-16 16:53:12 +01:00
Milan Broz
0b3a7ecd01 Update cryptsetup.pot. 2021-11-16 16:52:22 +01:00
Milan Broz
a364355c16 Fix missing translation macros. 2021-11-10 15:29:29 +00:00
Milan Broz
7086c414bc Avoid casting of uint64_t to unsigned int in debug messages. 2021-11-10 13:39:54 +00:00
Milan Broz
0bb193d487 Fix code style.
We do not use curly brackets in this context.
2021-11-10 13:39:54 +00:00
Milan Broz
80b57c6e24 Free json buffer on error path.
Code should not return allocated buffer if validation fails.

(But this does not fix a leak, memory is freed later, it is just more readable.)
2021-11-10 13:39:54 +00:00
Milan Broz
9576549fee Fix bogus memory allocation if LUKS2 header size is invalid.
LUKS2 code read the whole header to buffer to verify checksum,
so malloc is called on unvalidated input size parameter.

This can cause out of memory or unintentional device reads.
(Header validation will fail later anyway - the size is unsupported.)

Just do not allow too small and too big allocations here and fail quickly.

Fixes: #683.
2021-11-10 13:39:54 +00:00
Milan Broz
0cc5f2fdf9 Fix debug message printing LUKS2 checksum.
The trailing NUL is written already by snprintf, moreover,
it is written on wrong place here.

Just rely on snprintf here.

Fixes: #685.
2021-11-10 12:56:20 +01:00
Abhijit Menon-Sen
26a3f3b058 Fix typo ("Veryfing") 2021-11-02 08:08:28 +01:00
Milan Broz
e03f3bb36e Set devel version. 2021-11-01 17:11:33 +01:00
Daniel Zaťovič
be5ab79c9d Switch GitLab CI tags for the libvirt custom runner. 2021-10-26 19:28:42 +02:00
Milan Broz
083cdb9310 Add a debug message before running keyslot PBKDF.
This is useful for debugging if the process is killed by OOM.
2021-10-15 19:17:45 +02:00
leongross
ca30d3cda9 fix minor README.md issues 2021-10-12 14:55:16 +00:00
Мирослав Николић
5c17722854 po: update sr.po (from translationproject.org) 2021-10-12 16:54:00 +02:00
Milan Broz
49177aac46 Add test vector for empty password for Argon2.
While it is insecure, we need crypto backend to support this :)
2021-10-06 21:54:49 +02:00
Milan Broz
d20beacba0 Remove redundant link to uuid lib for static build.
Veritysetup does not need to link this library at all, for others
we have link already in flags.
2021-10-06 13:02:51 +02:00
Milan Broz
26cc1644b4 Do not link integritysetup and veritysetup with pwquality.
These tools do not read passphrases, no need to link to these libraries.

Just move the helper code that introduced this dependence as a side-effect.

Fixes: #677
2021-10-06 13:02:19 +02:00
Milan Broz
9ed0036286 CI: comment out fixed project rule for merge request jobs.
We need pipeline to be created here, seems GitLab does not
allow it otherwise.
2021-09-29 15:20:54 +02:00
Milan Broz
00f7d92514 OpenSSL backend: no need to use strlen for KDF param length. 2021-09-29 10:24:45 +00:00
Milan Broz
43674b2903 OpenSSL3 backend: avoid remaining deprecated calls in API.
Implement HMAC through new API.

In reality, these calls are never used (the only user is internal PBKDF2
that is never called with OpenSSL backend).
2021-09-29 10:24:45 +00:00
Milan Broz
5cfd5fc4cd Crypt vectors test: add test for hash/hmac context reset.
The crypto API expects that after final() call the context is reset,
let's test if backend properly supports it.
2021-09-29 10:24:45 +00:00
Milan Broz
9f252d4bf8 Install openssl binary for CI test. 2021-09-27 22:31:34 +02:00
Ondrej Kozina
321057eed5 Add Fedora rawhide runner to CI. 2021-09-27 17:25:13 +02:00
Ondrej Kozina
1a3d049454 Add tags for currently available runners. 2021-09-27 17:09:21 +02:00
Milan Broz
9d1f29a9fd OpenSSL backend: separate KDF wrappers.
Prepare code for later to add Argon2 OpenSSL wrapper more easily.
2021-09-22 08:25:19 +00:00
Milan Broz
da31341d5d OpenSSL3 backend: use predefined macros to construct KDF params. 2021-09-22 08:25:19 +00:00
Milan Broz
10b1d6493e Check if DM create device failed in an early phase.
This happens when concurrent creation of DM devices meets
in the very early state (no device node exists but creation fails).

Return -ENODEV here instead of -EINVAL.

(Should "fix" random verity concurrent test failure.)
2021-09-21 17:58:34 +02:00
Milan Broz
a76310b53f Do not try to set compiler optimization flag if wipe is implemented in libc.
If zeroing memory is implemented through libc call (like memset_bzero),
compiler should never remove such call. It is not needed to set O0
optimization flag explicitly.

Various checkers like annocheck causes problems with these flags,
just remove it where it makes no sense.

(Moreover, we use the same pattern without compiler magic
in crypt_backend_memzero() already.)
2021-09-20 17:42:20 +02:00
Yuri Kozlov
26d26d7134 po: update ru.po (from translationproject.org) 2021-09-17 18:52:18 +02:00
Hector Martin
a1b577c085 Do not attempt to unload external tokens if USE_EXTERNAL_TOKENS is disabled.
This allows building a static binary as long as --disable-external-tokens is used
2021-09-17 05:44:18 +00:00
Milan Broz
8a0682650e Version 2.4.1. 2021-09-15 11:29:09 +02:00
Milan Broz
85e5ccec17 Update cryptsetup.pot. 2021-09-15 11:26:57 +02:00
Milan Broz
3da5352b89 Fix compatible OpenSSL backend constructor definition. 2021-09-15 08:13:49 +02:00
Ondrej Kozina
1569558503 Fix offset bug in LUKS2 encryption code.
The code did not account for data offset when
set via --offset when creating new header in-before
LUKS2 encryption took place.
2021-09-14 16:10:24 +02:00
Ondrej Kozina
ce704859b8 Fix offset error in decryption hotzone.
The hotzone segment offset has to be altered
accordingly no matter the segment type.

Note for testing: This feature is currently
blocked in cli but it should be tested via
API tests anyway.
2021-09-14 15:21:07 +02:00
Milan Broz
fd18e0b1c9 Fix integrity test & non-fips algorithms.
Apparently algorithms can be in /proc/crypto despite they are not available.
Just limit failure of the test to sha and crc algorithms.
2021-09-14 14:51:50 +02:00
Milan Broz
ba4d5680d6 Fix typo and EOL in vector test. 2021-09-14 10:33:38 +02:00
Milan Broz
75e45462f0 Cache FIPS mode check.
We do not support switch while the crypto backend is already initialized,
so it does not make sense to check repeatedly for the FIPS mode status.
2021-09-14 09:56:05 +02:00
Milan Broz
f8eb7b225a Do not load own OpenSSL backend context in FIPS mode.
In the FIPS mode keep configuration up to the system wide config.
2021-09-13 21:56:59 +02:00
Milan Broz
29ea07ef66 OpenSSL backend: make legacy for OpenSSL3 optional and report loaded providers 2021-09-13 21:56:54 +02:00
Ondrej Kozina
6c9d386303 Adapt crypto backend to openssl3 lib context.
Fully leverage openssl custom library context for various
providers (default, legacy). It can be used to properly
free all openssl resources used by libcryptsetup when
libcryptsetup is unloaded (and destructor is triggered).
2021-09-13 16:54:40 +02:00
Arno Wagner
bf84ead85c sync to Wiki 2021-09-13 11:03:15 +02:00
Yuri Chornoivan
ca2ba1a6f5 po: update uk.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Jakub Bogusz
284d1615c8 po: update pl.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Hiroshi Takekawa
b4181ffa3b po: update ja.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Frédéric Marchal
8c0caf9a1f po: update fr.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Roland Illig
d2682c4841 po: update de.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Petr Pisar
39ddcfaaa0 po: update cs.po (from translationproject.org) 2021-09-07 12:41:48 +02:00
Milan Broz
669ad1933a Fix possible use of unallocated parameter.
(Introduced in previous patches.)
2021-08-30 12:39:17 +02:00
Milan Broz
84fa6ffbde Remove some Doxygen docs warnings. 2021-08-30 12:32:42 +02:00
Milan Broz
2206f7f108 Prepare version for translation. 2021-08-30 11:57:11 +02:00
JT Moree
ec946b17eb add headers
add headers for Help: documentation and mailing list
2021-08-27 14:39:03 +00:00
JT Moree
a619cc1757 rename reference to specifications 2021-08-27 14:39:03 +00:00
JT Moree
6c3e2e2bee rework Help section 2021-08-27 14:39:03 +00:00
Ondrej Kozina
621dcea8ee Do not init LUKS2 decryption for devices with data offset.
Currently LUKS2 decryption cannot perform data decryption
with data shift. Even though we can decrypt devices with
data offset > 0 in LUKS2 metadata it does not make much
sense. Such devices cannot be easily mounted after decryption
is finished due to said data offset (fs superblock is moved
typicaly by 16MiBs).
2021-08-27 16:26:37 +02:00
Milan Broz
f6fb530121 Repair also lowercase hash in LUKS1 header.
This patch removes magic for backup load that quietly
run lowecase conversion and add this possibility to repair command.

Most of crypto backends allow uppercase though.
2021-08-25 16:45:00 +00:00
Milan Broz
0066f9dd83 Fix LUKS1 repair to repair wrong ECB mode.
1) Crypsetup repair should try to call crypt_repair() even
if crypt_load is ok - it has no validate system unlike LUKS2
and some errors cannot be hard load errors.

2) Move ECB fix to repair code, do not try magic on load that
no longer works.

And do not use ECB :)

Fixes: #664
2021-08-25 16:45:00 +00:00
Ondrej Kozina
46b70d7317 Add error message when assigning token to inactive keyslot.
While adding or importing new token and assigning immediately to
keyslot it would be useful to provide specific error message
directly from cryptsetup utility when keyslot does not exist.
2021-08-25 16:11:00 +00:00
Milan Broz
8c28774917 Fix vector test print message additional parameter. 2021-08-25 18:09:56 +02:00
Milan Broz
e5d84156e4 Fix linker to use -ldl if external tokens are used.
Also run check for symbols only if external modules are really used.
2021-08-25 13:50:33 +02:00
Milan Broz
5f2c751dd8 Use dlsym() for token load if dlvsym() is not available.
To be discussed. Anyway, we need to support distros with musl...
2021-08-25 13:39:07 +02:00
Ondrej Kozina
53b22cc32e Fix deferred remove test failure on non-udev systems.
Deferred remove non-udev enabled libdevmapper removes
device mapper symlinks immediately. We have to check
device size from sysfs attributes.
2021-08-25 13:39:03 +02:00
Milan Broz
26679e223c Trigger read event for verity test to mark device as corrupted.
If distro does not use udev/blkid, there is no IO event after activation.
Kernel does not mark the device corrupted then (it happens on the
first IO). Just add a simple read to trigger it.
2021-08-25 13:38:58 +02:00
Milan Broz
9b7d3be5c6 Skip UUID= cryptsetup activation test if /dev has no uuid links.
There are still distros that tries to reinvent the wheel, let just
ignore if /dev is not propagated by symlinks that we depend on.
2021-08-25 13:38:54 +02:00
Milan Broz
358dec19b2 Use compatible flags for BusyBox diff command. 2021-08-25 13:38:50 +02:00
Milan Broz
863fd08305 Skip test if incompatible tar from BusyBox is installed.
We depend on sparse images that BusyBox tar cannot handle.
Just install the full tar package for tests.
2021-08-25 13:38:46 +02:00
Milan Broz
93481d1566 Use compatible flags for BusyBox free command. 2021-08-25 13:38:41 +02:00
Milan Broz
3a79b2b09b Fix gettext (-lintl) linker flags.
The external gettext library should be used on main libcryptsetup,
not later for programs (these do not call any translations).

(Also it was in the wrong order there failing compilation.)
2021-08-25 13:38:23 +02:00
Milan Broz
246d306eeb Check for argp library that can be standalone.
Some systems without glibc provides standalone package for argp.
2021-08-25 13:37:33 +02:00
Milan Broz
03943acbb1 Remove obsolete AC_HEADER_STDC macro.
This should be no longer used.
We do not support systems without standard headers anyway.
2021-08-25 13:37:29 +02:00
Milan Broz
20b678c9f3 Fix symbol version test if dlvsym() is not available.
If we have no dlvsym(), just run dlsym() test.
2021-08-25 13:37:25 +02:00
Milan Broz
e008a88b98 Test Coverity action. 2021-08-19 14:29:53 +02:00
Milan Broz
5efa782567 Ignore default algorithm test in FIPS mode.
This can cause unexpected failures (despite it is kind of misconfiguration).
2021-08-19 13:36:13 +02:00
Milan Broz
ab37ad0dc9 Update doxyfile. 2021-08-19 10:31:21 +02:00
Milan Broz
03208167b2 Fix release notes. 2021-08-18 17:19:50 +02:00
Milan Broz
0f8e7f317f Version 2.4.0. 2021-08-18 16:50:50 +02:00
Milan Broz
c5b0a4dd32 Remove Travis CI config. So long, and thanks for all the builds. 2021-08-18 16:01:36 +02:00
Ondrej Kozina
5c5551d1d3 Update release notes. 2021-08-18 15:11:18 +02:00
Vojtech Trefny
aa324567a8 ssh-plugin-test: Fix running the test in GitHub actions 2021-08-18 14:18:55 +02:00
Milan Broz
0ee752c42d Update 2.4.0 release notes. 2021-08-18 14:09:32 +02:00
Milan Broz
4746717b75 Update Fedora spec.
Rebuild configure suite locally, so we do not need to patch generated
scripts because of RPATH issues.
2021-08-18 14:02:28 +02:00
Milan Broz
3ad942e338 Add autogen.sh to distributions.
Allow dowsntream packagers to rebuild the whole buildsystem.
2021-08-18 14:01:09 +02:00
Milan Broz
b5190da581 Update cryptsetup.pot. 2021-08-18 14:00:29 +02:00
Ondrej Kozina
5fa8e84ef0 Also install directory for external plugins.
And remove custom target from reference .spec file.
2021-08-18 12:08:14 +02:00
Milan Broz
63adb3b0cf Fix LDFLAGS for all-symbols-test.
Option -ldl is for LDFLAGS, not for CFLAGS (fixes clang warning).
2021-08-17 21:45:49 +02:00
Milan Broz
20774374a9 Fail if default compiled hash is not implemented.
If crypto backend does not provide configured hash,
fail crypto backend tests.

(User has to use configure option if backend does not provide seclected algorithm.)

Seen recently with RIPEMD160.
Note: NSS does not provide RIPEMD, use --with-plain-hash etc.
2021-08-17 19:16:35 +00:00
Milan Broz
d169020001 Limit GitLab CI only to parent cryptsetup project. 2021-08-17 18:22:21 +02:00
Yuri Chornoivan
76766f11c0 po: update uk.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Мирослав Николић
5d6d65ce86 po: update sr.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Yuri Kozlov
24ab0871e7 po: update ru.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Jakub Bogusz
11e325a112 po: update pl.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Hiroshi Takekawa
6ea32db1fa po: update ja.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Frédéric Marchal
49c8a8b9ef po: update fr.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Roland Illig
a480c388b8 po: update de.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Petr Pisar
5406064f55 po: update cs.po (from translationproject.org) 2021-08-17 13:48:13 +02:00
Milan Broz
9b66d0d039 Add experimental GitLab CI config. 2021-08-15 21:52:37 +02:00
Milan Broz
adff844c46 Remove test image in SSH test if ssh config fails. 2021-08-15 21:50:56 +02:00
Milan Broz
f702246d78 Remove test images dir once test is finished.
THsi allows another user to run test later without permission collision..
2021-08-15 21:46:28 +02:00
Milan Broz
8606342b53 Limit GitHub Actions job to this repository. 2021-08-15 11:29:37 +02:00
Milan Broz
ccb0f7c0b2 Fix typo in CI configure. 2021-08-15 11:24:13 +02:00
Milan Broz
72384b43bd Add simple GitHub Action CI.
This runs only on push in selected branches.

(Not for push requests, we do not use PR on GitHub.)
2021-08-14 22:36:30 +02:00
Milan Broz
5ef3de8945 Add separate check-programs target. 2021-08-14 22:34:27 +02:00
Milan Broz
ad913cf437 Require only libtoolize in autogen.sh. 2021-08-12 21:30:02 +02:00
Milan Broz
7820f07e85 Fix libtool detection in autogen.sh.
The macro disappeared in 2.67 autoconf update (2010).

Fixes: #663.
2021-08-12 19:13:52 +02:00
JT Moree
01bda280ee man page
add note about searching the man page
2021-08-12 16:48:36 +00:00
JT Moree
b40f31fb8c FAQ
add memory FAQ
add non root FAQs
2021-08-11 05:18:05 -07:00
Milan Broz
066d651210 Fix a possible memory leak of verity signature description.
The signature description should be allocated only if params field is used,
otherwise we can leak the string value.

(Moreover, the query path is currently used only for flag, not for the value.)
2021-08-04 13:06:14 +02:00
Yuri Chornoivan
b00946d449 Fix minor typo: assing -> assign 2021-07-30 16:19:36 +00:00
Guilhem Moulin
6a14f52e5d Fix minor spelling errors.
(Found by Lintian.)
2021-07-30 02:56:38 +02:00
Milan Broz
3c68e3f5b1 Version 2.4.0-rc1 update. 2021-07-29 23:28:08 +02:00
Milan Broz
ec1ef8f19d Update cryptsetup.pot. 2021-07-29 23:22:33 +02:00
Milan Broz
6a64c2e932 Prepare 2.4.0-rc1 version. 2021-07-29 23:18:59 +02:00
Milan Broz
835c603b13 Use cannot in all messages. 2021-07-29 22:00:04 +02:00
Milan Broz
a718b90ac6 Fix some gcc warnings in compiled tests. 2021-07-29 20:40:48 +02:00
Milan Broz
089edb74b4 Fix return code for skipped align tests. 2021-07-29 20:19:45 +02:00
Milan Broz
8c60cf8645 Silence also scsi_debug module load in tests. 2021-07-29 17:41:25 +02:00
Ondrej Kozina
f364990b9b Do not fallback to pasphrase based activation when device exists.
If token based device activation activation fails with -EEXIST
report proper error and do not fallback to passphrase based
activation in cli.
2021-07-29 14:47:16 +00:00
Ondrej Kozina
3b826d0fa3 Add verbose messages explaining token errors. 2021-07-29 14:47:16 +00:00
Milan Broz
cab332c367 Silence all modprobe/rmmod calls in tests.
On systems where are modules compiled-in or missing this produces nois,
test will be skipped later anyway.
2021-07-29 16:20:00 +02:00
Ondrej Kozina
9ee74f59d7 Add cryptsetup --token-type parameter.
It restricts token type to parameter value in
case no specific token-id is selected.
2021-07-29 08:46:20 +00:00
Ondrej Kozina
46afee6299 Remove duplicate macro definition. 2021-07-29 08:46:20 +00:00
Milan Broz
90bba399ab Fix LOOP_CONFIGURE incompatibility is some kernels.
Kernels with 32bit userspace can return ENOTTY,
we should use fallback to old code in this case.

For more info see
  583990d25b
2021-07-29 10:32:13 +02:00
Milan Broz
c403f73ad0 Skip tests id scsi_debug is compiled-in or in use.
We need standalone scsi_debug module for some tests.
2021-07-28 23:20:45 +02:00
Milan Broz
470b99a647 Use long otpion for salt in tests.
Some old distros fail with -s=XX syntax (libpopt issue).
2021-07-28 19:36:56 +02:00
Milan Broz
a68968af8f Fix possible dereference of pbkdf params.
This can only happen during misconfiguration of default parameters,
but eliminates one gcc warning.
2021-07-27 12:44:13 +02:00
Ondrej Kozina
ee9c7855ca Use max token id in api test at least once.
so that we also test bitfield limits.
2021-07-26 14:10:08 +02:00
Ondrej Kozina
1a156458f2 Add PIN try loop for actions supporting tokens. 2021-07-26 14:10:08 +02:00
Ondrej Kozina
796b901912 Do not retry tokens that already returned -ENOANO.
In token based activation loop (token_id == CRYPT_ANY_TOKEN)
we do not want retry tokens that already returned -ENOANO (wrong pin)
once.
2021-07-26 14:10:08 +02:00
Milan Broz
508284cd28 Support build with older libssh.
The function ssh_session_is_known_server() was introduced later,
fallback to older version if libssh is available.
2021-07-25 21:57:09 +02:00
Milan Broz
5d1972bb97 Use depreacated attribute compatible with old gcc. 2021-07-25 18:27:55 +02:00
Vojtech Trefny
7c76d17a9c ssh token: Make strings in the plugin translatable 2021-07-25 18:08:22 +02:00
Мирослав Николић
8ff663a761 po: update sr.po (from translationproject.org) 2021-07-25 13:40:57 +02:00
Antonio Ceballos
d3ad9fe25f po: update es.po (from translationproject.org) 2021-07-25 13:40:57 +02:00
Luca Boccassi
cc374ee10d veritysetup: add --root-hash-file option
Allow to pass the root hash via a file, rather than verbatim on
the command line, for the open/verify/format actions.
It is much more convenient when using veritysetup in scripts.

[some modifications by mbroz:]
- Add additional syntax and option description to man page.
- Fix a segfault with non-existing path.
- Do not read full file.
- Small refactor for argc handling and option processing.
2021-07-25 13:40:17 +02:00
Ondrej Kozina
06f132066b Add crypt_reencrypt_run superseding now deprecated crypt_reencrypt.
This reverts commit 367cb7a761
and retains original crypt_reencrypt() symbol marked as deprecated
in favour of new crypt_reencrypt_run(). This makes cryptsetup 2.4.0
release fully backward compatible.
2021-07-22 15:59:01 +02:00
Ondrej Kozina
82816cb52f Suppress error message when keyslot is unusable for segment.
It's too verbose when run in loop for token based activation.
2021-07-22 13:55:22 +02:00
Ondrej Kozina
426cab3aeb Add more LUKS2 token based activation tests. 2021-07-22 13:55:22 +02:00
Ondrej Kozina
152ed1fb44 Speed up LUKS2 api test. 2021-07-22 13:55:22 +02:00
Ondrej Kozina
c6ff9f8bd7 Respect keyslot priority with token based activation.
crypt_activate_by_token functions did not respect LUKS2 keyslot
priorities. These calls were able to activate device via keyslot with
CRYPT_SLOT_PRIORITY_IGNORE even when token was set to
CRYPT_ANY_TOKEN. This commit changes the token based activation
so that keyslot with priority ignore is eligible for unlock only
when specific token is selected. Also when activating with token
set to CRYPT_ANY_TOKEN keyslots with higher priority take precedence
over keyslots with normal priority. Keyslot with priority ignore are
correctly ignored when token is CRYPT_ANY_TOKEN.
2021-07-22 13:55:22 +02:00
Ondrej Kozina
c104bccc3f Print some compile-time defaults in 00module-test. 2021-07-22 13:55:22 +02:00
Ondrej Kozina
4654e6f578 Add best effort try-loop for token based activation.
The loop is run only when token id in any of crypt_activate_by_token*
calls is set to CRYPT_ANY_TOKEN.
2021-07-22 13:55:19 +02:00
Ondrej Kozina
2cf38465c4 Change default error returned by token open.
It has to be -ENOENT since -EPERM would wrongly
implied the token provided wrong keyslot passphrase.
2021-07-22 13:47:40 +02:00
Ondrej Kozina
3428296186 Improve debug logs for external token handling. 2021-07-22 13:47:40 +02:00
Ondrej Kozina
877afd2281 Replace original token activation retcode -EAGAIN with -ENOANO.
crypt_activate_by_token (and _pin variant) now returns -ENOANO
instead -EAGAIN in case token handler identifies specific token
requires PIN to sucessfully complete token based activation.

-EAGAIN is now used for special case when additional system
resources are missing (HW token, other device, system daemon,
etc).
2021-07-22 13:47:14 +02:00
Ondrej Kozina
2f320f3148 Avoid possible lock deadlock after error.
The deadlock is hypothetical since libcryptsetup applications
usualy terminates after error. The deadlock could only emerge
in case where single process handles multiple crypt contexts.
2021-07-22 10:31:02 +02:00
Yuri Chornoivan
a0277d3ff6 po: update uk.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Josef Andersson
531ebba50b po: update sv.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Мирослав Николић
d8bac63e5c po: update sr.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Yuri Kozlov
b408b8238c po: update ru.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Jakub Bogusz
2e80962501 po: update pl.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Hiroshi Takekawa
43827ba380 po: update ja.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Frédéric Marchal
cd374664d4 po: update fr.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Roland Illig
3694f9c099 po: update de.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Petr Pisar
06249b8e99 po: update cs.po (from translationproject.org) 2021-07-14 16:59:03 +02:00
Vojtech Trefny
bf915e82f4 man: Add information about maximum number of key slots to --key-slot 2021-07-13 09:37:46 +02:00
Vojtech Trefny
bfe0c7fc5f Fix error message for invalid key slot with LUKS2
Fixes: #651
2021-07-13 07:22:16 +02:00
Ondrej Kozina
0eb8493156 Fix ssh-plugin test. 2021-07-02 22:56:45 +02:00
Ondrej Kozina
9736f533bb tests: Do not guess default pbkdf anymore.
Instead of guessing get pbkdf defaults via libcryptsetup
API.
2021-07-02 21:55:42 +02:00
Milan Broz
cc6df5fa39 Fix some random typos. 2021-07-02 14:05:41 +02:00
Milan Broz
62896c20ff Update README.md. 2021-07-02 13:34:12 +02:00
Milan Broz
ea5fb82a48 Update cryptsetup.pot. 2021-07-02 13:29:37 +02:00
Milan Broz
25c29b80b5 Add utils_argsa to translations file. 2021-07-02 13:28:11 +02:00
Milan Broz
f8caa82186 Prepare version 2.4.0-rc0. 2021-07-02 12:02:39 +02:00
Ondrej Kozina
c35b896209 cryptsetup.spec: remove .la file from plugins build dir. 2021-06-30 12:41:42 +02:00
Milan Broz
5a36a1f3a2 OpenSSL crypto backend: suppress deprecation warnings.
The old API is still supported and because we support very old
OpenSSL, this is the best wrokaround for the warnings.

Once we switch to the new OpenSSL version requirement, we can rewrite
HMAC to new EVP_MAC API.
2021-06-30 08:01:38 +00:00
Milan Broz
afb7cd6d01 OpenSSL crypt backend support for OpenSSL3.
For OpenSSL version 3 we need to load legacy provider for older
hash and ciphers.
2021-06-30 08:01:38 +00:00
Milan Broz
c9af248c38 Fix LUKS2 token installation directory. 2021-06-30 09:37:51 +02:00
Ondrej Kozina
95eb986206 Few fixes to ssh-token and related spec file. 2021-06-30 09:37:50 +02:00
Vojtech Trefny
b4670ce7f0 ssh token: Change license to LGPL
The cryptsetup-ssh binary stays under GPL.
2021-06-29 16:19:04 +02:00
Ondrej Kozina
6633fa626a Remove unused crypt_token_external_support.
API can expose same information with crypt_token_external_path.

Also add print out of external token in cryptsetup --help action
(if enabled)
2021-06-29 14:13:37 +00:00
Ondrej Kozina
df7a995fa2 Remove redundant (unreleased) API for token based activation.
Reverts commit 96d83455ca partially. It is not necessary to
have specific crypt_activate_by_token_type call. Users
may use crypt_activate_by_token_pin with pin argument set to NULL
and achieve same goal as with crypt_activate_by_token_type.
2021-06-29 14:13:37 +00:00
Vojtech Trefny
ca2e93b69d token ssh: Use autotools magic when linking libssh 2021-06-29 15:11:46 +02:00
Vojtech Trefny
3589f9578a ssh token: Fix -Wmissing-prototypes warnings 2021-06-29 15:11:46 +02:00
Vojtech Trefny
07d23c2ee8 Add cryptsetup-ssh to .gitignore 2021-06-29 15:11:46 +02:00
Vojtech Trefny
eadbcac115 ssh token: Add man page for cryptsetup-ssh 2021-06-29 15:11:46 +02:00
Vojtech Trefny
3dc7dff2b2 ssh token: Fix return code when adding multiple tokens
token_add returns ID of the added token so we can't use it as a
return code for the binary.
2021-06-29 15:11:46 +02:00
Vojtech Trefny
35793c24f0 ssh token: Allow specifying key slot when adding the token 2021-06-29 15:11:46 +02:00
Vojtech Trefny
ff958d376e ssh token: Remove unused sshplugin_context struct 2021-06-29 15:11:46 +02:00
Vojtech Trefny
6545523df3 ssh token: Add the token to the first keyslot with matching passphrase
Currently the "add" action adds the token to all keyslots, this
changes the behaviour to make sure the token is added to the first
keyslot that can be unlocked using the provided passphrase.
2021-06-29 15:11:46 +02:00
Vojtech Trefny
3e52aa820c ssh token: Move SSH code to a separate utils file 2021-06-29 15:11:43 +02:00
Milan Broz
73cd60b1cc Do not pack the whole tokens directory to the dist file. 2021-06-28 16:40:36 +02:00
Milan Broz
c7b0f8fcda Fix some issues introduce by too simplified fake lib build. 2021-06-28 16:33:55 +02:00
Ondrej Kozina
057af1e20a Fix ssh-plugin-test.
Test needs to work also in build environment
before installation takes place. For it we overload
crypt_token_external_path symbol from libcryptsetup
so that it can look for plugins in build environment.

[simplified by mbroz]
2021-06-26 23:13:34 +02:00
Ondrej Kozina
aea841eeb0 Add crypt_token_external_path. 2021-06-26 22:08:45 +02:00
Ondrej Kozina
5b9e98f941 Change external token handlers (plugins) default location.
Search for token handlers in %{libdir}/cryptsetup directory
by default. Distros may change default location via
--with-luks2-external-tokens-path parameter during configuration.
2021-06-24 12:54:13 +02:00
Antonio Niño Díaz
c645045adb Fix typo in cryptsetup man page 2021-06-23 16:43:46 +01:00
Milan Broz
224555aaf9 Add documentation of PBKDF limits for cryptsetup man page.
This patch adds basic description of PBKDF limits to cryprtsetup man page.

(Later we shoudl generate values from compiled-in constants.)

Fixes: #391
2021-06-22 13:08:50 +00:00
Milan Broz
d9fc45de04 Increase minimal memory cost for Argon2 benchmark to 64MiB.
Argon2 draft defines suggested parameters for disk encryption use, but LUKS2
approach is slightly different. We need to provide platform independent
values. The values in draft expects 64bit systems (suggesting using 6 GiB
of RAM), while we need to provide compatibility with all 32bit systems,
so allocating more than 4GiB memory is not option for LUKS2.

The maximal limit in LUKS2 stays for 4 GiB, and by default LUKS2
PBKDF benchmarking sets maximum to 1 GIB, prefering increase of CPU cost.

But for the minimal memory cost we had a quite low limit 32 MiB.

This patch increases the bechmarking value to 64 MiB (as minimal
suggested values in Argon2 RFC). For compatibility reasons we still
allow older limit if set by a parameter.
2021-06-22 13:08:50 +00:00
Milan Broz
db77541790 Switch to Argon2id as default PBKDF for LUKS2.
Cryptsetup LUKS2 was using Argon2 while there were two versions -
data independt (Argon2i) suitable for the KDF use case andm Argon2d
(data dependent), that is in princile unsuitable for LUKS2.

Later a new version Argon2id was introduced and this is now default
(and mandatory) algorithm as RFC Argon2 draft defines.

While Argon2id basically combines both approaches from Argon2i
and Argon2d (to provide bette side-channel resistence) it seems
reasonable to switch to Argon2id as default.

Fixes: #555
2021-06-22 13:08:50 +00:00
Milan Broz
e884fe93bd Fix veritysetup dump man page.
The option --no-superblock does not make sense here, it can take only
hash-offset that determines superblock position.
2021-06-21 14:51:07 +02:00
Yoann CONGAL
c2507f02cf readme: Update the "packages needed" list 2021-06-18 17:58:08 +00:00
Milan Broz
fc6982f577 Add spec file for Fedora.
Spec file will be needed for some automoatic tests.

THis is simplified version with some obsolete provides removal (cryptsetup-luks).
2021-06-18 09:47:02 +02:00
Milan Broz
06fff68255 Enable build of LUKS2 external tokens by default.
Also fail if ssh token is enabled and external token support is disabled.

Use --disable-external-tokens and --disable-ssh-token if needed.
2021-06-17 11:09:20 +00:00
Milan Broz
8f752a2bd7 Fix a Coverity warning. 2021-06-17 13:02:42 +02:00
Antonio Ceballos
07e687106a po: update es.po (from translationproject.org) 2021-06-16 13:04:36 +02:00
Vojtech Trefny
9125df1398 misc: Remove LUKS2 SSH token example
The SSH plugin in tokens/ssh replaces it.
2021-06-16 12:30:53 +02:00
Vojtech Trefny
52cc01c977 cryptsetup-ssh: Add debug and verbose options 2021-06-16 12:30:53 +02:00
Vojtech Trefny
b8d2218720 cryptsetup-ssh: Better argument parsing and help for the options 2021-06-16 12:30:49 +02:00
Milan Broz
05a4d3fe0a Use VeraCrypt option by default; add --disable-veracrypt option.
While TrueCrypt is no longer developed and supported since 2014,
VeraCrypt devices (as a successor of TrueCrypt) are much more
used today.

This patch switch default to scan for VeraCrypt signature, making
--veracrypt option obsolete (ignored by default as it is default).

If you need to disable VeraCrypt support, use new option
--disable-veracrypt.
2021-06-15 12:05:16 +00:00
Milan Broz
df5e54545e Add API and CLI option to disable token plugins.
This could be useful for debugging external plugins
or ot intentionally disable loading of a token library.
2021-06-13 23:22:44 +02:00
Vojtech Trefny
f79ef935a7 ssh-plugin-test: Do not use systemctl to check for SSH server
netcat should be also available on non-systemd systems.
2021-06-09 10:26:09 +02:00
Milan Broz
cd3cb945ab Update Readme.md. 2021-05-28 12:26:38 +02:00
Milan Broz
f1d624b6c8 Add 2.3.6 release notes. 2021-05-28 12:03:48 +02:00
Yuri Chornoivan
3f268c3052 po: update uk.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Yuri Kozlov
0ec7027d83 po: update ru.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Jakub Bogusz
0ae5240f55 po: update pl.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Hiroshi Takekawa
51f5f71ee0 po: update ja.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Frédéric Marchal
5784692218 po: update fr.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Roland Illig
f82d3ee51a po: update de.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Petr Pisar
d02c809bc7 po: update cs.po (from translationproject.org) 2021-05-28 11:59:51 +02:00
Klaus Zipfel
b7a07efdcf Fixing incorrect offsets for data/IV with TCRYPT system-encryption with a detached header
Related: #587
2021-05-26 09:41:08 +02:00
Milan Broz
a8bb07ae9f Fix typo in Makefile. 2021-05-24 14:52:45 +02:00
Milan Broz
897e798fc0 Add day do valglog (valgrind test output files). 2021-05-24 12:12:39 +02:00
Milan Broz
2d0b19b359 Allow tcrypt test to run under valgrind. 2021-05-24 12:09:54 +02:00
Milan Broz
702f9b1cf4 Add note about --header use in TCRYPT format to man page.
Related: #587
2021-05-24 10:43:51 +02:00
Milan Broz
1d20a60e4a Do not use Whirlpool hash in tests (some crypto backends do not implement it). 2021-05-23 11:12:10 +02:00
Milan Broz
71422b411e Increase interactive expect test timeout if runing under valgrind. 2021-05-22 09:47:14 +02:00
Мирослав Николић
f446dbb896 po: update sr.po (from translationproject.org) 2021-05-21 17:28:30 +02:00
Antonio Ceballos
975425d0eb po: update es.po (from translationproject.org) 2021-05-21 17:28:30 +02:00
Ondrej Kozina
c020fafd66 Fix LUKS2 detached header reencryption test. 2021-05-21 14:32:40 +02:00
Ondrej Kozina
2954b46d43 Move LUKS2 detached header decryption test.
It should not be skipped if dm-delay target is missing
2021-05-21 14:09:55 +02:00
Milan Broz
4cdd826282 Check exit value for snprintf where it makes sense. 2021-05-18 22:07:47 +02:00
Milan Broz
413b484774 Add some fixes and workarounds for gcc-11 static analyzer.
Not everything is a real bug (false positive rate is very high here),
but the code is actually more readable.
2021-05-18 17:28:47 +02:00
Milan Broz
351d7fefca integritysetup: mention maximal allowed key size
The error message and man page should contain this information.
2021-05-18 16:35:41 +02:00
Milan Broz
a7872ab856 Fix description of maximum passphrase size. 2021-05-18 16:35:36 +02:00
Milan Broz
c1613285e7 Add test for longer integritysetup keys. 2021-05-18 16:35:31 +02:00
Milan Broz
8805eb2b45 devmapper: avoid truncation of table features
This patch fixes several problems:
 - some optional features for dm-verity can be larger than pre-allocated buffer
 - device paths and other strings can be allocated dynamically
 - featured options with keys in dm-integrity are not wiped on stack
 - get rid of strncat()
 - always check return code of snprintf

Related #648
2021-05-18 16:35:16 +02:00
Andrii Pravorskyi
a3f919bd25 Add a note about CRC32 and other non-cryptographic checksums 2021-05-17 17:54:47 +02:00
Milan Broz
4f6f7404df Revert "Add a note about CRC32 and other non-cryptographic checksums"
This reverts commit 5776c52bcf.

This commit has no valid author and email address by mistake.
2021-05-17 17:43:20 +02:00
Your Name
5776c52bcf Add a note about CRC32 and other non-cryptographic checksums 2021-05-12 13:43:49 +00:00
Ondrej Kozina
db44e9de22 Add api exposing external token handlers support. 2021-05-12 14:32:54 +02:00
Ondrej Kozina
c40be6cc7a Replace condition with assert for obvious coding mistake. 2021-04-15 21:43:31 +02:00
Ondrej Kozina
b047b8ae20 Improvements to error code handling during token based activation. 2021-04-15 21:43:31 +02:00
Ondrej Kozina
e9434dc9e3 Check tokens are eligible for unlocking segment keyslots.
Defer token handler load and token unlock after check token
is assigned to keyslot containing proper data segment volume key.
2021-04-15 21:43:30 +02:00
Ondrej Kozina
c6149c9cd8 Do not search/load token handler when not needed. 2021-04-15 21:41:09 +02:00
Ondrej Kozina
8f2b23cd94 Refactor LUKS2 token activation.
Replace LUKS2_token_open_and_activate and
LUKS2_token_open_and_activavate_any with single function
instead.
2021-04-15 21:41:06 +02:00
Ondrej Kozina
8d449aa9a6 Add failsafe test for eventual broken symbol versioning.
Due to nature of recent change in GCC10 that silently
broken symbol versioning, let's be a bit pedantic
and test all symbols are available in all versions that
meant to be exported to users.
2021-04-13 16:42:14 +02:00
Ondrej Kozina
e6089dd9c9 Reflect on some incompatible changes in GCC 10.
Starting with GCC10 and LTO enabled, current symbols
versioning hack does not work anymore. This patch
reflects on that and should be compatible with older
compilers that does not support __attribute__((symver))
yet.

Inspired by following code:
https://github.com/linux-rdma/rdma-core/blob/master/util/symver.h
2021-04-12 20:38:19 +02:00
Ondrej Kozina
bc488fd4f1 Stick with general practice in symbol map file.
Including old versions section with every new one _should_
have no effect but since it's a convetion let's stick with
this format instead.
2021-04-09 16:56:08 +02:00
Milan Broz
ec3a9746a9 integritysetup: add recalculate-reset flag.
The new dm-integrity option in kernel 5.13 can restart
recalculation from the beginning of the device.
It can be used to change the integrity checksum function.

This patch adds support to libcryptsetup for this flag
and adds --integrity-recalculate-rest option to integritysetup.

Fixes: #631.
2021-03-30 21:40:35 +02:00
Milan Broz
530bcfd4fa Allow CRYPT_BUSY also a a valid check for active device.
In ideal system nothing should touch test devices, but to make tests
more robust, we should expect that something is still scanning devices
after activation. So replace all checks for CRYPT_ACTIVE to allow
also CRYPT_BUSY.

(Fixes some problems seen in #633)
2021-03-25 11:11:06 +01:00
Ondrej Kozina
bd4f374b47 Fix supposed debug message. 2021-03-25 08:44:42 +01:00
Milan Broz
0a7c13207d Fix broken loopaes test.
We actually try to write file in /dev because the device is deactivated.

Broken since 2018 in 8728ba08e2
2021-03-25 00:07:53 +01:00
Milan Broz
c5fc3fe84a Fix libintl detection for compiled tests.
Commit 99c4e83994 was incomplete.

See #633.
2021-03-25 00:07:46 +01:00
Ondrej Kozina
8d0e90b90a Autodetect optimal encryption sector size on LUKS2 format. 2021-03-24 16:14:35 +01:00
Ondrej Kozina
1aeb0a1f6e Set data device loop block size to encryption sector size. 2021-03-23 16:40:57 +01:00
Ondrej Kozina
ce80f7c5b1 Add support for larger block size in loop. 2021-03-23 16:40:57 +01:00
Milan Broz
25cd2b2fb7 Add Blake2b and Blake2s hash support for crypto backend.
We support most recent crypto algorithms, so this
is only addition of the Blake hash family.

Kernel and gcrypt crypto backend supports all variants,
OpenSSL only Blake2b-512 and Blake2s-256.

There is no useable support for NSS and Nettle yet.

Crypto backend supports kernel notation e.g. "blake2b-512"
that is translated to the library backend names.
2021-03-22 11:16:53 +01:00
Ondrej Kozina
78797ae078 Rename PIN enable token activation API function. 2021-03-19 15:26:36 +01:00
Ondrej Kozina
96d83455ca Add API for activating device by specific token type. 2021-03-19 15:26:35 +01:00
Ondrej Kozina
36805b3cfe Allow dash and underscore chars in external token names.
Current alphabet for external token types is alphanumeric
characters including '-' and '_'. Empty strings are also
forbiden.
2021-03-19 15:26:35 +01:00
Ondrej Kozina
5d0a11a21b Add pin size parameter in crypt_active_by_pin_token.
Well, after all it really should have supported binary data
of arbitrary length.
2021-03-18 18:06:13 +01:00
Milan Broz
d4cd675f33 Remove redundant plain-text README and other unused files.
Use README.md everywhere now.
2021-03-17 13:01:13 +01:00
Milan Broz
c3328a123c Add list of required packages
Fixes: #621.
2021-03-17 12:34:30 +01:00
Milan Broz
2cc320f180 Update Release notes version. 2021-03-11 12:58:05 +01:00
Milan Broz
6f26d7a77f Prepare Readme for version 2.3.5. 2021-03-11 12:57:53 +01:00
Milan Broz
9d559bba8f Add note for passwdqc change to release notes. 2021-03-11 11:32:01 +01:00
Dmitry V. Levin
cb9cb7154d Update libpasswdqc support
Starting with version 2.0.0, libpasswdqc can use memory allocation
when loading configuration that contains new optional parameters.
It's therefore recommended to free all memory allocated by
passwdqc_params_load using new passwdqc_params_free function
introduced in the same version of libpasswdqc.

[slightly modified by mbroz]
2021-03-11 11:24:08 +01:00
Yuri Chornoivan
da15a67c96 po: update uk.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Yuri Kozlov
69efb9177d po: update ru.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Jakub Bogusz
f9ce835e58 po: update pl.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Hiroshi Takekawa
3dd6e222c8 po: update ja.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Frédéric Marchal
04b8c4ff32 po: update fr.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Roland Illig
9b2adfede9 po: update de.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Petr Pisar
520aea9de0 po: update cs.po (from translationproject.org) 2021-03-09 20:35:38 +01:00
Milan Broz
9f233a68f3 Update 2.3.5 release notes.
And reformat it for strange problems with mail signature (line length).
2021-03-09 20:34:18 +01:00
Milan Broz
476cd2f764 Remove superfluous CONST_CAST.
It only confuses cppcheck.
2021-03-09 11:53:52 +01:00
Milan Broz
ca87b74333 Fix partial reads from TTY (interactive terminal).
Some stable kernels started to return buffer from terminal
in partial buffers of maximal size 64 bytes.

This breaks all passphrases longer than 64 characters entered
through interactive input (for all crypto formats).

(The problem is probably fixed in more recent kernels, but
the read() call can always return a partial read here.)

This patch also fixes wrong password limit, the last character
of passphrase of maximal size was never handled.
Now the maximal passphrase length is really 512 characters.

Fixes: #627.
2021-03-09 11:49:11 +01:00
Milan Broz
25a943ad01 Update Readme.md. 2021-03-04 13:12:43 +01:00
Milan Broz
f22a6613eb Fix typo. 2021-03-04 11:37:28 +01:00
Milan Broz
8914ae468b Add release notes for 2.3.5-rc. 2021-03-04 11:37:20 +01:00
Milan Broz
3e712b2dcd Add a note about FEC calculation to veritysetup manual. 2021-03-03 12:21:35 +01:00
Milan Broz
17e0e9fd27 Add final list of failures to valgrind-check test target. 2021-03-03 12:10:05 +01:00
Ondrej Kozina
e7f67f8928 Fix reencryption recovery tests w/ cipher_null. 2021-03-02 17:18:13 +01:00
Milan Broz
4b049fe848 Add disappeared device test. 2021-03-02 14:18:56 +01:00
Milan Broz
fea4074e8f Check internal device functions for NULL device.
Most of these functions already works even with device=NULL.

There can be some rare situations when this call could happen,
so be safe always.
(Like initialization for a device that disappears during init.)

Also see
https://bugzilla.redhat.com/show_bug.cgi?id=1932946
2021-03-01 20:38:52 +01:00
Milan Broz
9209d7e3b5 Use internal bit operations instead of network byte order functions. 2021-03-01 18:26:06 +01:00
Milan Broz
ca2e1fc956 Fix some includes. 2021-02-27 21:14:38 +01:00
Milan Broz
1592f1e274 Fix allocation of volume key in LUKS1 open_key.
This function should not return allocated key on error path.

Recent patch (suspend/resume) introduced a memory leak because of this.
2021-02-24 22:54:55 +01:00
Milan Broz
74027ca922 Remove VLAs from API test. 2021-02-24 21:44:36 +01:00
Ondrej Kozina
1910960364 Silent error messages in tests. 2021-02-24 16:06:19 +01:00
Ondrej Kozina
2708021e6f Add error message when suspending wrong device.
In case user tries to suspend LUKS data device instead
of dm-crypt mapping.

See issue#622.
2021-02-24 16:06:19 +01:00
Ondrej Kozina
8e8ecd50de Fix luksResume when called on non-LUKS device. 2021-02-24 16:06:19 +01:00
Ondrej Kozina
3ebf7fa3bd Drop duplicate type check in LUKS2 encryption. 2021-02-24 16:06:19 +01:00
Ondrej Kozina
68130ef2f5 Introduce isLUKS helpers in cryptsetup. 2021-02-24 16:06:19 +01:00
Ondrej Kozina
a77acb21c9 Fix reversed condition in LUKS2 api test.
get_luks2_offsets is based on get_luks_offsets from api-test.c
but for some odd reason 'metadata_device' parameter had reversed
meaning.
2021-02-24 15:57:12 +01:00
Ondrej Kozina
6e6e9f169e Fix keyslots size overflow when device too small.
It properly failed but debug message was confusing.
Now it fails later properly with "device too small"
error message.
2021-02-24 15:57:12 +01:00
Ondrej Kozina
6a8bade7e6 Allow LUKS resume for device with cipher_null. 2021-02-24 15:57:11 +01:00
Ondrej Kozina
3367b78958 Unify crypt_resume_by internal code. 2021-02-24 15:57:11 +01:00
Ondrej Kozina
28603e4de7 Do not upload VK in keyring when data cipher is null. 2021-02-24 15:57:11 +01:00
Ondrej Kozina
d8cf203d46 Remove redundant check.
It can't be non-LUKS2 device at this branching.
2021-02-24 15:57:11 +01:00
Ondrej Kozina
9faa602f6c Add tests for cipher_null suspend/resume. 2021-02-24 15:57:11 +01:00
Milan Broz
c9b727e9ea verity: run FEC check even if root hash fails.
The error correction can fix even problem with root hash.

For now, always return fail if initial check of root hash failed.

FIXME: The FEC verify code need to be rewritten to repair only
blocks where hash is wrong and the re-check hash after recovery,
inclkuding root hash.

Now we do not check hash after FEC recovery. The Reed-Solomon
decoder can then "repair" code wrongly if parity is too damaged.

For now, the information about FEC repaired errors is only
advisory, it does not mean device is fully repaireable.
2021-02-23 17:36:58 +00:00
Milan Broz
1534dc6c61 verity: do not process hash image if it is empty. 2021-02-23 17:36:58 +00:00
Milan Broz
dd6d6cfa1c verity: do not calculate hash offset if hash area is not used.
Sometimes device is so small that there is only root hash needed
and the hash area is not used.
2021-02-23 17:36:58 +00:00
Milan Broz
8e564bbb5c veritysetup: do not increase hash image size if hash area is not used.
Do not write more than needed header if hash area is not used later.

All space in hash area is then used in FEC calculation, so it makes
no sense to add unused area.
2021-02-23 17:36:58 +00:00
Ondrej Kozina
284a49443e Extend LUKS2 reencryption tests w/ cipher_null. 2021-02-18 15:01:01 +01:00
Ondrej Kozina
61abbc6e5d Bypass keyring activation flag if cipher is null. 2021-02-18 14:22:51 +01:00
Ondrej Kozina
1fe2d3d92b Use crypt_is_cipher_null check where possible. 2021-02-18 14:19:09 +01:00
Ondrej Kozina
b0da623c8a Fix default xts mode key size in reencryption.
Reencryption did not take into account adjusted xts
key size configuration option. This patch fix the
issue by using same logic as in luksFormat with xts
mode selected for data encryption.
2021-02-18 12:14:54 +01:00
Milan Broz
ff1502edd0 Remove VLAs from TCRYPT code. 2021-02-18 11:10:20 +00:00
Milan Broz
2d9c0b507d Remove VLAs from UUID block parsing code. 2021-02-18 11:10:20 +00:00
Milan Broz
20320dfd0e Remove VLAs from blockdev utils code. 2021-02-18 11:10:20 +00:00
Milan Broz
6483fb027a Remove VLAs from FEC verity code. 2021-02-18 11:10:20 +00:00
Ondrej Kozina
030d50f6ba Fix reencryption test on systems w/o keyring. 2021-02-17 16:36:21 +01:00
Milan Broz
dc8bbbf352 Rename label fo consistency. 2021-02-17 10:03:18 +01:00
Milan Broz
c72030d25a Avoid using goto in Nettle crypto wrapper. 2021-02-17 10:03:18 +01:00
Milan Broz
4309294c2a Remove unnecessary goto from cipher kernel wrapper. 2021-02-17 10:03:18 +01:00
Milan Broz
f5dd3c8e32 Rename label in utils for consistency. 2021-02-17 10:03:18 +01:00
Milan Broz
6dd347ddb4 Rewrite reload code to avoid two goto labels. 2021-02-17 10:03:18 +01:00
Milan Broz
e15e09025d Use err label for error consitently for RNG code. 2021-02-17 10:03:18 +01:00
Milan Broz
caf71248df Use dm_task_destroy consistently. 2021-02-17 10:03:18 +01:00
Milan Broz
7b327509b4 Remove unnecessary goto and use out label for non-error path in libdevmapper code. 2021-02-17 10:03:18 +01:00
Milan Broz
83138b7803 Remove confusing goto from TCRYPT code. 2021-02-17 10:03:18 +01:00
Milan Broz
cea7a1489a Remove unnecessary goto and use out label for non-error path in reencrypt code. 2021-02-17 10:03:18 +01:00
Milan Broz
f6e2fbb366 Remove unnecessary goto from LUKS2_hdr_version_unlocked. 2021-02-17 10:03:18 +01:00
Milan Broz
2e4a3a9888 Remove unnecessary goto from token load. 2021-02-17 10:03:18 +01:00
Milan Broz
639ffa36a5 Rename goto err to out, it is not error path only.
Also try to use the same "goto out" pattern everywhere.
2021-02-17 10:03:18 +01:00
Milan Broz
05f9297141 Avoid goto patern in crypt_init.
Also device_free is not needed, it never allocates anything in error path.
2021-02-17 10:03:18 +01:00
Milan Broz
28baeca882 Clear goto use in tools.
Allow only one pattern for goto - one place for releasing resources.

Avoid all other use of the goto pattern.
2021-02-17 10:03:18 +01:00
Milan Broz
b1558ec973 USe ARG_SET macro to check that device size is set for resize.
And move the check to the beginning of function.
2021-02-17 10:03:18 +01:00
Ondrej Kozina
4862c38ca9 Prefer default cipher when reencrypting cipher_null device.
By default when reencrypting LUKS2 device we regenerate only
the volume key. But if the device was 'encrypted' by cipher_null
this change did not make sense. The key was always empty.

Change the behaviour so that unless user specifies --cipher
parameter on command line, we change data encryption cipher
to default when old segment cipher was cipher_null.
2021-02-16 21:08:54 +01:00
Ondrej Kozina
bec7394722 Improve key handling with cipher_null in reencryption. 2021-02-16 18:08:35 +01:00
Ondrej Kozina
42479bd1df Add debug message for activated cipher_null device. 2021-02-16 18:08:35 +01:00
Ondrej Kozina
01f896711e Replace bogus cipher_null keyslots before reencryption.
By mistake LUKS2 allowed keyslots 'not-so-encrypted' by
cipher_null (only explicitly requested by --cipher or
--keyslot-cipher parameters). If we encounter
such old key during reencryption let's replace the cipher
for new keyslot with default LUKS2 keyslot cipher.
2021-02-16 18:08:35 +01:00
Ondrej Kozina
ed2117c724 Fix device comparison for dm-crypt with cipher_null.
Do not compare volume keys if segment uses cipher_null.
The key is ignored by lower layer (internal libdevmapper)
anyway.
2021-02-16 18:08:35 +01:00
Ondrej Kozina
bc7511762f Do not upload vk in keyring for cipher_null segment.
It does not make sense to upload volume keys in
kernel keyring if segment cipher is cipher_null.
The real volume_key is thrown away and replaced
with empty key anyway.
2021-02-16 18:08:35 +01:00
Ondrej Kozina
03cc8a9ce4 Fix broken detection of null cipher in LUKS2.
This bug enabled to create LUKS2 keyslots encrypted by
cipher_null when explicitely requested by user. LUKS2
was never meant to allow keyslot encryption with
cipher_null. cipher_null is meant for debug purposes
only as a segment cipher.
2021-02-16 18:08:34 +01:00
Ondrej Kozina
a4d7c46d80 Move cipher_null check in internal function crypt_is_cipher_null.
Also removes tools helper so that we keep check in one place.
2021-02-16 18:08:34 +01:00
Ondrej Kozina
7d912c7d3e Make crypt_keyslot_set_encryption a bit more robust.
Nitpicking(tm) but let's not free old cipher spec unless
we have valid new one.
2021-02-16 18:08:34 +01:00
Ondrej Kozina
65b43d5d12 Add tests for various keyslot cipher null bugs. 2021-02-16 18:08:34 +01:00
Milan Broz
36fd8d6b3c Get rid of off_t integers and use uint64_t.
Also move uint64 multiplication overflow check to internal library.
2021-02-14 12:24:18 +01:00
Milan Broz
f28e159ff2 Fix debug message displaying required hash device size.
If located on the same device with hashes, offset must be subtracted.
(Also there could be one block more for superblock.)
2021-02-14 12:24:18 +01:00
Milan Broz
633ffbf8b7 Get rid of the long paramete list in FEC verity function.
Also params struct will be needed in following patch.
2021-02-14 12:24:18 +01:00
Milan Broz
4359973586 Fix dm-verity FEC calculation if stored in the same image with hashes.
FEC (Forward Error Correction) data should cover the whole data area,
hashes (Merkle tree) and optionally additional metadata (located after hash area).

Unfortunately, if FEC data is stored in the same file as hash, the calculation
wrongly used the whole file size thus overlaps with FEC area itself.
This produces unusable and too large FEC data.

(There is not a problem if FEC image is a separate image.)

This patch fixes the problem, introducing FEC blocks calculation as:

 -If hash device is in a separate image, metadata covers the whole rest of the image after hash area.
  (Unchanged behaviour.)

 -If hash and FEC device is in the image, metadata ends on the FEC area offset.

This should probably fix several issues reported with FEC wrong calculations.

Fixes: #554
2021-02-14 12:24:18 +01:00
Milan Broz
0dfeb304cc Fix veritysetup exit code for bad root hash with FEC enabled.
If FEC was enabled, the error for bad root hash was replaced
by error correction (datga were ok, only root hash was wrong).

Do not run recovery test if root hash is incorrect.
2021-02-14 12:24:18 +01:00
Milan Broz
12cc7ea745 Simplify include directories.
To avoid confusion, use just one lib include and specify sub-directories
for format inclusions.
This should also help some analysis tools to find proper includes.
2021-02-11 13:14:58 +01:00
Milan Broz
1ff2b85252 Rename SECTOR_SIZE in tests to avoid conflict with library definition. 2021-02-11 11:12:11 +00:00
Milan Broz
76301cef4c Use one file for macros and basic constants for the whole project.
And avoid some dual definitions between tools and library.
2021-02-11 11:12:11 +00:00
Milan Broz
4471452105 Remove some stale FIXME markings. 2021-02-11 11:12:11 +00:00
Milan Broz
d703301fe8 Mark or remove unused parameters.
Mark unused parameters with proper attribute where it is a part
of API or some internal logic.

And remove other unused parameters completely.
2021-02-11 11:12:11 +00:00
Milan Broz
85f7ee59f8 Rename local test keyring check to avoid confusion with intenal function. 2021-02-11 11:12:11 +00:00
Milan Broz
fe71fd469a Remove unused arg argument from tool actions. 2021-02-11 11:12:11 +00:00
Milan Broz
f05c9833ee Add a missing stdbool include. 2021-02-11 11:12:11 +00:00
Milan Broz
11e7e267f7 Use ISO C compatible __typeof__.
As used already in the same header abeve and to fix ridiculous warnings
in static analysis.
2021-02-11 11:12:11 +00:00
Milan Broz
0738ba2451 Do not hide function prototype.
It is called from kernel crypt backend unconditionally with
the proper define in config.h but some static parrsers are not so clever.

Compilation will fail in linker phase anyway if wrongly used.
2021-02-11 11:12:11 +00:00
Milan Broz
12ff94c02f Rename verion function to avoid conflict with crypto backend. 2021-02-11 11:12:11 +00:00
Milan Broz
da2f6e9d93 Fix compat interactive test to run with valgrind too. 2021-02-08 17:33:19 +01:00
Josef Andersson
49b246193b po: update sv.po (from translationproject.org) 2021-02-07 10:47:54 +01:00
Ondrej Kozina
1862a991d8 Remove useless code.
The routine was originaly used in code for resetting default
argument values. It was used in cli plugins related code
where we needed to parse command line arguments twice.
2021-02-04 18:30:31 +01:00
Milan Broz
89839cb1cf Do not use const default structure on stack.
This decrease stack space used and avoids Coverity warning.
2021-02-04 18:10:38 +01:00
Milan Broz
07bb8b3023 Coverity workaround for tainted warnings.
Password can be any string and the function allocates
string properly, so mark it is as sanitized.
2021-02-04 18:01:45 +01:00
Milan Broz
56d55a4585 Fix an error path memory leak. 2021-02-04 17:54:36 +01:00
Vojtech Trefny
3cd158b983 bitlk: Fix parsing startup key metadata
This fixes multiple issues found by coverity in the startup key
code and also makes the parsing less complicated -- we don't need
to loop through all metadata entries in the BEK file if we are
expecting only one metadata entry of a specific type.
2021-02-04 14:49:54 +01:00
Milan Broz
d1ffca3189 Avoid "output may be truncated" gcc warnings.
These are false positives and gcc internal detection of this
pattern seems to be broken again.

In this path we must avoid memcpy the whole buffer, it can contain
some bytes after null char, so use MIN/strlen here.
2021-02-03 21:14:52 +01:00
Milan Broz
e21e3b298a Remove WARNING from the debug message. 2021-02-03 21:14:17 +01:00
Milan Broz
f47f6b7fb4 Remove redundant EOL in the previous patch. 2021-02-03 19:56:33 +01:00
Milan Broz
1e7521c056 Rephrase lockinging dir warning and move it to debug level.
System should later provide safe transition to tempdir configuration.
2021-02-03 19:37:33 +01:00
Milan Broz
bb6d522198 Mark ssh token as experimental. 2021-02-03 15:17:07 +01:00
Vojtech Trefny
c0b2f99b04 Add test for example SSH token handler.
Activation test needs ssh server running on the machine. The test
creates a new user "sshtest" and uses it to test activation using
the plugin.
2021-02-03 11:43:04 +00:00
Milan Broz
89b3105493 Add example SSH token handler.
Provides example of loadable token handler for activation
json validation and metadata dump.

For creating new ssh example token use special cryptsetup-ssh
binary.
2021-02-03 11:43:04 +00:00
Milan Broz
37cc06444d Add crypt_dump_json() API call.
Add API call that can directly print JSON metadata area from LUKS2 device.

For commandline it also adds --dump-json-metadata option for luksDump action.

Note that the binary metadata (UUID, version etc) is not part of this output.
(We reserve flags parameter to be able to add this later.)

Fixes: #511
2021-02-01 14:38:29 +01:00
Milan Broz
2d10545e70 Check if there is a free space in keyslot area early (LUKS2).
The code expects that change key is done in-place if there is not
a free space in keyslot area for safe key swap.

This patch makes the code behaves the same as in LUKS1,
luksChangeKey now works the same.
2021-02-01 11:57:35 +00:00
Milan Broz
04b781d613 Retain keyslot number in luksChangeKey for LUKS2.
With JSON, we can actually retain the slot number in all cases
(except user intentionally set new slot #).

This patch changes the crypt_keyslot_change_by_passphrase() API
call to retain keyslot number for LUKS2.

Fixes: #464
2021-02-01 11:57:35 +00:00
Milan Broz
5a252c9166 Fix LUKS1 repair code.
We cannot trust possibly broken keyslots metadata here through LUKS_keyslots_offset().
Expect first keyslot is aligned, if not, then manual repair is neccessary.

(This situation happen if partition table signarture overwrites slot 4 area).

Also, if keyslot order is different, current repair code does not work properly
(this can happen only with downconverting LUKS2 device).
2021-02-01 10:50:08 +01:00
Milan Broz
373d4c9848 Disable alternative backends in CI build for now.
These will run in release time only.
2021-01-31 16:59:04 +01:00
Ondrej Kozina
fa84d60586 Fix crypt_keyslot_change_by_passphrase tokens bug.
crypt_keyslot_change_by_passphrase broke token references
to keyslots while existing keyslot id was different from
new keyslot id.
2021-01-29 18:17:53 +01:00
Ondrej Kozina
7dc4a336bd Test crypt_keyslot_change_by_passphrase does not break tokens. 2021-01-29 17:58:10 +01:00
Milan Broz
362d523fa6 Fix previous commit error condition.
This hints actually failed even if return code was OK.
2021-01-29 13:34:27 +01:00
Milan Broz
586b0a39d8 Fix dm-integrity HMAC recalculation problem.
This patch adds support for Linux kernel (since version 5.11) dm-integrity
fixes that disables integrity recalculation if keyed algorithms (HMAC) is used.

Original dm-integrity superblock version <=4 is recalculation offset
field not protected by HMAC. An attacker can move this pointer and force
the kernel to recalculate the data area, ignoring original HMAC tags.

N.B. dm-integrity was not intended to protect against intentional changes.
Better use authenticated encryption (AEAD) in combination with dm-crypt.
It is designed to protect against random data corruption caused by hardware
or storage medium faults.

Despite that, we try to keep the system secure if keyed algorithms are used.

There are two possible keyed algorithms in dm-integrity - algorithm used
to protect journal and superblock (--journal-integrity) and algorithms
for protecting data (--integrity).
The dm-integrity superblock is guarded by --journal-integrity, so if you want
to protect data with HMAC, you should always also use HMAC for --journal-integrity.
The keys are independent. If HMAC is used for data but not for the journal,
recalculation is disabled by default.

For new kernel dm-integrity, the HMAC option also uses salt in superblock
to avoid an easy way to distinguish that the HMAC key is the same for two devices
(if data are the same).

The new HMAC and superblock are enabled automatically if the kernel supports it
(you can see superblock version 5 and fix_hmac flag in dump command).

If you need to use (insecure) backward compatibility, then two new integritysetup
options are introduced:

 Use --integrity-legacy-recalc (instead of --integrity-recalc) to allow recalculation
 on legacy devices.

 Use --integrity-legacy-hmac in format action to force old insecure version
 format (with HMAC).

Libcryptsetup API also introduces flags
  CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC and
  CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC
to set these through crypt_set_compatibility() call.
2021-01-27 11:44:29 +01:00
Ondrej Kozina
6df3488654 Add token handler version function prototype.
Dynamicaly loaded token handlers should provide
version string for debug purposes.
2021-01-26 12:41:37 +01:00
Ondrej Kozina
10e4d8fbac Make crypt_activate_by_pin_token addition backward compatible.
The crypt_activate_by_pin_token may be used only from new
dynamicly loadable token plugins.

Also refactors code for dynamically loadable plugins so
that it does not use crypt_token_handler structure anymore.

Old structure remains used only in crypt_token_register call.
2021-01-26 12:41:37 +01:00
Ondrej Kozina
81c44b5eee Remove crypt_token_load from API. 2021-01-26 12:41:37 +01:00
Ondrej Kozina
aa9eef28c4 Tag new symbols with up to date version. 2021-01-26 12:41:37 +01:00
Ondrej Kozina
0a2c6fccc3 Refactor verbose token action reporting.
also avoids unlikely possibility of reporting succcessful
token add before failing assigning the token to keyslot.
2021-01-26 12:41:37 +01:00
Ondrej Kozina
88a95c7f03 Allow checking token arguments in dry run. 2021-01-26 12:41:37 +01:00
Milan Broz
90c1873134 Fix copy & paste typo in integrity test. 2021-01-25 22:04:42 +01:00
Milan Broz
d1d9dd8e20 Update Copyright year. 2021-01-25 22:00:25 +01:00
Luca Boccassi
39dc77d825 verity: fix strncpy boundary check compiler warning
lib/verity/verity.c: In function ‘VERITY_write_sb’:
lib/verity/verity.c:200:2: warning: ‘strncpy’ specified bound 32 equals destination size [-Wstringop-truncation]
  strncpy(algorithm, params->hash_name, sizeof(sb.algorithm));
2021-01-25 14:28:02 +00:00
Luca Boccassi
24d349f491 verity: improve crypt_activate_by_signed_key debug log
Check if a signature is actually available before logging that the
volume is being activated with a signed key.
2021-01-25 14:28:02 +00:00
Ondrej Kozina
0eff642d2f Add pedantic check for key helpers arguments. 2021-01-19 10:50:31 +01:00
Ondrej Kozina
b7c1f1e13d Revert libcryptsetup_cli.
This reverts mostly these commits:

42692418c2
a985c12659

The library was ment to export common functions shared by
all cryptsetup tools and planned LUKS2 tokens plugins.
It is no longer needed.
2021-01-19 10:50:01 +01:00
Lars Wendler
c27123cf61 cryptsetup.8: Fix no_write_workqueue option name
It's called --perf-no_write_workqueue

Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
2021-01-12 17:39:48 +00:00
Arno Wagner
0edfeb19f1 Update FAQ: Clarified statement about block sizes in 5.16 2021-01-12 12:14:27 +00:00
Milan Broz
f069c256a6 Unify handling of password retries on terminal.
THis fixes a problem for TCRYPT and reencryption in scripts
where "Nothing to read on input." is displayed because
cryptsetup retries password query even in stdin mode.
2021-01-07 17:08:13 +01:00
Ondrej Kozina
670d08b406 Reject LUKS2 decryption with broken cmd line arguments.
LUKS2 decryption is currently not supported for devices
with LUKS2 metadata placed in head of data devices. The decryption
still works correctly, but resulting plaintext device has data on
unexpected (original) offset. For example at offset of 16MiB in case
of default LUKS2 header.

Fixes: #614.
2020-12-29 23:24:15 +01:00
Milan Broz
0c29321407 Introduce crypt_header_is_detached API call.
crypt_header_is_detached checks if initialized LUKS context uses detached header
(LUKS header located on a different device than data.)

This is a runtime attribute, it does not say if a LUKS device requires detached header.
2020-12-29 23:23:32 +01:00
Milan Broz
b4643cb5be Fix some formatting and typos in man page. 2020-12-29 23:13:39 +01:00
Milan Broz
3c886ccff8 tcrypt: Support --hash and --cipher options to limit opening time.
If user knows which particular PBKDF2 hash or cipher is used for
True/VeraCrypt container, using --hash of --cipher option in tcryptDump
and tcryptOpen can scan only these variants.
Note for the cipher it means substring (all cipher chains containing
the cipher are tried).

For example, you can use
  cryptsetup tcryptDump --hash sha512 <container>

Note: for speed up, usually the hash option matters, cipher variants
are scanned very quickly.
Use witch care, in a script it can reveal some sensitive attribute
of the container.

Fixes #608.
2020-12-29 15:11:43 +01:00
Milan Broz
eddc3b0381 Fix comment for max_tokens function. 2020-12-28 19:59:18 +01:00
Milan Broz
83cc90be5d Remove obsolete tpm-luks project link from FAQ. 2020-12-28 19:47:00 +01:00
Milan Broz
ba92a5e865 Remove redundant LUKS type condition. 2020-12-28 18:02:10 +01:00
Milan Broz
8a12f6dc2c Add crypt_token_max() API to query max token id for LUKS2.
Fixes #615.
2020-12-28 17:57:24 +01:00
Milan Broz
9fad8a8c92 Add lore.kernel.org list archive link. 2020-12-21 20:39:12 +01:00
Milan Broz
57eab17262 Use tabs in tests scripts consistently.
Really...
2020-12-02 13:04:44 +01:00
Samanta Navarro
fc5f9cc46d lib: always clear size in crypt_safe_free
Writing into allocated memory right before calling free can be optimized
away by smart compilers. To prevent this, a volatile access must be
performed. This happens already in crypt_safe_memzero.

It was difficult to provoke GCC to remove the assignment, but I was able
to find a way to prove the theory:

* Build cryptsetup with: CFLAGS="-flto -O3 -g" ./configure --enable-static
* Create main.c:

#include <libcryptsetup.h>

int
main(void) {
        char *x = crypt_safe_alloc(64);
        crypt_safe_free(x);
        return 0;
}

* Build the program with: gcc -O3 -flto -static -o main main.c -lcryptsetup
* Disassemble: objdump -d main

My output on an amd64 system is:

0000000000401670 <main>:
  401670:       41 54                   push   %r12
  401672:       bf f0 03 00 00          mov    $0x3f0,%edi
  401677:       55                      push   %rbp
  401678:       48 83 ec 08             sub    $0x8,%rsp
  40167c:       e8 ff 4d 01 00          callq  416480 <__libc_malloc>
  401681:       48 85 c0                test   %rax,%rax
  401684:       74 2f                   je     4016b5 <main+0x45>
  401686:       48 c7 00 e8 03 00 00    movq   $0x3e8,(%rax)
  40168d:       4c 8d 60 08             lea    0x8(%rax),%r12
  401691:       48 89 c5                mov    %rax,%rbp
  401694:       be e8 03 00 00          mov    $0x3e8,%esi
  401699:       4c 89 e7                mov    %r12,%rdi
  40169c:       e8 4f 76 01 00          callq  418cf0 <explicit_bzero>
  4016a1:       48 8b 75 00             mov    0x0(%rbp),%rsi
  4016a5:       4c 89 e7                mov    %r12,%rdi
  4016a8:       e8 43 76 01 00          callq  418cf0 <explicit_bzero>
  4016ad:       48 89 ef                mov    %rbp,%rdi
  4016b0:       e8 3b 54 01 00          callq  416af0 <__free>
  4016b5:       48 83 c4 08             add    $0x8,%rsp
  4016b9:       31 c0                   xor    %eax,%eax
  4016bb:       5d                      pop    %rbp
  4016bc:       41 5c                   pop    %r12
  4016be:       c3                      retq
  4016bf:       90                      nop

You can see that the memory allocation and explicit_bzero calls were not
optimized away. But the size assignment disappeared.

Compiling without -O3 or without -flto does not inline the calls and
keeps the assignment. Also the shared library shipped with my
distribution has the assignment.
2020-12-02 11:57:03 +00:00
Samanta Navarro
38e631d174 Fix typos.
Typos found with codespell.
2020-11-28 11:41:48 +00:00
Samanta Navarro
3283135f16 lib: fix utils_safe_memory function comments. 2020-11-28 11:41:45 +00:00
Ondrej Kozina
bd491b4479 Rephrase utils_args.c header comments. 2020-11-23 14:10:55 +01:00
Ondrej Kozina
6dbfe52c35 Remove global variables from tools utilities. 2020-11-23 14:10:49 +01:00
Ondrej Kozina
9da23371d5 Add missing translation anotation. 2020-11-23 14:10:03 +01:00
Ondrej Kozina
29c5deb4f1 Make symbol version mapping reflect package version. 2020-11-23 14:09:56 +01:00
Ondrej Kozina
9bc45ae15f Make the crypt_reencrypt() API fix actually matter.
Pick one:
Thou shalt not skip writting tests!
One does not simply fix a bug
2020-11-23 14:09:46 +01:00
Milan Broz
08abc0eb77 Enable Travis test for GOST crypto in VeraCrypt (install GOST external kernel crypto modules). 2020-11-23 13:40:31 +01:00
Vojtech Trefny
fea3a76c38 bitlk: Update BITLK man page section
Add information about the new options for open and dump and about
the newly supported activation using startup key and master key.
2020-11-12 12:16:32 +01:00
Vojtech Trefny
3a7f03bae6 bitlk: Add test for dumping master key and opening using it 2020-11-12 12:16:32 +01:00
Vojtech Trefny
652081426b bitlk: Add support for activating BITLK devices using volume key
Both with "crypt_activate_by_volume_key" and using cli with
--master-key option.
2020-11-12 12:16:32 +01:00
Vojtech Trefny
406d2d8b0a bitlk: Allow dumping BitLocker master key (FVEK) using --dump-master-key 2020-11-12 12:16:32 +01:00
Vojtech Trefny
7a1df1c323 bitlk: Fix key sizes for BITLK encryption types
It makes more sense to return "real" key sizes, e.g. 256 bit for
AES-XTS 128 and 256/512 bit for AES-CBC with Elephant which has
a separate key for the Elephant mode.
2020-11-12 12:16:32 +01:00
Vojtech Trefny
5a44d14d97 bitlk: Allow running bitlk_metadata_free with NULL 2020-11-12 12:16:32 +01:00
Joerg Kastning
b444d1ecd7 Update cryptsetup.8
* Improved information about calling luksFormat on devices.
2020-11-12 12:14:47 +01:00
Joerg Kastning
0456670328 Update cryptsetup.8
* Rename "BASIC COMMANDS" to "BASIC ACTIONS"
 * Changed a sentence saying that luksFormat would work on unmapped luks containers, only.
 * Insert 6 examples of using cryptsetup for luks containers
2020-11-12 12:14:47 +01:00
lixiaokeng
eff4da95a1 lib: fix memory leak in crypt_pbkdf_check
There is a memory leak when PBKDF2_temp > UINT32_MAX. Here,
we change return to goto out to free key.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
2020-11-09 09:57:25 +08:00
lixiaokeng
ad7d16a1b4 lib: fix potential segfault in LUKS2_token_buffer_free
The value of h may be NULL. Check it vefore visiting its
memeber to avoid segfault.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
2020-11-09 09:57:21 +08:00
lixiaokeng
f5abfde1fa lib: fix potential segfault in _crypt_cipher_crypt
The value of header may be NULL. Check it to avoid
segfault.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
2020-11-09 09:57:16 +08:00
lixiaokeng
02d13d7257 lib: fix potential segfault in _keyslot_repair
The value of vk may be NULL in _keyslot_repair. It will
be dereferenced in LUKS_generate_phdr. Check it to avoid
segfault.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
2020-11-09 09:57:13 +08:00
lixiaokeng
941b82a8be lib: check return value of malloc in BITLK_read_sb
The return value of malloc vmk and params->fvek is not
checked. Here we add checking.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
Signed-off-by: Linfeilong <linfeilong@huawei.com>
2020-11-09 09:56:45 +08:00
Ondrej Kozina
482fcd0602 Do not set confirm callback when not needed.
It's currently used only in crypt_set_uuid and crypt_header_restore
API calls.
2020-10-18 13:06:43 +02:00
Ondrej Kozina
14c7148edd Enable user stored params with default log callback. 2020-10-18 13:06:20 +02:00
Ondrej Kozina
a00722e80c Fix cryptsetup resize using LUKS2 tokens.
Fix a bug where cryptsetup needlessly asked for passphrase
even though volume key was already unlocked via LUKS2 token.

Fixes: #601.
2020-10-18 13:05:23 +02:00
Milan Broz
42f4dcef88 Introduce crypt_logf and remove logger wrapper.
Export (alredy existing) log function with variable parameter count.
2020-10-18 13:03:44 +02:00
Мирослав Николић
37188482fe po: update sr.po (from translationproject.org) 2020-10-17 12:53:20 +02:00
Antonio Ceballos
eb3228233a po: update es.po (from translationproject.org) 2020-10-17 12:53:20 +02:00
dofrupisla
8dec7eac05 Fix typo 2020-10-05 23:03:48 +02:00
Samanta Navarro
e9c2aaccb5 fix typo in manual page 2020-10-03 11:26:46 +00:00
Milan Broz
112c0ff08b Add deferred removal test for all utilities. 2020-09-26 13:04:05 +02:00
Luca Boccassi
e431cbdfa7 integritysetup: add close --deferred and --cancel-deferred
Same effect as the equivalent options in cryptsetup and veritysetup

[mbroz: ported to new CLI parsing]
2020-09-26 13:04:01 +02:00
Luca Boccassi
6514d1bc2e veritysetup: add close --deferred and --cancel-deferred
Same effect as the equivalent options in cryptsetup

[mbroz: ported to new CLI parsing]
2020-09-26 13:03:53 +02:00
Luca Boccassi
53d3ca0062 cryptsetup: add close --cancel-deferred
Allows to remove a previously set deferred removal from the command
line.

[mbroz: ported to new CLI parsing]
2020-09-26 13:03:49 +02:00
Luca Boccassi
3062a9ba91 libcrypsetup: add CRYPT_DEACTIVATE_DEFERRED_CANCEL for crypt_deactivate_by_name
Allows to cancel a previously set deferred deactivation flag
for a specific device.

[mbroz: slight changes]
2020-09-26 13:03:16 +02:00
Vojtech Trefny
dcc2b252dd bitlk: Show better error when trying to open an NTFS device
Both BitLocker version 1 and NTFS have the same bootcode eb 52 90
so when trying to open an NTFS device user will get error message
saying that BitLocker version 1 is not supported. This patch
switches to check the superblock first to inform user that the
device is not a BITLK device.
2020-09-22 14:09:20 +02:00
Vojtech Trefny
66b3aa9582 bitlk: Fix test image for startup key
We zero data parts of the test images to make them as small as
possible and for the latest startup key image I deleted bigger
portion of the NTFS header by accident which caused older blkid
on CentOS/RHEL 6 to not identify the NTFS filesystem on the
cleartext device.
2020-09-22 13:32:10 +02:00
Milan Broz
32a141d548 bitlk: Fix a compiler warning. 2020-09-21 20:52:12 +02:00
Vojtech Trefny
69e7d64c49 bitlk: Add support for startup key protected VMKs (keyslots)
Fixes: #588
2020-09-21 20:35:42 +02:00
Vojtech Trefny
7d5025a865 bitlk: Try all keyslots even if some checks fails for passphrase
We can't easily distinguish between a passphrase and other
protectors like recovery passphrase or startup key during
activation so we can't stop when attempted passphrase activation
fails because a binary startup key can't be conveted to UTF-16
during KDF.
2020-09-21 20:35:35 +02:00
Sinan Kaya
c65cd4eb74 tests: refresh loop code to the library
Refresh loopback device loading code to support LOOP_CONFIGURE ioctl.

Signed-off-by: Sinan Kaya <sinan.kaya@microsoft.com>
2020-09-21 10:55:10 -04:00
Sinan Kaya
8ff3b0cd63 Support LOOP_CONFIGURE ioctl to improve speed
More data about the new IOCTL is here:
https://lwn.net/Articles/818870/

We see 200-500ms boot speed improvement on our platform.

Prefer to define IOCTL when kernel is older version. Also eliminate
duplication since as a result of introduced ifdef.

Signed-off-by: Sinan Kaya <sinan.kaya@microsoft.com>
2020-09-21 10:54:55 -04:00
Joe Richey
cc2d29dbf4 Include correct type definition in .h files
Right now, cryptsetup makes an attempt to include the correct
definitions in all of its header files, allowing the headers to
compile regardless of the context in which they are included.

A few files were missed, this change fixes them by adding the minimal
set of #includes needed to get them to compile.

Signed-off-by: Joe Richey <joerichey@google.com>
2020-09-19 20:35:55 +00:00
Milan Broz
6ed739d9ca Print a visible error if requesting resize on unsupported format.
Fixes: #571.
2020-09-19 22:05:42 +02:00
Milan Broz
5d07b0730c Allow to use backup header for tcrypt format.
TrueCrypt/VeraCrypt supports backup header, it seems to have
the same format as normal header.

Let's use --header option here, it can be used to unlock data partition
with header backup (open and dump commands).

Fixes: #587.
2020-09-19 21:42:08 +02:00
Antonio Ceballos
fe05e47656 po: update es.po (from translationproject.org) 2020-09-19 17:21:51 +02:00
Roland Illig
8399bd8309 po: update de.po (from translationproject.org) 2020-09-19 17:21:51 +02:00
Ondrej Kozina
a730d56e66 Do not print opt_io_size warning needlessly.
In fallback path min_io_size and opt_io_size could be
same and the warning was confusing.
2020-09-19 17:20:46 +02:00
Ondrej Kozina
6599ae1f2f Make tools_args_free double-free safe 2020-09-19 17:20:42 +02:00
Ondrej Kozina
0b5426da12 Add explicit ARG_SET_TRUE macro.
and dissalow ARG_SET() query macro to be abused to change
the value.
2020-09-19 17:20:38 +02:00
Milan Broz
be9c3cd979 Print warning if msgfmt utility from gettext is missing.
User have to install gettext package or manually disable translation
using --disable-nls.

Also remove links to GNU packages ftp, all of these should by provided
by native distro packaging systems.

Fixes: #591.
2020-09-06 10:41:49 +02:00
Milan Broz
02106c3292 Update Readme.md. 2020-09-03 20:40:54 +02:00
Milan Broz
e078650435 Add stable version release notes. 2020-09-03 19:10:02 +02:00
Yuri Chornoivan
7d6b4d9936 po: update uk.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Yuri Kozlov
ab087f7342 po: update ru.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Jakub Bogusz
962735cf7a po: update pl.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Hiroshi Takekawa
4ce7766e14 po: update ja.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Frédéric Marchal
cdc70991f7 po: update fr.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Petr Pisar
a1fe799afd po: update cs.po (from translationproject.org) 2020-09-03 16:19:28 +02:00
Milan Broz
157f72f611 Always store dm-verity hash algorithm in superblock in lowercase.
Fixes: #586.
2020-08-29 15:51:20 +02:00
Milan Broz
c97080cee7 Fix disaplay of dm-integrity recalculating sector in dump command.
Fixes: #578.
2020-08-29 13:59:42 +02:00
Milan Broz
5b623d2314 Fix a memleak in blockwise test. 2020-08-29 12:21:32 +02:00
Milan Broz
26f87c284b Remove a gcc warning. 2020-08-27 21:23:00 +02:00
Ondrej Kozina
8cddcb76b2 Explicitly terminate cipher strings during down conversion. 2020-08-27 14:14:12 +02:00
Ondrej Kozina
6199fed6bb Fix posible buffer overflows in LUKS conversion.
cipher[31] and cipher_mode[31] buffers were passed to
crypt_parse_name_and_mode() routine where sscanf(s, "%31[^-]-%31s",
cipher, cipher_mode) was called.

In corner case it could cause terminating 0 byte written beyond
respective arrays.
2020-08-27 14:14:05 +02:00
Ondrej Kozina
96da06430b Add test for LUKS2 segments validation code fix. 2020-08-27 14:13:54 +02:00
Ondrej Kozina
752c9a5279 Simplify validation code a bit.
Keep it simple. If there's not enough memory we can't validate
segments. The LUKS2 specification does not recommend to continue
processing LUKS2 metadata if it can not be properly validated.
2020-08-27 14:13:32 +02:00
Ondrej Kozina
46ee71edcd Avoid needlessly large allocations in LUKS2 validation code.
In case LUKS2 backup segment creates gap in between last regular
segment and backup segment report invalid metadata imediately. We stop
on first error so there's no need to allocate large memory on heap
(we may ran with mlock(MCL_FUTURE) set).

Example:
- total segments count is 3
- regular segments have keys "0" and "1"
- first backup segment has key "42"
2020-08-27 14:13:25 +02:00
Milan Broz
bcfb7731ab Build branch v2.3.x in Travis. 2020-08-26 15:43:40 +02:00
Milan Broz
57d0f19bda Fix error message in previous commit. 2020-08-26 13:27:00 +02:00
Milan Broz
4cf663a661 Ignore optimal-io if not aligned to minimal page size
This values is bogus on some systems and causes wrong alignment
for data area. Just ignore it there.

Fixes: #585.
2020-08-26 13:17:26 +02:00
Milan Broz
0b9893c640 Print a warning if API test generates too long log. 2020-08-26 13:16:21 +02:00
Tobias Stoeckmann
ba4c028f5f Fixed some typos.
The large text block happened due to reformat. It's just addition
of "the" in front of problem, i.e. "If this is _the_ problem, ..."
2020-08-24 17:36:52 +00:00
Tobias Stoeckmann
52f5cb8ced Check segment gaps regardless of heap space.
Segments are validated in hdr_validate_segments. Gaps in segment keys
are detected when collecting offsets. But if an invalid segment is very
large, larger than count, it could happen that cryptsetup is unable to
allocate enough memory, not giving a clue about what actually is the
problem.

Therefore check for gaps even if not enough memory is available. This
gives much more information with debug output enabled.

Obviously cryptsetup still fails if segments are perfectly fine but not
enough RAM available. But at that stage, the user knows that it's the
fault of the system, not of an invalid segment.
2020-08-24 17:35:24 +00:00
Milan Broz
f3ec1e2254 Add some descriptive output to device test - performance flags. 2020-08-20 22:38:03 +02:00
Milan Broz
d5729bdf01 Add no_read/write_wrokqueue to dm-crypt options.
These performance options, introduced in kernel 5.9, configures
dm-crypt to bypass read or write workqueues and run encryption
synchronously.

Also support persistent storage of these flags for LUKS2.
2020-08-20 20:58:44 +02:00
Milan Broz
3c54d8a239 Support panic_on_corruption option form dm-verity.
The panic_on_corruption switch is available since kernel 5.9 (dm-verity 1.7.0).
2020-08-20 18:52:31 +02:00
Ondrej Kozina
f647333f49 Add test for reencryption with --master-key-file argument. 2020-08-20 18:17:17 +02:00
Ondrej Kozina
fcddbf5c03 Add API test for reencryption with specific new key. 2020-08-20 18:17:06 +02:00
Ingo Franzki
1bce69cfde Support online reencryption for PAES cipher.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

(With few adjustments by Ondrej Kozina)
2020-08-20 18:16:48 +02:00
Vojtech Trefny
32d4f243e6 bitlk: Set sector size to 512 when unknown/zero
Fixes: #584
2020-08-20 12:08:06 +02:00
Ondrej Kozina
8e6b8cd6e6 Revert "Allow base autodetection base in integer args parsing."
This reverts commit 018680046c.

We do not want integer cl arguments in non-decimal format. This was
experimental patch.
2020-08-17 13:44:13 +02:00
Milan Broz
6a6c4d0887 Fix 32bit invalid CLI arguments check on 32bit systems.
Comparison to > UINT32_MAX cannot be true if argument
is 32bit unsigned long.
2020-08-15 22:32:47 +02:00
Milan Broz
737ecd9d42 Use Ubuntu 20.04 in Travis CI builds. 2020-08-15 17:16:58 +02:00
Milan Broz
191d8a0716 Add libcryptsetup_cli headers to distribution files. 2020-08-15 15:39:55 +02:00
Ondrej Kozina
cfcc908cae Move clogger to libcryptsetup_cli crypt_cli_logger. 2020-08-15 15:28:42 +02:00
Ondrej Kozina
cf2e099087 Use new crypt_cli_read_mk in integritysetup.
Check key size while parsing cli arguments.
2020-08-15 15:28:32 +02:00
Ondrej Kozina
d6cc88cabb Move tools_write_mk in cryptsetup.
Also drops dependency on lib/utils_io.c in some tools.
2020-08-15 15:28:09 +02:00
Ondrej Kozina
42692418c2 Move tools_read_mk helper in libcryptsetup_cli. 2020-08-15 15:27:33 +02:00
Ondrej Kozina
a985c12659 WIP: Introduce libcryptsetup_cli.
Introducing new library supposed to be used in
cryptsetup tools and future cryptsetup loadable plugins

TODO:
  - distribution
  - cleanup header files
  - incorporate also plugin API?
2020-08-15 15:24:18 +02:00
Josef Andersson
5ebf128023 po: update sv.po (from translationproject.org) 2020-08-15 11:30:09 +02:00
Мирослав Николић
911b16bab8 po: update sr.po (from translationproject.org) 2020-08-15 11:30:09 +02:00
Milan Broz
693f61c47f Fix missing cryptsetup-reencrypt header files in dist. 2020-08-15 11:23:44 +02:00
Ondrej Kozina
3a8c866393 Reinstate original argument type hints in --help output. 2020-08-15 11:16:25 +02:00
Ondrej Kozina
0851c2cfb0 Port veritysetup to new args parsing. 2020-08-15 11:15:47 +02:00
Ondrej Kozina
958eaf4b24 Make tools_clear_line internal routine. 2020-08-15 11:12:05 +02:00
Ondrej Kozina
07f9248448 Make quiet_log decision logic more obvious. 2020-08-15 11:11:55 +02:00
Ondrej Kozina
c2371f95c6 Move decision on forcing weak password to tool directly. 2020-08-15 11:11:31 +02:00
Ondrej Kozina
379322f0b8 Port cryptsetup-reencrypt to new arguments parsing code. 2020-08-15 11:10:27 +02:00
Ondrej Kozina
b30b17d1eb Port integritysetup to new arguments parsing code. 2020-08-15 11:09:02 +02:00
Ondrej Kozina
ef3beeb390 Port cryptsetup to new arguments parsing code. 2020-08-15 11:07:15 +02:00
Ondrej Kozina
48e0b20e62 Add arguments helper macros.
used later to read and set command line arguments in
all tools
2020-08-15 10:44:06 +02:00
Ondrej Kozina
018680046c Allow base autodetection base in integer args parsing. 2020-08-15 10:43:46 +02:00
Ondrej Kozina
aebe14a6e9 Introduce new function to parse command line arguments.
To be used later in all tools.
2020-08-15 10:22:53 +02:00
Ondrej Kozina
c4b7bf8635 Add optional context parameter in crypt_token_load. 2020-08-15 10:15:17 +02:00
Ondrej Kozina
3973f6a57c Align token dump with other outputs. 2020-08-15 10:12:46 +02:00
Milan Broz
5906ca25f7 Move blkid signature checking to blockdev file. 2020-08-15 10:12:29 +02:00
Milan Broz
2ce8573f04 Add PIN processing to tokens. 2020-08-15 10:10:40 +02:00
Luca Boccassi
f6706ce124 Add a test function to exercise concurrent activations
The issue can be reproduced very easily by starting 2 veritysetup processes
at the same time:

$ sudo veritysetup open -v ./img.raw img ./img.verity  & sudo veritysetup open -v ./img.raw img ./img.verity
[1] 814021
device-mapper: create ioctl on img CRYPT-VERITY-cea03b7bc5b94e088e5754ff33be71d6-img failed: Device or resource busy
Verity device detected corruption after activation.
Command successful.
Command failed with code -1 (wrong or missing parameters).

Note how veritysetup open is reporting -EINVAL as the return code.

After the fix:

$ sudo veritysetup open -v ./img.raw img ./img.verity  & sudo veritysetup open -v ./img.raw img ./img.verity
[1] 814649
Verity device detected corruption after activation.
Command successful.
Device img already exists.
Command failed with code -5 (device already exists or device is busy).
2020-08-12 16:51:20 +01:00
Milan Broz
31ebf3dc2c libdevmapper: always return EEXIST if a task fails because the device already exists
Allows concurrent opens to return a usable error instead of EINVAL
2020-08-12 16:50:57 +01:00
Milan Broz
cb183de1da Add configure option for LUKS2 external tokens lib.
This is an experimental extension that is disabled for now.
2020-08-11 17:59:51 +02:00
Ondrej Kozina
c867f2e8a0 Unload all external tokens on exit. 2020-08-11 17:36:30 +02:00
Ondrej Kozina
c9ff83bfa3 Implement external tokens unload. 2020-08-11 17:36:26 +02:00
Ondrej Kozina
05c997da1f Store dynamic plugin handle.
For use later when unloading cryptsetup library.
2020-08-11 17:36:22 +02:00
Ondrej Kozina
f677bdc12f Fix few bugs in previous commit.
- crypt_token_register must not be called from withing crypt_token_load
(see later commits)

- minor bug in dlvsym/dlerror handling

- check for overflow in LUKS2_token_handler_type
2020-08-11 17:36:15 +02:00
Milan Broz
2178461c89 Add external token load.
(just very minor fixes by okozina to compile w/ previous commit)
2020-08-11 17:36:11 +02:00
Ondrej Kozina
d438151f25 Partially revert few changes. 2020-08-09 13:17:54 +02:00
Milan Broz
7d475266b6 Simplify internal tokens handling. 2020-08-09 13:17:40 +02:00
Ondrej Kozina
367cb7a761 Fix API mistake in crypt_reencrypt.
Introducing new version of crypt_reencrypt symbol including
previously missing usrptr parameter. This change should be
backward compatible for existing libcryptsetup users
until next recompilation where it needs to be fixed.
2020-08-09 13:16:57 +02:00
Ondrej Kozina
4604f00218 Remove unreachable code in cryptsetup-reencrypt.
opt_key_size variable can't be zero at that specific
code path.
2020-08-09 13:16:32 +02:00
Ondrej Kozina
8eff9151ac Set proper debug level defined in API. 2020-08-09 13:16:27 +02:00
Ondrej Kozina
50797c7948 Make total_keyfiles counter global variable. 2020-08-09 13:16:23 +02:00
Ondrej Kozina
c34a3e2c5b Add initial arguments compat test. 2020-08-09 11:31:27 +02:00
Ondrej Kozina
35211cdc8f Add --test-args option. 2020-08-09 11:30:20 +02:00
Milan Broz
4a8a1f2dde Do not use /tmp for test images.
Keep all temporary files in local test directory.
2020-08-09 11:24:53 +02:00
Milan Broz
f2ab443cca Fix a problem in integritysetup if a hash algorithm has dash in the name.
If users want to use blake2b/blake2s, the kernel algorithm name
includes dash - like "blake2s-256".

Because we use dash as a separator, this patch adds an exception
for this case.

Fixes: #581.
2020-07-27 12:50:46 +02:00
Milan Broz
abc15094c6 tcrypt: Support activation of devices with a larger sector.
TrueCrypt/VeraCrypt always use 512-bytes sector for encryption,
but for devices with a larger native sector it stores this value in header.

This patch allows activating of such devices, basically ignoring
the mentioned sector size in header (it only must be multiple
of 512-bytes sector).

Fixes: #580.
2020-07-26 21:13:55 +02:00
Milan Broz
f390695767 Fix crypto backend to properly handle ECB mode.
Despite it should be never used, it should still work :)

Bug introduced in version 2.3.2.
2020-07-21 14:14:54 +02:00
Milan Broz
f092bcdfdb Use the most recent image in travis.yml. 2020-07-12 08:14:25 +02:00
Milan Broz
1633f030e8 Rename reenc_keyslot_update to reencrypt_keyslot_update. 2020-07-07 14:20:39 +02:00
Milan Broz
4451df15b4 Rename luks2_reenc_context to luks2_reecrypt. 2020-07-07 14:20:39 +02:00
Milan Broz
f50062517e Rename crypt_get/set reenc_context to luks2_reencrypt. 2020-07-07 14:20:39 +02:00
Milan Broz
967e3de552 Rename LUKS2_reenc_status to LUKS2_reencrypt_status. 2020-07-07 14:20:39 +02:00
Milan Broz
d95472e757 Rename LUKS2_reencrypt_status to LUKS2_reencrypt_get_params to avoid confusion. 2020-07-07 14:20:39 +02:00
Milan Broz
3e0e5bac2a Use LUKS2_reencrypt prefix for function defined in luks2.h.
This should clean up prefixes a little bit.
2020-07-07 14:20:39 +02:00
Milan Broz
08cb76bbfd Do not expose json_object in luks2.h.
Later we can use different implementation of JSON parser.
Also define structs in one place.
2020-07-07 14:20:39 +02:00
Milan Broz
281dd51f5a Remove json_object argument from area size checks.
These functions are internal to LUKS2 implementation.
2020-07-07 14:20:39 +02:00
Milan Broz
1c7c815108 Move LUKS2 internal functions to internal header.
This is the first step to remove json_object from internal API.
2020-07-07 14:20:39 +02:00
Ondrej Kozina
d177af8842 Do not create excessively large headers.
When creating LUKS2 header with specified --offset much larger
then LUKS2 header size we needlessly also wipe (allocate up to
--offset) much larger file than needed.
2020-07-07 14:20:19 +02:00
Francesco Turco
544129d240 fix capitalization 2020-07-04 16:43:40 +02:00
Francesco Turco
9f79678723 fix typos 2020-07-04 16:43:27 +02:00
Francesco Turco
a491b938ba use HTTPS for URLs 2020-07-04 16:43:23 +02:00
Vojtech Trefny
588c8cf5b3 bitlk: Fix reading key data size in the decrypted key material
We've assumed that first 4 bytes of the decrypted key data is the
size of the key + metadata. Looks like this isn't true and only
first two bytes contain the size and the other two bytes are
unknown data, possibly related to reencryption and/or passphrase
change.

Fixes: #575
2020-07-03 13:18:42 +02:00
Milan Broz
876ca59234 Set devel version. 2020-05-31 20:26:20 +02:00
Milan Broz
f5910d83c4 Add option for large IV to storage wrapper.
Also implement some test vectors and use the same limits
as in dm-crypt (IV offset alignnment).
2020-05-29 10:59:24 +02:00
Ondrej Kozina
e43a22abcf Allow bitlk tests to run with valgrind. 2020-05-29 10:59:24 +02:00
Ondrej Kozina
2a7aa8992b Remove bogus valgrind suppressions. 2020-05-29 10:59:24 +02:00
Ondrej Kozina
e36597e2c6 Fix popt string related memory leaks.
All POPT_ARG_STRING pointers must be free'd manually
in calling application. This is unfortunately not documented
well behaviour of popt and we were having memory leaks due to
it.
2020-05-29 10:59:23 +02:00
Ondrej Kozina
6403de2109 Add utilities cleanup routine. 2020-05-29 10:59:23 +02:00
Ondrej Kozina
9b49e47b13 Drop unreachable code and useless conditions.
integrity_alg variable can not be NULL.
2020-05-29 10:59:23 +02:00
Ondrej Kozina
8540be5b82 Remove const from all opt_ string declarations.
Those variables contain pointers to dynamically alocated memory.
2020-05-29 10:59:23 +02:00
Ondrej Kozina
ae6d6261a1 Do not pass constant strings to option string variables.
This is part of effort to eliminate all memory leaks related
to options parsing in popt but for that to work we must avoid
passing constant strings to free().
2020-05-29 10:59:23 +02:00
Ondrej Kozina
ce4fcd2009 Group all string options variables together. 2020-05-29 10:59:23 +02:00
Ondrej Kozina
76620881f4 Properly prefix all popt variables in veritysetup. 2020-05-29 10:59:23 +02:00
Milan Broz
f99efd6166 Update Readme.md. 2020-05-28 11:42:58 +02:00
Milan Broz
74e94e7bdd Prepare version 2.3.3. 2020-05-28 11:26:27 +02:00
Milan Broz
72cd628357 Update cryptsetup.pot. 2020-05-24 23:37:31 +02:00
Yuri Chornoivan
45367e4a34 po: update uk.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Yuri Kozlov
7d76831250 po: update ru.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Jakub Bogusz
d2ff3fc2ee po: update pl.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Hiroshi Takekawa
537b8454a4 po: update ja.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Frédéric Marchal
a7c71b90b1 po: update fr.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Antonio Ceballos
e0be3deb3a po: update es.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Roland Illig
5490476d84 po: update de.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Petr Pisar
90865eb887 po: update cs.po (from translationproject.org) 2020-05-24 23:22:15 +02:00
Milan Broz
157f71d78e Add IV vector tests.
This test checks IV wrapper implemented in userspace.
2020-05-24 23:19:46 +02:00
Milan Broz
176fee54e4 Require both keyslot cipher ane key size options.
If not specified together, cryptsetup silently fail.
2020-05-15 22:07:52 +02:00
Milan Broz
61f4363ed7 Implement EBOIV in userspace storage wrapper.
The EBOIV initialization vector is intended to be used
internally with BitLocker devices (for CBC mode).
It can be used in some specific cases for other devices.

This patch adds userspace implementation duplicating
the same EBOIV as the dm-crypt kernel.

Fixes: #562
2020-05-15 17:33:06 +02:00
Vojtech Trefny
86cc67e081 bitlk: Fix memory leak when freeing bitlk_fvek structure 2020-05-15 17:15:07 +02:00
Milan Broz
dcc9888350 Update pot file. 2020-05-15 10:56:36 +02:00
Мирослав Николић
6af6a424b4 po: update sr.po (from translationproject.org) 2020-05-15 10:44:11 +02:00
Milan Broz
e1ceb63023 Set devel version. 2020-05-15 10:43:52 +02:00
Milan Broz
4eb7193a27 Support large IV count option for plain device
The iv_large_sector option is supported in dm-crypt since introduction
of larger sectors encryption.
It counts Initialization Vector (IV) in larger sector size (if set) instead
of 512 bytes sectors.

This option does not have any performance or security impact, but it can be
used for accessing incompatible existing disk images from other systems.
(It is used internally in BitLocker compatibily code).

This patch allows it to be used for plain type device, so users
can manually map foreign disk images.
Only open action with plain device and sector size > 512 bytes is supported.
2020-05-15 10:37:33 +02:00
Arno Wagner
e6ff3b37a4 sync with wiki 2020-05-12 17:21:49 +02:00
Milan Broz
c3e095969f Skip 4k Bitlk images (some older systems cannot activate them). 2020-05-07 09:15:45 +02:00
Vojtěch Trefný
2e345a1059 bitlk: Fix working with 4k sector devices
We need to use the iv_large_sectors flag and correct sector size
for the crypt segments for these devices. Used sector size is
read from the device header. This commit also adds two new test
images with 4k sectors.

Fixes: #557
2020-05-06 21:20:26 +02:00
Milan Broz
e759ebe0bd Better explain --persistent option for flag removals.
Also fix a error message that was not displayed
properly for the persistent discard flag incompatibility.

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

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

or to terminal:

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

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

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

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

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

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

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

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

Also some test images are added for regression testing.

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

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

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

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

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

Print at least error message to user in this case.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

The kernel will use the signature to validate the roothash.

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

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

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

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

This leads to confusion and shortened tags.

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

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

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

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

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

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

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

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

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

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

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

Fixes: #491.
2019-11-19 12:41:14 +01:00
Milan Broz
b03cb3f3d8 Export memory safe functions.
Make crypt_safe_alloc/realloc/free and memzero part of API.
2019-11-16 21:28:54 +01:00
Ondrej Kozina
e08401a2ec Properly fix encryption initialization message. 2019-11-08 13:15:37 +01:00
Ondrej Kozina
0a9e7028ae Fix LUKS2 encryption initialization with non-zero keyslot.
Positive keyslot number was interpreted as a failure.
2019-11-08 13:15:37 +01:00
Milan Broz
ba0ecc54df Test Bionic distro in Travis. 2019-11-05 22:09:05 +01:00
Milan Broz
6920f9dc27 Set devel version. 2019-11-05 17:56:58 +01:00
Milan Broz
ba2547212e Allow bitlk branch for CI tests. 2019-11-05 17:53:07 +01:00
Milan Broz
bbe1a8a5b6 Update Readme.md for 2.2.2. 2019-11-01 10:16:05 +01:00
Milan Broz
c82728f04d Version 2.2.2. 2019-11-01 09:02:46 +01:00
Milan Broz
cc0d33bca7 Fix DM_DEVICE_GET_TARGET_VERSION detection.
Stable libdevampper used changed name for dm task, let's fix it.
2019-10-31 20:35:46 +01:00
Milan Broz
3933ec7dce Add Ondra to authors. 2019-10-31 20:02:51 +01:00
Petr Pisar
f8c9507612 po: update cs.po (from translationproject.org) 2019-10-31 20:01:51 +01:00
Yuri Kozlov
7c5c9ae8fd po: update ru.po (from translationproject.org) 2019-10-31 12:10:04 +01:00
Frédéric Marchal
cd00792fe9 po: update fr.po (from translationproject.org) 2019-10-31 12:10:04 +01:00
Ondrej Kozina
df390509b2 Hotfix missing new line character in translated string.
Without this fix the message gets immediately overwritten with
reencryption progress bar.
2019-10-31 12:02:55 +01:00
Ondrej Kozina
dd6abe9375 Add luks2-reencryption-test to valgrind checks. 2019-10-22 15:07:57 +02:00
Milan Broz
a3f199d0a3 po: update pot file 2019-10-20 10:40:12 +02:00
Yuri Chornoivan
8e3b85ee12 po: update uk.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Jakub Bogusz
e60fbfc865 po: update pl.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Hiroshi Takekawa
a512488fd7 po: update ja.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Antonio Ceballos
1981d909cf po: update es.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Roland Illig
ea14f2c98c po: update de.po (from translationproject.org) 2019-10-20 10:35:43 +02:00
Milan Broz
c81becf10d Prepare version tag, and sync po files.
(For some reason I unsynced all po files again,
this patch reverts them to the translationproject versions...)
2019-10-18 10:52:33 +02:00
dofrupisla
1433d040ae Fix luksHeaderRestore occuring twice 2019-10-17 11:07:32 +02:00
Milan Broz
206b70c837 Explicitly print error message if keyslot open failed.
The only quiet message now is EPERM (wrong password) that is
processed by the caller.

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

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

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

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

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

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

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

Fixes #445.
2019-09-09 19:01:01 +02:00
Ondrej Kozina
2c0914b2ba Fix LUKS2 reencryption recovery test.
Fix corner case when head or tail of test device is remapped
to error target for writes.
2019-09-09 14:07:30 +02:00
Milan Broz
3ebedfe7b0 Update readme.md. 2019-09-06 13:13:44 +02:00
Milan Broz
1af2f85d43 Fix Release notes. 2019-09-06 12:49:31 +02:00
Milan Broz
0395e8935a Version 2.2.1. 2019-09-06 11:21:15 +02:00
Milan Broz
7ffd182197 Re-add cryptsetup.pot to git. 2019-09-06 10:53:34 +02:00
Milan Broz
fae1abdea9 Update gitignore (remove pot file). 2019-09-06 10:48:18 +02:00
Milan Broz
f17b8ad550 Update po files. 2019-09-06 10:02:15 +02:00
Milan Broz
883b600617 Update po files. 2019-09-02 11:22:06 +02:00
Yuri Chornoivan
f26a9abddb Fix minor typos 2019-09-02 09:20:47 +00:00
Milan Broz
4a7180a4f2 Clarify comments in API examples. 2019-08-30 16:24:56 +02:00
Milan Broz
af0c5c3ccb Set version to 2.2.1-rc0. 2019-08-30 13:15:17 +02:00
Milan Broz
a6e8db99b3 Fix test for very old kernels that truncate loop backing file info. 2019-08-30 10:41:04 +02:00
Milan Broz
e4684752c2 Update po file. 2019-08-30 09:42:27 +02:00
Milan Broz
4d6269a42d Fix some gcc warnings on 32bit systems. 2019-08-30 09:41:04 +02:00
Ondrej Kozina
593f5ee569 Reinstate missing backing file hint for loop device.
This regression was introduced in cryptsetup 2.0.0 release
with refactoring "Enter passphrase for (dev)" prompt.

With cryptsetup 1.7.5, "cryptsetup open /dev/loop0" printed
following prompt:

"Enter passphrase for /path/to/loop/backing_file:"

Whereas cryptsetup 2.0.0 and on printed following one:

"Enter passphrase for /dev/loop:"

Reported in https://bugzilla.redhat.com/show_bug.cgi?id=1726287

Fixes: 39698fa6b7 ("Remove terminal input from libcryptsetup API calls.")
Fixes: c80acbe4c8 ("Add back "Passphrase for (dev):" prompt.")
Fixes: 5171f65c05 ("tests only: Return back password retry support for luksOpen.")
2019-08-30 09:39:41 +02:00
Ondrej Kozina
4862e22cd0 Add opt-io size parameter to LUKS2 reencrypt test device.
So that we can test recovery is not broken for optimal io size
optimization added to reencryption code.
2019-08-30 09:39:38 +02:00
Ondrej Kozina
d13a6f7487 Take optimal io size in account with LUKS2 reencryption.
If device properly exposes optimal io size, let's align
reencryption hotzone to it. Otherwise device-mapper driver
complaints about misaligned tables and reencryption performance
is not optimal.
2019-08-30 09:39:35 +02:00
Milan Broz
09066b1ba6 Simplify API example and use LUKS2. 2019-08-29 13:07:32 +02:00
Milan Broz
8f8f0b3258 Fix mapped segments overflow on 32bit architectures.
All set_segment funcions must use uin64_t everywhere,
not size_t that is platform dependent.

The code later uses it correctly, it is just wrong function
prototype definitions.

Reported in
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=935702

(TODO: add a test for other segment types.)
2019-08-26 10:04:07 +02:00
Milan Broz
d9283970a5 Fix API test in FIPS mode. 2019-08-22 23:35:28 +02:00
Milan Broz
994afad279 Add veracrypt system encryption image. 2019-08-22 15:38:35 +02:00
Ondrej Kozina
b72ea28540 Fix regression in veracrypt system partition unlock.
Do not close base device file descriptor before reading from it.

Fixes #472.
2019-08-22 13:57:16 +02:00
Ondrej Kozina
fc69c6fac4 Add hint for online reencryption in cryptsetup-reencrypt man page.
command "man cryptsetup reencrypt" gets redirected to
cryptsetup-reencrypt man page. This may confuse users that LUKS2 online
reencryption is managed by offline utility.
2019-08-20 13:14:01 +02:00
Milan Broz
4100fd2817 Update Readme.md for 2.2.0. 2019-08-15 08:48:25 +02:00
236 changed files with 49021 additions and 25956 deletions

28
.github/workflows/cibuild-setup-ubuntu.sh vendored Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
set -ex
PACKAGES=(
git make autoconf automake autopoint pkg-config libtool libtool-bin
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
)
COMPILER="${COMPILER:?}"
COMPILER_VERSION="${COMPILER_VERSION:?}"
RELEASE="$(lsb_release -cs)"
bash -c "echo 'deb-src http://archive.ubuntu.com/ubuntu/ $RELEASE main restricted universe multiverse' >>/etc/apt/sources.list"
# Latest gcc stack deb packages provided by
# https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test
add-apt-repository -y ppa:ubuntu-toolchain-r/test
PACKAGES+=(gcc-$COMPILER_VERSION)
# scsi_debug, gost crypto
PACKAGES+=(dkms linux-headers-$(uname -r) linux-modules-extra-$(uname -r) gost-crypto-dkms)
apt-get -y update --fix-missing
apt-get -y install "${PACKAGES[@]}"
apt-get -y build-dep cryptsetup

38
.github/workflows/cibuild.sh vendored Executable file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
PHASES=(${@:-CONFIGURE MAKE CHECK})
COMPILER="${COMPILER:?}"
COMPILER_VERSION="${COMPILER_VERSION}"
CFLAGS=(-O1 -g)
CXXFLAGS=(-O1 -g)
CC="gcc${COMPILER_VERSION:+-$COMPILER_VERSION}"
CXX="g++${COMPILER_VERSION:+-$COMPILER_VERSION}"
set -ex
for phase in "${PHASES[@]}"; do
case $phase in
CONFIGURE)
opts=(
--enable-libargon2
)
sudo -E git clean -xdf
./autogen.sh
CC="$CC" CXX="$CXX" CFLAGS="${CFLAGS[@]}" CXXFLAGS="${CXXFLAGS[@]}" ./configure "${opts[@]}"
;;
MAKE)
make -j
make -j -C tests check-programs
;;
CHECK)
make check
;;
*)
echo >&2 "Unknown phase '$phase'"
exit 1
esac
done

29
.github/workflows/cibuild.yml vendored Normal file
View File

@@ -0,0 +1,29 @@
name: Build test
on:
push:
branches:
- 'master'
- 'wip-luks2'
- 'v2.3.x'
paths-ignore:
- 'docs/**'
jobs:
build:
runs-on: ubuntu-latest
if: github.repository == 'mbroz/cryptsetup'
strategy:
fail-fast: false
matrix:
env:
- { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
env: ${{ matrix.env }}
steps:
- name: Repository checkout
uses: actions/checkout@v1
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
- name: Configure & Make
run: .github/workflows/cibuild.sh CONFIGURE MAKE
- name: Check
run: sudo -E .github/workflows/cibuild.sh CHECK

48
.github/workflows/coverity.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Coverity test
on:
push:
branches:
- 'coverity_scan'
paths-ignore:
- 'docs/**'
jobs:
latest:
runs-on: ubuntu-latest
if: github.repository == 'mbroz/cryptsetup'
steps:
- name: Repository checkout
uses: actions/checkout@v1
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
env:
COMPILER: "gcc"
COMPILER_VERSION: "11"
- name: Install Coverity
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=mbroz/cryptsetup" -O cov-analysis-linux64.tar.gz
mkdir cov-analysis-linux64
tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
- name: Run autoconf & configure
run: |
./autogen.sh
./configure
- name: Run cov-build
run: |
export PATH=`pwd`/cov-analysis-linux64/bin:$PATH
cov-build --dir cov-int make
- name: Submit to Coverity Scan
run: |
tar czvf cryptsetup.tgz cov-int
curl \
--form project=mbroz/cryptsetup \
--form token=$TOKEN \
--form email=gmazyland@gmail.com \
--form file=@cryptsetup.tgz \
--form version=trunk \
--form description="`./cryptsetup --version`" \
https://scan.coverity.com/builds?project=mbroz/cryptsetup
env:
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}

2
.gitignore vendored
View File

@@ -25,6 +25,7 @@ config.sub
configure
cryptsetup
cryptsetup-reencrypt
cryptsetup-ssh
depcomp
install-sh
integritysetup
@@ -36,7 +37,6 @@ missing
po/Makevars.template
po/POTFILES
po/Rules-quot
po/*.pot
po/*.header
po/*.sed
po/*.sin

108
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,108 @@
stages:
- test
.debian-prep:
before_script:
- sudo apt-get -y update --fix-missing
- >
sudo apt-get -y install -y -qq git gcc make
autoconf automake autopoint pkg-config libtool libtool-bin gettext
libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev
libpwquality-dev sharutils dmsetup jq xxd expect keyutils
netcat passwd openssh-client sshpass
- sudo apt-get -y build-dep cryptsetup
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-libargon2
.dnf-openssl-backend:
before_script:
- >
sudo dnf -y -q install
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
libssh-devel libtool libuuid-devel make popt-devel
libsepol-devel.x86_64 netcat openssh-clients passwd pkgconfig sharutils
sshpass tar uuid-devel vim-common device-mapper expect gettext git jq
keyutils openssl-devel openssl
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-fips --enable-pwquality --enable-libargon2 --with-crypto_backend=openssl
# Merge request: Build and run only non-root tests
test-mergerq-job-debian-noroot:
extends:
- .debian-prep
tags:
- libvirt
- debian10
stage: test
interruptible: true
rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- make check
# For main branch commit, run all tests as root
test-main-commit-job-debian:
extends:
- .debian-prep
tags:
- libvirt
- debian10
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
- sudo -E make clean
test-main-commit-job-dnf:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-mergerq-job-dnf:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check

View File

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

View File

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

View File

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

View File

@@ -1,160 +0,0 @@
#!/bin/bash
#
# .travis-functions.sh:
# - helper functions to be sourced from .travis.yml
# - designed to respect travis' environment but testing locally is possible
# - modified copy from util-linux project
#
if [ ! -f "configure.ac" ]; then
echo ".travis-functions.sh must be sourced from source dir" >&2
return 1 || exit 1
fi
## some config settings
# travis docs say we get 1.5 CPUs
MAKE="make -j2"
DUMP_CONFIG_LOG="short"
export TS_OPT_parsable="yes"
function configure_travis
{
./configure "$@"
err=$?
if [ "$DUMP_CONFIG_LOG" = "short" ]; then
grep -B1 -A10000 "^## Output variables" config.log | grep -v "_FALSE="
elif [ "$DUMP_CONFIG_LOG" = "full" ]; then
cat config.log
fi
return $err
}
function check_nonroot
{
local cfg_opts="$1"
[ -z "$cfg_opts" ] && return
configure_travis \
--enable-cryptsetup-reencrypt \
--enable-internal-sse-argon2 \
"$cfg_opts" \
|| return
$MAKE || return
make check
}
function check_root
{
local cfg_opts="$1"
[ -z "$cfg_opts" ] && return
configure_travis \
--enable-cryptsetup-reencrypt \
--enable-internal-sse-argon2 \
"$cfg_opts" \
|| return
$MAKE || return
# FIXME: we should use -E option here
sudo make check
}
function check_nonroot_compile_only
{
local cfg_opts="$1"
[ -z "$cfg_opts" ] && return
configure_travis \
--enable-cryptsetup-reencrypt \
--enable-internal-sse-argon2 \
"$cfg_opts" \
|| return
$MAKE
}
function travis_install_script
{
# install some packages from Ubuntu's default sources
sudo apt-get -qq update
sudo apt-get install -qq >/dev/null \
sharutils \
libgcrypt20-dev \
libssl-dev \
libdevmapper-dev \
libpopt-dev \
uuid-dev \
libsepol1-dev \
libtool \
dmsetup \
autoconf \
automake \
pkg-config \
autopoint \
gettext \
expect \
keyutils \
libjson-c-dev \
libblkid-dev \
|| return
}
function travis_before_script
{
set -o xtrace
./autogen.sh
ret=$?
set +o xtrace
return $ret
}
function travis_script
{
local ret
set -o xtrace
case "$MAKE_CHECK" in
gcrypt)
check_nonroot "--with-crypto_backend=gcrypt" && \
check_root "--with-crypto_backend=gcrypt"
;;
gcrypt_compile)
check_nonroot_compile_only "--with-crypto_backend=gcrypt"
;;
openssl)
check_nonroot "--with-crypto_backend=openssl" && \
check_root "--with-crypto_backend=openssl"
;;
openssl_compile)
check_nonroot_compile_only "--with-crypto_backend=openssl"
;;
kernel)
check_nonroot "--with-crypto_backend=kernel" && \
check_root "--with-crypto_backend=kernel"
;;
kernel_compile)
check_nonroot_compile_only "--with-crypto_backend=kernel"
;;
*)
echo "error, check environment (travis.yml)" >&2
false
;;
esac
ret=$?
set +o xtrace
return $ret
}
function travis_after_script
{
return 0
}

View File

@@ -1,40 +0,0 @@
language: c
sudo: required
dist: xenial
compiler:
- gcc
env:
- MAKE_CHECK="gcrypt"
- MAKE_CHECK="openssl"
- MAKE_CHECK="kernel"
branches:
only:
- master
- wip-luks2
- v2_0_x
before_install:
- uname -a
- $CC --version
- which $CC
# workaround clang not system wide, fail on sudo make install
- export CC=`which $CC`
# workaround travis-ci issue #5301
- unset PYTHON_CFLAGS
install:
- source ./.travis-functions.sh
- travis_install_script
before_script:
- travis_before_script
script:
- travis_script
after_script:
- travis_after_script

View File

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

View File

@@ -1,6 +0,0 @@
Since version 1.6 this file is no longer maintained.
See docs/*ReleaseNotes for release changes documentation.
See version control history for full commit messages.
https://gitlab.com/cryptsetup/cryptsetup/commits/master

3166
FAQ

File diff suppressed because it is too large Load Diff

229
INSTALL
View File

@@ -1,229 +0,0 @@
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@@ -1,4 +1,4 @@
EXTRA_DIST = COPYING.LGPL FAQ docs misc
EXTRA_DIST = README.md COPYING.LGPL FAQ docs misc autogen.sh
SUBDIRS = po tests
CLEANFILES =
DISTCLEAN_TARGETS =
@@ -11,16 +11,22 @@ AM_CPPFLAGS = \
-DLIBDIR=\""$(libdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION=\""$(VERSION)"\"
-DVERSION=\""$(VERSION)"\" \
-DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
AM_CFLAGS = -Wall
AM_LDFLAGS =
LDADD = $(LTLIBINTL) -lm
tmpfilesddir = @DEFAULT_TMPFILESDIR@
include_HEADERS =
lib_LTLIBRARIES =
noinst_LTLIBRARIES =
sbin_PROGRAMS =
man8_MANS =
tmpfilesd_DATA =
pkgconfig_DATA =
include man/Makemodule.am
@@ -33,12 +39,14 @@ include lib/crypto_backend/Makemodule.am
include lib/Makemodule.am
include src/Makemodule.am
include tokens/Makemodule.am
ACLOCAL_AMFLAGS = -I m4
DISTCHECK_CONFIGURE_FLAGS = \
--with-tmpfilesdir=$$dc_install_base/usr/lib/tmpfiles.d \
--enable-internal-argon2 --enable-internal-sse-argon2
--enable-internal-argon2 --enable-internal-sse-argon2 \
--enable-external-tokens --enable-ssh-token
distclean-local:
-find . -name \*~ -o -name \*.orig -o -name \*.rej | xargs rm -f
@@ -46,3 +54,9 @@ distclean-local:
clean-local:
-rm -rf docs/doxygen_api_docs libargon2.la
install-data-local:
$(MKDIR_P) -m 0755 $(DESTDIR)/${EXTERNAL_LUKS2_TOKENS_PATH}
uninstall-local:
rmdir $(DESTDIR)/${EXTERNAL_LUKS2_TOKENS_PATH} 2>/dev/null || :

1
NEWS
View File

@@ -1 +0,0 @@
See docs/* directory for Release Notes.

31
README
View File

@@ -1,31 +0,0 @@
cryptsetup
setup cryptographic volumes for dm-crypt (including LUKS extension)
WEB PAGE:
https://gitlab.com/cryptsetup/cryptsetup/
FAQ:
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions
MAILING LIST:
E-MAIL: dm-crypt@saout.de
URL: http://www.saout.de/mailman/listinfo/dm-crypt
DOWNLOAD:
https://www.kernel.org/pub/linux/utils/cryptsetup/
SOURCE CODE:
URL: https://gitlab.com/cryptsetup/cryptsetup/tree/master
Checkout: git clone https://gitlab.com/cryptsetup/cryptsetup.git
NLS (PO TRANSLATIONS):
PO files are maintained by:
http://translationproject.org/domain/cryptsetup.html

View File

@@ -5,12 +5,12 @@ What the ...?
**Cryptsetup** is a utility used to conveniently set up disk encryption based
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
and **TrueCrypt** (including **VeraCrypt** extension) formats.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
The project also includes a **veritysetup** utility used to conveniently setup
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
and, since version 2.0, **integritysetup** to setup
and **integritysetup** to setup
[DMIntegrity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMIntegrity) block integrity kernel module.
@@ -20,6 +20,8 @@ LUKS Design
only facilitate compatibility among distributions, but also provides secure management of multiple user passwords.
LUKS stores all necessary setup information in the partition header, enabling to transport or migrate data seamlessly.
### Specifications
Last version of the LUKS2 format specification is
[available here](https://gitlab.com/cryptsetup/LUKS2-docs).
@@ -44,58 +46,19 @@ 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.1.0**
* [cryptsetup-2.1.0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.xz)
* Signature [cryptsetup-2.1.0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/cryptsetup-2.1.0.tar.sign)
**The latest stable cryptsetup version is 2.4.2**
* [cryptsetup-2.4.2.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.2.tar.xz)
* Signature [cryptsetup-2.4.2.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-2.4.2.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.1.0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.1/v2.1.0-ReleaseNotes).
**The latest testing and experimental cryptsetup version is 2.2.0-rc1**
* [cryptsetup-2.2.0-rc1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0-rc1.tar.xz)
* Signature [cryptsetup-2.2.0-rc1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0-rc1.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.2.0-rc1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-rc1-ReleaseNotes).
* [Cryptsetup 2.4.2 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/v2.4.2-ReleaseNotes).
Previous versions
* [Version 2.0.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.6.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.6-ReleaseNotes).
* [Version 2.0.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.5.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.5-ReleaseNotes).
* [Version 2.0.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.4.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.4-ReleaseNotes).
* [Version 2.0.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.3.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.3-ReleaseNotes).
* [Version 2.0.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.2.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.2-ReleaseNotes).
* [Version 2.0.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.1.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.1-ReleaseNotes).
* [Version 2.0.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-2.0.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/v2.0.0-ReleaseNotes).
* [Version 2.3.6](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.6.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.6.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.6-ReleaseNotes).
* [Version 1.7.5](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.5.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.5-ReleaseNotes).
* [Version 1.7.4](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.4.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.4-ReleaseNotes).
* [Version 1.7.3](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.3.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.3-ReleaseNotes).
* [Version 1.7.2](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.2.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.2-ReleaseNotes).
* [Version 1.7.1](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.1.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.1-ReleaseNotes).
* [Version 1.7.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-1.7.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/v1.7.0-ReleaseNotes).
Source and API docs
-------------------
@@ -106,14 +69,39 @@ For libcryptsetup documentation see [libcryptsetup API](https://mbroz.fedorapeop
The libcryptsetup API/ABI changes are tracked in [compatibility report](https://abi-laboratory.pro/tracker/timeline/cryptsetup/).
NLS PO files are maintained by [TranslationProject](http://translationproject.org/domain/cryptsetup.html).
NLS PO files are maintained by [TranslationProject](https://translationproject.org/domain/cryptsetup.html).
Required packages
-----------------
All distributions provide cryptsetup as distro package. If you need to compile cryptsetup youfself, some packages are required for compilation. Please always prefer distro specific build tools to manually configuring cryptsetup.
For available compile options, check ``configure --help`` for more info. If you are using a git snapshot, you need to generate a configure script with ``autogen.sh`` script.
Here is the list of packages needed for the compilation of project for particular distributions:
* For Fedora: `git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar`. Optionally `libargon2-devel libpwquality-devel`. To run the internal testsuite you also need to install `sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openssh-clients openssh sshpass`.
* For Debian and Ubuntu: `git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar`. Optionally `libargon2-0-dev libpwquality-dev`. To run the internal testsuite you also need to install `sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass`
Note that the list could change as the distributions evolve.
Help!
-----
Please always read [FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions) first.
For cryptsetup and LUKS related questions, please use the dm-crypt mailing list, [dm-crypt@saout.de](mailto:dm-crypt@saout.de).
If you want to subscribe just send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
### Documentation
You can also browse [list archive](http://www.saout.de/pipermail/dm-crypt/) or read it through
[web interface](https://marc.info/?l=dm-crypt).
Please read the following documentation before posting questions in the mailing list. You will be able to ask better questions and better understand the answers.
* [FAQ](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
* LUKS Specifications
* manuals (aka man page, man pages, man-page)
The FAQ is online and in the source code for the project. The Specifications are referenced above in this document. The man pages are in source and should be available after installation using standard man commands. e.g. man cryptsetup
### Mailing List
For cryptsetup and LUKS related questions, please use the dm-crypt mailing list, [dm-crypt@saout.de](mailto:dm-crypt@saout.de). To subscribe send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
You can also browse and/or search the mailing list archives using the following resources:
* [list archive](https://www.saout.de/pipermail/dm-crypt/)
* [web interface on lore.kernel.org](https://lore.kernel.org/dm-crypt/)
* [marc.info](https://marc.info/?l=dm-crypt).

1
TODO
View File

@@ -1 +0,0 @@
Please see issues tracked at https://gitlab.com/cryptsetup/cryptsetup/issues.

View File

@@ -9,25 +9,31 @@ DIE=0
(autopoint --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have autopoint installed."
echo "Download the appropriate package for your distribution,"
echo "or see http://www.gnu.org/software/gettext"
echo "Download the appropriate package for your distribution."
DIE=1
}
(msgfmt --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Warning**: You should have gettext installed."
echo "Download the appropriate package for your distribution."
echo "To disable translation, you can also use --disable-nls"
echo "configure option."
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have autoconf installed to."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
echo "**Error**: You must have autoconf installed."
echo "Download the appropriate package for your distribution."
DIE=1
}
(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
(libtool --version) < /dev/null > /dev/null 2>&1 || {
(grep "^LT_INIT" $srcdir/configure.ac >/dev/null) && {
(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have libtool installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
echo "**Error**: You must have libtoolize installed."
echo "Download the appropriate package for your distribution."
DIE=1
}
}
@@ -35,8 +41,7 @@ DIE=0
(automake --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have automake installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
echo "Download the appropriate package for your distribution."
DIE=1
NO_AUTOMAKE=yes
}
@@ -47,8 +52,6 @@ test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing aclocal. The version of automake"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/"
echo "(or a newer version if it is available)"
DIE=1
}

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.2.0])
AC_INIT([cryptsetup],[2.4.2])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=17:0:5
LIBCRYPTSETUP_VERSION_INFO=19:0:7
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c)
@@ -16,7 +16,7 @@ AC_CONFIG_HEADERS([config.h:config.h.in])
# For old automake use this
#AM_INIT_AUTOMAKE(dist-xz subdir-objects)
AM_INIT_AUTOMAKE([dist-xz 1.12 serial-tests subdir-objects])
AM_INIT_AUTOMAKE([dist-xz 1.12 serial-tests subdir-objects foreign])
if test "x$prefix" = "xNONE"; then
sysconfdir=/etc
@@ -30,9 +30,11 @@ AM_PROG_CC_C_O
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
AC_ENABLE_STATIC(no)
LT_INIT
PKG_PROG_PKG_CONFIG
AM_ICONV
dnl ==========================================================================
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
@@ -56,9 +58,14 @@ dnl ==========================================================================
AC_C_RESTRICT
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
[[
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
]])
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
@@ -108,6 +115,31 @@ AC_FUNC_FSEEKO
AC_PROG_GCC_TRADITIONAL
AC_FUNC_STRERROR_R
dnl ==========================================================================
dnl LUKS2 external tokens
AC_ARG_ENABLE([external-tokens],
AS_HELP_STRING([--disable-external-tokens], [disable external LUKS2 tokens]),
[], [enable_external_tokens=yes])
if test "x$enable_external_tokens" = "xyes"; then
AC_DEFINE(USE_EXTERNAL_TOKENS, 1, [Use external tokens])
dnl we need dynamic library loading here
saved_LIBS=$LIBS
AC_SEARCH_LIBS([dlsym],[dl])
AC_CHECK_FUNCS([dlvsym])
AC_SUBST(DL_LIBS, $LIBS)
LIBS=$saved_LIBS
fi
AC_ARG_ENABLE([ssh-token],
AS_HELP_STRING([--disable-ssh-token], [disable LUKS2 ssh-token]),
[], [enable_ssh_token=yes])
AM_CONDITIONAL(SSHPLUGIN_TOKEN, test "x$enable_ssh_token" = "xyes")
if test "x$enable_ssh_token" = "xyes" -a "x$enable_external_tokens" = "xno"; then
AC_MSG_ERROR([Requested LUKS2 ssh-token build, but external tokens are disabled.])
fi
dnl ==========================================================================
AM_GNU_GETTEXT([external],[need-ngettext])
@@ -169,7 +201,15 @@ AC_DEFINE_UNQUOTED([PASSWDQC_CONFIG_FILE], ["$use_passwdqc_config"], [passwdqc l
if test "x$enable_passwdqc" = "xyes"; then
AC_DEFINE(ENABLE_PASSWDQC, 1, [Enable password quality checking using passwdqc library])
PASSWDQC_LIBS="-lpasswdqc"
saved_LIBS="$LIBS"
AC_SEARCH_LIBS([passwdqc_check], [passwdqc])
case "$ac_cv_search_passwdqc_check" in
no) AC_MSG_ERROR([failed to find passwdqc_check]) ;;
-l*) PASSWDQC_LIBS="$ac_cv_search_passwdqc_check" ;;
*) PASSWDQC_LIBS= ;;
esac
AC_CHECK_FUNCS([passwdqc_params_free])
LIBS="$saved_LIBS"
fi
if test "x$enable_pwquality$enable_passwdqc" = "xyesyes"; then
@@ -348,6 +388,8 @@ AC_CHECK_DECLS([dm_task_retry_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_task_deferred_remove], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_mounted_fs], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_has_holders], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([dm_device_get_name], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_DEVICE_GET_TARGET_VERSION], [], [], [#include <libdevmapper.h>])
AC_CHECK_DECLS([DM_UDEV_DISABLE_DISK_RULES_FLAG], [have_cookie=yes], [have_cookie=no], [#include <libdevmapper.h>])
if test "x$enable_udev" = xyes; then
if test "x$have_cookie" = xno; then
@@ -363,6 +405,17 @@ PKG_CHECK_MODULES([JSON_C], [json-c])
AC_CHECK_DECLS([json_object_object_add_ex], [], [], [#include <json-c/json.h>])
AC_CHECK_DECLS([json_object_deep_copy], [], [], [#include <json-c/json.h>])
dnl Check for libssh and argp for SSH plugin
if test "x$enable_ssh_token" = "xyes"; then
PKG_CHECK_MODULES([LIBSSH], [libssh])
AC_CHECK_DECLS([ssh_session_is_known_server], [], [], [#include <libssh/libssh.h>])
AC_CHECK_HEADER([argp.h], [], AC_MSG_ERROR([You need argp library.]))
saved_LIBS=$LIBS
AC_SEARCH_LIBS([argp_usage],[argp])
AC_SUBST(ARGP_LIBS, $LIBS)
LIBS=$saved_LIBS
fi
dnl Crypto backend configuration.
AC_ARG_WITH([crypto_backend],
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [openssl]]),
@@ -519,6 +572,8 @@ AC_SUBST([JSON_C_LIBS])
AC_SUBST([LIBARGON2_LIBS])
AC_SUBST([BLKID_LIBS])
AC_SUBST([LIBSSH_LIBS])
AC_SUBST([LIBCRYPTSETUP_VERSION])
AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
@@ -574,7 +629,7 @@ if test "x$enable_luks_adjust_xts_keysize" = "xyes"; then
AC_DEFINE(ENABLE_LUKS_ADJUST_XTS_KEYSIZE, 1, [XTS mode - double default LUKS keysize if needed])
fi
CS_STR_WITH([luks2-pbkdf], [Default PBKDF algorithm (pbkdf2 or argon2i/argon2id) for LUKS2], [argon2i])
CS_STR_WITH([luks2-pbkdf], [Default PBKDF algorithm (pbkdf2 or argon2i/argon2id) for LUKS2], [argon2id])
CS_NUM_WITH([luks1-iter-time], [PBKDF2 iteration time for LUKS1 (in ms)], [2000])
CS_NUM_WITH([luks2-iter-time], [Argon2 PBKDF iteration time for LUKS2 (in ms)], [2000])
CS_NUM_WITH([luks2-memory-kb], [Argon2 PBKDF memory cost for LUKS2 (in kB)], [1048576])
@@ -587,7 +642,8 @@ CS_STR_WITH([loopaes-cipher], [cipher for loop-AES mode], [aes])
CS_NUM_WITH([loopaes-keybits],[key length in bits for loop-AES mode], [256])
CS_NUM_WITH([keyfile-size-maxkb],[maximum keyfile size (in KiB)], [8192])
CS_NUM_WITH([passphrase-size-max],[maximum keyfile size (in characters)], [512])
CS_NUM_WITH([integrity-keyfile-size-maxkb],[maximum integritysetup keyfile size (in KiB)], [4])
CS_NUM_WITH([passphrase-size-max],[maximum passphrase size (in characters)], [512])
CS_STR_WITH([verity-hash], [hash function for verity mode], [sha256])
CS_NUM_WITH([verity-data-block], [data block size for verity mode], [4096])
@@ -615,6 +671,15 @@ test -z "$with_luks2_lock_dir_perms" && with_luks2_lock_dir_perms=0700
DEFAULT_LUKS2_LOCK_DIR_PERMS=$with_luks2_lock_dir_perms
AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS)
CS_STR_WITH([luks2-external-tokens-path], [path to directory with LUKSv2 external token handlers (plugins)], [LIBDIR/cryptsetup])
if test -n "$with_luks2_external_tokens_path"; then
CS_ABSPATH([${with_luks2_external_tokens_path}],[with-luks2-external-tokens-path])
EXTERNAL_LUKS2_TOKENS_PATH=$with_luks2_external_tokens_path
else
EXTERNAL_LUKS2_TOKENS_PATH="\${libdir}/cryptsetup"
fi
AC_SUBST(EXTERNAL_LUKS2_TOKENS_PATH)
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) [LUKS2]]),

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.8.8
# Doxyfile 1.9.1
#---------------------------------------------------------------------------
# Project related configuration options
@@ -12,6 +12,7 @@ OUTPUT_DIRECTORY = doxygen_api_docs
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
OUTPUT_TEXT_DIRECTION = None
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
@@ -22,40 +23,47 @@ STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
JAVADOC_BANNER = NO
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
PYTHON_DOCSTRING = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
TCL_SUBST =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = YES
DISTRIBUTE_GROUP_DOC = NO
GROUP_NESTED_COMPOUNDS = NO
SUBGROUPING = YES
INLINE_GROUPED_CLASSES = NO
INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = YES
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_PRIV_VIRTUAL = NO
EXTRACT_PACKAGE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
RESOLVE_UNNAMED_PARAMS = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
@@ -63,6 +71,7 @@ HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
@@ -93,13 +102,14 @@ WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = "doxygen_index.h" \
"../lib/libcryptsetup.h"
INPUT = doxygen_index.h \
../lib/libcryptsetup.h
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
@@ -107,7 +117,7 @@ EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH = "examples"
EXAMPLE_PATH = examples
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
@@ -129,12 +139,13 @@ SOURCE_TOOLTIPS = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
CLANG_ASSISTED_PARSING = NO
CLANG_ADD_INC_PATHS = YES
CLANG_OPTIONS =
CLANG_DATABASE_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
@@ -151,6 +162,7 @@ HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
@@ -180,8 +192,10 @@ GENERATE_TREEVIEW = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE =
USE_MATHJAX = NO
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
@@ -201,11 +215,13 @@ GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
LATEX_MAKEINDEX_CMD = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4
EXTRA_PACKAGES =
LATEX_HEADER =
LATEX_FOOTER =
LATEX_EXTRA_STYLESHEET =
LATEX_EXTRA_FILES =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
@@ -213,6 +229,8 @@ LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
@@ -222,6 +240,7 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -236,6 +255,7 @@ MAN_LINKS = NO
GENERATE_XML = NO
XML_OUTPUT = xml
XML_PROGRAMLISTING = YES
XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
@@ -273,12 +293,10 @@ GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
PERL_PATH =
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
@@ -291,6 +309,8 @@ COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
UML_LIMIT_NUM_FIELDS = 10
DOT_UML_DETAILS = NO
DOT_WRAP_THRESHOLD = 17
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
@@ -305,6 +325,8 @@ DOTFILE_DIRS =
MSCFILE_DIRS =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO

View File

@@ -1,7 +1,7 @@
/*
* An example of using logging through libcryptsetup API
* libcryptsetup API log example
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,10 +25,8 @@
#include <libcryptsetup.h>
/*
* This is an example of function that can be registered using crypt_set_log_callback API.
* This is an example of crypt_set_log_callback API callback.
*
* Its prototype is void (*log)(int level, const char *msg, void *usrptr) as defined
* in crypt_set_log_callback
*/
static void simple_syslog_wrapper(int level, const char *msg, void *usrptr)
{
@@ -71,7 +69,7 @@ int main(void)
return 2;
}
/* crypt_set_log_callback() - register a log function for crypt context */
/* crypt_set_log_callback() - register a log callback for crypt context */
crypt_set_log_callback(cd, &simple_syslog_wrapper, (void *)usrprefix);
/* send messages ithrough the crypt_log() interface */
@@ -83,7 +81,7 @@ int main(void)
/* release crypt context */
crypt_free(cd);
/* Initialize default (global) log function */
/* Initialize default (global) log callback */
crypt_set_log_callback(NULL, &simple_syslog_wrapper, NULL);
crypt_log(NULL, CRYPT_LOG_NORMAL, "This is normal log message");

View File

@@ -1,7 +1,7 @@
/*
* An example of using LUKS device through libcryptsetup API
* libcryptsetup API - using LUKS device example
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,23 +29,18 @@
static int format_and_add_keyslots(const char *path)
{
struct crypt_device *cd;
struct crypt_params_luks1 params;
int r;
/*
* crypt_init() call precedes most of operations of cryptsetup API. The call is used
* to initialize crypt device context stored in structure referenced by _cd_ in
* the example. Second parameter is used to pass underlaying device path.
* The crypt_init() call is used to initialize crypt_device context,
* The path parameter specifies a device path.
*
* Note:
* If path refers to a regular file it'll be attached to a first free loop device.
* crypt_init() operation fails in case there's no more loop device available.
* Also, loop device will have the AUTOCLEAR flag set, so the file loopback will
* be detached automatically.
* For path, you can use either link to a file or block device.
* The loopback device will be detached automatically.
*/
r = crypt_init(&cd, path);
if (r < 0 ) {
if (r < 0) {
printf("crypt_init() failed for %s.\n", path);
return r;
}
@@ -53,73 +48,37 @@ static int format_and_add_keyslots(const char *path)
printf("Context is attached to block device %s.\n", crypt_get_device_name(cd));
/*
* So far no data were written on your device. This will change with call of
* crypt_format() only if you specify CRYPT_LUKS1 as device type.
* So far, no data were written to the device.
*/
printf("Device %s will be formatted to LUKS device after 5 seconds.\n"
printf("Device %s will be formatted as a LUKS device after 5 seconds.\n"
"Press CTRL+C now if you want to cancel this operation.\n", path);
sleep(5);
/*
* Prepare LUKS format parameters
*
* hash parameter defines PBKDF2 hash algorithm used in LUKS header.
* For compatibility reason we use SHA1 here.
*/
params.hash = "sha1";
/*
* data_alignment parameter is relevant only in case of the luks header
* and the payload are both stored on same device.
*
* if you set data_alignment = 0, cryptsetup will autodetect
* data_alignment according to underlaying device topology.
*/
params.data_alignment = 0;
/*
* data_device parameter defines that no external device
* for luks header will be used
*/
params.data_device = NULL;
/*
* NULLs for uuid and volume_key means that these attributes will be
* generated during crypt_format(). Volume key is generated with respect
* to key size parameter passed to function.
*
* crypt_format() checks device size (LUKS header must fit there).
* generated during crypt_format().
*/
r = crypt_format(cd, /* crypt context */
CRYPT_LUKS1, /* LUKS1 is standard LUKS header */
CRYPT_LUKS2, /* LUKS2 is a new LUKS format; use CRYPT_LUKS1 for LUKS1 */
"aes", /* used cipher */
"xts-plain64", /* used block mode and IV generator*/
"xts-plain64", /* used block mode and IV */
NULL, /* generate UUID */
NULL, /* generate volume key from RNG */
256 / 8, /* 256bit key - here AES-128 in XTS mode, size is in bytes */
&params); /* parameters above */
512 / 8, /* 512bit key - here AES-256 in XTS mode, size is in bytes */
NULL); /* default parameters */
if(r < 0) {
if (r < 0) {
printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd));
crypt_free(cd);
return r;
}
/*
* The device now contains LUKS1 header, but there is
* no active keyslot with encrypted volume key yet.
*/
/*
* cryptt_kesylot_add_* call stores volume_key in encrypted form into keyslot.
* Without keyslot you can't manipulate with LUKS device after the context will be freed.
* The device now contains a LUKS header, but there is no active keyslot.
*
* To create a new keyslot you need to supply the existing one (to get the volume key from) or
* you need to supply the volume key.
* crypt_keyslot_add_* call stores the volume_key in the encrypted form into the keyslot.
*
* After format, we have volume key stored internally in context so add new keyslot
* using this internal volume key.
* After format, the volume key is stored internally.
*/
r = crypt_keyslot_add_by_volume_key(cd, /* crypt context */
CRYPT_ANY_SLOT, /* just use first free slot */
@@ -137,8 +96,8 @@ static int format_and_add_keyslots(const char *path)
printf("The first keyslot is initialized.\n");
/*
* Add another keyslot, now using the first keyslot.
* It will decrypt volume key from the first keyslot and creates new one with another passphrase.
* Add another keyslot, now authenticating with the first keyslot.
* It decrypts the volume key from the first keyslot and creates a new one with the specified passphrase.
*/
r = crypt_keyslot_add_by_passphrase(cd, /* crypt context */
CRYPT_ANY_SLOT, /* just use first free slot */
@@ -164,21 +123,18 @@ static int activate_and_check_status(const char *path, const char *device_name)
/*
* LUKS device activation example.
* It's sequence of sub-steps: device initialization, LUKS header load
* and the device activation itself.
*/
r = crypt_init(&cd, path);
if (r < 0 ) {
if (r < 0) {
printf("crypt_init() failed for %s.\n", path);
return r;
}
/*
* crypt_load() is used to load the LUKS header from block device
* into crypt_device context.
* crypt_load() is used to load existing LUKS header from a block device
*/
r = crypt_load(cd, /* crypt context */
CRYPT_LUKS1, /* requested type */
CRYPT_LUKS, /* requested type - here LUKS of any type */
NULL); /* additional parameters (not used) */
if (r < 0) {
@@ -188,11 +144,11 @@ static int activate_and_check_status(const char *path, const char *device_name)
}
/*
* Device activation creates device-mapper devie mapping with name device_name.
* Device activation creates a device-mapper device with the specified name.
*/
r = crypt_activate_by_passphrase(cd, /* crypt context */
device_name, /* device name to activate */
CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */
CRYPT_ANY_SLOT,/* the keyslot use (try all here) */
"foo", 3, /* passphrase */
CRYPT_ACTIVATE_READONLY); /* flags */
if (r < 0) {
@@ -201,13 +157,13 @@ static int activate_and_check_status(const char *path, const char *device_name)
return r;
}
printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name);
printf("%s device %s/%s is active.\n", crypt_get_type(cd), crypt_get_dir(), device_name);
printf("\tcipher used: %s\n", crypt_get_cipher(cd));
printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd));
printf("\tdevice UUID: %s\n", crypt_get_uuid(cd));
/*
* Get info about active device (query DM backend)
* Get info about the active device.
*/
r = crypt_get_active_device(cd, device_name, &cad);
if (r < 0) {
@@ -235,7 +191,7 @@ static int handle_active_device(const char *device_name)
int r;
/*
* crypt_init_by_name() initializes device context and loads LUKS header from backing device
* crypt_init_by_name() initializes context by an active device-mapper name
*/
r = crypt_init_by_name(&cd, device_name);
if (r < 0) {
@@ -252,7 +208,7 @@ static int handle_active_device(const char *device_name)
}
/*
* crypt_deactivate() is used to deactivate device
* crypt_deactivate() is used to deactivate a device
*/
r = crypt_deactivate(cd, device_name);
if (r < 0) {

36
docs/v2.2.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,36 @@
Cryptsetup 2.2.1 Release Notes
==============================
Stable bug-fix release.
This version contains a fix for a possible data corruption bug
on 32-bit platforms.
All users of cryptsetup 2.1 and 2.2 should upgrade to this version.
Changes since version 2.2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix possible data length and IV offset overflow on 32bit architectures.
Other 64-bit architectures are not affected.
The flawed helper function prototypes (introduced in version 2.1.0) used
size_t type, that is 32-bit integer on 32-bit systems.
This patch fixes the problem to properly use 64-bit types.
If the offset parameter addresses devices larger than 2TB, the value
overflows and stores incorrect information in the metadata.
For example, integrity device is smaller than expected size if used
over large disk on 32-bit architecture.
This issue is not present with the standard LUKS1/LUKS2 devices without
integrity extensions.
* Fix a regression in TrueCrypt/VeraCrypt system partition activation.
* Reinstate missing backing file hint for loop device.
If the encrypted device is backed by a file (loopback), cryptsetup now
shows the path to the backing file in passphrase query (as in 1.x version).
* LUKS2 reencryption block size is now aligned to reported optimal IO size.
This change eliminates possible non-aligned device warnings in kernel log
during reencryption.

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

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

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

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

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

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

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

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

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

@@ -0,0 +1,42 @@
Cryptsetup 2.3.3 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.x should upgrade to this version.
Changes since version 2.3.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix BitLocker compatible device access that uses native 4kB sectors.
Devices formatted with storage that natively support 4096-bytes
sectors can also use this sector size for encryption units.
* Support large IV count (--iv-large-sectors) cryptsetup option
for plain device mapping.
The large IV count is supported in dm-crypt together with larger
sector encryption. It counts the Initialization Vector (IV) in
a larger sector size instead of 512-bytes sectors.
This option does not have any performance or security impact,
but it can be used for accessing incompatible existing disk images
from other systems.
Only open action with plain device type and sector size > 512 bytes
are supported.
* Fix a memory leak in BitLocker compatible handling.
* Allow EBOIV (Initialization Vector algorithm) use.
The EBOIV initialization vector is intended to be used internally
with BitLocker devices (for CBC mode). It can now be used also
outside of the BitLocker compatible code.
* Require both keyslot cipher and key size options.
If these LUKS2 keyslot parameters were not specified together,
cryptsetup silently failed.
* Update to man pages and FAQ.

112
docs/v2.3.4-ReleaseNotes Normal file
View File

@@ -0,0 +1,112 @@
Cryptsetup 2.3.4 Release Notes
==============================
Stable bug-fix release with a security fix (32-bit only).
All users of cryptsetup 2.2.x and later should upgrade to this version.
Changes since version 2.3.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix a possible out-of-bounds memory write while validating LUKS2 data
segments metadata (CVE-2020-14382).
This problem can be triggered only on 32-bit builds (64-bit systems
are not affected).
LUKS2 format validation code contains a bug in segments validation code
where the code does not check for possible overflow on memory allocation.
Due to the bug, the libcryptsetup can be tricked to expect such allocation
was successful. Later it may read data from image crafted by an attacker and
actually write such data beyond allocated memory.
The bug was introduced in cryptsetup 2.2.0. All later releases until 2.3.4
are affected.
If you only backport the fix for this CVE, these master branch git commits
should be backported:
52f5cb8cedf22fb3e14c744814ec8af7614146c7
46ee71edcd13e1dad50815ad65c28779aa6f7503
752c9a52798f11d3b765b673ebaa3058eb25316e
Thanks to Tobias Stoeckmann for discovering this issue.
* Ignore reported optimal IO size if not aligned to minimal page size.
Some USB enclosures report bogus block device topology (see lsblk -t) that
prevents LUKS2 format with 4k sector size (reported values are not correctly
aligned). The code now ignores such values and uses the default alignment.
* Added support for new no_read/write_wrokqueue dm-crypt options (kernel 5.9).
These performance options, introduced in kernel 5.9, configure dm-crypt
to bypass read or write workqueues and run encryption synchronously.
Use --perf-no_read_workqueue or --perf-no_write_workqueue cryptsetup arguments
to use these dm-crypt flags.
These options are available only for low-level dm-crypt performance tuning,
use only if you need a change to default dm-crypt behavior.
For LUKS2, these flags can be persistently stored in metadata with
the --persistent option.
* Added support panic_on_corruption option for dm-verity devices (kernel 5.9).
Veritysetup now supports --panic-on-corruption argument that configures
the dm-verity device to panics kernel if a corruption is detected.
This option is intended for specific configurations, do not use it in
standard configurations.
* Support --master-key-file option for online LUKS2 reencryption
This can be used for reencryption of devices that uses protected key AES cipher
on some mainframes crypto accelerators.
* Always return EEXIST error code if a device already exists.
Some libcryptsetup functions (activate_by*) now return EEXIST error code,
so the caller can distinguish that call fails because some parallel process
already activated the device.
Previously all fails returned EINVAL (invalid value).
* Fix a problem in integritysetup if a hash algorithm has dash in the name.
If users want to use blake2b/blake2s, the kernel algorithm name includes
a dash (like "blake2s-256").
Theses algorithms can now be used for integritysetup devices.
* Fix crypto backend to properly handle ECB mode.
Even though it should never be used, it should still work for testing :)
This fixes a bug introduced in cryptsetup version 2.3.2.
* TrueCrypt/VeraCrypt compatible mode now supports the activation of devices
with a larger sector.
TrueCrypt/VeraCrypt always uses 512-byte sector for encryption, but for devices
with a larger native sector, it stores this value in the header.
This patch allows activation of such devices, basically ignoring
the mentioned sector size.
* LUKS2: Do not create excessively large headers.
When creating a LUKS2 header with a specified --offset larger than
the LUKS2 header size, do not create a larger file than needed.
* Fix unspecified sector size for BitLocker compatible mode.
Some BitLocker devices can contain zeroed sector size in the header.
In this case, the 512-byte sector should be used.
The bug was introduced in version 2.3.3.
* Fix reading key data size in metadata for BitLocker compatible mode.
Such devices with an unexpected entry in metadata can now be activated.
Thanks to all users reporting these problems, BitLocker metadata documentation
is not publicly available, and we depend only on these reports.
* Fix typos in documentation.

181
docs/v2.3.5-ReleaseNotes Normal file
View File

@@ -0,0 +1,181 @@
Cryptsetup 2.3.5 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.x and later should upgrade to this version.
Changes since version 2.3.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix partial reads of passphrase from an interactive terminal.
Some stable kernels (5.3.11) started to return buffer from a terminal
in parts of maximal size 64 bytes.
This breaks the reading of passphrases longer than 64 characters
entered through an interactive terminal. The change is already fixed
in later kernel releases, but tools now support such partial read from
terminal properly.
* Fix maximal length of password entered through a terminal.
Now the maximal interactive passphrase length is exactly
512 characters (not 511).
* integritysetup: support new dm-integrity HMAC recalculation options.
In older kernels (since version 4.19), an attacker can force
an automatic recalculation of integrity tags by modifying
the dm-integrity superblock.
This is a problem with a keyed algorithms (HMAC), where it expects
nobody can trigger such recalculation without the key.
(Automatic recalculation will start after the next activation.)
Note that dm-integrity in standalone mode was *not* supposed
to provide cryptographic data integrity protection.
Despite that, we try to keep the system secure if keyed algorithms
are used.
Thank Daniel Glöckner for the original report of this problem.
Authenticated encryption that provides data integrity protection (in
combination with dm-crypt and LUKS2) is not affected by this problem.
The fix in the kernel for this problem contains two parts.
Firstly, the dm-integrity kernel module disables integrity
recalculation if keyed algorithms (HMAC) are used.
This change is included in long-term stable kernels.
Secondly, since the kernel version 5.11, dm-integrity introduces
modified protection where a journal-integrity algorithm guards
superblock; also, journal sections are protected. An attacker cannot
copy sectors from one journal section to another, and the superblock
also contains salt to prevent header replacement from another device.
If you want to protect data with HMAC, you should always also use HMAC
for --journal-integrity. Keys can be independent.
If HMAC is used for data but not for the journal, the recalculation
option is disabled.
If you need to use (insecure) backward compatibility implementation,
two new integritysetup options are introduced:
- Use --integrity-legacy-recalc (instead of --integrity-recalc)
to allow recalculation on legacy devices.
- Use --integrity-legacy-hmac in format action to force old insecure
HMAC format.
Libcryptsetup API also introduces flags
CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC and
CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC
to set these through crypt_set_compatibility() call.
* integritysetup: display of recalculating sector in dump command.
* veritysetup: fix verity FEC if stored in the same image with hashes.
Optional FEC (Forward Error Correction) data should cover the whole
data area, hashes (Merkle tree), and optionally additional metadata
(located after hash area).
Unfortunately, if FEC data is stored in the same file as hash,
the calculation wrongly used the whole file size, thus overlaps with
the FEC area itself. This produced unusable and too large FEC data.
There is no problem if the FEC image is a separate image.
The problem is now fixed, introducing FEC blocks calculation as:
- If the hash device is in a separate image, metadata covers the
whole rest of the image after the hash area. (Unchanged behavior.)
- If hash and FEC device is in the image, metadata ends on the FEC
area offset.
Note: there is also a fix for FEC in the dm-verity kernel (on the way
to stable kernels) that fixes error correction with larger RS roots.
* veritysetup: run FEC repair check even if root hash fails.
Note: The userspace FEC verify command reports are only informational
for now. Code does not check verity hash after FEC recovery in
userspace. The Reed-Solomon decoder can then report the possibility
that it fixed data even if parity is too damaged.
This will be fixed in the next major release.
* veritysetup: do not process hash image if hash area is empty.
Sometimes the device is so small that there is only a root hash
needed, and the hash area is not used.
Also, the size of the hash image is not increased for hash block
alignment in this case.
* veritysetup: store verity hash algorithm in superblock in lowercase.
Otherwise, the kernel could refuse the activation of the device.
* bitlk: fix a crash if the device disappears during BitLocker scan.
* bitlk: show a better error when trying to open an NTFS device.
Both BitLocker version 1 and NTFS have the same signature.
If a user opens an NTFS device without BitLocker, it now correctly
informs that it is not a BITLK device.
* bitlk: add support for startup key protected VMKs.
The startup key can be provided in --key-file option for open command.
* Fix LUKS1 repair code (regression since version 1.7.x).
We cannot trust possibly broken keyslots metadata in repair, so the
code recalculates them instead.
This makes the repair code working again when the master boot record
signature overwrites the LUKS header.
* Fix luksKeyChange for LUKS2 with assigned tokens.
The token references are now correctly assigned to the new keyslot
number.
* Fix cryptsetup resize using LUKS2 tokens.
Code needlessly asked for passphrase even though volume key was
already unlocked via LUKS2 token.
* Print a visible error if device resize is not supported.
* Add error message when suspending wrong non-LUKS device.
* Fix default XTS mode key size in reencryption.
The same luksFormat logic (double key size because XTS uses two keys)
is applied in the reencryption code.
* Rephrase missing locking directory warning and move it to debug level.
The system should later provide a safe transition to tempdir
configuration, so creating locking directory inside libcryptsetup
call is safe.
* Many fixes for the use of cipher_null (empty debug cipher).
Support for this empty cipher was intended as a debug feature and for
measuring performance overhead. Unfortunately, many systems started to
use it as an "empty shell" for LUKS (to enable encryption later).
This use is very dangerous and it creates a false sense of security.
Anyway, to not break such systems, we try to support these
configurations.
Using cipher_null in any production system is strongly discouraged!
Fixes include:
- allow LUKS resume for a device with cipher_null.
- do not upload key in keyring when data cipher is null.
- switch to default cipher when reencrypting cipher_null device.
- replace possible bogus cipher_null keyslots before reencryption.
- fix broken detection of null cipher in LUKS2.
cipher_null is no longer possible to be used in keyslot encryption
in LUKS2, it can be used only for data for debugging purposes.
* Fixes for libpasswdqc 2.0.x (optional passphrase quality check).
* Fixes for problems discovered by various tools for code analysis.
Fixes include a rework of libpopt command line option string leaks.
* Various fixes to man pages.

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

@@ -0,0 +1,56 @@
Cryptsetup 2.3.6 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.x and later should upgrade to this version.
Changes since version 2.3.5
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* integritysetup: Fix possible dm-integrity mapping table truncation.
While integritysetup in standalone mode (no encryption) was not
designed to provide keyed (and cryptographically strong) data
integrity protection, some options can use such algorithms (HMAC).
If a key is used, it is directly sent to the kernel dm-integrity as
a mapping table option (no key derivation is performed).
For HMAC, such a key could be quite long (up to 4096 bytes in
integritysetup CLI).
Unfortunately, due to fixed buffers and not correctly checking string
truncation, some parameter combinations could cause truncation
of the dm-integrity mapping table.
In most cases, the table was rejected by the kernel.
The worst possible case was key truncation for HMAC options
(internal_hash and journal_mac dm-integrity table options).
This release fixes possible truncation and also adds more sanity
checks to reject truncated options.
Also, integritysetup now mentions maximal allowed key size
in --help output.
For old standalone dm-integrity devices where the key length was
truncated, you have to modify (shorten) --integrity-key-size
resp. --journal-integrity-key-size option now.
This bug is _not_ present for dm-crypt/LUKS, LUKS2 (including
integrity protection), or dm-verity devices; it affects only
standalone dm-integrity with HMAC integrity protection.
* cryptsetup: Backup header can be used to activate TCRYPT device.
Use --header option to specify the header.
* cryptsetup: Avoid LUKS2 decryption without detached header.
This feature will be added later and is currently not supported.
* Additional fixes and workarounds for common warnings produced
by some static analysis tools (like gcc-11 analyzer) and additional
code hardening.
* Fix standalone libintl detection for compiled tests.
* Add Blake2b and Blake2s hash support for crypto backends.
Kernel and gcrypt crypto backend support all variants.
OpenSSL supports only Blake2b-512 and Blake2s-256.
Crypto backend supports kernel notation e.g. "blake2b-512".

302
docs/v2.4.0-ReleaseNotes Normal file
View File

@@ -0,0 +1,302 @@
Cryptsetup 2.4.0 Release Notes
==============================
Stable release with new features and bug fixes.
This version introduces support for external libraries
(plugins) for handling LUKS2 token objects.
Changes since version 2.3.6
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* External LUKS token plugins
A LUKS2 token is an object that can describe how to get a passphrase
to unlock a particular keyslot. The generic metadata format is part
of the LUKS2 specification.
Cryptsetup 2.4 adds the possibility to implement token handlers
in external libraries (possibly provided by other projects).
A token library allows cryptsetup to understand metadata and provide
basic operations. Currently external tokens may be used to unlock
keyslots for following CLI actions: open (luksOpen),
refresh (open --refresh), resize and dump (prints token specific
content).
LUKS2 devices cannot be resumed (luksResume action) via tokens yet.
Support for resume and other actions will be added later.
The library now provides an interface that automatically tries to load
an external library for a token object in LUKS2 metadata.
Token libraries should be installed in the cryptsetup subdirectory
(usually /lib*/cryptsetup). This path is configurable through
--with-luks2-external-tokens-path configure option.
The external plugin loading can be compiled entirely out if
--disable-external-tokens configure option is used. The external token
interface can also be disabled runtime on the command line by
--disable-external-tokens cryptsetup switch or by calling
crypt_token_external_disable() API function.
The name of the loaded token library is determined from the JSON LUKS
metadata token object type. For example, "ssh" token will load library
"libcryptsetup-token-ssh.so".
External projects can use this interface to handle specific hardware
without introducing additional dependencies to libcryptsetup core.
As of cryptsetup 2.4.0 release systemd project already merged upstream
native cryptsetup token handler for its systemd-tpm2 LUKS2 token
released originally in systemd-v248. The token can be created using
systemd-cryptenroll utility and devices may be manipulated either by
systemd-cryptsetup cli or by cryptsetup for actions listed above.
Other tokens like systemd-fido2 and systemd-pkcs11 are currently
in-review.
* Experimental SSH token
As a demonstration of the external LUKS2 token interface, a new SSH
token handler and cryptsetup-ssh utility is now provided and compiled
by default.
Crypsetup SSH token allows using remote keyfile through SSH protocol
(it will authenticate through SSH certificates).
You can disable the build of this token library with
--disable-ssh-token configure option.
To configure the token metadata, you need cryptsetup-ssh utility.
Activation of the device is then performed by the cryptsetup utility.
Example (how to activate LUKS2 through remote keyfile):
- configure existing LUKS2 device with keyslot activated by a keyfile
# cryptsetup luksAddKey <device> keyfile --key-slot 2
- store that keyfile on a remote system accessible through SSH
- configure SSH to use certificate for authentication
- add a LUKS2 token with cryptsetup-ssh utility:
# cryptsetup-ssh add <device>1 --key-slot 2 \
--ssh-server test-vm \
--ssh-user test \
--ssh-path /home/test/keyfile \
--ssh-keypath /home/test/.ssh/test_rsa_key
- you should see token metadata now with "cryptsetup luksDump ..."
...
Tokens:
0: ssh
ssh_server: test-vm
ssh_user: test
ssh_path: /home/test/keyfile
ssh_key_path: /home/test/.ssh/test_rsa_key
Keyslot: 2
- activation now should be automatic
# cryptsetup open <device> test --verbose
SSH token initiating ssh session.
Key slot 2 unlocked.
Command successful.
- to remove a token, you can use "cryptsetup token remove" command
(no plugin library required)
Please note SSH token is just demonstration of plugin interface API,
it is an EXPERIMENTAL feature.
* Add cryptsetup --token-type parameter.
It restricts token type to the parameter value in case no specific
token-id is selected.
* Support for token based activation with PIN.
If specific token requires PIN to unlock keyslot passphrase and
--token-only parameter was used cryptsetup asks for additional
token PIN.
* Respect keyslot priority with token-based activation.
* Default LUKS2 PBKDF is now Argon2id
Cryptsetup LUKS2 was using Argon2 while there were two versions,
data-independent (Argon2i) suitable for the KDF use case and
Argon2d (data-dependent). Later Argon2id was introduced as a new
mandatory algorithm.
We switched the password-based key derivation algorithms
following the latest version of Argon2 RFC draft
(https://datatracker.ietf.org/doc/draft-irtf-cfrg-argon2/) to Argon2id
(from Argon2i) as it is the mandatory and primary version
of the Argon2 algorithm.
There is no need to modify older containers; the main reason is that
RFC makes Argon2id the primary variant, while Argon2i subvariant is
only optional.
Argon2id provides better protection to side-channel attacks while
still providing protection to time-memory tradeoffs.
We will switch to OpenSSL implementation once it is available.
With a crystal ball as a reference, it could happen early in
OpenSSL 3.1 release.
Watch https://github.com/openssl/openssl/issues/4091.
* Increase minimal memory cost for Argon2 benchmark to 64MiB.
This patch increases the benchmarking value to 64 MiB (as minimal
suggested values in Argon2 RFC). For compatibility reasons, we still
allow older limits if set by a parameter.
NOTE: Argon2 RFC draft defines suggested parameters for disk
encryption, but the LUKS2 approach is slightly different. We need to
provide platform-independent values. The values in the draft expect
64bit systems (suggesting using 6 GiB of RAM). In comparison, we need
to provide compatibility with all 32bit systems, so allocating more
than 4GiB memory is not an option for LUKS2.
The maximal limit in LUKS2 stays for 4 GiB, and by default LUKS2 PBKDF
benchmarking sets maximum to 1 GIB, preferring an increase of CPU cost
while running benchmark
* Autodetect optimal encryption sector size on LUKS2 format.
While the support for larger encryption sectors is supported
for several releases, it required an additional parameter.
Code now uses automatic detection of 4096-bytes native sector devices
and automatically enables 4096-bytes encryption size for LUKS2.
If no setor size option is used, sector size is detected
automatically by cryptsetup. For libcryptsetup API, autodetection
happens once you specify sector_size to 0.
NOTE: crypt_format() function runs autodetection ONLY if you
recompile your application to the new API symbol version.
For backward compatibility, older applications ignore this parameter.
* Use VeraCrypt option by default and add --disable-veracrypt option.
While TrueCrypt is no longer developed and supported since 2014,
VeraCrypt devices (a successor of TrueCrypt) are much more used today.
Default is now to support VeraCrypt format (in addition to TrueCrypt),
making the --veracrypt option obsolete (ignored as it is the default).
If you need to disable VeraCrypt support, use the new option
--disable-veracrypt.
This option increases the time to recognize wrong passwords because
some VeraCrypt modes use a high PBKDF2 iteration count, and the code
must try all variants. This could be limited by using --hash and
--cipher options mentioned below.
* Support --hash and --cipher to limit opening time for TCRYPT type
If a user knows which particular PBKDF2 hash or cipher is used for
TrueCrypt/VeraCrypt container, TCRYPT format now supports --hash and
--cipher option.
Note the value means substring (all cipher chains containing
the cipher substring are tried).
For example, you can use
# cryptsetup tcryptDump --hash sha512 <container>
Note: to speed up the scan, the hash option (used for PBKDF)2 matters.
Cipher variants are scanned very quickly.
Use with care.
It can reveal some sensitive attributes of the container!
* Fixed default OpenSSL crypt backend support for OpenSSL3.
For OpenSSL version 3, we need to load legacy provider for older hash
and ciphers. For example, RIPEMD160 and Whirlpool hash algorithms are
no longer available by default.
NOTE: the plain format still uses RIPEMD160 for password hashing by
default. Changing the default would cause incompatibilities for many
old systems. Nevertheless, such a change will be needed very soon.
* integritysetup: add integrity-recalculate-reset flag.
The new dm-integrity option in kernel 5.13 can restart recalculation
from the beginning of the device.
It can be used to change the integrity checksum function.
New integritysetup --integrity-recalculate-reset option is added to
integritysetup, and CRYPT_ACTIVATE_RECALCULATE_RESET flag to API.
* cryptsetup: retains keyslot number in luksChangeKey for LUKS2.
In LUKS1, any change in keyslot means keyslot number change.
In LUKS2, we can retain the keyslot number.
Now luksKeyChange and crypt_keyslot_change_by_passphrase() API
retains keyslot number for LUKS2 by default.
* Fix cryptsetup resize using LUKS2 tokens.
Fix a bug where cryptsetup needlessly asked for a passphrase even
though the volume key was already unlocked via LUKS2 token.
* Add close --deferred and --cancel-deferred options.
All command-line utilities now understand deferred options for the
close command. Deferred close means that the device is removed
automagically after the last user closed the device.
Cancel deferred means to cancel this operation (so the device remains
active even if there a no longer active users).
CRYPT_DEACTIVATE_DEFERRED and CRYPT_DEACTIVATE_DEFERRED_CANCEL flags
are now available for API.
* Rewritten command-line option parsing to avoid libpopt arguments
memory leaks.
Note: some distributions use patched lipopt that still leaks memory
inside internal code (see Debian bug 941814).
* Add --test-args option.
New --test-args option can be used for syntax checking for valid
command-line arguments with no actions performed.
Note that it cannot detect unknown algorithm names and similar where
we need call API functions.
* veritysetup: add --root-hash-file option
Allow passing the root hash via a file, rather than verbatim on
the command line, for the open, verify, and format actions.
* libcryptsetup C API extensions (see libcryptsetup.h for details)
- crypt_logf - a printf like log function
- crypt_dump_json - dump LUKS2 metadata in JSON format
- crypt_header_is_detached - check if context use detached header
- crypt_token_max - get maximal tokens number
- crypt_token_external_path - get path for plugins (or NULL)
- crypt_token_external_disable - disable runtime support for plugins
- crypt_activate_by_token_pin - activate by token with additional PIN
- crypt_reencrypt_run - fixed API for deprecated crypt_reencrypt
The token plugin library interface cosists from these versioned
exported symbols (for details see header file and SSH token example):
cryptsetup_token_open
cryptsetup_token_open_pin
cryptsetup_token_buffer_free
cryptsetup_token_validate
cryptsetup_token_dump
cryptsetup_token_version
Since version 2.4 libcryptsetup uses exact symbol versioning
Newly introduced functions have CRYPTSETUP_2.4 namespace (the old
symbol always used CRYPTSETUP_2.0).
There is no change in soname (the library is backward compatible).
* Many fixes and additions to documentation and man pages.

47
docs/v2.4.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,47 @@
Cryptsetup 2.4.1 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.4.0 should upgrade to this version.
Changes since version 2.4.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix compilation for libc implementations without dlvsym().
Some alternative libc implementations (like musl) do not provide
versioned symbols dlvsym function. Code now fallbacks to dlsym
operation for dynamic LUKS2 token load.
It is up to maintainers to ensure that LUKS2 token plugins are
compiled for the supported version.
* Fix compilation and tests on systems with non-standard libraries
(standalone argp library, external gettext library, BusyBox
implementations of standard tools).
* Try to workaround some issues on systems without udev support.
NOTE: non-udev systems cannot provide all functionality for kernel
device-mapper, and some operations can fail.
* Fixes for OpenSSL3 crypto backend (including FIPS mode).
Because cryptsetup still requires some hash functions implemented
in OpenSSL3 legacy provider, crypto backend now uses its library
context and tries to load both default and legacy OpenSSL3 providers.
If FIPS mode is detected, no library context is used, and it is up
to the OpenSSL system-wide policy to load proper providers.
NOTE: We still use some deprecated API in the OpenSSL3 backend,
and there are some known problems in OpenSSL 3.0.0.
* Print error message when assigning a token to an inactive keyslot.
* Fix offset bug in LUKS2 encryption code if --offset option was used.
* Do not allow LUKS2 decryption for devices with data offset.
Such devices cannot be used after decryption.
* Fix LUKS1 cryptsetup repair command for some specific problems.
Repair code can now fix wrongly used initialization vector
specification in ECB mode (that is insecure anyway!) and repair
the upper-case hash specification in the LUKS1 header.

37
docs/v2.4.2-ReleaseNotes Normal file
View File

@@ -0,0 +1,37 @@
Cryptsetup 2.4.2 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.4.1 should upgrade to this version.
Changes since version 2.4.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix possible large memory allocation if LUKS2 header size is invalid.
LUKS2 code read the full header to buffer to verify the checksum.
The maximal supported header size now limits the memory allocation.
* Fix memory corruption in debug message printing LUKS2 checksum.
* veritysetup: remove link to the UUID library for the static build.
* Remove link to pwquality library for integritysetup and veritysetup.
These tools do not read passphrases.
* OpenSSL3 backend: avoid remaining deprecated calls in API.
Crypto backend no longer use API deprecated in OpenSSL 3.0
* Check if kernel device-mapper create device failed in an early phase.
This happens when a concurrent creation of device-mapper devices
meets in the very early state.
* Do not set compiler optimization flag for Argon2 KDF if the memory
wipe is implemented in libc.
* Do not attempt to unload LUKS2 tokens if external tokens are disabled.
This allows building a static binary with --disable-external-tokens.
* LUKS convert: also check sysfs for device activity.
If udev symlink is missing, code fallbacks to sysfs scan to prevent
data corruption for the active device.

View File

@@ -1,11 +1,11 @@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = lib/libcryptsetup.pc
pkgconfig_DATA += lib/libcryptsetup.pc
lib_LTLIBRARIES = libcryptsetup.la
lib_LTLIBRARIES += libcryptsetup.la
noinst_LTLIBRARIES += libutils_io.la
include_HEADERS = lib/libcryptsetup.h
include_HEADERS += lib/libcryptsetup.h
EXTRA_DIST += lib/libcryptsetup.pc.in lib/libcryptsetup.sym
@@ -15,14 +15,7 @@ libutils_io_la_SOURCES = \
lib/utils_io.c \
lib/utils_io.h
libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS) \
-I $(top_srcdir)/lib/crypto_backend \
-I $(top_srcdir)/lib/luks1 \
-I $(top_srcdir)/lib/luks2 \
-I $(top_srcdir)/lib/loopaes \
-I $(top_srcdir)/lib/verity \
-I $(top_srcdir)/lib/tcrypt \
-I $(top_srcdir)/lib/integrity
libcryptsetup_la_CPPFLAGS = $(AM_CPPFLAGS)
libcryptsetup_la_DEPENDENCIES = libutils_io.la libcrypto_backend.la lib/libcryptsetup.sym
@@ -39,6 +32,9 @@ libcryptsetup_la_LIBADD = \
@LIBARGON2_LIBS@ \
@JSON_C_LIBS@ \
@BLKID_LIBS@ \
@DL_LIBS@ \
$(LTLIBICONV) \
$(LTLIBINTL) \
libcrypto_backend.la \
libutils_io.la
@@ -48,6 +44,8 @@ libcryptsetup_la_SOURCES = \
lib/bitops.h \
lib/nls.h \
lib/libcryptsetup.h \
lib/libcryptsetup_macros.h \
lib/libcryptsetup_symver.h \
lib/utils.c \
lib/utils_benchmark.c \
lib/utils_crypt.c \
@@ -64,6 +62,7 @@ libcryptsetup_la_SOURCES = \
lib/utils_device_locking.c \
lib/utils_device_locking.h \
lib/utils_pbkdf.c \
lib/utils_safe_memory.c \
lib/utils_storage_wrappers.c \
lib/utils_storage_wrappers.h \
lib/libdevmapper.c \
@@ -74,7 +73,7 @@ libcryptsetup_la_SOURCES = \
lib/base64.h \
lib/base64.c \
lib/integrity/integrity.h \
lib/integrity/integrity.c \
lib/integrity/integrity.c \
lib/loopaes/loopaes.h \
lib/loopaes/loopaes.c \
lib/tcrypt/tcrypt.h \
@@ -90,7 +89,7 @@ libcryptsetup_la_SOURCES = \
lib/verity/verity.h \
lib/verity/rs_encode_char.c \
lib/verity/rs_decode_char.c \
lib/verity/rs.h \
lib/verity/rs.h \
lib/luks2/luks2_disk_metadata.c \
lib/luks2/luks2_json_format.c \
lib/luks2/luks2_json_metadata.c \
@@ -107,4 +106,6 @@ libcryptsetup_la_SOURCES = \
lib/luks2/luks2_internal.h \
lib/luks2/luks2.h \
lib/utils_blkid.c \
lib/utils_blkid.h
lib/utils_blkid.h \
lib/bitlk/bitlk.h \
lib/bitlk/bitlk.c

1443
lib/bitlk/bitlk.c Normal file

File diff suppressed because it is too large Load Diff

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

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

View File

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

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
@@ -450,6 +450,8 @@ const char *argon2_error_message(int error_code) {
size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
uint32_t saltlen, uint32_t hashlen, argon2_type type) {
if (!argon2_type2string(type, 0))
return 0;
return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.
@@ -120,18 +120,24 @@ void free_memory(const argon2_context *context, uint8_t *memory,
}
}
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
#if defined(_MSC_VER) && VC_GE_2005(_MSC_VER)
void secure_wipe_memory(void *v, size_t n) {
SecureZeroMemory(v, n);
}
#elif defined memset_s
void secure_wipe_memory(void *v, size_t n) {
memset_s(v, n, 0, n);
}
#elif defined(HAVE_EXPLICIT_BZERO)
void secure_wipe_memory(void *v, size_t n) {
explicit_bzero(v, n);
}
#else
void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) {
static void *(*const volatile memset_sec)(void *, int, size_t) = &memset;
memset_sec(v, 0, n);
#endif
}
#endif
/* Memory clear flag defaults to true. */
int FLAG_clear_internal_memory = 1;

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

@@ -8,8 +8,8 @@
* License/Waiver or the Apache Public License 2.0, at your option. The terms of
* these licenses can be found at:
*
* - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
* - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
* - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
*
* You should have received a copy of both of these licenses along with this
* software. If not, they may be obtained at the above URLs.

View File

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

View File

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

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel cipher generic utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2019 Milan Broz
* Copyright (C) 2018-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,6 @@ struct cipher_alg {
bool wrapped_key;
};
/* FIXME: Getting block size should be dynamic from cipher backend. */
static const struct cipher_alg cipher_algs[] = {
{ "cipher_null", NULL, 16, false },
{ "aes", NULL, 16, false },
@@ -51,6 +50,7 @@ static const struct cipher_alg cipher_algs[] = {
{ "paes", NULL, 16, true }, /* protected AES, s390 wrapped key scheme */
{ "xchacha12,aes", "adiantum", 32, false },
{ "xchacha20,aes", "adiantum", 32, false },
{ "sm4", NULL, 16, false },
{ NULL, NULL, 0, false }
};
@@ -72,7 +72,13 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
{
const struct cipher_alg *ca = _get_alg(name, mode);
return ca ? ca->blocksize : -EINVAL;
if (!ca)
return -EINVAL;
if (mode && !strcasecmp(mode, "ecb"))
return 0;
return ca->blocksize;
}
int crypt_cipher_wrapped_key(const char *name, const char *mode)

View File

@@ -19,7 +19,7 @@
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way,
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to hight-bit; and the result is transmission bit
* sends each low-bit to high-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly.
*

View File

@@ -1,8 +1,8 @@
/*
* crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,13 +26,12 @@
#include <stddef.h>
#include <string.h>
struct crypt_device;
struct crypt_hash;
struct crypt_hmac;
struct crypt_cipher;
struct crypt_storage;
int crypt_backend_init(struct crypt_device *ctx);
int crypt_backend_init(bool fips);
void crypt_backend_destroy(void);
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
@@ -63,7 +62,7 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips);
/* PBKDF*/
struct crypt_pbkdf_limits {
uint32_t min_iterations, max_iterations;
uint32_t min_memory, max_memory;
uint32_t min_memory, max_memory, min_bench_memory;
uint32_t min_parallel, max_parallel;
};
@@ -110,7 +109,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
/* Storage encryption wrappers */
int crypt_storage_init(struct crypt_storage **ctx, size_t sector_size,
const char *cipher, const char *cipher_mode,
const void *key, size_t key_length);
const void *key, size_t key_length, bool large_iv);
void crypt_storage_destroy(struct crypt_storage *ctx);
int crypt_storage_decrypt(struct crypt_storage *ctx, uint64_t iv_offset,
uint64_t length, char *buffer);
@@ -119,6 +118,12 @@ int crypt_storage_encrypt(struct crypt_storage *ctx, uint64_t iv_offset,
bool crypt_storage_kernel_only(struct crypt_storage *ctx);
/* Temporary Bitlk helper */
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
/* Memzero helper (memset on stack can be optimized out) */
static inline void crypt_backend_memzero(void *s, size_t n)
{

View File

@@ -1,8 +1,8 @@
/*
* crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,6 @@
#include "crypto_backend.h"
#if USE_INTERNAL_PBKDF2
/* internal PBKDF2 implementation */
int pkcs5_pbkdf2(const char *hash,
const char *P, size_t Plen,
@@ -31,7 +30,6 @@ int pkcs5_pbkdf2(const char *hash,
unsigned int c,
unsigned int dkLen, char *DK,
unsigned int hash_block_size);
#endif
/* Argon2 implementation wrapper */
int argon2(const char *type, const char *password, size_t password_length,
@@ -55,5 +53,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length);
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,6 +40,10 @@
#define SOL_ALG 279
#endif
#ifndef ALG_SET_AEAD_AUTHSIZE
#define ALG_SET_AEAD_AUTHSIZE 5
#endif
/*
* ciphers
*
@@ -49,7 +53,7 @@
*/
static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
const void *key, size_t key_length,
struct sockaddr_alg *sa)
size_t tag_length, struct sockaddr_alg *sa)
{
if (!ctx)
return -EINVAL;
@@ -71,6 +75,11 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
return -EINVAL;
}
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, tag_length) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
ctx->opfd = accept(ctx->tfmfd, NULL, 0);
if (ctx->opfd < 0) {
crypt_cipher_destroy_kernel(ctx);
@@ -87,18 +96,22 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
.salg_family = AF_ALG,
.salg_type = "skcipher",
};
int r;
if (!strcmp(name, "cipher_null"))
key_length = 0;
snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name), "%s(%s)", mode, name);
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
return -EINVAL;
return _crypt_cipher_init(ctx, key, key_length, &sa);
return _crypt_cipher_init(ctx, key, key_length, 0, &sa);
}
/* The in/out should be aligned to page boundary */
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *in, size_t in_length,
char *out, size_t out_length,
const char *iv, size_t iv_length,
uint32_t direction)
{
@@ -109,7 +122,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
uint32_t *type;
struct iovec iov = {
.iov_base = (void*)(uintptr_t)in,
.iov_len = length,
.iov_len = in_length,
};
int iv_msg_size = iv ? CMSG_SPACE(sizeof(*alg_iv) + iv_length) : 0;
char buffer[CMSG_SPACE(sizeof(*type)) + iv_msg_size];
@@ -120,7 +133,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
.msg_iovlen = 1,
};
if (!in || !out || !length)
if (!in || !out || !in_length)
return -EINVAL;
if ((!iv && iv_length) || (iv && !iv_length))
@@ -142,6 +155,9 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
/* Set IV */
if (iv) {
header = CMSG_NXTHDR(&msg, header);
if (!header)
return -EINVAL;
header->cmsg_level = SOL_ALG;
header->cmsg_type = ALG_SET_IV;
header->cmsg_len = iv_msg_size;
@@ -151,15 +167,14 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
}
len = sendmsg(ctx->opfd, &msg, 0);
if (len != (ssize_t)length) {
if (len != (ssize_t)(in_length))
r = -EIO;
goto bad;
else {
len = read(ctx->opfd, out, out_length);
if (len != (ssize_t)out_length)
r = -EIO;
}
len = read(ctx->opfd, out, length);
if (len != (ssize_t)length)
r = -EIO;
bad:
crypt_backend_memzero(buffer, sizeof(buffer));
return r;
}
@@ -168,7 +183,7 @@ int crypt_cipher_encrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return _crypt_cipher_crypt(ctx, in, out, length,
return _crypt_cipher_crypt(ctx, in, length, out, length,
iv, iv_length, ALG_OP_ENCRYPT);
}
@@ -176,7 +191,7 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return _crypt_cipher_crypt(ctx, in, out, length,
return _crypt_cipher_crypt(ctx, in, length, out, length,
iv, iv_length, ALG_OP_DECRYPT);
}
@@ -217,7 +232,10 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
}
salg_type = aead ? "aead" : "skcipher";
snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type);
r = snprintf((char *)sa.salg_type, sizeof(sa.salg_type), "%s", salg_type);
if (r < 0 || (size_t)r >= sizeof(sa.salg_name))
return -EINVAL;
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
/* FIXME: this is duplicating a part of devmapper backend */
@@ -230,7 +248,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
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))
if (r < 0 || (size_t)r >= sizeof(tmp_salg_name))
return -EINVAL;
memcpy(sa.salg_name, tmp_salg_name, sizeof(sa.salg_name));
@@ -243,13 +261,56 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
memset(key, 0xab, key_length);
*key = 0xef;
r = _crypt_cipher_init(&c, key, key_length, &sa);
r = _crypt_cipher_init(&c, key, key_length, 0, &sa);
crypt_cipher_destroy_kernel(&c);
free(key);
return r;
}
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
struct crypt_cipher_kernel c;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "aead",
.salg_name = "ccm(aes)",
};
int r;
char buffer[128], ccm_iv[16];
if (length + tag_length > sizeof(buffer))
return -EINVAL;
if (iv_length > sizeof(ccm_iv) - 2)
return -EINVAL;
r = _crypt_cipher_init(&c, key, key_length, tag_length, &sa);
if (r < 0)
return r;
memcpy(buffer, in, length);
memcpy(buffer + length, tag, tag_length);
/* CCM IV - RFC3610 */
memset(ccm_iv, 0, sizeof(ccm_iv));
ccm_iv[0] = 15 - iv_length - 1;
memcpy(ccm_iv + 1, iv, iv_length);
memset(ccm_iv + 1 + iv_length, 0, ccm_iv[0] + 1);
iv_length = sizeof(ccm_iv);
r = _crypt_cipher_crypt(&c, buffer, length + tag_length, out, length,
ccm_iv, iv_length, ALG_OP_DECRYPT);
crypt_cipher_destroy_kernel(&c);
crypt_backend_memzero(buffer, sizeof(buffer));
return r;
}
#else /* ENABLE_AF_ALG */
int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
const char *mode, const void *key, size_t key_length)
@@ -280,4 +341,11 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
/* Cannot check, expect success. */
return 0;
}
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return -ENOTSUP;
}
#endif

View File

@@ -1,8 +1,8 @@
/*
* GCRYPT crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -51,9 +51,14 @@ struct crypt_cipher {
} u;
};
struct hash_alg {
const char *name;
const char *gcrypt_name;
};
/*
* Test for wrong Whirlpool variant,
* Ref: http://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
* Ref: https://lists.gnupg.org/pipermail/gcrypt-devel/2014-January/002889.html
*/
static void crypt_hash_test_whirlpool_bug(void)
{
@@ -89,8 +94,10 @@ static void crypt_hash_test_whirlpool_bug(void)
crypto_backend_whirlpool_bug = 1;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(bool fips __attribute__((unused)))
{
int r;
if (crypto_backend_initialised)
return 0;
@@ -99,7 +106,7 @@ int crypt_backend_init(struct crypt_device *ctx)
return -ENOSYS;
}
/* FIXME: If gcrypt compiled to support POSIX 1003.1e capabilities,
/* If gcrypt compiled to support POSIX 1003.1e capabilities,
* it drops all privileges during secure memory initialisation.
* For now, the only workaround is to disable secure memory in gcrypt.
* cryptsetup always need at least cap_sys_admin privilege for dm-ioctl
@@ -120,11 +127,12 @@ int crypt_backend_init(struct crypt_device *ctx)
crypto_backend_initialised = 1;
crypt_hash_test_whirlpool_bug();
snprintf(version, 64, "gcrypt %s%s%s",
r = snprintf(version, sizeof(version), "gcrypt %s%s%s",
gcry_check_version(NULL),
crypto_backend_secmem ? "" : ", secmem disabled",
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : ""
);
crypto_backend_whirlpool_bug > 0 ? ", flawed whirlpool" : "");
if (r < 0 || (size_t)r >= sizeof(version))
return -EINVAL;
return 0;
}
@@ -150,10 +158,24 @@ uint32_t crypt_backend_flags(void)
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
{
const char *hash_name = name;
int i;
static struct hash_alg hash_algs[] = {
{ "blake2b-160", "blake2b_160" },
{ "blake2b-256", "blake2b_256" },
{ "blake2b-384", "blake2b_384" },
{ "blake2b-512", "blake2b_512" },
{ "blake2s-128", "blake2s_128" },
{ "blake2s-160", "blake2s_160" },
{ "blake2s-224", "blake2s_224" },
{ "blake2s-256", "blake2s_256" },
{ NULL, NULL, }};
if (!name)
return NULL;
/* "whirlpool_gcryptbug" is out shortcut to flawed whirlpool
* in libgcrypt < 1.6.0 */
if (name && !strcasecmp(name, "whirlpool_gcryptbug")) {
if (!strcasecmp(name, "whirlpool_gcryptbug")) {
#if GCRYPT_VERSION_NUMBER >= 0x010601
if (flags)
*flags |= GCRY_MD_FLAG_BUGEMU1;
@@ -161,6 +183,15 @@ static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
hash_name = "whirlpool";
}
i = 0;
while (hash_algs[i].name) {
if (!strcasecmp(name, hash_algs[i].name)) {
hash_name = hash_algs[i].gcrypt_name;
break;
}
i++;
}
return hash_name;
}
@@ -316,7 +347,7 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx)
}
/* RNG */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips __attribute__((unused)))
{
switch(quality) {
case CRYPT_RND_NORMAL:
@@ -479,3 +510,43 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return ctx->use_kernel;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
#ifdef GCRY_CCM_BLOCK_LEN
gcry_cipher_hd_t hd;
uint64_t l[3];
int r = -EINVAL;
if (gcry_cipher_open(&hd, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CCM, 0))
return -EINVAL;
if (gcry_cipher_setkey(hd, key, key_length))
goto out;
if (gcry_cipher_setiv(hd, iv, iv_length))
goto out;
l[0] = length;
l[1] = 0;
l[2] = tag_length;
if (gcry_cipher_ctl(hd, GCRYCTL_SET_CCM_LENGTHS, l, sizeof(l)))
goto out;
if (gcry_cipher_decrypt(hd, out, length, in, length))
goto out;
if (gcry_cipher_checktag(hd, tag, tag_length))
goto out;
r = 0;
out:
gcry_cipher_close(hd);
return r;
#else
return -ENOTSUP;
#endif
}

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel userspace API crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,7 +29,6 @@
#include <linux/if_alg.h>
#include "crypto_backend_internal.h"
/* FIXME: remove later */
#ifndef AF_ALG
#define AF_ALG 38
#endif
@@ -62,6 +61,14 @@ static struct hash_alg hash_algs[] = {
{ "stribog256","streebog256", 32, 64 },
{ "stribog512","streebog512", 64, 64 },
{ "sm3", "sm3", 32, 64 },
{ "blake2b-160","blake2b-160",20, 128 },
{ "blake2b-256","blake2b-256",32, 128 },
{ "blake2b-384","blake2b-384",48, 128 },
{ "blake2b-512","blake2b-512",64, 128 },
{ "blake2s-128","blake2s-128",16, 64 },
{ "blake2s-160","blake2s-160",20, 64 },
{ "blake2s-224","blake2s-224",28, 64 },
{ "blake2s-256","blake2s-256",32, 64 },
{ NULL, NULL, 0, 0 }
};
@@ -110,7 +117,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
return 0;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(bool fips __attribute__((unused)))
{
struct utsname uts;
struct sockaddr_alg sa = {
@@ -118,7 +125,7 @@ int crypt_backend_init(struct crypt_device *ctx)
.salg_type = "hash",
.salg_name = "sha256",
};
int tfmfd = -1, opfd = -1;
int r, tfmfd = -1, opfd = -1;
if (crypto_backend_initialised)
return 0;
@@ -126,15 +133,17 @@ int crypt_backend_init(struct crypt_device *ctx)
if (uname(&uts) == -1 || strcmp(uts.sysname, "Linux"))
return -EINVAL;
r = snprintf(version, sizeof(version), "%s %s kernel cryptoAPI",
uts.sysname, uts.release);
if (r < 0 || (size_t)r >= sizeof(version))
return -EINVAL;
if (crypt_kernel_socket_init(&sa, &tfmfd, &opfd, NULL, 0) < 0)
return -EINVAL;
close(tfmfd);
close(opfd);
snprintf(version, sizeof(version), "%s %s kernel cryptoAPI",
uts.sysname, uts.release);
crypto_backend_initialised = 1;
return 0;
}
@@ -255,6 +264,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
.salg_family = AF_ALG,
.salg_type = "hash",
};
int r;
h = malloc(sizeof(*h));
if (!h)
@@ -267,8 +277,12 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
}
h->hash_len = ha->length;
snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
r = snprintf((char *)sa.salg_name, sizeof(sa.salg_name),
"hmac(%s)", ha->kernel_name);
if (r < 0 || (size_t)r >= sizeof(sa.salg_name)) {
free(h);
return -EINVAL;
}
if (crypt_kernel_socket_init(&sa, &h->tfmfd, &h->opfd, key, key_length) < 0) {
free(h);
@@ -315,7 +329,8 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx)
}
/* RNG - N/A */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
int crypt_backend_rng(char *buffer __attribute__((unused)), size_t length __attribute__((unused)),
int quality __attribute__((unused)), int fips __attribute__((unused)))
{
return -EINVAL;
}
@@ -388,7 +403,16 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* Nettle crypto backend implementation
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(bool fips __attribute__((unused)))
{
return 0;
}
@@ -301,12 +301,16 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
h->hash = _get_alg(name);
if (!h->hash)
goto bad;
if (!h->hash) {
free(h);
return -EINVAL;
}
h->key = malloc(key_length);
if (!h->key)
goto bad;
if (!h->key) {
free(h);
return -ENOMEM;
}
memcpy(h->key, key, key_length);
h->key_length = key_length;
@@ -316,9 +320,6 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
*ctx = h;
return 0;
bad:
free(h);
return -EINVAL;
}
static void crypt_hmac_restart(struct crypt_hmac *ctx)
@@ -351,7 +352,10 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx)
}
/* RNG - N/A */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
int crypt_backend_rng(char *buffer __attribute__((unused)),
size_t length __attribute__((unused)),
int quality __attribute__((unused)),
int fips __attribute__((unused)))
{
return -EINVAL;
}
@@ -429,7 +433,16 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* NSS crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -75,8 +75,10 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(bool fips __attribute__((unused)))
{
int r;
if (crypto_backend_initialised)
return 0;
@@ -84,10 +86,13 @@ int crypt_backend_init(struct crypt_device *ctx)
return -EINVAL;
#if HAVE_DECL_NSS_GETVERSION
snprintf(version, 64, "NSS %s", NSS_GetVersion());
r = snprintf(version, sizeof(version), "NSS %s", NSS_GetVersion());
#else
snprintf(version, 64, "NSS");
r = snprintf(version, sizeof(version), "NSS");
#endif
if (r < 0 || (size_t)r >= sizeof(version))
return -EINVAL;
crypto_backend_initialised = 1;
return 0;
}
@@ -220,28 +225,28 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
h->hash = _get_alg(name);
if (!h->hash)
goto bad;
goto err;
h->slot = PK11_GetInternalKeySlot();
if (!h->slot)
goto bad;
goto err;
h->key = PK11_ImportSymKey(h->slot, h->hash->ck_type, PK11_OriginUnwrap,
CKA_SIGN, &keyItem, NULL);
if (!h->key)
goto bad;
goto err;
h->md = PK11_CreateContextBySymKey(h->hash->ck_type, CKA_SIGN, h->key,
&noParams);
if (!h->md)
goto bad;
goto err;
if (PK11_DigestBegin(h->md) != SECSuccess)
goto bad;
goto err;
*ctx = h;
return 0;
bad:
err:
crypt_hmac_destroy(h);
return -EINVAL;
}
@@ -298,7 +303,7 @@ void crypt_hmac_destroy(struct crypt_hmac *ctx)
}
/* RNG */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
int crypt_backend_rng(char *buffer, size_t length, int quality __attribute__((unused)), int fips)
{
if (fips)
return -EINVAL;
@@ -377,7 +382,16 @@ int crypt_cipher_decrypt(struct crypt_cipher *ctx,
return crypt_cipher_decrypt_kernel(&ctx->ck, in, out, length, iv, iv_length);
}
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* OPENSSL crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,17 @@
#include <openssl/hmac.h>
#include <openssl/rand.h>
#include "crypto_backend_internal.h"
#if OPENSSL_VERSION_MAJOR >= 3
#include <openssl/provider.h>
#include <openssl/kdf.h>
#include <openssl/core_names.h>
static OSSL_PROVIDER *ossl_legacy = NULL;
static OSSL_PROVIDER *ossl_default = NULL;
static OSSL_LIB_CTX *ossl_ctx = NULL;
static char backend_version[256] = "OpenSSL";
#endif
#define CONST_CAST(x) (x)(uintptr_t)
static int crypto_backend_initialised = 0;
@@ -44,8 +55,14 @@ struct crypt_hash {
};
struct crypt_hmac {
#if OPENSSL_VERSION_MAJOR >= 3
EVP_MAC *mac;
EVP_MAC_CTX *md;
EVP_MAC_CTX *md_org;
#else
HMAC_CTX *md;
const EVP_MD *hash_id;
#endif
int hash_len;
};
@@ -56,20 +73,31 @@ struct crypt_cipher {
struct {
EVP_CIPHER_CTX *hd_enc;
EVP_CIPHER_CTX *hd_dec;
const EVP_CIPHER *cipher_type;
size_t iv_length;
} lib;
} u;
};
struct hash_alg {
const char *name;
const char *openssl_name;
};
/*
* Compatible wrappers for OpenSSL < 1.1.0 and LibreSSL < 2.7.0
*/
#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
static void openssl_backend_init(void)
static int openssl_backend_init(bool fips __attribute__((unused)))
{
OpenSSL_add_all_algorithms();
return 0;
}
static void openssl_backend_exit(void)
{
}
static const char *openssl_backend_version(void)
@@ -109,22 +137,79 @@ static void HMAC_CTX_free(HMAC_CTX *md)
free(md);
}
#else
static void openssl_backend_init(void)
static void openssl_backend_exit(void)
{
#if OPENSSL_VERSION_MAJOR >= 3
if (ossl_legacy)
OSSL_PROVIDER_unload(ossl_legacy);
if (ossl_default)
OSSL_PROVIDER_unload(ossl_default);
if (ossl_ctx)
OSSL_LIB_CTX_free(ossl_ctx);
ossl_legacy = NULL;
ossl_default = NULL;
ossl_ctx = NULL;
#endif
}
static int openssl_backend_init(bool fips)
{
/*
* OpenSSL >= 3.0.0 provides some algorithms in legacy provider
*/
#if OPENSSL_VERSION_MAJOR >= 3
int r;
/*
* In FIPS mode we keep default OpenSSL context & global config
*/
if (!fips) {
ossl_ctx = OSSL_LIB_CTX_new();
if (!ossl_ctx)
return -EINVAL;
ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0);
if (!ossl_default) {
OSSL_LIB_CTX_free(ossl_ctx);
return -EINVAL;
}
/* Optional */
ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0);
}
r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s",
OpenSSL_version(OPENSSL_VERSION),
ossl_default ? "[default]" : "",
ossl_legacy ? "[legacy]" : "",
fips ? "[fips]" : "");
if (r < 0 || (size_t)r >= sizeof(backend_version)) {
openssl_backend_exit();
return -EINVAL;
}
#endif
return 0;
}
static const char *openssl_backend_version(void)
{
return OpenSSL_version(OPENSSL_VERSION);
#if OPENSSL_VERSION_MAJOR >= 3
return backend_version;
#else
return OpenSSL_version(OPENSSL_VERSION);
#endif
}
#endif
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(bool fips)
{
if (crypto_backend_initialised)
return 0;
openssl_backend_init();
if (openssl_backend_init(fips))
return -EINVAL;
crypto_backend_initialised = 1;
return 0;
@@ -132,7 +217,15 @@ int crypt_backend_init(struct crypt_device *ctx)
void crypt_backend_destroy(void)
{
/*
* If Destructor was already called, we must not call it again
*/
if (!crypto_backend_initialised)
return;
crypto_backend_initialised = 0;
openssl_backend_exit();
}
uint32_t crypt_backend_flags(void)
@@ -145,15 +238,75 @@ const char *crypt_backend_version(void)
return openssl_backend_version();
}
static const char *crypt_hash_compat_name(const char *name)
{
const char *hash_name = name;
int i;
static struct hash_alg hash_algs[] = {
{ "blake2b-512", "blake2b512" },
{ "blake2s-256", "blake2s256" },
{ NULL, NULL, }};
if (!name)
return NULL;
i = 0;
while (hash_algs[i].name) {
if (!strcasecmp(name, hash_algs[i].name)) {
hash_name = hash_algs[i].openssl_name;
break;
}
i++;
}
return hash_name;
}
static const EVP_MD *hash_id_get(const char *name)
{
#if OPENSSL_VERSION_MAJOR >= 3
return EVP_MD_fetch(ossl_ctx, crypt_hash_compat_name(name), NULL);
#else
return EVP_get_digestbyname(crypt_hash_compat_name(name));
#endif
}
static void hash_id_free(const EVP_MD *hash_id)
{
#if OPENSSL_VERSION_MAJOR >= 3
EVP_MD_free(CONST_CAST(EVP_MD*)hash_id);
#endif
}
static const EVP_CIPHER *cipher_type_get(const char *name)
{
#if OPENSSL_VERSION_MAJOR >= 3
return EVP_CIPHER_fetch(ossl_ctx, name, NULL);
#else
return EVP_get_cipherbyname(name);
#endif
}
static void cipher_type_free(const EVP_CIPHER *cipher_type)
{
#if OPENSSL_VERSION_MAJOR >= 3
EVP_CIPHER_free(CONST_CAST(EVP_CIPHER*)cipher_type);
#endif
}
/* HASH */
int crypt_hash_size(const char *name)
{
const EVP_MD *hash_id = EVP_get_digestbyname(name);
int size;
const EVP_MD *hash_id;
hash_id = hash_id_get(name);
if (!hash_id)
return -EINVAL;
return EVP_MD_size(hash_id);
size = EVP_MD_size(hash_id);
hash_id_free(hash_id);
return size;
}
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
@@ -170,7 +323,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return -ENOMEM;
}
h->hash_id = EVP_get_digestbyname(name);
h->hash_id = hash_id_get(name);
if (!h->hash_id) {
EVP_MD_CTX_free(h->md);
free(h);
@@ -178,6 +331,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
}
if (EVP_DigestInit_ex(h->md, h->hash_id, NULL) != 1) {
hash_id_free(h->hash_id);
EVP_MD_CTX_free(h->md);
free(h);
return -EINVAL;
@@ -229,6 +383,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
void crypt_hash_destroy(struct crypt_hash *ctx)
{
hash_id_free(ctx->hash_id);
EVP_MD_CTX_free(ctx->md);
memset(ctx, 0, sizeof(*ctx));
free(ctx);
@@ -244,7 +399,39 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
const void *key, size_t key_length)
{
struct crypt_hmac *h;
#if OPENSSL_VERSION_MAJOR >= 3
OSSL_PARAM params[] = {
OSSL_PARAM_utf8_string(OSSL_MAC_PARAM_DIGEST, CONST_CAST(void*)name, 0),
OSSL_PARAM_END
};
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
h->mac = EVP_MAC_fetch(ossl_ctx, OSSL_MAC_NAME_HMAC, NULL);
if (!h->mac) {
free(h);
return -EINVAL;
}
h->md = EVP_MAC_CTX_new(h->mac);
if (!h->md) {
EVP_MAC_free(h->mac);
free(h);
return -ENOMEM;
}
if (EVP_MAC_init(h->md, key, key_length, params) != 1) {
EVP_MAC_CTX_free(h->md);
EVP_MAC_free(h->mac);
free(h);
return -EINVAL;
}
h->hash_len = EVP_MAC_CTX_get_mac_size(h->md);
h->md_org = EVP_MAC_CTX_dup(h->md);
#else
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
@@ -255,7 +442,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return -ENOMEM;
}
h->hash_id = EVP_get_digestbyname(name);
h->hash_id = hash_id_get(name);
if (!h->hash_id) {
HMAC_CTX_free(h->md);
free(h);
@@ -265,51 +452,82 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
HMAC_Init_ex(h->md, key, key_length, h->hash_id, NULL);
h->hash_len = EVP_MD_size(h->hash_id);
#endif
*ctx = h;
return 0;
}
static void crypt_hmac_restart(struct crypt_hmac *ctx)
static int crypt_hmac_restart(struct crypt_hmac *ctx)
{
#if OPENSSL_VERSION_MAJOR >= 3
EVP_MAC_CTX_free(ctx->md);
ctx->md = EVP_MAC_CTX_dup(ctx->md_org);
if (!ctx->md)
return -EINVAL;
#else
HMAC_Init_ex(ctx->md, NULL, 0, ctx->hash_id, NULL);
#endif
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
{
#if OPENSSL_VERSION_MAJOR >= 3
return EVP_MAC_update(ctx->md, (const unsigned char *)buffer, length) == 1 ? 0 : -EINVAL;
#else
HMAC_Update(ctx->md, (const unsigned char *)buffer, length);
return 0;
#endif
}
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
{
unsigned char tmp[EVP_MAX_MD_SIZE];
#if OPENSSL_VERSION_MAJOR >= 3
size_t tmp_len = 0;
if (length > (size_t)ctx->hash_len)
return -EINVAL;
if (EVP_MAC_final(ctx->md, tmp, &tmp_len, sizeof(tmp)) != 1)
return -EINVAL;
#else
unsigned int tmp_len = 0;
if (length > (size_t)ctx->hash_len)
return -EINVAL;
HMAC_Final(ctx->md, tmp, &tmp_len);
#endif
memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (tmp_len < length)
return -EINVAL;
crypt_hmac_restart(ctx);
if (crypt_hmac_restart(ctx))
return -EINVAL;
return 0;
}
void crypt_hmac_destroy(struct crypt_hmac *ctx)
{
#if OPENSSL_VERSION_MAJOR >= 3
EVP_MAC_CTX_free(ctx->md);
EVP_MAC_CTX_free(ctx->md_org);
EVP_MAC_free(ctx->mac);
#else
hash_id_free(ctx->hash_id);
HMAC_CTX_free(ctx->md);
#endif
memset(ctx, 0, sizeof(*ctx));
free(ctx);
}
/* RNG */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
int crypt_backend_rng(char *buffer, size_t length,
int quality __attribute__((unused)), int fips __attribute__((unused)))
{
if (RAND_bytes((unsigned char *)buffer, length) != 1)
return -EINVAL;
@@ -317,48 +535,91 @@ int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
return 0;
}
static int openssl_pbkdf2(const char *password, size_t password_length,
const char *salt, size_t salt_length, uint32_t iterations,
const char *hash, char *key, size_t key_length)
{
int r;
#if OPENSSL_VERSION_MAJOR >= 3
EVP_KDF_CTX *ctx;
EVP_KDF *pbkdf2;
OSSL_PARAM params[] = {
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_PASSWORD,
CONST_CAST(void*)password, password_length),
OSSL_PARAM_octet_string(OSSL_KDF_PARAM_SALT,
CONST_CAST(void*)salt, salt_length),
OSSL_PARAM_uint32(OSSL_KDF_PARAM_ITER, &iterations),
OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_DIGEST,
CONST_CAST(void*)hash, 0),
OSSL_PARAM_END
};
pbkdf2 = EVP_KDF_fetch(ossl_ctx, "pbkdf2", NULL);
if (!pbkdf2)
return -EINVAL;
ctx = EVP_KDF_CTX_new(pbkdf2);
if (!ctx) {
EVP_KDF_free(pbkdf2);
return -EINVAL;
}
r = EVP_KDF_derive(ctx, (unsigned char*)key, key_length, params);
EVP_KDF_CTX_free(ctx);
EVP_KDF_free(pbkdf2);
#else
const EVP_MD *hash_id = EVP_get_digestbyname(crypt_hash_compat_name(hash));
if (!hash_id)
return -EINVAL;
r = PKCS5_PBKDF2_HMAC(password, (int)password_length, (const unsigned char *)salt,
(int)salt_length, iterations, hash_id, (int)key_length, (unsigned char*) key);
#endif
return r == 1 ? 0 : -EINVAL;
}
static int openssl_argon2(const char *type, const char *password, size_t password_length,
const char *salt, size_t salt_length, char *key, size_t key_length,
uint32_t iterations, uint32_t memory, uint32_t parallel)
{
return argon2(type, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
}
/* PBKDF */
int crypt_pbkdf(const char *kdf, const char *hash,
const char *password, size_t password_length,
const char *salt, size_t salt_length,
char *key, size_t key_length,
uint32_t iterations, uint32_t memory, uint32_t parallel)
{
const EVP_MD *hash_id;
if (!kdf)
return -EINVAL;
if (!strcmp(kdf, "pbkdf2")) {
hash_id = EVP_get_digestbyname(hash);
if (!hash_id)
return -EINVAL;
if (!PKCS5_PBKDF2_HMAC(password, (int)password_length,
(const unsigned char *)salt, (int)salt_length,
(int)iterations, hash_id, (int)key_length, (unsigned char *)key))
return -EINVAL;
return 0;
} else if (!strncmp(kdf, "argon2", 6)) {
return argon2(kdf, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
}
if (!strcmp(kdf, "pbkdf2"))
return openssl_pbkdf2(password, password_length, salt, salt_length,
iterations, hash, key, key_length);
if (!strncmp(kdf, "argon2", 6))
return openssl_argon2(kdf, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
return -EINVAL;
}
/* Block ciphers */
static void _cipher_destroy(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec)
static void _cipher_destroy(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const EVP_CIPHER **cipher_type)
{
EVP_CIPHER_CTX_free(*hd_enc);
*hd_enc = NULL;
EVP_CIPHER_CTX_free(*hd_dec);
*hd_dec = NULL;
cipher_type_free(*cipher_type);
*cipher_type = NULL;
}
static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const char *name,
static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const EVP_CIPHER **cipher_type, const char *name,
const char *mode, const void *key, size_t key_length, size_t *iv_length)
{
char cipher_name[256];
@@ -370,35 +631,41 @@ static int _cipher_init(EVP_CIPHER_CTX **hd_enc, EVP_CIPHER_CTX **hd_dec, const
key_bits /= 2;
r = snprintf(cipher_name, sizeof(cipher_name), "%s-%d-%s", name, key_bits, mode);
if (r < 0 || r >= (int)sizeof(cipher_name))
if (r < 0 || (size_t)r >= sizeof(cipher_name))
return -EINVAL;
type = EVP_get_cipherbyname(cipher_name);
type = cipher_type_get(cipher_name);
if (!type)
return -ENOENT;
if (EVP_CIPHER_key_length(type) != (int)key_length)
if (EVP_CIPHER_key_length(type) != (int)key_length) {
cipher_type_free(type);
return -EINVAL;
}
*hd_enc = EVP_CIPHER_CTX_new();
*hd_dec = EVP_CIPHER_CTX_new();
*iv_length = EVP_CIPHER_iv_length(type);
if (!*hd_enc || !*hd_dec)
if (!*hd_enc || !*hd_dec) {
cipher_type_free(type);
return -EINVAL;
}
if (EVP_EncryptInit_ex(*hd_enc, type, NULL, key, NULL) != 1 ||
EVP_DecryptInit_ex(*hd_dec, type, NULL, key, NULL) != 1) {
_cipher_destroy(hd_enc, hd_dec);
_cipher_destroy(hd_enc, hd_dec, &type);
return -EINVAL;
}
if (EVP_CIPHER_CTX_set_padding(*hd_enc, 0) != 1 ||
EVP_CIPHER_CTX_set_padding(*hd_dec, 0) != 1) {
_cipher_destroy(hd_enc, hd_dec);
_cipher_destroy(hd_enc, hd_dec, &type);
return -EINVAL;
}
*cipher_type = type;
return 0;
}
@@ -412,7 +679,7 @@ int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
if (!h)
return -ENOMEM;
if (!_cipher_init(&h->u.lib.hd_enc, &h->u.lib.hd_dec, name, mode, key,
if (!_cipher_init(&h->u.lib.hd_enc, &h->u.lib.hd_dec, &h->u.lib.cipher_type, name, mode, key,
key_length, &h->u.lib.iv_length)) {
h->use_kernel = false;
*ctx = h;
@@ -435,7 +702,7 @@ void crypt_cipher_destroy(struct crypt_cipher *ctx)
if (ctx->use_kernel)
crypt_cipher_destroy_kernel(&ctx->u.kernel);
else
_cipher_destroy(&ctx->u.lib.hd_enc, &ctx->u.lib.hd_dec);
_cipher_destroy(&ctx->u.lib.hd_enc, &ctx->u.lib.hd_dec, &ctx->u.lib.cipher_type);
free(ctx);
}
@@ -505,3 +772,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return ctx->use_kernel;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length __attribute__((unused)),
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
#ifdef EVP_CTRL_CCM_SET_IVLEN
EVP_CIPHER_CTX *ctx;
int len = 0, r = -EINVAL;
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
return -EINVAL;
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
goto out;
//EVP_CIPHER_CTX_key_length(ctx)
//EVP_CIPHER_CTX_iv_length(ctx)
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
goto out;
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
goto out;
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
goto out;
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
r = 0;
out:
EVP_CIPHER_CTX_free(ctx);
return r;
#else
return -ENOTSUP;
#endif
}

View File

@@ -2,7 +2,7 @@
* Generic wrapper for storage encryption modes and Initial Vectors
* (reimplementation of some functions from Linux dm-crypt kernel)
*
* Copyright (C) 2014-2019 Milan Broz
* Copyright (C) 2014-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,6 +21,7 @@
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include "bitops.h"
#include "crypto_backend.h"
@@ -31,16 +32,16 @@
* IV documentation: https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
*/
struct crypt_sector_iv {
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE } type;
enum { IV_NONE, IV_NULL, IV_PLAIN, IV_PLAIN64, IV_ESSIV, IV_BENBI, IV_PLAIN64BE, IV_EBOIV } type;
int iv_size;
char *iv;
struct crypt_cipher *essiv_cipher;
int benbi_shift;
struct crypt_cipher *cipher;
int shift;
};
/* Block encryption storage context */
struct crypt_storage {
unsigned sector_shift;
size_t sector_size;
unsigned iv_shift;
struct crypt_cipher *cipher;
struct crypt_sector_iv cipher_iv;
@@ -56,12 +57,15 @@ static int int_log2(unsigned int x)
static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
const char *cipher_name, const char *mode_name,
const char *iv_name, const void *key, size_t key_length)
const char *iv_name, const void *key, size_t key_length,
size_t sector_size)
{
int r;
memset(ctx, 0, sizeof(*ctx));
ctx->iv_size = crypt_cipher_ivsize(cipher_name, mode_name);
if (ctx->iv_size < 8)
if (ctx->iv_size < 0 || (strcmp(mode_name, "ecb") && ctx->iv_size < 8))
return -ENOENT;
if (!strcmp(cipher_name, "cipher_null") ||
@@ -86,7 +90,6 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
char *hash_name = strchr(iv_name, ':');
int hash_size;
char tmp[256];
int r;
if (!hash_name)
return -EINVAL;
@@ -114,7 +117,7 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
return r;
}
r = crypt_cipher_init(&ctx->essiv_cipher, cipher_name, "ecb",
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
tmp, hash_size);
crypt_backend_memzero(tmp, sizeof(tmp));
if (r)
@@ -127,7 +130,15 @@ static int crypt_sector_iv_init(struct crypt_sector_iv *ctx,
return -EINVAL;
ctx->type = IV_BENBI;
ctx->benbi_shift = SECTOR_SHIFT - log;
ctx->shift = SECTOR_SHIFT - log;
} else if (!strncasecmp(iv_name, "eboiv", 5)) {
r = crypt_cipher_init(&ctx->cipher, cipher_name, "ecb",
key, key_length);
if (r)
return r;
ctx->type = IV_EBOIV;
ctx->shift = int_log2(sector_size);
} else
return -ENOENT;
@@ -163,14 +174,20 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
case IV_ESSIV:
memset(ctx->iv, 0, ctx->iv_size);
*(uint64_t *)ctx->iv = cpu_to_le64(sector);
return crypt_cipher_encrypt(ctx->essiv_cipher,
return crypt_cipher_encrypt(ctx->cipher,
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
break;
case IV_BENBI:
memset(ctx->iv, 0, ctx->iv_size);
val = cpu_to_be64((sector << ctx->benbi_shift) + 1);
val = cpu_to_be64((sector << ctx->shift) + 1);
memcpy(ctx->iv + ctx->iv_size - sizeof(val), &val, sizeof(val));
break;
case IV_EBOIV:
memset(ctx->iv, 0, ctx->iv_size);
*(uint64_t *)ctx->iv = cpu_to_le64(sector << ctx->shift);
return crypt_cipher_encrypt(ctx->cipher,
ctx->iv, ctx->iv, ctx->iv_size, NULL, 0);
break;
default:
return -EINVAL;
}
@@ -180,8 +197,8 @@ static int crypt_sector_iv_generate(struct crypt_sector_iv *ctx, uint64_t sector
static void crypt_sector_iv_destroy(struct crypt_sector_iv *ctx)
{
if (ctx->type == IV_ESSIV)
crypt_cipher_destroy(ctx->essiv_cipher);
if (ctx->type == IV_ESSIV || ctx->type == IV_EBOIV)
crypt_cipher_destroy(ctx->cipher);
if (ctx->iv) {
memset(ctx->iv, 0, ctx->iv_size);
@@ -197,7 +214,8 @@ int crypt_storage_init(struct crypt_storage **ctx,
size_t sector_size,
const char *cipher,
const char *cipher_mode,
const void *key, size_t key_length)
const void *key, size_t key_length,
bool large_iv)
{
struct crypt_storage *s;
char mode_name[64];
@@ -229,14 +247,14 @@ int crypt_storage_init(struct crypt_storage **ctx,
return r;
}
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length);
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
if (r) {
crypt_storage_destroy(s);
return r;
}
s->sector_shift = int_log2(sector_size);
s->iv_shift = s->sector_shift - SECTOR_SHIFT;
s->sector_size = sector_size;
s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
*ctx = s;
return 0;
@@ -249,19 +267,20 @@ int crypt_storage_decrypt(struct crypt_storage *ctx,
uint64_t i;
int r = 0;
if (length & ((1 << ctx->sector_shift) - 1))
if (length & (ctx->sector_size - 1))
return -EINVAL;
length >>= ctx->sector_shift;
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
return -EINVAL;
for (i = 0; i < length; i++) {
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (uint64_t)(i << ctx->iv_shift));
for (i = 0; i < length; i += ctx->sector_size) {
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
if (r)
break;
r = crypt_cipher_decrypt(ctx->cipher,
&buffer[i << ctx->sector_shift],
&buffer[i << ctx->sector_shift],
1 << ctx->sector_shift,
&buffer[i],
&buffer[i],
ctx->sector_size,
ctx->cipher_iv.iv,
ctx->cipher_iv.iv_size);
if (r)
@@ -278,19 +297,20 @@ int crypt_storage_encrypt(struct crypt_storage *ctx,
uint64_t i;
int r = 0;
if (length & ((1 << ctx->sector_shift) - 1))
if (length & (ctx->sector_size - 1))
return -EINVAL;
length >>= ctx->sector_shift;
if (iv_offset & ((ctx->sector_size >> SECTOR_SHIFT) - 1))
return -EINVAL;
for (i = 0; i < length; i++) {
r = crypt_sector_iv_generate(&ctx->cipher_iv, iv_offset + (i << ctx->iv_shift));
for (i = 0; i < length; i += ctx->sector_size) {
r = crypt_sector_iv_generate(&ctx->cipher_iv, (iv_offset + (i >> SECTOR_SHIFT)) >> ctx->iv_shift);
if (r)
break;
r = crypt_cipher_encrypt(ctx->cipher,
&buffer[i << ctx->sector_shift],
&buffer[i << ctx->sector_shift],
1 << ctx->sector_shift,
&buffer[i],
&buffer[i],
ctx->sector_size,
ctx->cipher_iv.iv,
ctx->cipher_iv.iv_size);
if (r)

View File

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

View File

@@ -1,8 +1,8 @@
/*
* PBKDF performance check
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2016-2019 Ondrej Mosnacek
* Copyright (C) 2012-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2021 Milan Broz
* Copyright (C) 2016-2020 Ondrej Mosnacek
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,6 +27,10 @@
#include <sys/resource.h>
#include "crypto_backend.h"
#ifndef CLOCK_MONOTONIC_RAW
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC
#endif
#define BENCH_MIN_MS 250
#define BENCH_MIN_MS_FAST 10
#define BENCH_PERCENT_ATLEAST 95
@@ -44,6 +48,7 @@ int crypt_pbkdf_get_limits(const char *kdf, struct crypt_pbkdf_limits *limits)
limits->min_iterations = 1000; /* recommendation in NIST SP 800-132 */
limits->max_iterations = UINT32_MAX;
limits->min_memory = 0; /* N/A */
limits->min_bench_memory=0; /* N/A */
limits->max_memory = 0; /* N/A */
limits->min_parallel = 0; /* N/A */
limits->max_parallel = 0; /* N/A */
@@ -51,7 +56,8 @@ int crypt_pbkdf_get_limits(const char *kdf, struct crypt_pbkdf_limits *limits)
} else if (!strcmp(kdf, "argon2i") || !strcmp(kdf, "argon2id")) {
limits->min_iterations = 4;
limits->max_iterations = UINT32_MAX;
limits->min_memory = 32;
limits->min_memory = 32; /* hard limit */
limits->min_bench_memory=64*1024; /* 64 MiB minimum for benchmark */
limits->max_memory = 4*1024*1024; /* 4GiB */
limits->min_parallel = 1;
limits->max_parallel = 4;
@@ -70,7 +76,7 @@ static long time_ms(struct rusage *start, struct rusage *end)
count_kernel_time = 1;
/*
* FIXME: if there is no self usage info, count system time.
* If there is no self usage info, count system time.
* This seem like getrusage() bug in some hypervisors...
*/
if (!end->ru_utime.tv_sec && !start->ru_utime.tv_sec &&
@@ -151,7 +157,7 @@ static int next_argon2_params(uint32_t *t_cost, uint32_t *m_cost,
old_t_cost = *t_cost;
old_m_cost = *m_cost;
if (ms > target_ms) {
if ((uint32_t)ms > target_ms) {
/* decreasing, first try to lower t_cost, then m_cost */
num = (uint64_t)*t_cost * (uint64_t)target_ms;
denom = (uint64_t)ms;
@@ -357,8 +363,10 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
ms = time_ms(&rstart, &rend);
if (ms) {
PBKDF2_temp = (double)iterations * target_ms / ms;
if (PBKDF2_temp > UINT32_MAX)
return -EINVAL;
if (PBKDF2_temp > UINT32_MAX) {
r = -EINVAL;
goto out;
}
*iter_secs = (uint32_t)PBKDF2_temp;
}
@@ -402,15 +410,19 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
{
struct crypt_pbkdf_limits pbkdf_limits;
int r = -EINVAL;
uint32_t min_memory;
if (!kdf || !iterations_out || !memory_out)
return -EINVAL;
/* FIXME: whole limits propagation should be more clear here */
r = crypt_pbkdf_get_limits(kdf, &pbkdf_limits);
if (r < 0)
return r;
min_memory = pbkdf_limits.min_bench_memory;
if (min_memory > max_memory_kb)
min_memory = max_memory_kb;
*memory_out = 0;
*iterations_out = 0;
@@ -423,7 +435,7 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
r = crypt_argon2_check(kdf, password, password_size,
salt, salt_size, volume_key_size,
pbkdf_limits.min_iterations,
pbkdf_limits.min_memory,
min_memory,
max_memory_kb,
parallel_threads, time_ms, iterations_out,
memory_out, progress, usrptr);

View File

@@ -1,7 +1,7 @@
/*
* Integrity volume handling
*
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <uuid/uuid.h>
#include "integrity.h"
@@ -41,8 +40,7 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb) ||
memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic)) ||
(sb->version != SB_VERSION_1 && sb->version != SB_VERSION_2 &&
sb->version != SB_VERSION_3)) {
sb->version < SB_VERSION_1 || sb->version > SB_VERSION_5) {
log_std(cd, "No integrity superblock detected on %s.\n",
device_path(device));
r = -EINVAL;
@@ -58,7 +56,9 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
return r;
}
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params)
int INTEGRITY_read_sb(struct crypt_device *cd,
struct crypt_params_integrity *params,
uint32_t *flags)
{
struct superblock sb;
int r;
@@ -70,6 +70,9 @@ int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *pa
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
params->tag_size = sb.integrity_tag_size;
if (flags)
*flags = sb.flags;
return 0;
}
@@ -89,13 +92,15 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
log_std(cd, "journal_sections %u\n", sb.journal_sections);
log_std(cd, "provided_data_sectors %" PRIu64 "\n", sb.provided_data_sectors);
log_std(cd, "sector_size %u\n", SECTOR_SIZE << sb.log2_sectors_per_block);
if (sb.version == SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
if (sb.version >= SB_VERSION_2 && (sb.flags & SB_FLAG_RECALCULATING))
log_std(cd, "recalc_sector %" PRIu64 "\n", sb.recalc_sector);
log_std(cd, "log2_blocks_per_bitmap %u\n", sb.log2_blocks_per_bitmap_bit);
log_std(cd, "flags %s%s%s\n",
log_std(cd, "flags %s%s%s%s%s\n",
sb.flags & SB_FLAG_HAVE_JOURNAL_MAC ? "have_journal_mac " : "",
sb.flags & SB_FLAG_RECALCULATING ? "recalculating " : "",
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "");
sb.flags & SB_FLAG_DIRTY_BITMAP ? "dirty_bitmap " : "",
sb.flags & SB_FLAG_FIXED_PADDING ? "fix_padding " : "",
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "");
return 0;
}
@@ -115,7 +120,7 @@ int INTEGRITY_data_sectors(struct crypt_device *cd,
return 0;
}
int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
int INTEGRITY_key_size(struct crypt_device *cd __attribute__((unused)), const char *integrity)
{
if (!integrity)
return 0;
@@ -137,7 +142,28 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
return -EINVAL;
}
int INTEGRITY_tag_size(struct crypt_device *cd,
/* Return hash or hmac(hash) size, if known */
int INTEGRITY_hash_tag_size(const char *integrity)
{
char hash[MAX_CIPHER_LEN];
int r;
if (!integrity)
return 0;
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
return 4;
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
if (r == 1)
r = crypt_hash_size(hash);
else
r = crypt_hash_size(integrity);
return r < 0 ? 0 : r;
}
int INTEGRITY_tag_size(struct crypt_device *cd __attribute__((unused)),
const char *integrity,
const char *cipher,
const char *cipher_mode)
@@ -163,7 +189,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
if (!integrity || !strcmp(integrity, "none"))
auth_tag_size = 0;
else if (!strcmp(integrity, "aead"))
auth_tag_size = 16; //FIXME gcm- mode only
auth_tag_size = 16; /* gcm- mode only */
else if (!strcmp(integrity, "cmac(aes)"))
auth_tag_size = 16;
else if (!strcmp(integrity, "hmac(sha1)"))
@@ -187,7 +213,7 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
struct crypt_dm_active_device *dmd,
uint32_t flags)
uint32_t flags, uint32_t sb_flags)
{
int r;
@@ -198,12 +224,16 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
.flags = flags,
};
/* Workaround for kernel dm-integrity table bug */
if (sb_flags & SB_FLAG_RECALCULATING)
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
r = INTEGRITY_data_sectors(cd, crypt_metadata_device(cd),
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
if (r < 0)
return r;
return dm_integrity_target_set(&dmd->segment, 0, dmd->size,
return dm_integrity_target_set(cd, &dmd->segment, 0, dmd->size,
crypt_metadata_device(cd), crypt_data_device(cd),
crypt_get_integrity_tag_size(cd), crypt_get_data_offset(cd),
crypt_get_sector_size(cd), vk, journal_crypt_key,
@@ -213,7 +243,8 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
const char *name,
const char *type,
struct crypt_dm_active_device *dmd)
struct crypt_dm_active_device *dmd,
uint32_t sb_flags)
{
int r;
uint32_t dmi_flags;
@@ -238,7 +269,22 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
r = dm_create_device(cd, name, type, dmd);
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
log_err(cd, _("Kernel does not support dm-integrity mapping."));
return -ENOTSUP;
}
if (r < 0 && (sb_flags & SB_FLAG_FIXED_PADDING) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
!(dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED)) {
log_err(cd, _("Kernel does not support dm-integrity fixed metadata alignment."));
return -ENOTSUP;
}
if (r < 0 && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
!(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC) &&
((sb_flags & SB_FLAG_FIXED_HMAC) ?
(tgt->u.integrity.vk && !tgt->u.integrity.journal_integrity_key) :
(tgt->u.integrity.vk || tgt->u.integrity.journal_integrity_key))) {
log_err(cd, _("Kernel refuses to activate insecure recalculate option (see legacy activation options to override)."));
return -ENOTSUP;
}
@@ -251,15 +297,16 @@ int INTEGRITY_activate(struct crypt_device *cd,
struct volume_key *vk,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
uint32_t flags)
uint32_t flags, uint32_t sb_flags)
{
struct crypt_dm_active_device dmd = {};
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key, journal_mac_key, &dmd, flags);
int r = INTEGRITY_create_dmd_device(cd, params, vk, journal_crypt_key,
journal_mac_key, &dmd, flags, sb_flags);
if (r < 0)
return r;
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd);
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
dm_targets_free(cd, &dmd);
return r;
}
@@ -283,13 +330,15 @@ int INTEGRITY_format(struct crypt_device *cd,
uuid_generate(tmp_uuid_bin);
uuid_unparse(tmp_uuid_bin, tmp_uuid);
snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_uuid);
r = snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_uuid);
if (r < 0 || (size_t)r >= sizeof(tmp_name))
return -EINVAL;
/* There is no data area, we can actually use fake zeroed key */
if (params && params->integrity_key_size)
vk = crypt_alloc_volume_key(params->integrity_key_size, NULL);
r = dm_integrity_target_set(tgt, 0, dmdi.size, crypt_metadata_device(cd),
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, crypt_metadata_device(cd),
crypt_data_device(cd), crypt_get_integrity_tag_size(cd),
crypt_get_data_offset(cd), crypt_get_sector_size(cd), vk,
journal_crypt_key, journal_mac_key, params);
@@ -303,7 +352,7 @@ int INTEGRITY_format(struct crypt_device *cd,
r = device_block_adjust(cd, tgt->data_device, DEV_EXCL, tgt->u.integrity.offset, NULL, NULL);
if (r < 0 && (dm_flags(cd, DM_INTEGRITY, &dmi_flags) || !(dmi_flags & DM_INTEGRITY_SUPPORTED))) {
log_err(cd, _("Kernel doesn't support dm-integrity mapping."));
log_err(cd, _("Kernel does not support dm-integrity mapping."));
r = -ENOTSUP;
}
if (r) {

View File

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

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,6 +30,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <fcntl.h>
#include "nls.h"
#include "bitops.h"
@@ -40,45 +41,25 @@
#include "utils_fips.h"
#include "utils_keyring.h"
#include "utils_io.h"
#include "crypto_backend.h"
#include "crypto_backend/crypto_backend.h"
#include "utils_storage_wrappers.h"
#include "libcryptsetup.h"
/* to silent gcc -Wcast-qual for const cast */
#define CONST_CAST(x) (x)(uintptr_t)
#include "libcryptsetup_macros.h"
#include "libcryptsetup_symver.h"
#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 */
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
#define DEFAULT_MEM_ALIGNMENT 4096
#define LOG_MAX_LEN 4096
#define MAX_DM_DEPS 32
#define CRYPT_SUBDEV "SUBDEV" /* prefix for sublayered devices underneath public crypt types */
#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]))
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
#define MOVE_REF(x, y) \
do { \
typeof (x) *_px = &(x), *_py = &(y); \
*_px = *_py; \
*_py = NULL; \
} while (0)
struct crypt_device;
struct luks2_reenc_context;
struct luks2_reencrypt;
struct volume_key {
int id;
@@ -139,6 +120,8 @@ void device_sync(struct crypt_device *cd, struct device *device);
int device_check_size(struct crypt_device *cd,
struct device *device,
uint64_t req_offset, int falloc);
void device_set_block_size(struct device *device, size_t size);
size_t device_optimal_encryption_sector_size(struct crypt_device *cd, struct device *device);
int device_open_locked(struct crypt_device *cd, struct device *device, int flags);
int device_read_lock(struct crypt_device *cd, struct device *device);
@@ -179,7 +162,7 @@ char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t
char *crypt_get_base_device(const char *dev_path);
uint64_t crypt_dev_partition_offset(const char *dev_path);
int lookup_by_disk_id(const char *dm_uuid);
int lookup_by_sysfs_uuid_field(const char *dm_uuid, size_t max_len);
int lookup_by_sysfs_uuid_field(const char *dm_uuid);
int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid);
size_t crypt_getpagesize(void);
@@ -188,11 +171,10 @@ uint64_t crypt_getphysmemory_kb(void);
int init_crypto(struct crypt_device *ctx);
void logger(struct crypt_device *cd, int level, const char *file, int line, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
#define log_dbg(c, x...) logger(c, CRYPT_LOG_DEBUG, __FILE__, __LINE__, x)
#define log_std(c, x...) logger(c, CRYPT_LOG_NORMAL, __FILE__, __LINE__, x)
#define log_verbose(c, x...) logger(c, CRYPT_LOG_VERBOSE, __FILE__, __LINE__, x)
#define log_err(c, x...) logger(c, CRYPT_LOG_ERROR, __FILE__, __LINE__, x)
#define log_dbg(c, x...) crypt_logf(c, CRYPT_LOG_DEBUG, x)
#define log_std(c, x...) crypt_logf(c, CRYPT_LOG_NORMAL, x)
#define log_verbose(c, x...) crypt_logf(c, CRYPT_LOG_VERBOSE, x)
#define log_err(c, x...) crypt_logf(c, CRYPT_LOG_ERROR, x)
int crypt_get_debug_level(void);
@@ -217,8 +199,8 @@ int PLAIN_activate(struct crypt_device *cd,
uint32_t flags);
void *crypt_get_hdr(struct crypt_device *cd, const char *type);
void crypt_set_reenc_context(struct crypt_device *cd, struct luks2_reenc_context *rh);
struct luks2_reenc_context *crypt_get_reenc_context(struct crypt_device *cd);
void crypt_set_luks2_reencrypt(struct crypt_device *cd, struct luks2_reencrypt *rh);
struct luks2_reencrypt *crypt_get_luks2_reencrypt(struct crypt_device *cd);
int onlyLUKS2(struct crypt_device *cd);
int onlyLUKS2mask(struct crypt_device *cd, uint32_t mask);
@@ -244,7 +226,7 @@ int crypt_use_keyring_for_vk(struct crypt_device *cd);
void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype);
void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks);
static inline uint64_t version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
static inline uint64_t compact_version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
{
return (uint64_t)release | ((uint64_t)patch << 16) | ((uint64_t)minor << 32) | ((uint64_t)major << 48);
}
@@ -261,4 +243,12 @@ int crypt_compare_dm_devices(struct crypt_device *cd,
const struct crypt_dm_active_device *tgt);
static inline void *crypt_zalloc(size_t size) { return calloc(1, size); }
static inline bool uint64_mult_overflow(uint64_t *u, uint64_t b, size_t size)
{
*u = (uint64_t)b * size;
if ((uint64_t)(*u / size) != b)
return true;
return false;
}
#endif /* INTERNAL_H */

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -129,9 +129,10 @@ void crypt_free(struct crypt_device *cd);
* other values mean accepted.
*
* @param cd crypt device handle
* @param confirm user defined confirm callback reference
* @param confirm user defined confirm callback reference; use
* @p msg for message for user to confirm and
* @p usrptr for identification in callback
* @param usrptr provided identification in callback
* @param msg Message for user to confirm
*
* @note Current version of cryptsetup API requires confirmation for UUID change and
* LUKS header restore only.
@@ -196,10 +197,11 @@ int crypt_set_data_offset(struct crypt_device *cd, uint64_t data_offset);
* Set log function.
*
* @param cd crypt device handle (can be @e NULL to set default log function)
* @param log user defined log function reference
* @param log user defined log function reference; use
* @p level for log level,
* @p msg for message, and
* @p usrptr for identification in callback
* @param usrptr provided identification in callback
* @param level log level below (debug messages can uses other levels)
* @param msg log message
*/
void crypt_set_log_callback(struct crypt_device *cd,
void (*log)(int level, const char *msg, void *usrptr),
@@ -215,6 +217,15 @@ void crypt_set_log_callback(struct crypt_device *cd,
* @param msg log message
*/
void crypt_log(struct crypt_device *cd, int level, const char *msg);
/**
* Log function with variable arguments.
*
* @param cd crypt device handle
* @param level log level
* @param format formatted log message
*/
void crypt_logf(struct crypt_device *cd, int level, const char *format, ...);
/** @} */
/**
@@ -414,6 +425,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
#define CRYPT_TCRYPT "TCRYPT"
/** INTEGRITY dm-integrity device */
#define CRYPT_INTEGRITY "INTEGRITY"
/** BITLK (BitLocker-compatible mode) */
#define CRYPT_BITLK "BITLK"
/** LUKS any version */
#define CRYPT_LUKS NULL
@@ -505,6 +518,8 @@ struct crypt_params_verity {
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
/** Create hash - format hash device */
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
/** Root hash signature required for activation */
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
/**
*
@@ -586,7 +601,7 @@ struct crypt_params_luks2 {
const struct crypt_params_integrity *integrity_params; /**< Data integrity parameters or @e NULL*/
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 */
uint32_t sector_size; /**< encryption sector size, 0 triggers auto-detection for optimal encryption sector size */
const char *label; /**< header label or @e NULL*/
const char *subsystem; /**< header subsystem label or @e NULL*/
};
@@ -629,6 +644,30 @@ int crypt_format(struct crypt_device *cd,
size_t volume_key_size,
void *params);
/**
* Set format compatibility flags.
*
* @param cd crypt device handle
* @param flags CRYPT_COMPATIBILITY_* flags
*/
void crypt_set_compatibility(struct crypt_device *cd, uint32_t flags);
/**
* Get compatibility flags.
*
* @param cd crypt device handle
*
* @returns compatibility flags
*/
uint32_t crypt_get_compatibility(struct crypt_device *cd);
/** dm-integrity device uses less effective (legacy) padding (old kernels) */
#define CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING (1 << 0)
/** dm-integrity device does not protect superblock with HMAC (old kernels) */
#define CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC (1 << 1)
/** dm-integrity allow recalculating of volumes with HMAC keys (old kernels) */
#define CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC (1 << 2)
/**
* Convert to new type for already existing device.
*
@@ -828,6 +867,20 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
int keyslot,
const char *keyfile,
size_t keyfile_size);
/**
* Resume crypt device using provided volume key.
*
* @param cd crypt device handle
* @param name name of device to resume
* @param volume_key provided volume key
* @param volume_key_size size of volume_key
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_resume_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size);
/** @} */
/**
@@ -1061,6 +1114,18 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF (1 << 19)
/** dm-integrity: direct writes, use bitmap to track dirty sectors */
#define CRYPT_ACTIVATE_NO_JOURNAL_BITMAP (1 << 20)
/** device is suspended (key should be wiped from memory), output only */
#define CRYPT_ACTIVATE_SUSPENDED (1 << 21)
/** use IV sector counted in sector_size instead of default 512 bytes sectors */
#define CRYPT_ACTIVATE_IV_LARGE_SECTORS (1 << 22)
/** dm-verity: panic_on_corruption flag - panic kernel on corruption */
#define CRYPT_ACTIVATE_PANIC_ON_CORRUPTION (1 << 23)
/** dm-crypt: bypass internal workqueue and process read requests synchronously. */
#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
/** dm-crypt: bypass internal workqueue and process write requests synchronously. */
#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
/** dm-integrity: reset automatic recalculation */
#define CRYPT_ACTIVATE_RECALCULATE_RESET (1 << 26)
/**
* Active device runtime attributes
@@ -1252,6 +1317,31 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
size_t volume_key_size,
uint32_t flags);
/**
* Activate VERITY device using provided key and optional signature).
*
* @param cd crypt device handle
* @param name name of device to create
* @param volume_key provided volume key
* @param volume_key_size size of volume_key
* @param signature buffer with signature for the key
* @param signature_size bsize of signature buffer
* @param flags activation flags
*
* @return @e 0 on success or negative errno value otherwise.
*
* @note For VERITY the volume key means root hash required for activation.
* Because kernel dm-verity is always read only, you have to provide
* CRYPT_ACTIVATE_READONLY flag always.
*/
int crypt_activate_by_signed_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
uint32_t flags);
/**
* Activate device using passphrase stored in kernel keyring.
*
@@ -1278,6 +1368,8 @@ int crypt_activate_by_keyring(struct crypt_device *cd,
#define CRYPT_DEACTIVATE_DEFERRED (1 << 0)
/** force deactivation - if the device is busy, it is replaced by error device */
#define CRYPT_DEACTIVATE_FORCE (1 << 1)
/** if set, remove lazy deactivation */
#define CRYPT_DEACTIVATE_DEFERRED_CANCEL (1 << 2)
/**
* Deactivate crypt device. This function tries to remove active device-mapper
@@ -1322,6 +1414,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
*
* @note For TCRYPT cipher chain is the volume key concatenated
* for all ciphers in chain.
* @note For VERITY the volume key means root hash used for activation.
*/
int crypt_volume_key_get(struct crypt_device *cd,
int keyslot,
@@ -1380,6 +1473,17 @@ crypt_status_info crypt_status(struct crypt_device *cd, const char *name);
*/
int crypt_dump(struct crypt_device *cd);
/**
* Dump JSON-formatted information about LUKS2 device
*
* @param cd crypt device handle (only LUKS2 format supported)
* @param json buffer with JSON, if NULL use log callback for output
* @param flags dump flags (reserved)
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_dump_json(struct crypt_device *cd, const char **json, uint32_t flags);
/**
* Get cipher used in device.
*
@@ -1411,11 +1515,11 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd);
const char *crypt_get_uuid(struct crypt_device *cd);
/**
* Get path to underlaying device.
* Get path to underlying device.
*
* @param cd crypt device handle
*
* @return path to underlaying device name
* @return path to underlying device name
*
*/
const char *crypt_get_device_name(struct crypt_device *cd);
@@ -1425,7 +1529,7 @@ const char *crypt_get_device_name(struct crypt_device *cd);
*
* @param cd crypt device handle
*
* @return path to underlaying device name
* @return path to underlying device name
*
*/
const char *crypt_get_metadata_device_name(struct crypt_device *cd);
@@ -1472,6 +1576,21 @@ int crypt_get_volume_key_size(struct crypt_device *cd);
*/
int crypt_get_sector_size(struct crypt_device *cd);
/**
* Check if initialized LUKS context uses detached header
* (LUKS header located on a different device than data.)
*
* @param cd crypt device handle
*
* @return @e 1 if detached header is used, @e 0 if not
* or negative errno value otherwise.
*
* @note This is a runtime attribute, it does not say
* if a LUKS device requires detached header.
* This function works only with LUKS devices.
*/
int crypt_header_is_detached(struct crypt_device *cd);
/**
* Get device parameters for VERITY device.
*
@@ -1869,6 +1988,19 @@ int crypt_wipe(struct crypt_device *cd,
* @{
*/
/**
* Get number of tokens supported for device type.
*
* @param type crypt device type
*
* @return token count or negative errno otherwise if device
* doesn't not support tokens.
*
* @note Real number of supported tokens for a particular device depends
* on usable metadata area size.
*/
int crypt_token_max(const char *type);
/** Iterate through all tokens */
#define CRYPT_ANY_TOKEN -1
@@ -2026,6 +2158,15 @@ int crypt_token_is_assigned(struct crypt_device *cd,
* @param buffer returned allocated buffer with password
* @param buffer_len length of the buffer
* @param usrptr user data in @link crypt_activate_by_token @endlink
*
* @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or
* negative errno otherwise.
*
* @note Negative ENOANO errno means that token is PIN protected and caller should
* use @link crypt_activate_by_token_pin @endlink with PIN provided.
*
* @note Negative EAGAIN errno means token handler requires additional hardware
* not present in the system.
*/
typedef int (*crypt_token_open_func) (
struct crypt_device *cd,
@@ -2034,6 +2175,38 @@ typedef int (*crypt_token_open_func) (
size_t *buffer_len,
void *usrptr);
/**
* Token handler open with passphrase/PIN function prototype.
* This function retrieves password from a token and return allocated buffer
* containing this password. This buffer has to be deallocated by calling
* free() function and content should be wiped before deallocation.
*
* @param cd crypt device handle
* @param token token id
* @param pin passphrase (or PIN) to unlock token (may be binary data)
* @param pin_size size of @e pin
* @param buffer returned allocated buffer with password
* @param buffer_len length of the buffer
* @param usrptr user data in @link crypt_activate_by_token @endlink
*
* @return 0 on success (token passed LUKS2 keyslot passphrase in buffer) or
* negative errno otherwise.
*
* @note Negative ENOANO errno means that token is PIN protected and PIN was
* missing or wrong.
*
* @note Negative EAGAIN errno means token handler requires additional hardware
* not present in the system.
*/
typedef int (*crypt_token_open_pin_func) (
struct crypt_device *cd,
int token,
const char *pin,
size_t pin_size,
char **buffer,
size_t *buffer_len,
void *usrptr);
/**
* Token handler buffer free function prototype.
* This function is used by library to free the buffer with keyslot
@@ -2071,6 +2244,16 @@ typedef int (*crypt_token_validate_func) (struct crypt_device *cd, const char *j
*/
typedef void (*crypt_token_dump_func) (struct crypt_device *cd, const char *json);
/**
* Token handler version function prototype.
* This function is supposed to return pointer to version string information.
*
* @note The returned string is advised to contain only version.
* For example '1.0.0' or 'v1.2.3.4'.
*
*/
typedef const char * (*crypt_token_version_func) (void);
/**
* Token handler
*/
@@ -2091,6 +2274,35 @@ typedef struct {
*/
int crypt_token_register(const crypt_token_handler *handler);
/**
* Report configured path where library searches for external token handlers
*
* @return @e absolute path when external tokens are enabled or @e NULL otherwise.
*/
const char *crypt_token_external_path(void);
/**
* Disable external token handlers (plugins) support
* If disabled, it cannot be enabled again.
*/
void crypt_token_external_disable(void);
/** ABI version for external token in libcryptsetup-token-[name].so */
#define CRYPT_TOKEN_ABI_VERSION1 "CRYPTSETUP_TOKEN_1.0"
/** open by token - ABI exported symbol for external token (mandatory) */
#define CRYPT_TOKEN_ABI_OPEN "cryptsetup_token_open"
/** open by token with PIN - ABI exported symbol for external token */
#define CRYPT_TOKEN_ABI_OPEN_PIN "cryptsetup_token_open_pin"
/** deallocate callback - ABI exported symbol for external token */
#define CRYPT_TOKEN_ABI_BUFFER_FREE "cryptsetup_token_buffer_free"
/** validate token metadata - ABI exported symbol for external token */
#define CRYPT_TOKEN_ABI_VALIDATE "cryptsetup_token_validate"
/** dump token metadata - ABI exported symbol for external token */
#define CRYPT_TOKEN_ABI_DUMP "cryptsetup_token_dump"
/** token version - ABI exported symbol for external token */
#define CRYPT_TOKEN_ABI_VERSION "cryptsetup_token_version"
/**
* Activate device or check key using a token.
*
@@ -2101,12 +2313,71 @@ int crypt_token_register(const crypt_token_handler *handler);
* @param flags activation flags
*
* @return unlocked key slot number or negative errno otherwise.
*
* @note EPERM errno means token provided passphrase successfully, but
* passphrase did not unlock any keyslot associated with the token.
*
* @note ENOENT errno means no token (or subsequently assigned keyslot) was
* eligible to unlock device.
*
* @note ENOANO errno means that token is PIN protected and you should call
* @link crypt_activate_by_token_pin @endlink with PIN
*
* @note Negative EAGAIN errno means token handler requires additional hardware
* not present in the system.
*
* @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop
* to unlock device using any available token. It may happen that various token handlers
* return different error codes. At the end loop returns error codes in the following
* order (from the most significant to the least) any negative errno except those
* listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT.
*/
int crypt_activate_by_token(struct crypt_device *cd,
const char *name,
int token,
void *usrptr,
uint32_t flags);
/**
* Activate device or check key using a token with PIN.
*
* @param cd crypt device handle
* @param name name of device to create, if @e NULL only check token
* @param type restrict type of token, if @e NULL all types are allowed
* @param token requested token to check or CRYPT_ANY_TOKEN to check all
* @param pin passphrase (or PIN) to unlock token (may be binary data)
* @param pin_size size of @e pin
* @param usrptr provided identification in callback
* @param flags activation flags
*
* @return unlocked key slot number or negative errno otherwise.
*
* @note EPERM errno means token provided passphrase successfully, but
* passphrase did not unlock any keyslot associated with the token.
*
* @note ENOENT errno means no token (or subsequently assigned keyslot) was
* eligible to unlock device.
*
* @note ENOANO errno means that token is PIN protected and was either missing
* (NULL) or wrong.
*
* @note Negative EAGAIN errno means token handler requires additional hardware
* not present in the system.
*
* @note with @e token set to CRYPT_ANY_TOKEN libcryptsetup runs best effort loop
* to unlock device using any available token. It may happen that various token handlers
* return different error codes. At the end loop returns error codes in the following
* order (from the most significant to the least) any negative errno except those
* listed below, non negative token id (success), -ENOANO, -EAGAIN, -EPERM, -ENOENT.
*/
int crypt_activate_by_token_pin(struct crypt_device *cd,
const char *name,
const char *type,
int token,
const char *pin,
size_t pin_size,
void *usrptr,
uint32_t flags);
/** @} */
/**
@@ -2218,16 +2489,33 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
const struct crypt_params_reencrypt *params);
/**
* Run data reencryption.
* Legacy data reencryption function.
*
* @param cd crypt device handle
* @param progress is a callback funtion reporting device \b size,
* @param progress is a callback function reporting device \b size,
* current \b offset of reencryption and provided \b usrptr identification
*
* @return @e 0 on success or negative errno value otherwise.
*
* @deprecated Use @link crypt_reencrypt_run @endlink instead.
*/
int crypt_reencrypt(struct crypt_device *cd,
int (*progress)(uint64_t size, uint64_t offset, void *usrptr));
int (*progress)(uint64_t size, uint64_t offset, void *usrptr))
__attribute__((deprecated));
/**
* Run data reencryption.
*
* @param cd crypt device handle
* @param progress is a callback function reporting device \b size,
* current \b offset of reencryption and provided \b usrptr identification
* @param usrptr progress specific data
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_reencrypt_run(struct crypt_device *cd,
int (*progress)(uint64_t size, uint64_t offset, void *usrptr),
void *usrptr);
/**
* Reencryption status info
@@ -2251,6 +2539,49 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
struct crypt_params_reencrypt *params);
/** @} */
/**
* @defgroup crypt-memory Safe memory helpers functions
* @addtogroup crypt-memory
* @{
*/
/**
* Allocate safe memory (content is safely wiped on deallocation).
*
* @param size size of memory in bytes
*
* @return pointer to allocated memory or @e NULL.
*/
void *crypt_safe_alloc(size_t size);
/**
* Release safe memory, content is safely wiped.
* The pointer must be allocated with @link crypt_safe_alloc @endlink
*
* @param data pointer to memory to be deallocated
*/
void crypt_safe_free(void *data);
/**
* Reallocate safe memory (content is copied and safely wiped on deallocation).
*
* @param data pointer to memory to be deallocated
* @param size new size of memory in bytes
*
* @return pointer to allocated memory or @e NULL.
*/
void *crypt_safe_realloc(void *data, size_t size);
/**
* Safe clear memory area (compile should not compile this call out).
*
* @param data pointer to memory to be cleared
* @param size size of memory in bytes
*/
void crypt_safe_memzero(void *data, size_t size);
/** @} */
#ifdef __cplusplus
}
#endif

View File

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

View File

@@ -0,0 +1,67 @@
/*
* Definitions of common constant and generic macros fo libcryptsetup
*
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _LIBCRYPTSETUP_MACROS_H
#define _LIBCRYPTSETUP_MACROS_H
/* to silent gcc -Wcast-qual for const cast */
#define CONST_CAST(x) (x)(uintptr_t)
#define UNUSED(x) (void)(x)
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif
#define BITFIELD_SIZE(BF_PTR) (sizeof(*(BF_PTR)) * 8)
#define MOVE_REF(x, y) \
do { \
__typeof__(x) *_px = &(x), *_py = &(y); \
*_px = *_py; \
*_py = NULL; \
} while (0)
#define FREE_AND_NULL(x) do { free(x); x = NULL; } while (0)
#define AT_LEAST(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
#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 */
#define ROUND_SECTOR(x) (((x) + SECTOR_SIZE - 1) / SECTOR_SIZE)
#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))
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
#define DEFAULT_MEM_ALIGNMENT 4096
#define DM_UUID_LEN 129
#define DM_BY_ID_PREFIX "dm-uuid-"
#define DM_BY_ID_PREFIX_LEN 8
#define DM_UUID_PREFIX "CRYPT-"
#define DM_UUID_PREFIX_LEN 6
#endif /* _LIBCRYPTSETUP_MACROS_H */

105
lib/libcryptsetup_symver.h Normal file
View File

@@ -0,0 +1,105 @@
/*
* Helpers for defining versioned symbols
*
* Copyright (C) 2021 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* 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.
*/
#ifndef _LIBCRYPTSETUP_SYMVER_H
#define _LIBCRYPTSETUP_SYMVER_H
/*
* Note on usage:
*
* Do not use CRYPT_SYMBOL_EXPORT_NEW and CRYPT_SYMBOL_EXPORT_OLD on public
* symbols being exported only once. Linker will handle it automatically as
* always.
*
* It's supposed to be used only with symbols that are exported in at least
* two versions simultaneously as follows:
*
* - the latest version is marked with _NEW variant and oll other compatible
* symbols should be marked with _OLD variant
*
* Examples:
*
* - int crypt_func_X(unsigned *x, long y) gets introduced in CRYPTSETUP_2.4.
*
* No need to use any macro referenced here, just add proper version
* mapping in libcryptsetup.sym file.
*
* In later version CRYPTSETUP_2.5 symbol crypt_func_X has to fixed
* in incompatible way by adding new function parameter. The new version
* has to be added in mapping file libcryptsetup.sym as well.
*
* The definition of compatible function gets prefixed with following macro:
*
* CRYPT_SYMBOL_EXPORT_OLD(int, crypt_func_X, 2, 4,
* unsigned *x, long y)
* {
* function body
* }
*
* Whereas new version introduced in CRYPTSETUP_2.5 is defined as follows:
*
* CRYPT_SYMBOL_EXPORT_NEW(int, crypt_func_X, 2, 5,
* unsigned *x, long y, void *new_parameter)
* {
* function body
* }
*
* If in later version CRYPTSETUP_2.6 yet another version of crypt_func_X gets
* introduced it will be prefixed with CRYPT_SYMBOL_EXPORT_NEW(int, crypt_func_X, 2, 6...)
* macro and all previous versions CRYPTSETUP_2.4 and CRYPTSETUP_2.5 will be
* under CRYPT_SYMBOL_EXPORT_OLD(int, crypt_func_X, ...) macro
*/
#ifdef __has_attribute
# if __has_attribute(symver)
# define _CRYPT_SYMVER(_local_sym, _public_sym, _ver_str, _maj, _min) \
__attribute__((__symver__(#_public_sym _ver_str #_maj "." #_min)))
# endif
#endif
#if !defined(_CRYPT_SYMVER) && defined(__GNUC__)
# define _CRYPT_SYMVER(_local_sym, _public_sym, _ver_str, _maj, _min) \
asm(".symver " #_local_sym "," #_public_sym _ver_str #_maj "." #_min);
#endif
#define _CRYPT_FUNC(_public_sym, _prefix_str, _maj, _min, _ret, ...) \
_ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__); \
_CRYPT_SYMVER(__##_public_sym##_v##_maj##_##_min, _public_sym, _prefix_str "CRYPTSETUP_", _maj, _min) \
_ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__)
#ifdef _CRYPT_SYMVER
# define CRYPT_SYMBOL_EXPORT_OLD(_ret, _public_sym, _maj, _min, ...) \
_CRYPT_FUNC(_public_sym, "@", _maj, _min, _ret, __VA_ARGS__)
# define CRYPT_SYMBOL_EXPORT_NEW(_ret, _public_sym, _maj, _min, ...) \
_CRYPT_FUNC(_public_sym, "@@", _maj, _min, _ret, __VA_ARGS__)
#else /* no support for symbol versioning at all */
# define CRYPT_SYMBOL_EXPORT_OLD(_ret, _public_sym, _maj, _min, ...) \
static inline __attribute__((unused)) \
_ret __##_public_sym##_v##_maj##_##_min(__VA_ARGS__)
# define CRYPT_SYMBOL_EXPORT_NEW(_ret, _public_sym, _maj, _min, ...) \
_ret _public_sym(__VA_ARGS__)
#endif
#endif /* _LIBCRYPTSETUP_SYMVER_H */

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -1,8 +1,8 @@
/*
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2021 Milan Broz
*
* This file is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,7 +23,7 @@
#define _LOOPAES_H
#include <stdint.h>
#include <unistd.h>
#include <stddef.h>
struct crypt_device;
struct volume_key;

View File

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

View File

@@ -2,7 +2,7 @@
* AFsplitter - Anti forensic information splitter
*
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
*
* AFsplitter diffuses information over a large stripe of data,
* therefore supporting secure data destruction.
@@ -26,6 +26,9 @@
#include <stddef.h>
struct crypt_device;
struct volume_key;
/*
* AF_split operates on src and produces information split data in
* dst. src is assumed to be of the length blocksize. The data stripe

View File

@@ -2,8 +2,8 @@
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,7 +22,6 @@
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include "luks.h"
@@ -89,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
r = device_block_adjust(ctx, crypt_metadata_device(ctx), DEV_OK,
sector, &dmd.size, &dmd.flags);
if (r < 0) {
log_err(ctx, _("Device %s doesn't exist or access denied."),
log_err(ctx, _("Device %s does not exist or access denied."),
device_path(crypt_metadata_device(ctx)));
return -EIO;
}
@@ -154,7 +153,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
return -EINVAL;
/* Encrypt buffer */
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
if (r)
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
@@ -219,7 +218,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
if (MISALIGNED_512(dstLength))
return -EINVAL;
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
if (r)
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",

View File

@@ -2,8 +2,8 @@
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2019 Milan Broz
* Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -22,8 +22,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@@ -67,6 +65,27 @@ static void LUKS_sort_keyslots(const struct luks_phdr *hdr, int *array)
}
}
static int _is_not_lower(char *str, unsigned max_len)
{
for(; *str && max_len; str++, max_len--)
if (isupper(*str))
return 1;
return 0;
}
static int _to_lower(char *str, unsigned max_len)
{
int r = 0;
for(; *str && max_len; str++, max_len--)
if (isupper(*str)) {
*str = tolower(*str);
r = 1;
}
return r;
}
size_t LUKS_device_sectors(const struct luks_phdr *hdr)
{
int sorted_areas[LUKS_NUMKEYS] = { 0, 1, 2, 3, 4, 5, 6, 7 };
@@ -260,7 +279,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
r = 0;
out:
crypt_memzero(&hdr, sizeof(hdr));
crypt_safe_memzero(&hdr, sizeof(hdr));
crypt_safe_free(buffer);
return r;
}
@@ -284,7 +303,7 @@ int LUKS_hdr_restore(
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
log_err(ctx, _("Backup file does not contain valid LUKS header."));
r = -EINVAL;
goto out;
}
@@ -376,17 +395,48 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
log_err(ctx, _("Non standard key size, manual repair required."));
return -EINVAL;
}
/* cryptsetup 1.0 did not align to 4k, cannot repair this one */
if (LUKS_keyslots_offset(phdr) < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) {
/*
* cryptsetup 1.0 did not align keyslots to 4k, cannot repair this one
* Also we cannot trust possibly broken keyslots metadata here through LUKS_keyslots_offset().
* Expect first keyslot is aligned, if not, then manual repair is neccessary.
*/
if (phdr->keyblock[0].keyMaterialOffset < (LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE)) {
log_err(ctx, _("Non standard keyslots alignment, manual repair required."));
return -EINVAL;
}
/*
* ECB mode does not use IV but legacy dmcrypt silently allows it.
* Today device cannot be activated anyway, so we need to fix it here.
*/
if (!strncmp(phdr->cipherMode, "ecb-", 4)) {
log_err(ctx, _("Cipher mode repaired (%s -> %s)."), phdr->cipherMode, "ecb");
memset(phdr->cipherMode, 0, LUKS_CIPHERMODE_L);
strcpy(phdr->cipherMode, "ecb");
need_write = 1;
}
/*
* Old cryptsetup expects "sha1", gcrypt allows case insensitive names,
* so always convert hash to lower case in header
*/
if (_to_lower(phdr->hashSpec, LUKS_HASHSPEC_L)) {
log_err(ctx, _("Cipher hash repaired to lowercase (%s)."), phdr->hashSpec);
if (crypt_hmac_size(phdr->hashSpec) < LUKS_DIGESTSIZE) {
log_err(ctx, _("Requested LUKS hash %s is not supported."), phdr->hashSpec);
return -EINVAL;
}
need_write = 1;
}
r = LUKS_check_cipher(ctx, phdr->keyBytes, phdr->cipherName, phdr->cipherMode);
if (r < 0)
return -EINVAL;
vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
if (!vk)
return -ENOMEM;
log_verbose(ctx, _("Repairing keyslots."));
@@ -453,7 +503,7 @@ out:
if (r)
log_err(ctx, _("Repair failed."));
crypt_free_volume_key(vk);
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
return r;
}
@@ -467,12 +517,13 @@ static int _check_and_convert_hdr(const char *device,
unsigned int i;
char luksMagic[] = LUKS_MAGIC;
if(memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
hdr->version = be16_to_cpu(hdr->version);
if (memcmp(hdr->magic, luksMagic, LUKS_MAGIC_L)) { /* Check magic */
log_dbg(ctx, "LUKS header not detected.");
if (require_luks_device)
log_err(ctx, _("Device %s is not a valid LUKS device."), device);
return -EINVAL;
} else if((hdr->version = ntohs(hdr->version)) != 1) { /* Convert every uint16/32_t item from network byte order */
} else if (hdr->version != 1) {
log_err(ctx, _("Unsupported LUKS version %d."), hdr->version);
return -EINVAL;
}
@@ -480,19 +531,19 @@ static int _check_and_convert_hdr(const char *device,
hdr->hashSpec[LUKS_HASHSPEC_L - 1] = '\0';
if (crypt_hmac_size(hdr->hashSpec) < LUKS_DIGESTSIZE) {
log_err(ctx, _("Requested LUKS hash %s is not supported."), hdr->hashSpec);
return -EINVAL;
r = -EINVAL;
}
/* Header detected */
hdr->payloadOffset = ntohl(hdr->payloadOffset);
hdr->keyBytes = ntohl(hdr->keyBytes);
hdr->mkDigestIterations = ntohl(hdr->mkDigestIterations);
hdr->payloadOffset = be32_to_cpu(hdr->payloadOffset);
hdr->keyBytes = be32_to_cpu(hdr->keyBytes);
hdr->mkDigestIterations = be32_to_cpu(hdr->mkDigestIterations);
for(i = 0; i < LUKS_NUMKEYS; ++i) {
hdr->keyblock[i].active = ntohl(hdr->keyblock[i].active);
hdr->keyblock[i].passwordIterations = ntohl(hdr->keyblock[i].passwordIterations);
hdr->keyblock[i].keyMaterialOffset = ntohl(hdr->keyblock[i].keyMaterialOffset);
hdr->keyblock[i].stripes = ntohl(hdr->keyblock[i].stripes);
for (i = 0; i < LUKS_NUMKEYS; ++i) {
hdr->keyblock[i].active = be32_to_cpu(hdr->keyblock[i].active);
hdr->keyblock[i].passwordIterations = be32_to_cpu(hdr->keyblock[i].passwordIterations);
hdr->keyblock[i].keyMaterialOffset = be32_to_cpu(hdr->keyblock[i].keyMaterialOffset);
hdr->keyblock[i].stripes = be32_to_cpu(hdr->keyblock[i].stripes);
}
if (LUKS_check_keyslots(ctx, hdr))
@@ -504,6 +555,16 @@ static int _check_and_convert_hdr(const char *device,
hdr->uuid[UUID_STRING_L - 1] = '\0';
if (repair) {
if (!strncmp(hdr->cipherMode, "ecb-", 4)) {
log_err(ctx, _("LUKS cipher mode %s is invalid."), hdr->cipherMode);
r = -EINVAL;
}
if (_is_not_lower(hdr->hashSpec, LUKS_HASHSPEC_L)) {
log_err(ctx, _("LUKS hash %s is invalid."), hdr->hashSpec);
r = -EINVAL;
}
if (r == -EINVAL)
r = _keyslot_repair(hdr, ctx);
else
@@ -513,27 +574,6 @@ static int _check_and_convert_hdr(const char *device,
return r;
}
static void _to_lower(char *str, unsigned max_len)
{
for(; *str && max_len; str++, max_len--)
if (isupper(*str))
*str = tolower(*str);
}
static void LUKS_fix_header_compatible(struct luks_phdr *header)
{
/* Old cryptsetup expects "sha1", gcrypt allows case insensitive names,
* so always convert hash to lower case in header */
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
/* ECB mode does not use IV but dmcrypt silently allows it.
* Drop any IV here if ECB is used (that is not secure anyway).*/
if (!strncmp(header->cipherMode, "ecb-", 4)) {
memset(header->cipherMode, 0, LUKS_CIPHERMODE_L);
strcpy(header->cipherMode, "ecb");
}
}
int LUKS_read_phdr_backup(const char *backup_file,
struct luks_phdr *hdr,
int require_luks_device,
@@ -553,11 +593,9 @@ int LUKS_read_phdr_backup(const char *backup_file,
if (read_buffer(devfd, hdr, hdr_size) < hdr_size)
r = -EIO;
else {
LUKS_fix_header_compatible(hdr);
else
r = _check_and_convert_hdr(backup_file, hdr,
require_luks_device, 0, ctx);
}
close(devfd);
return r;
@@ -644,15 +682,15 @@ int LUKS_write_phdr(struct luks_phdr *hdr,
memset(&convHdr._padding, 0, sizeof(convHdr._padding));
/* Convert every uint16/32_t item to network byte order */
convHdr.version = htons(hdr->version);
convHdr.payloadOffset = htonl(hdr->payloadOffset);
convHdr.keyBytes = htonl(hdr->keyBytes);
convHdr.mkDigestIterations = htonl(hdr->mkDigestIterations);
convHdr.version = cpu_to_be16(hdr->version);
convHdr.payloadOffset = cpu_to_be32(hdr->payloadOffset);
convHdr.keyBytes = cpu_to_be32(hdr->keyBytes);
convHdr.mkDigestIterations = cpu_to_be32(hdr->mkDigestIterations);
for(i = 0; i < LUKS_NUMKEYS; ++i) {
convHdr.keyblock[i].active = htonl(hdr->keyblock[i].active);
convHdr.keyblock[i].passwordIterations = htonl(hdr->keyblock[i].passwordIterations);
convHdr.keyblock[i].keyMaterialOffset = htonl(hdr->keyblock[i].keyMaterialOffset);
convHdr.keyblock[i].stripes = htonl(hdr->keyblock[i].stripes);
convHdr.keyblock[i].active = cpu_to_be32(hdr->keyblock[i].active);
convHdr.keyblock[i].passwordIterations = cpu_to_be32(hdr->keyblock[i].passwordIterations);
convHdr.keyblock[i].keyMaterialOffset = cpu_to_be32(hdr->keyblock[i].keyMaterialOffset);
convHdr.keyblock[i].stripes = cpu_to_be32(hdr->keyblock[i].stripes);
}
r = write_lseek_blockwise(devfd, device_block_size(ctx, device), device_alignment(device),
@@ -692,7 +730,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
crypt_free_volume_key(empty_key);
crypt_memzero(buf, sizeof(buf));
crypt_safe_memzero(buf, sizeof(buf));
return r;
}
@@ -765,11 +803,10 @@ int LUKS_generate_phdr(struct luks_phdr *header,
strncpy(header->cipherName,cipherName,LUKS_CIPHERNAME_L-1);
strncpy(header->cipherMode,cipherMode,LUKS_CIPHERMODE_L-1);
strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L-1);
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
header->keyBytes=vk->keylength;
LUKS_fix_header_compatible(header);
log_dbg(ctx, "Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes",
header->version, header->hashSpec ,header->cipherName, header->cipherMode,
header->keyBytes);
@@ -787,10 +824,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
return r;
assert(pbkdf->iterations);
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (PBKDF2_temp > (double)UINT32_MAX)
return -EINVAL;
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
header->mkDigestIterations = AT_LEAST((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
assert(header->mkDigestIterations);
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
header->mkDigestSalt, LUKS_SALTSIZE,
@@ -863,7 +905,7 @@ int LUKS_set_key(unsigned int keyIndex,
* Final iteration count is at least LUKS_SLOT_ITERATIONS_MIN
*/
hdr->keyblock[keyIndex].passwordIterations =
at_least(pbkdf->iterations, LUKS_SLOT_ITERATIONS_MIN);
AT_LEAST(pbkdf->iterations, LUKS_SLOT_ITERATIONS_MIN);
log_dbg(ctx, "Key slot %d use %" PRIu32 " password iterations.", keyIndex,
hdr->keyblock[keyIndex].passwordIterations);
@@ -951,12 +993,12 @@ static int LUKS_open_key(unsigned int keyIndex,
const char *password,
size_t passwordLen,
struct luks_phdr *hdr,
struct volume_key *vk,
struct volume_key **vk,
struct crypt_device *ctx)
{
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
struct volume_key *derived_key;
char *AfKey;
char *AfKey = NULL;
size_t AFEKSize;
int r;
@@ -970,8 +1012,13 @@ static int LUKS_open_key(unsigned int keyIndex,
if (!derived_key)
return -ENOMEM;
assert(vk->keylength == hdr->keyBytes);
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!*vk) {
r = -ENOMEM;
goto out;
}
AFEKSize = AF_split_sectors(hdr->keyBytes, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) {
r = -ENOMEM;
@@ -982,8 +1029,10 @@ static int LUKS_open_key(unsigned int keyIndex,
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
derived_key->key, hdr->keyBytes,
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
if (r < 0)
if (r < 0) {
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
goto out;
}
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
r = LUKS_decrypt_from_storage(AfKey,
@@ -995,16 +1044,20 @@ static int LUKS_open_key(unsigned int keyIndex,
if (r < 0)
goto out;
r = AF_merge(ctx, AfKey, vk->key, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
r = AF_merge(ctx, AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
if (r < 0)
goto out;
r = LUKS_verify_volume_key(hdr, vk);
r = LUKS_verify_volume_key(hdr, *vk);
/* Allow only empty passphrase with null cipher */
if (!r && !strcmp(hdr->cipherName, "cipher_null") && passwordLen)
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
r = -EPERM;
out:
if (r < 0) {
crypt_free_volume_key(*vk);
*vk = NULL;
}
crypt_safe_free(AfKey);
crypt_free_volume_key(derived_key);
return r;
@@ -1020,16 +1073,14 @@ int LUKS_open_key_with_hdr(int keyIndex,
unsigned int i, tried = 0;
int r;
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (keyIndex >= 0) {
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, *vk, ctx);
r = LUKS_open_key(keyIndex, password, passwordLen, hdr, vk, ctx);
return (r < 0) ? r : keyIndex;
}
for (i = 0; i < LUKS_NUMKEYS; i++) {
r = LUKS_open_key(i, password, passwordLen, hdr, *vk, ctx);
if(r == 0)
r = LUKS_open_key(i, password, passwordLen, hdr, vk, ctx);
if (r == 0)
return i;
/* Do not retry for errors that are no -EPERM or -ENOENT,
@@ -1224,7 +1275,7 @@ int LUKS_wipe_header_areas(struct luks_phdr *hdr,
int LUKS_keyslot_pbkdf(struct luks_phdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf)
{
if (keyslot >= LUKS_NUMKEYS || keyslot < 0)
if (LUKS_keyslot_info(hdr, keyslot) < CRYPT_SLOT_ACTIVE)
return -EINVAL;
pbkdf->type = CRYPT_KDF_PBKDF2;

View File

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

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,6 +23,8 @@
#define _CRYPTSETUP_LUKS2_ONDISK_H
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
#include "libcryptsetup.h"
@@ -42,6 +44,8 @@
#define LUKS2_BUILTIN_TOKEN_PREFIX "luks2-"
#define LUKS2_BUILTIN_TOKEN_PREFIX_LEN 6
#define LUKS2_TOKEN_NAME_MAX 64
#define LUKS2_TOKEN_KEYRING LUKS2_BUILTIN_TOKEN_PREFIX "keyring"
#define LUKS2_DIGEST_MAX 8
@@ -55,7 +59,14 @@
/* 20 MiBs */
#define LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH 0x1400000
/* 1 GiB */
#define LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH 0x40000000
struct device;
struct luks2_reencrypt;
struct crypt_lock_handle;
struct crypt_dm_active_device;
struct luks_phdr; /* LUKS1 for conversion */
/*
* LUKS2 header on-disk.
@@ -91,7 +102,6 @@ struct luks2_hdr_disk {
/*
* LUKS2 header in-memory.
*/
typedef struct json_object json_object;
struct luks2_hdr {
size_t hdr_size;
uint64_t seqid;
@@ -102,7 +112,7 @@ struct luks2_hdr {
uint8_t salt1[LUKS2_SALT_L];
uint8_t salt2[LUKS2_SALT_L];
char uuid[LUKS2_UUID_L];
json_object *jobj;
void *jobj;
};
struct luks2_keyslot_params {
@@ -124,76 +134,6 @@ struct luks2_keyslot_params {
} area;
};
struct reenc_protection {
enum { REENC_PROTECTION_NONE = 0, /* none should be 0 always */
REENC_PROTECTION_CHECKSUM,
REENC_PROTECTION_JOURNAL,
REENC_PROTECTION_DATASHIFT } type;
union {
struct {
} none;
struct {
char hash[LUKS2_CHECKSUM_ALG_L]; // or include luks.h
struct crypt_hash *ch;
size_t hash_size;
/* buffer for checksums */
void *checksums;
size_t checksums_len;
} csum;
struct {
} ds;
} p;
};
struct luks2_reenc_context {
/* reencryption window attributes */
uint64_t offset;
uint64_t progress;
uint64_t length;
uint64_t data_shift;
size_t alignment;
uint64_t device_size;
bool online;
bool fixed_length;
crypt_reencrypt_direction_info direction;
crypt_reencrypt_mode_info mode;
char *device_name;
char *hotzone_name;
char *overlay_name;
/* reencryption window persistence attributes */
struct reenc_protection rp;
int reenc_keyslot;
/* already running reencryption */
json_object *jobj_segs_hot;
json_object *jobj_segs_post;
/* backup segments */
json_object *jobj_segment_new;
int digest_new;
json_object *jobj_segment_old;
int digest_old;
json_object *jobj_segment_moved;
struct volume_key *vks;
void *reenc_buffer;
ssize_t read;
struct crypt_storage_wrapper *cw1;
struct crypt_storage_wrapper *cw2;
uint32_t wflags1;
uint32_t wflags2;
struct crypt_lock_handle *reenc_lock;
};
crypt_reencrypt_info LUKS2_reenc_status(struct luks2_hdr *hdr);
/*
* Supportable header sizes (hdr_disk + JSON area)
* Also used as offset for the 2nd header.
@@ -216,13 +156,11 @@ crypt_reencrypt_info LUKS2_reenc_status(struct luks2_hdr *hdr);
int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
const char *backup_file);
int LUKS2_device_write_lock(struct crypt_device *cd,
struct luks2_hdr *hdr, struct device *device);
int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair);
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr);
int LUKS2_hdr_dump_json(struct crypt_device *cd, struct luks2_hdr *hdr, const char **json);
int LUKS2_hdr_uuid(struct crypt_device *cd,
struct luks2_hdr *hdr,
@@ -243,9 +181,9 @@ int LUKS2_hdr_restore(struct crypt_device *cd,
struct luks2_hdr *hdr,
const char *backup_file);
uint64_t LUKS2_hdr_and_areas_size(json_object *jobj);
uint64_t LUKS2_keyslots_size(json_object *jobj);
uint64_t LUKS2_metadata_size(json_object *jobj);
uint64_t LUKS2_hdr_and_areas_size(struct luks2_hdr *hdr);
uint64_t LUKS2_keyslots_size(struct luks2_hdr *hdr);
uint64_t LUKS2_metadata_size(struct luks2_hdr *hdr);
int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd, const char *cipher_spec);
@@ -274,28 +212,11 @@ int LUKS2_keyslot_store(struct crypt_device *cd,
const struct volume_key *vk,
const struct luks2_keyslot_params *params);
int LUKS2_keyslot_reencrypt_store(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
const void *buffer,
size_t buffer_length);
int LUKS2_keyslot_reencrypt_create(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
const struct crypt_params_reencrypt *params);
int reenc_keyslot_update(struct crypt_device *cd,
const struct luks2_reenc_context *rh);
int LUKS2_keyslot_wipe(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int wipe_area_only);
int LUKS2_keyslot_dump(struct crypt_device *cd,
int keyslot);
crypt_keyslot_priority LUKS2_keyslot_priority_get(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot);
@@ -306,6 +227,11 @@ int LUKS2_keyslot_priority_set(struct crypt_device *cd,
crypt_keyslot_priority priority,
int commit);
int LUKS2_keyslot_swap(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int keyslot2);
/*
* Generic LUKS2 token
*/
@@ -326,6 +252,12 @@ int LUKS2_token_is_assigned(struct crypt_device *cd,
int keyslot,
int token);
int LUKS2_token_assignment_copy(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot_from,
int keyslot_to,
int commit);
int LUKS2_token_create(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
@@ -337,89 +269,25 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
int token,
const char **type);
int LUKS2_builtin_token_get(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *type,
void *params);
int LUKS2_builtin_token_create(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *type,
const void *params,
int commit);
int LUKS2_token_open_and_activate(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *name,
uint32_t flags,
void *usrptr);
int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *name,
uint32_t flags);
const char *type,
const char *pin,
size_t pin_size,
uint32_t flags,
void *usrptr);
int LUKS2_tokens_count(struct luks2_hdr *hdr);
/*
* Generic LUKS2 segment
*/
uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_type(json_object *jobj_segment);
uint64_t json_segment_get_iv_offset(json_object *jobj_segment);
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_get_cipher(json_object *jobj_segment);
int json_segment_get_sector_size(json_object *jobj_segment);
bool json_segment_is_backup(json_object *jobj_segment);
json_object *json_segments_get_segment(json_object *jobj_segments, int segment);
unsigned json_segments_count(json_object *jobj_segments);
void json_segment_remove_flag(json_object *jobj_segment, const char *flag);
uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise);
json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption);
json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, const char *cipher, uint32_t sector_size, unsigned reencryption);
int json_segments_segment_in_reencrypt(json_object *jobj_segments);
int LUKS2_segments_count(struct luks2_hdr *hdr);
int LUKS2_segment_first_unused_id(struct luks2_hdr *hdr);
int LUKS2_segment_set_flag(json_object *jobj_segment, const char *flag);
json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag);
int LUKS2_get_segment_id_by_flag(struct luks2_hdr *hdr, const char *flag);
int LUKS2_segments_set(struct crypt_device *cd,
int LUKS2_token_keyring_get(struct crypt_device *cd,
struct luks2_hdr *hdr,
json_object *jobj_segments,
int commit);
int token,
struct crypt_token_params_luks2_keyring *keyring_params);
uint64_t LUKS2_segment_offset(struct luks2_hdr *hdr,
int segment,
unsigned blockwise);
int LUKS2_token_keyring_json(char *buffer, size_t buffer_size,
const struct crypt_token_params_luks2_keyring *keyring_params);
uint64_t LUKS2_segment_size(struct luks2_hdr *hdr,
int segment,
unsigned blockwise);
int LUKS2_segment_is_type(struct luks2_hdr *hdr,
int segment,
const char *type);
int LUKS2_segment_by_type(struct luks2_hdr *hdr,
const char *type);
int LUKS2_last_segment_by_type(struct luks2_hdr *hdr,
const char *type);
int LUKS2_get_default_segment(struct luks2_hdr *hdr);
int LUKS2_reencrypt_digest_new(struct luks2_hdr *hdr);
int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr);
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);
void crypt_token_unload_external_all(struct crypt_device *cd);
/*
* Generic LUKS2 digest
@@ -428,29 +296,16 @@ int LUKS2_digest_any_matching(struct crypt_device *cd,
struct luks2_hdr *hdr,
const struct volume_key *vk);
int LUKS2_digest_by_segment(struct luks2_hdr *hdr, int segment);
int LUKS2_digest_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
int digest,
const struct volume_key *vk);
int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr,
int segment,
const struct volume_key *vk);
void LUKS2_digests_erase_unused(struct crypt_device *cd,
struct luks2_hdr *hdr);
int LUKS2_digest_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
const struct volume_key *vk,
int keyslot);
int LUKS2_digest_dump(struct crypt_device *cd,
int digest);
int LUKS2_digest_assign(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -467,6 +322,8 @@ int LUKS2_digest_segment_assign(struct crypt_device *cd,
int LUKS2_digest_by_keyslot(struct luks2_hdr *hdr, int keyslot);
int LUKS2_digest_by_segment(struct luks2_hdr *hdr, int segment);
int LUKS2_digest_create(struct crypt_device *cd,
const char *type,
struct luks2_hdr *hdr,
@@ -486,20 +343,12 @@ int LUKS2_activate_multi(struct crypt_device *cd,
uint64_t device_size,
uint32_t flags);
struct crypt_dm_active_device;
int LUKS2_deactivate(struct crypt_device *cd,
const char *name,
struct luks2_hdr *hdr,
struct crypt_dm_active_device *dmd,
uint32_t flags);
int LUKS2_reload(struct crypt_device *cd,
const char *name,
struct volume_key *vks,
uint64_t device_size,
uint32_t flags);
int LUKS2_generate_hdr(
struct crypt_device *cd,
struct luks2_hdr *hdr,
@@ -519,7 +368,7 @@ 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);
struct luks2_hdr *hdr, bool detached_header);
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
@@ -531,19 +380,14 @@ int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment);
int LUKS2_get_keyslot_stored_key_size(struct luks2_hdr *hdr, int keyslot);
const char *LUKS2_get_keyslot_cipher(struct luks2_hdr *hdr, int keyslot, size_t *key_size);
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr);
int LUKS2_keyslot_find_empty(struct crypt_device *cd, struct luks2_hdr *hdr, size_t keylength);
int LUKS2_keyslot_active_count(struct luks2_hdr *hdr, int segment);
int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment);
int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type);
crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot);
int LUKS2_keyslot_area(struct luks2_hdr *hdr,
int keyslot,
uint64_t *offset,
uint64_t *length);
int LUKS2_keyslot_pbkdf(struct luks2_hdr *hdr, int keyslot, struct crypt_pbkdf_type *pbkdf);
int LUKS2_set_keyslots_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
uint64_t data_offset);
/*
* Permanent activation flags stored in header
@@ -566,7 +410,6 @@ int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int digest);
struct luks_phdr;
int LUKS2_luks1_to_luks2(struct crypt_device *cd,
struct luks_phdr *hdr1,
struct luks2_hdr *hdr2);
@@ -585,20 +428,29 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
uint32_t flags,
struct volume_key **vks);
void LUKS2_reenc_context_free(struct crypt_device *cd, struct luks2_reenc_context *rh);
void LUKS2_reencrypt_free(struct crypt_device *cd,
struct luks2_reencrypt *rh);
int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct volume_key *vks,
json_object *jobj_segments,
struct crypt_dm_active_device *dmd);
crypt_reencrypt_info LUKS2_reencrypt_status(struct luks2_hdr *hdr);
crypt_reencrypt_info LUKS2_reencrypt_status(struct crypt_device *cd,
crypt_reencrypt_info LUKS2_reencrypt_get_params(struct luks2_hdr *hdr,
struct crypt_params_reencrypt *params);
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
int LUKS2_reencrypt_lock(struct crypt_device *cd,
struct crypt_lock_handle **reencrypt_lock);
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *dev_size, bool activation, bool dynamic);
int LUKS2_reencrypt_lock_by_dm_uuid(struct crypt_device *cd,
const char *dm_uuid,
struct crypt_lock_handle **reencrypt_lock);
void LUKS2_reencrypt_unlock(struct crypt_device *cd,
struct crypt_lock_handle *reencrypt_lock);
int LUKS2_reencrypt_check_device_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
uint64_t check_size,
uint64_t *dev_size,
bool activation,
bool dynamic);
#endif

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, digest handling
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -28,7 +28,7 @@ static const digest_handler *digest_handlers[LUKS2_DIGEST_MAX] = {
NULL
};
static const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type)
static const digest_handler *LUKS2_digest_handler_type(const char *type)
{
int i;
@@ -57,10 +57,10 @@ static const digest_handler *LUKS2_digest_handler(struct crypt_device *cd, int d
if (!json_object_object_get_ex(jobj1, "type", &jobj2))
return NULL;
return LUKS2_digest_handler_type(cd, json_object_get_string(jobj2));
return LUKS2_digest_handler_type(json_object_get_string(jobj2));
}
static int LUKS2_digest_find_free(struct crypt_device *cd, struct luks2_hdr *hdr)
static int LUKS2_digest_find_free(struct luks2_hdr *hdr)
{
int digest = 0;
@@ -78,11 +78,11 @@ int LUKS2_digest_create(struct crypt_device *cd,
int digest;
const digest_handler *dh;
dh = LUKS2_digest_handler_type(cd, type);
dh = LUKS2_digest_handler_type(type);
if (!dh)
return -EINVAL;
digest = LUKS2_digest_find_free(cd, hdr);
digest = LUKS2_digest_find_free(hdr);
if (digest < 0)
return -EINVAL;
@@ -111,7 +111,7 @@ int LUKS2_digest_by_keyslot(struct luks2_hdr *hdr, int keyslot)
}
int LUKS2_digest_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct luks2_hdr *hdr __attribute__((unused)),
int digest,
const struct volume_key *vk)
{
@@ -219,7 +219,9 @@ static int assign_one_digest(struct crypt_device *cd, struct luks2_hdr *hdr,
if (!jobj_digest_keyslots)
return -EINVAL;
snprintf(num, sizeof(num), "%d", keyslot);
if (snprintf(num, sizeof(num), "%d", keyslot) < 0)
return -EINVAL;
if (assign) {
jobj1 = LUKS2_array_jobj(jobj_digest_keyslots, num);
if (!jobj1)
@@ -254,12 +256,11 @@ int LUKS2_digest_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
if (r < 0)
return r;
// FIXME: do not write header in nothing changed
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
}
static int assign_all_segments(struct crypt_device *cd, struct luks2_hdr *hdr,
int digest, int assign)
static int assign_all_segments(struct crypt_device *cd __attribute__((unused)),
struct luks2_hdr *hdr, int digest, int assign)
{
json_object *jobj1, *jobj_digest, *jobj_digest_segments;
@@ -304,7 +305,9 @@ static int assign_one_segment(struct crypt_device *cd, struct luks2_hdr *hdr,
if (!jobj_digest_segments)
return -EINVAL;
snprintf(num, sizeof(num), "%d", segment);
if (snprintf(num, sizeof(num), "%d", segment) < 0)
return -EINVAL;
if (assign) {
jobj1 = LUKS2_array_jobj(jobj_digest_segments, num);
if (!jobj1)
@@ -349,7 +352,6 @@ int LUKS2_digest_segment_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
if (r < 0)
return r;
// FIXME: do not write header in nothing changed
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
}
@@ -441,7 +443,7 @@ int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
}
int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int digest)
struct luks2_hdr *hdr __attribute__((unused)), struct volume_key *vk, int digest)
{
char *desc = get_key_description_by_digest(cd, digest);
int r;

View File

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

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -62,8 +62,8 @@ static void log_dbg_checksum(struct crypt_device *cd,
int i;
for (i = 0; i < crypt_hash_size(csum_alg); i++)
snprintf(&csum_txt[i*2], 3, "%02hhx", (const char)csum[i]);
csum_txt[i*2+1] = '\0'; /* Just to be safe, sprintf should write \0 there. */
if (snprintf(&csum_txt[i*2], 3, "%02hhx", (const char)csum[i]) != 2)
return;
log_dbg(cd, "Checksum:%s (%s)", &csum_txt[0], info);
}
@@ -175,13 +175,13 @@ static void hdr_to_disk(struct luks2_hdr *hdr,
hdr_disk->hdr_offset = cpu_to_be64(offset);
hdr_disk->seqid = cpu_to_be64(hdr->seqid);
strncpy(hdr_disk->label, hdr->label, LUKS2_LABEL_L);
memcpy(hdr_disk->label, hdr->label, MIN(strlen(hdr->label), LUKS2_LABEL_L));
hdr_disk->label[LUKS2_LABEL_L - 1] = '\0';
strncpy(hdr_disk->subsystem, hdr->subsystem, LUKS2_LABEL_L);
memcpy(hdr_disk->subsystem, hdr->subsystem, MIN(strlen(hdr->subsystem), LUKS2_LABEL_L));
hdr_disk->subsystem[LUKS2_LABEL_L - 1] = '\0';
strncpy(hdr_disk->checksum_alg, hdr->checksum_alg, LUKS2_CHECKSUM_ALG_L);
memcpy(hdr_disk->checksum_alg, hdr->checksum_alg, MIN(strlen(hdr->checksum_alg), LUKS2_CHECKSUM_ALG_L));
hdr_disk->checksum_alg[LUKS2_CHECKSUM_ALG_L - 1] = '\0';
strncpy(hdr_disk->uuid, hdr->uuid, LUKS2_UUID_L);
memcpy(hdr_disk->uuid, hdr->uuid, MIN(strlen(hdr->uuid), LUKS2_UUID_L));
hdr_disk->uuid[LUKS2_UUID_L - 1] = '\0';
memcpy(hdr_disk->salt, secondary ? hdr->salt2 : hdr->salt1, LUKS2_SALT_L);
@@ -195,6 +195,8 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
size_t *hdr_json_size, int secondary,
uint64_t offset)
{
uint64_t hdr_size;
if (memcmp(hdr->magic, secondary ? LUKS2_MAGIC_2ND : LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
return -EINVAL;
@@ -204,24 +206,31 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
}
if (offset != be64_to_cpu(hdr->hdr_offset)) {
log_dbg(cd, "LUKS2 offset 0x%04x on device differs to expected offset 0x%04x.",
(unsigned)be64_to_cpu(hdr->hdr_offset), (unsigned)offset);
log_dbg(cd, "LUKS2 offset 0x%04" PRIx64 " on device differs to expected offset 0x%04" PRIx64 ".",
be64_to_cpu(hdr->hdr_offset), offset);
return -EINVAL;
}
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
hdr_size = be64_to_cpu(hdr->hdr_size);
if (hdr_size < LUKS2_HDR_16K_LEN || hdr_size > LUKS2_HDR_OFFSET_MAX) {
log_dbg(cd, "LUKS2 header has bogus size 0x%04" PRIx64 ".", hdr_size);
return -EINVAL;
}
if (secondary && (offset != hdr_size)) {
log_dbg(cd, "LUKS2 offset 0x%04" PRIx64 " in secondary header does not match size 0x%04" PRIx64 ".",
offset, hdr_size);
return -EINVAL;
}
/* FIXME: sanity check checksum alg. */
log_dbg(cd, "LUKS2 header version %u of size %u bytes, checksum %s.",
(unsigned)be16_to_cpu(hdr->version), (unsigned)be64_to_cpu(hdr->hdr_size),
log_dbg(cd, "LUKS2 header version %u of size %" PRIu64 " bytes, checksum %s.",
be16_to_cpu(hdr->version), hdr_size,
hdr->checksum_alg);
*hdr_json_size = be64_to_cpu(hdr->hdr_size) - LUKS2_HDR_BIN_LEN;
*hdr_json_size = hdr_size - LUKS2_HDR_BIN_LEN;
return 0;
}
@@ -252,18 +261,19 @@ static int hdr_read_disk(struct crypt_device *cd,
return -EIO;
}
/*
* hdr_json_size is validated if this call succeeds
*/
r = hdr_disk_sanity_check_pre(cd, hdr_disk, &hdr_json_size, secondary, offset);
if (r < 0) {
if (r < 0)
return r;
}
/*
* Allocate and read JSON area. Always the whole area must be read.
*/
*json_area = malloc(hdr_json_size);
if (!*json_area) {
if (!*json_area)
return -ENOMEM;
}
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), *json_area, hdr_json_size,
@@ -279,6 +289,8 @@ static int hdr_read_disk(struct crypt_device *cd,
if (hdr_checksum_check(cd, hdr_disk->checksum_alg, hdr_disk,
*json_area, hdr_json_size)) {
log_dbg(cd, "LUKS2 header checksum error (offset %" PRIu64 ").", offset);
free(*json_area);
*json_area = NULL;
r = -EINVAL;
}
memset(hdr_disk->csum, 0, LUKS2_CHECKSUM_L);
@@ -301,8 +313,6 @@ static int hdr_write_disk(struct crypt_device *cd,
log_dbg(cd, "Trying to write LUKS2 header (%zu bytes) at offset %" PRIu64 ".",
hdr->hdr_size, offset);
/* FIXME: read-only device silent fail? */
devfd = device_open_locked(cd, device, O_RDWR);
if (devfd < 0)
return devfd == -1 ? -EINVAL : devfd;
@@ -385,7 +395,7 @@ int LUKS2_device_write_lock(struct crypt_device *cd, struct luks2_hdr *hdr, stru
}
/* run sequence id check only on first write lock (r == 1) and w/o LUKS2 reencryption in-progress */
if (r == 1 && !crypt_get_reenc_context(cd)) {
if (r == 1 && !crypt_get_luks2_reencrypt(cd)) {
log_dbg(cd, "Checking context sequence id matches value stored on disk.");
if (LUKS2_check_sequence_id(cd, hdr, device)) {
device_write_unlock(cd, device);
@@ -413,7 +423,7 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
return -EINVAL;
}
r = device_check_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
r = device_check_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr), 1);
if (r)
return r;
@@ -669,9 +679,9 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
/* check header with keyslots to fit the device */
if (state_hdr1 == HDR_OK)
hdr_size = LUKS2_hdr_and_areas_size(jobj_hdr1);
hdr_size = LUKS2_hdr_and_areas_size_jobj(jobj_hdr1);
else if (state_hdr2 == HDR_OK)
hdr_size = LUKS2_hdr_and_areas_size(jobj_hdr2);
hdr_size = LUKS2_hdr_and_areas_size_jobj(jobj_hdr2);
else {
r = (state_hdr1 == HDR_FAIL_IO && state_hdr2 == HDR_FAIL_IO) ? -EIO : -EINVAL;
goto err;
@@ -788,14 +798,11 @@ int LUKS2_hdr_version_unlocked(struct crypt_device *cd, const char *backup_file)
flags |= O_DIRECT;
devfd = open(device_path(device), flags);
if (devfd < 0)
goto err;
if ((read_lseek_blockwise(devfd, device_block_size(cd, device),
if (devfd != -1 && (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &hdr, sizeof(hdr), 0) == sizeof(hdr)) &&
!memcmp(hdr.magic, LUKS2_MAGIC_1ST, LUKS2_MAGIC_L))
r = (int)be16_to_cpu(hdr.version);
err:
if (devfd != -1)
close(devfd);

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,7 +23,6 @@
#define _CRYPTSETUP_LUKS2_INTERNAL_H
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <json-c/json.h>
@@ -31,8 +30,6 @@
#include "base64.h"
#include "luks2.h"
#define UNUSED(x) (void)(x)
/* override useless forward slash escape when supported by json-c */
#ifndef JSON_C_TO_STRING_NOSLASHESCAPE
#define JSON_C_TO_STRING_NOSLASHESCAPE 0
@@ -45,6 +42,8 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
struct device *device, int do_recovery, int do_blkprobe);
int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr,
struct device *device, bool seqid_check);
int LUKS2_device_write_lock(struct crypt_device *cd,
struct luks2_hdr *hdr, struct device *device);
/*
* JSON struct access helpers
@@ -59,9 +58,9 @@ json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr);
void hexprint_base64(struct crypt_device *cd, json_object *jobj,
const char *sep, const char *line_sep);
uint64_t json_object_get_uint64(json_object *jobj);
uint32_t json_object_get_uint32(json_object *jobj);
json_object *json_object_new_uint64(uint64_t value);
uint64_t crypt_jobj_get_uint64(json_object *jobj);
uint32_t crypt_jobj_get_uint32(json_object *jobj);
json_object *crypt_jobj_new_uint64(uint64_t value);
int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object *jobj_val);
void json_object_object_del_by_uint(json_object *jobj, unsigned key);
@@ -93,8 +92,8 @@ void LUKS2_keyslots_repair(struct crypt_device *cd, json_object *jobj_hdr);
/*
* JSON array helpers
*/
struct json_object *LUKS2_array_jobj(struct json_object *array, const char *num);
struct json_object *LUKS2_array_remove(struct json_object *array, const char *num);
json_object *LUKS2_array_jobj(json_object *array, const char *num);
json_object *LUKS2_array_remove(json_object *array, const char *num);
/*
* Plugins API
@@ -163,28 +162,53 @@ typedef struct {
digest_dump_func dump;
} digest_handler;
/**
* LUKS2 token handlers (internal use only)
int keyring_open(struct crypt_device *cd,
int token,
char **buffer,
size_t *buffer_len,
void *usrptr);
void keyring_dump(struct crypt_device *cd, const char *json);
int keyring_validate(struct crypt_device *cd, const char *json);
struct crypt_token_handler_v2 {
const char *name;
crypt_token_open_func open;
crypt_token_buffer_free_func buffer_free;
crypt_token_validate_func validate;
crypt_token_dump_func dump;
/* here ends v1. Do not touch anything above */
crypt_token_open_pin_func open_pin;
crypt_token_version_func version;
void *dlhandle;
};
/*
* Initial sequence of structure members in union 'u' must be always
* identical. Version 4 must fully contain version 3 which must
* subsequently fully contain version 2, etc.
*
* See C standard, section 6.5.2.3, item 5.
*/
typedef int (*builtin_token_get_func) (json_object *jobj_token, void *params);
typedef int (*builtin_token_set_func) (json_object **jobj_token, const void *params);
typedef struct {
/* internal only section used by builtin tokens */
builtin_token_get_func get;
builtin_token_set_func set;
/* public token handler */
const crypt_token_handler *h;
} token_handler;
int token_keyring_set(json_object **, const void *);
int token_keyring_get(json_object *, void *);
struct crypt_token_handler_internal {
uint32_t version;
union {
crypt_token_handler v1; /* deprecated public structure */
struct crypt_token_handler_v2 v2; /* internal helper v2 structure */
} u;
};
int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
size_t keylength, uint64_t *area_offset, uint64_t *area_length);
int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
uint64_t *area_offset, uint64_t *area_length);
uint64_t LUKS2_hdr_and_areas_size_jobj(json_object *jobj);
int LUKS2_check_cipher(struct crypt_device *cd,
size_t keylength,
const char *cipher,
@@ -201,4 +225,119 @@ static inline const char *crypt_reencrypt_mode_to_str(crypt_reencrypt_mode_info
return "<unknown>";
}
/*
* Generic LUKS2 keyslot
*/
int LUKS2_keyslot_reencrypt_store(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
const void *buffer,
size_t buffer_length);
int LUKS2_keyslot_reencrypt_create(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
const struct crypt_params_reencrypt *params);
int LUKS2_keyslot_dump(struct crypt_device *cd,
int keyslot);
/* JSON helpers */
uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_type(json_object *jobj_segment);
uint64_t json_segment_get_iv_offset(json_object *jobj_segment);
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise);
const char *json_segment_get_cipher(json_object *jobj_segment);
int json_segment_get_sector_size(json_object *jobj_segment);
bool json_segment_is_backup(json_object *jobj_segment);
json_object *json_segments_get_segment(json_object *jobj_segments, int segment);
unsigned json_segments_count(json_object *jobj_segments);
void json_segment_remove_flag(json_object *jobj_segment, const char *flag);
uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise);
json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption);
json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, const char *cipher, uint32_t sector_size, unsigned reencryption);
int json_segments_segment_in_reencrypt(json_object *jobj_segments);
int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct volume_key *vks,
json_object *jobj_segments,
struct crypt_dm_active_device *dmd);
/*
* Generic LUKS2 segment
*/
int LUKS2_segments_count(struct luks2_hdr *hdr);
int LUKS2_segment_first_unused_id(struct luks2_hdr *hdr);
int LUKS2_segment_set_flag(json_object *jobj_segment, const char *flag);
json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag);
int LUKS2_get_segment_id_by_flag(struct luks2_hdr *hdr, const char *flag);
int LUKS2_segments_set(struct crypt_device *cd,
struct luks2_hdr *hdr,
json_object *jobj_segments,
int commit);
uint64_t LUKS2_segment_offset(struct luks2_hdr *hdr,
int segment,
unsigned blockwise);
uint64_t LUKS2_segment_size(struct luks2_hdr *hdr,
int segment,
unsigned blockwise);
int LUKS2_segment_is_type(struct luks2_hdr *hdr,
int segment,
const char *type);
int LUKS2_segment_by_type(struct luks2_hdr *hdr,
const char *type);
int LUKS2_last_segment_by_type(struct luks2_hdr *hdr,
const char *type);
int LUKS2_get_default_segment(struct luks2_hdr *hdr);
int LUKS2_reencrypt_digest_new(struct luks2_hdr *hdr);
int LUKS2_reencrypt_digest_old(struct luks2_hdr *hdr);
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);
/*
* Generic LUKS2 digest
*/
int LUKS2_digest_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
int digest,
const struct volume_key *vk);
void LUKS2_digests_erase_unused(struct crypt_device *cd,
struct luks2_hdr *hdr);
int LUKS2_digest_dump(struct crypt_device *cd,
int digest);
/*
* Generic LUKS2 token
*/
int LUKS2_tokens_count(struct luks2_hdr *hdr);
/*
* LUKS2 generic
*/
int LUKS2_reload(struct crypt_device *cd,
const char *name,
struct volume_key *vks,
uint64_t device_size,
uint32_t flags);
int LUKS2_keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment);
int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type);
int LUKS2_set_keyslots_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
uint64_t data_offset);
#endif

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS2 header format code
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -30,7 +30,7 @@ struct area {
static size_t get_area_size(size_t keylength)
{
//FIXME: calculate this properly, for now it is AF_split_sectors
/* for now it is AF_split_sectors */
return size_round_up(keylength * 4000, 4096);
}
@@ -41,7 +41,7 @@ static size_t get_min_offset(struct luks2_hdr *hdr)
static size_t get_max_offset(struct luks2_hdr *hdr)
{
return LUKS2_hdr_and_areas_size(hdr->jobj);
return LUKS2_hdr_and_areas_size(hdr);
}
int LUKS2_find_area_max_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
@@ -177,8 +177,11 @@ int LUKS2_find_area_gap(struct crypt_device *cd, struct luks2_hdr *hdr,
log_dbg(cd, "Found area %zu -> %zu", offset, length + offset);
*area_offset = offset;
*area_length = length;
if (area_offset)
*area_offset = offset;
if (area_length)
*area_length = length;
return 0;
}
@@ -216,7 +219,7 @@ int LUKS2_generate_hdr(
struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
char cipher[128];
uuid_t partitionUuid;
int digest;
int r, digest;
uint64_t mdev_size;
if (!metadata_size)
@@ -244,7 +247,8 @@ int LUKS2_generate_hdr(
/* Decrease keyslots_size due to metadata device being too small */
if (!device_size(crypt_metadata_device(cd), &mdev_size) &&
((keyslots_size + get_min_offset(hdr)) > mdev_size) &&
device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)))
device_fallocate(crypt_metadata_device(cd), keyslots_size + get_min_offset(hdr)) &&
(get_min_offset(hdr) <= mdev_size))
keyslots_size = mdev_size - get_min_offset(hdr);
}
@@ -289,9 +293,11 @@ int LUKS2_generate_hdr(
uuid_unparse(partitionUuid, hdr->uuid);
if (*cipherMode != '\0')
snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode);
r = snprintf(cipher, sizeof(cipher), "%s-%s", cipherName, cipherMode);
else
snprintf(cipher, sizeof(cipher), "%s", cipherName);
r = snprintf(cipher, sizeof(cipher), "%s", cipherName);
if (r < 0 || (size_t)r >= sizeof(cipher))
return -EINVAL;
hdr->jobj = json_object_new_object();
@@ -325,8 +331,8 @@ int LUKS2_generate_hdr(
json_object_object_add_by_uint(jobj_segments, 0, jobj_segment);
json_object_object_add(jobj_config, "json_size", json_object_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(jobj_config, "json_size", crypt_jobj_new_uint64(metadata_size - LUKS2_HDR_BIN_LEN));
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
JSON_DBG(cd, hdr->jobj, "Header JSON:");
return 0;
@@ -337,7 +343,7 @@ err:
}
int LUKS2_wipe_header_areas(struct crypt_device *cd,
struct luks2_hdr *hdr)
struct luks2_hdr *hdr, bool detached_header)
{
int r;
uint64_t offset, length;
@@ -352,7 +358,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
return -EINVAL;
/* On detached header wipe at least the first 4k */
if (length == 0) {
if (detached_header) {
length = 4096;
wipe_block = 4096;
}
@@ -368,7 +374,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
/* Wipe keyslot area */
wipe_block = 1024 * 1024;
offset = get_min_offset(hdr);
length = LUKS2_keyslots_size(hdr->jobj);
length = LUKS2_keyslots_size(hdr);
log_dbg(cd, "Wiping keyslots area (0x%06" PRIx64 " - 0x%06" PRIx64") with random data.",
offset, length + offset);
@@ -377,8 +383,7 @@ int LUKS2_wipe_header_areas(struct crypt_device *cd,
offset, length, wipe_block, NULL, NULL);
}
/* FIXME: what if user wanted to keep original keyslots size? */
int LUKS2_set_keyslots_size(struct crypt_device *cd,
int LUKS2_set_keyslots_size(struct crypt_device *cd __attribute__((unused)),
struct luks2_hdr *hdr,
uint64_t data_offset)
{
@@ -400,6 +405,6 @@ int LUKS2_set_keyslots_size(struct crypt_device *cd,
if (!json_object_object_get_ex(hdr->jobj, "config", &jobj_config))
return 1;
json_object_object_add(jobj_config, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(jobj_config, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
return 0;
}

View File

@@ -1,9 +1,9 @@
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2019 Ondrej Kozina
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
* Copyright (C) 2015-2021 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -45,11 +45,11 @@ void hexprint_base64(struct crypt_device *cd, json_object *jobj,
&buf, &buf_len))
return;
for (i = 0; i < buf_len / 2; i++)
log_std(cd, "%02hhx%s", buf[i], sep);
log_std(cd, "\n\t%s", line_sep);
for (i = buf_len / 2; i < buf_len; i++)
for (i = 0; i < buf_len; i++) {
if (i && !(i % 16))
log_std(cd, "\n\t%s", line_sep);
log_std(cd, "%02hhx%s", buf[i], sep);
}
log_std(cd, "\n");
free(buf);
}
@@ -219,7 +219,7 @@ int LUKS2_get_default_segment(struct luks2_hdr *hdr)
* json_type_int needs to be validated first.
* See validate_json_uint32()
*/
uint32_t json_object_get_uint32(json_object *jobj)
uint32_t crypt_jobj_get_uint32(json_object *jobj)
{
return json_object_get_int64(jobj);
}
@@ -234,21 +234,21 @@ static json_bool json_str_to_uint64(json_object *jobj, uint64_t *value)
tmp = strtoull(json_object_get_string(jobj), &endptr, 10);
if (*endptr || errno) {
*value = 0;
return FALSE;
return 0;
}
*value = tmp;
return TRUE;
return 1;
}
uint64_t json_object_get_uint64(json_object *jobj)
uint64_t crypt_jobj_get_uint64(json_object *jobj)
{
uint64_t r;
json_str_to_uint64(jobj, &r);
return r;
}
json_object *json_object_new_uint64(uint64_t value)
json_object *crypt_jobj_new_uint64(uint64_t value)
{
/* 18446744073709551615 */
char num[21];
@@ -273,9 +273,9 @@ static json_bool numbered(struct crypt_device *cd, const char *name, const char
for (i = 0; key[i]; i++)
if (!isdigit(key[i])) {
log_dbg(cd, "%s \"%s\" is not in numbered form.", name, key);
return FALSE;
return 0;
}
return TRUE;
return 1;
}
json_object *json_contains(struct crypt_device *cd, json_object *jobj, const char *name,
@@ -300,7 +300,7 @@ json_bool validate_json_uint32(json_object *jobj)
errno = 0;
tmp = json_object_get_int64(jobj);
return (errno || tmp < 0 || tmp > UINT32_MAX) ? FALSE : TRUE;
return (errno || tmp < 0 || tmp > UINT32_MAX) ? 0 : 1;
}
static json_bool validate_keyslots_array(struct crypt_device *cd,
@@ -313,17 +313,17 @@ static json_bool validate_keyslots_array(struct crypt_device *cd,
jobj = json_object_array_get_idx(jarr, i);
if (!json_object_is_type(jobj, json_type_string)) {
log_dbg(cd, "Illegal value type in keyslots array at index %d.", i);
return FALSE;
return 0;
}
if (!json_contains(cd, jobj_keys, "", "Keyslots section",
json_object_get_string(jobj), json_type_object))
return FALSE;
return 0;
i++;
}
return TRUE;
return 1;
}
static json_bool validate_segments_array(struct crypt_device *cd,
@@ -336,17 +336,17 @@ static json_bool validate_segments_array(struct crypt_device *cd,
jobj = json_object_array_get_idx(jarr, i);
if (!json_object_is_type(jobj, json_type_string)) {
log_dbg(cd, "Illegal value type in segments array at index %d.", i);
return FALSE;
return 0;
}
if (!json_contains(cd, jobj_segments, "", "Segments section",
json_object_get_string(jobj), json_type_object))
return FALSE;
return 0;
i++;
}
return TRUE;
return 1;
}
static json_bool segment_has_digest(const char *segment_name, json_object *jobj_digests)
@@ -357,10 +357,10 @@ static json_bool segment_has_digest(const char *segment_name, json_object *jobj_
UNUSED(key);
json_object_object_get_ex(val, "segments", &jobj_segments);
if (LUKS2_array_jobj(jobj_segments, segment_name))
return TRUE;
return 1;
}
return FALSE;
return 0;
}
static json_bool validate_intervals(struct crypt_device *cd,
@@ -372,18 +372,18 @@ static json_bool validate_intervals(struct crypt_device *cd,
while (i < length) {
if (ix[i].offset < 2 * metadata_size) {
log_dbg(cd, "Illegal area offset: %" PRIu64 ".", ix[i].offset);
return FALSE;
return 0;
}
if (!ix[i].length) {
log_dbg(cd, "Area length must be greater than zero.");
return FALSE;
return 0;
}
if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
log_dbg(cd, "Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
return FALSE;
return 0;
}
for (j = 0; j < length; j++) {
@@ -393,17 +393,18 @@ static json_bool validate_intervals(struct crypt_device *cd,
log_dbg(cd, "Overlapping areas [%" PRIu64 ",%" PRIu64 "] and [%" PRIu64 ",%" PRIu64 "].",
ix[i].offset, ix[i].offset + ix[i].length,
ix[j].offset, ix[j].offset + ix[j].length);
return FALSE;
return 0;
}
}
i++;
}
return TRUE;
return 1;
}
static int LUKS2_keyslot_validate(struct crypt_device *cd, json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
static int LUKS2_keyslot_validate(struct crypt_device *cd, json_object *hdr_jobj __attribute__((unused)),
json_object *hdr_keyslot, const char *key)
{
json_object *jobj_key_size;
@@ -455,16 +456,16 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
json = json_object_to_json_string_ext(hdr_jobj,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
json_area_size = json_object_get_uint64(jobj1);
json_area_size = crypt_jobj_get_uint64(jobj1);
json_size = (uint64_t)strlen(json);
if (hdr_json_size != json_area_size) {
log_dbg(cd, "JSON area size doesn't match value in binary header.");
log_dbg(cd, "JSON area size does not match value in binary header.");
return 1;
}
if (json_size > json_area_size) {
log_dbg(cd, "JSON doesn't fit in the designated area.");
log_dbg(cd, "JSON does not fit in the designated area.");
return 1;
}
@@ -516,7 +517,7 @@ static int hdr_validate_tokens(struct crypt_device *cd, json_object *hdr_jobj)
static int hdr_validate_crypt_segment(struct crypt_device *cd,
json_object *jobj, const char *key, json_object *jobj_digests,
uint64_t offset, uint64_t size)
uint64_t offset __attribute__((unused)), uint64_t size)
{
json_object *jobj_ivoffset, *jobj_sector_size, *jobj_integrity;
uint32_t sector_size;
@@ -543,7 +544,7 @@ static int hdr_validate_crypt_segment(struct crypt_device *cd,
return 1;
}
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (!sector_size || MISALIGNED_512(sector_size)) {
log_dbg(cd, "Illegal sector size: %" PRIu32, sector_size);
return 1;
@@ -594,9 +595,9 @@ static bool validate_segment_intervals(struct crypt_device *cd,
static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
{
json_object *jobj_segments, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags, *jobj;
struct interval *intervals;
uint64_t offset, size;
int i, r, count, first_backup = -1;
struct interval *intervals = NULL;
if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments)) {
log_dbg(cd, "Missing segments section.");
@@ -676,10 +677,18 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
return 1;
}
/* avoid needlessly large allocation when first backup segment is invalid */
if (first_backup >= count) {
log_dbg(cd, "Gap between last regular segment and backup segment at key %d.", first_backup);
return 1;
}
if (first_backup < 0)
first_backup = count;
intervals = malloc(first_backup * sizeof(*intervals));
if ((size_t)first_backup < SIZE_MAX / sizeof(*intervals))
intervals = malloc(first_backup * sizeof(*intervals));
if (!intervals) {
log_dbg(cd, "Not enough memory.");
return 1;
@@ -712,7 +721,7 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
return 0;
}
uint64_t LUKS2_metadata_size(json_object *jobj)
static uint64_t LUKS2_metadata_size_jobj(json_object *jobj)
{
json_object *jobj1, *jobj2;
uint64_t json_size;
@@ -724,6 +733,11 @@ uint64_t LUKS2_metadata_size(json_object *jobj)
return json_size + LUKS2_HDR_BIN_LEN;
}
uint64_t LUKS2_metadata_size(struct luks2_hdr *hdr)
{
return LUKS2_metadata_size_jobj(hdr->jobj);
}
static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
{
struct interval *intervals;
@@ -739,7 +753,7 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
return 1;
/* config is already validated */
metadata_size = LUKS2_metadata_size(hdr_jobj);
metadata_size = LUKS2_metadata_size_jobj(hdr_jobj);
length = json_object_object_length(jobj_keyslots);
@@ -785,7 +799,7 @@ static int hdr_validate_areas(struct crypt_device *cd, json_object *hdr_jobj)
return 1;
}
ret = validate_intervals(cd, length, intervals, metadata_size, LUKS2_hdr_and_areas_size(hdr_jobj)) ? 0 : 1;
ret = validate_intervals(cd, length, intervals, metadata_size, LUKS2_hdr_and_areas_size_jobj(hdr_jobj)) ? 0 : 1;
free(intervals);
@@ -970,13 +984,16 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
return r;
}
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
static int hdr_cleanup_and_validate(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* NOTE: is called before LUKS2 validation routines */
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
return LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
}
int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
{
if (hdr_cleanup_and_validate(cd, hdr))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), false);
@@ -984,11 +1001,7 @@ int LUKS2_hdr_write_force(struct crypt_device *cd, struct luks2_hdr *hdr)
int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr)
{
/* NOTE: is called before LUKS2 validation routines */
/* erase unused digests (no assigned keyslot or segment) */
LUKS2_digests_erase_unused(cd, hdr);
if (LUKS2_hdr_validate(cd, hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
if (hdr_cleanup_and_validate(cd, hdr))
return -EINVAL;
return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd), true);
@@ -1034,7 +1047,7 @@ void LUKS2_hdr_free(struct crypt_device *cd, struct luks2_hdr *hdr)
log_dbg(cd, "LUKS2 header still in use");
}
uint64_t LUKS2_keyslots_size(json_object *jobj)
static uint64_t LUKS2_keyslots_size_jobj(json_object *jobj)
{
json_object *jobj1, *jobj2;
uint64_t keyslots_size;
@@ -1046,9 +1059,19 @@ uint64_t LUKS2_keyslots_size(json_object *jobj)
return keyslots_size;
}
uint64_t LUKS2_hdr_and_areas_size(json_object *jobj)
uint64_t LUKS2_keyslots_size(struct luks2_hdr *hdr)
{
return 2 * LUKS2_metadata_size(jobj) + LUKS2_keyslots_size(jobj);
return LUKS2_keyslots_size_jobj(hdr->jobj);
}
uint64_t LUKS2_hdr_and_areas_size_jobj(json_object *jobj)
{
return 2 * LUKS2_metadata_size_jobj(jobj) + LUKS2_keyslots_size_jobj(jobj);
}
uint64_t LUKS2_hdr_and_areas_size(struct luks2_hdr *hdr)
{
return LUKS2_hdr_and_areas_size_jobj(hdr->jobj);
}
int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
@@ -1060,7 +1083,7 @@ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
ssize_t ret, buffer_size;
char *buffer = NULL;
hdr_size = LUKS2_hdr_and_areas_size(hdr->jobj);
hdr_size = LUKS2_hdr_and_areas_size(hdr);
buffer_size = size_round_up(hdr_size, crypt_getpagesize());
buffer = crypt_safe_alloc(buffer_size);
@@ -1159,7 +1182,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
device_free(cd, backup_device);
if (r < 0) {
log_err(cd, _("Backup file doesn't contain valid LUKS header."));
log_err(cd, _("Backup file does not contain valid LUKS header."));
goto out;
}
@@ -1171,7 +1194,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
goto out;
}
buffer_size = LUKS2_hdr_and_areas_size(hdr_file.jobj);
buffer_size = LUKS2_hdr_and_areas_size(&hdr_file);
buffer = crypt_safe_alloc(buffer_size);
if (!buffer) {
r = -ENOMEM;
@@ -1211,7 +1234,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
goto out;
}
/* FIXME: what could go wrong? Erase if we're fine with consequences */
if (buffer_size != (ssize_t) LUKS2_hdr_and_areas_size(tmp_hdr.jobj)) {
if (buffer_size != (ssize_t) LUKS2_hdr_and_areas_size(&tmp_hdr)) {
log_err(cd, _("Binary header with keyslot areas size differ on device and backup, restore failed."));
r = -EINVAL;
goto out;
@@ -1270,8 +1293,8 @@ out:
LUKS2_hdr_free(cd, hdr);
LUKS2_hdr_free(cd, &hdr_file);
LUKS2_hdr_free(cd, &tmp_hdr);
crypt_memzero(&hdr_file, sizeof(hdr_file));
crypt_memzero(&tmp_hdr, sizeof(tmp_hdr));
crypt_safe_memzero(&hdr_file, sizeof(hdr_file));
crypt_safe_memzero(&tmp_hdr, sizeof(tmp_hdr));
crypt_safe_free(buffer);
device_sync(cd, device);
@@ -1290,6 +1313,8 @@ static const struct {
{ CRYPT_ACTIVATE_SAME_CPU_CRYPT, "same-cpu-crypt" },
{ CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS, "submit-from-crypt-cpus" },
{ CRYPT_ACTIVATE_NO_JOURNAL, "no-journal" },
{ CRYPT_ACTIVATE_NO_READ_WORKQUEUE, "no-read-workqueue" },
{ CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE, "no-write-workqueue" },
{ 0, NULL }
};
@@ -1567,7 +1592,7 @@ static void hdr_dump_keyslots(struct crypt_device *cd, json_object *hdr_jobj)
log_std(cd, " %s: %s%s\n", slot, tmps, r == -ENOENT ? " (unbound)" : "");
if (json_object_object_get_ex(val, "key_size", &jobj2))
log_std(cd, "\tKey: %u bits\n", json_object_get_uint32(jobj2) * 8);
log_std(cd, "\tKey: %u bits\n", crypt_jobj_get_uint32(jobj2) * 8);
log_std(cd, "\tPriority: %s\n", get_priority_desc(val));
@@ -1611,7 +1636,7 @@ static void hdr_dump_tokens(struct crypt_device *cd, json_object *hdr_jobj)
json_object_object_get_ex(val, "keyslots", &jobj2);
for (i = 0; i < (int) json_object_array_length(jobj2); i++) {
jobj3 = json_object_array_get_idx(jobj2, i);
log_std(cd, "\tKeyslot: %s\n", json_object_get_string(jobj3));
log_std(cd, "\tKeyslot: %s\n", json_object_get_string(jobj3));
}
}
}
@@ -1650,7 +1675,7 @@ static void hdr_dump_segments(struct crypt_device *cd, json_object *hdr_jobj)
log_std(cd, "\tcipher: %s\n", json_object_get_string(jobj1));
if (json_object_object_get_ex(jobj_segment, "sector_size", &jobj1))
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", json_object_get_uint32(jobj1));
log_std(cd, "\tsector: %" PRIu32 " [bytes]\n", crypt_jobj_get_uint32(jobj1));
if (json_object_object_get_ex(jobj_segment, "integrity", &jobj1) &&
json_object_object_get_ex(jobj1, "type", &jobj2))
@@ -1705,8 +1730,8 @@ int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr)
log_std(cd, "LUKS header information\n");
log_std(cd, "Version: \t%u\n", hdr->version);
log_std(cd, "Epoch: \t%" PRIu64 "\n", hdr->seqid);
log_std(cd, "Metadata area: \t%" PRIu64 " [bytes]\n", LUKS2_metadata_size(hdr->jobj));
log_std(cd, "Keyslots area: \t%" PRIu64 " [bytes]\n", LUKS2_keyslots_size(hdr->jobj));
log_std(cd, "Metadata area: \t%" PRIu64 " [bytes]\n", LUKS2_metadata_size(hdr));
log_std(cd, "Keyslots area: \t%" PRIu64 " [bytes]\n", LUKS2_keyslots_size(hdr));
log_std(cd, "UUID: \t%s\n", *hdr->uuid ? hdr->uuid : "(no UUID)");
log_std(cd, "Label: \t%s\n", *hdr->label ? hdr->label : "(no label)");
log_std(cd, "Subsystem: \t%s\n", *hdr->subsystem ? hdr->subsystem : "(no subsystem)");
@@ -1720,6 +1745,24 @@ int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr)
return 0;
}
int LUKS2_hdr_dump_json(struct crypt_device *cd, struct luks2_hdr *hdr, const char **json)
{
const char *json_buf;
json_buf = json_object_to_json_string_ext(hdr->jobj,
JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_NOSLASHESCAPE);
if (!json_buf)
return -EINVAL;
if (json)
*json = json_buf;
else
crypt_log(cd, CRYPT_LOG_NORMAL, json_buf);
return 0;
}
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic)
{
int sector_size;
@@ -1747,7 +1790,7 @@ int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic)
return 0;
}
tmp += json_object_get_uint64(jobj_size);
tmp += crypt_jobj_get_uint64(jobj_size);
}
/* impossible, real device size must not be zero */
@@ -1765,7 +1808,7 @@ uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr)
crypt_reencrypt_info ri;
json_object *jobj;
ri = LUKS2_reenc_status(hdr);
ri = LUKS2_reencrypt_status(hdr);
if (ri == CRYPT_REENCRYPT_CLEAN || ri == CRYPT_REENCRYPT_CRASH) {
jobj = LUKS2_get_segment_by_flag(hdr, "backup-final");
if (jobj)
@@ -1793,7 +1836,7 @@ const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment)
return json_segment_get_cipher(jobj_segment) ?: "null";
}
crypt_reencrypt_info LUKS2_reenc_status(struct luks2_hdr *hdr)
crypt_reencrypt_info LUKS2_reencrypt_status(struct luks2_hdr *hdr)
{
uint32_t reqs;
@@ -2157,7 +2200,12 @@ int LUKS2_activate(struct crypt_device *cd,
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags);
if (dmd.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) {
log_err(cd, _("Discard/TRIM is not supported."));
return -EINVAL;
}
r = INTEGRITY_create_dmd_device(cd, NULL, NULL, NULL, NULL, &dmdi, dmd.flags, 0);
if (r)
return r;
@@ -2205,26 +2253,21 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
struct dm_target *tgt;
crypt_status_info ci;
struct crypt_dm_active_device dmdc;
char **dep, uuid[37], deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
char **dep, deps_uuid_prefix[40], *deps[MAX_DM_DEPS+1] = { 0 };
const char *namei = NULL;
struct crypt_lock_handle *reencrypt_lock = NULL;
if (!dmd || !dmd->uuid)
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
return -EINVAL;
/* uuid mismatch with metadata (if available) */
if (hdr && crypt_uuid_cmp(dmd->uuid, hdr->uuid))
return -EINVAL;
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), CRYPT_SUBDEV "-%.32s", dmd->uuid + 6);
if (r < 0 || (size_t)r != (sizeof(deps_uuid_prefix) - 1))
return -EINVAL;
r = snprintf(uuid, sizeof(uuid), "%.8s-%.4s-%.4s-%.4s-%.12s",
dmd->uuid + 6, dmd->uuid + 14, dmd->uuid + 18, dmd->uuid + 22, dmd->uuid + 26);
if (r < 0 || (size_t)r != (sizeof(uuid) - 1))
return -EINVAL;
/* uuid mismatch with metadata (if available) */
if (hdr && strcmp(hdr->uuid, uuid))
return -EINVAL;
tgt = &dmd->segment;
/* TODO: We have LUKS2 dependencies now */
@@ -2236,7 +2279,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
goto out;
if (contains_reencryption_helper(deps)) {
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
r = LUKS2_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
@@ -2315,7 +2358,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
}
out:
crypt_reencrypt_unlock(cd, reencrypt_lock);
LUKS2_reencrypt_unlock(cd, reencrypt_lock);
dep = deps;
while (*dep)
free(*dep++);
@@ -2345,9 +2388,9 @@ int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uin
reqs &= ~reqs_mask;
if (reqs_reencrypt(reqs) && !quiet)
log_err(cd, _("Offline reencryption in progress. Aborting."));
log_err(cd, _("Operation incompatible with device marked for legacy reencryption. Aborting."));
if (reqs_reencrypt_online(reqs) && !quiet)
log_err(cd, _("Online reencryption in progress. Aborting."));
log_err(cd, _("Operation incompatible with device marked for LUKS2 reencryption. Aborting."));
/* any remaining unmasked requirement fails the check */
return reqs ? -EINVAL : 0;
@@ -2400,7 +2443,7 @@ int json_object_object_add_by_uint(json_object *jobj, unsigned key, json_object
#endif
}
/* jobj_dst must contain pointer initialised to NULL (see json-c json_object_deep_copy API) */
/* jobj_dst must contain pointer initialized to NULL (see json-c json_object_deep_copy API) */
int json_object_copy(json_object *jobj_src, json_object **jobj_dst)
{
if (!jobj_src || !jobj_dst || *jobj_dst)

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, keyslot handling
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,7 +32,7 @@ static const keyslot_handler *keyslot_handlers[LUKS2_KEYSLOTS_MAX] = {
};
static const keyslot_handler
*LUKS2_keyslot_handler_type(struct crypt_device *cd, const char *type)
*LUKS2_keyslot_handler_type(struct crypt_device *cd __attribute__((unused)), const char *type)
{
int i;
@@ -65,33 +65,39 @@ static const keyslot_handler
return LUKS2_keyslot_handler_type(cd, json_object_get_string(jobj2));
}
int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
int LUKS2_keyslot_find_empty(struct crypt_device *cd, struct luks2_hdr *hdr, size_t keylength)
{
int i;
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++)
if (!LUKS2_get_keyslot_jobj(hdr, i))
return i;
break;
return -EINVAL;
if (i == LUKS2_KEYSLOTS_MAX)
return -EINVAL;
/* Check also there is a space for the key in keyslots area */
if (keylength && LUKS2_find_area_gap(cd, hdr, keylength, NULL, NULL) < 0)
return -ENOSPC;
return i;
}
/* Check if a keyslot is assigned to specific segment */
static int _keyslot_for_segment(struct luks2_hdr *hdr, int keyslot, int segment)
{
int keyslot_digest, segment_digest, s, count = 0;
int keyslot_digest, count = 0;
unsigned s;
keyslot_digest = LUKS2_digest_by_keyslot(hdr, keyslot);
if (keyslot_digest < 0)
return keyslot_digest;
if (segment >= 0) {
segment_digest = LUKS2_digest_by_segment(hdr, segment);
return segment_digest == keyslot_digest;
}
for (s = 0; s < 3; s++) {
segment_digest = LUKS2_digest_by_segment(hdr, s);
if (segment_digest == keyslot_digest)
if (segment >= 0)
return keyslot_digest == LUKS2_digest_by_segment(hdr, segment);
for (s = 0; s < json_segments_count(LUKS2_get_segments_jobj(hdr)); s++) {
if (keyslot_digest == LUKS2_digest_by_segment(hdr, s))
count++;
}
@@ -149,7 +155,7 @@ int LUKS2_keyslot_cipher_incompatible(struct crypt_device *cd, const char *ciphe
{
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
if (!cipher_spec || !strcmp(cipher_spec, "null") || !strcmp(cipher_spec, "cipher_null"))
if (!cipher_spec || crypt_is_cipher_null(cipher_spec))
return 1;
if (crypt_parse_name_and_mode(cipher_spec, cipher, NULL, cipher_mode) < 0)
@@ -301,37 +307,25 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj))
return -EINVAL;
*offset = json_object_get_uint64(jobj);
*offset = crypt_jobj_get_uint64(jobj);
if (!json_object_object_get_ex(jobj_area, "size", &jobj))
return -EINVAL;
*length = json_object_get_uint64(jobj);
*length = crypt_jobj_get_uint64(jobj);
return 0;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
static int _open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
const keyslot_handler *h,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
@@ -350,9 +344,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
*vk = NULL;
}
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
if (r) {
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
return r;
}
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -362,7 +388,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
@@ -380,29 +406,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
return r;
}
key_size = LUKS2_get_volume_key_size(hdr, segment);
if (key_size < 0)
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
*vk = crypt_alloc_volume_key(key_size, NULL);
if (!*vk)
return -ENOMEM;
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
if (r < 0)
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
else
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
if (r < 0) {
crypt_free_volume_key(*vk);
*vk = NULL;
} else
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
@@ -520,7 +524,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
size_t password_len,
struct volume_key **vks)
{
struct volume_key *vk;
struct volume_key *vk = NULL;
int digest_old, digest_new, r = -EINVAL;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
@@ -530,7 +534,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_old);
crypt_volume_key_add_next(vks, vk);
}
@@ -540,13 +543,17 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_new);
crypt_volume_key_add_next(vks, vk);
}
out:
if (r < 0) {
crypt_free_volume_key(*vks);
*vks = NULL;
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM && r != -ENOENT)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -579,6 +586,13 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
} else
r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk);
if (r < 0) {
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM && r != -ENOENT)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -593,7 +607,6 @@ int LUKS2_keyslot_reencrypt_create(struct crypt_device *cd,
if (keyslot == CRYPT_ANY_SLOT)
return -EINVAL;
/* FIXME: find keyslot by type */
h = LUKS2_keyslot_handler_type(cd, "reencrypt");
if (!h)
return -EINVAL;
@@ -762,7 +775,7 @@ int LUKS2_keyslot_dump(struct crypt_device *cd, int keyslot)
return h->dump(cd, keyslot);
}
crypt_keyslot_priority LUKS2_keyslot_priority_get(struct crypt_device *cd,
crypt_keyslot_priority LUKS2_keyslot_priority_get(struct crypt_device *cd __attribute__((unused)),
struct luks2_hdr *hdr, int keyslot)
{
json_object *jobj_keyslot, *jobj_priority;
@@ -798,7 +811,7 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
int keyslot,
uint64_t area_offset,
uint64_t area_length,
size_t volume_key_len)
size_t volume_key_len __attribute__((unused)))
{
struct luks2_hdr *hdr;
json_object *jobj_keyslots, *jobj_keyslot, *jobj_area;
@@ -828,8 +841,8 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
@@ -928,3 +941,40 @@ int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type)
return -ENOENT;
}
/* assumes valid header, it does not move references in tokens/digests etc! */
int LUKS2_keyslot_swap(struct crypt_device *cd, struct luks2_hdr *hdr,
int keyslot, int keyslot2)
{
json_object *jobj_keyslots, *jobj_keyslot, *jobj_keyslot2;
int r;
if (!json_object_object_get_ex(hdr->jobj, "keyslots", &jobj_keyslots))
return -EINVAL;
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
if (!jobj_keyslot)
return -EINVAL;
jobj_keyslot2 = LUKS2_get_keyslot_jobj(hdr, keyslot2);
if (!jobj_keyslot2)
return -EINVAL;
/* This transfer owner of object, no need for json_object_put */
json_object_get(jobj_keyslot);
json_object_get(jobj_keyslot2);
json_object_object_del_by_uint(jobj_keyslots, keyslot);
r = json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot2);
if (r < 0) {
log_dbg(cd, "Failed to swap keyslot %d.", keyslot);
return r;
}
json_object_object_del_by_uint(jobj_keyslots, keyslot2);
r = json_object_object_add_by_uint(jobj_keyslots, keyslot2, jobj_keyslot);
if (r < 0)
log_dbg(cd, "Failed to swap keyslot2 %d.", keyslot2);
return r;
}

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS2 type keyslot handler
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -48,7 +48,7 @@ static int luks2_encrypt_to_storage(char *src, size_t srcLength,
return -EINVAL;
/* Encrypt buffer */
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
if (r) {
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
return r;
@@ -103,7 +103,7 @@ static int luks2_decrypt_from_storage(char *dst, size_t dstLength,
if (MISALIGNED_512(dstLength))
return -EINVAL;
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, vk->key, vk->keylength, false);
if (r) {
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
return r;
@@ -220,7 +220,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
return -EINVAL;
area_offset = json_object_get_uint64(jobj2);
area_offset = crypt_jobj_get_uint64(jobj2);
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL;
@@ -248,6 +248,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
/*
* Calculate keyslot content, split and store it to keyslot area.
*/
log_dbg(cd, "Running keyslot key derivation.");
r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen,
salt, LUKS_SALTSIZE,
derived_key->key, derived_key->keylength,
@@ -269,7 +270,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
r = AF_split(cd, volume_key, AfKey, volume_key_len, LUKS_STRIPES, af_hash);
if (r == 0) {
log_dbg(cd, "Updating keyslot area [0x%04x].", (unsigned)area_offset);
log_dbg(cd, "Updating keyslot area [0x%04" PRIx64 "].", area_offset);
/* FIXME: sector_offset should be size_t, fix LUKS_encrypt... accordingly */
r = luks2_encrypt_to_storage(AfKey, AFEKSize, cipher, cipher_mode,
derived_key, (unsigned)(area_offset / SECTOR_SIZE), cd);
@@ -313,7 +314,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
return -EINVAL;
area_offset = json_object_get_uint64(jobj2);
area_offset = crypt_jobj_get_uint64(jobj2);
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL;
@@ -325,13 +326,6 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
return -EINVAL;
keyslot_key_len = json_object_get_int(jobj2);
/*
* If requested, serialize unlocking for memory-hard KDF. Usually NOOP.
*/
if (pbkdf.max_memory_kb > MIN_MEMORY_FOR_SERIALIZE_LOCK_KB)
try_serialize_lock = true;
if (try_serialize_lock && crypt_serialize_lock(cd))
return -EINVAL;
/*
* Allocate derived key storage space.
*/
@@ -342,12 +336,22 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
AFEKSize = AF_split_sectors(volume_key_len, LUKS_STRIPES) * SECTOR_SIZE;
AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) {
crypt_free_volume_key(derived_key);
return -ENOMEM;
r = -ENOMEM;
goto out;
}
/*
* If requested, serialize unlocking for memory-hard KDF. Usually NOOP.
*/
if (pbkdf.max_memory_kb > MIN_MEMORY_FOR_SERIALIZE_LOCK_KB)
try_serialize_lock = true;
if (try_serialize_lock && (r = crypt_serialize_lock(cd)))
goto out;
/*
* Calculate derived key, decrypt keyslot content and merge it.
*/
log_dbg(cd, "Running keyslot key derivation.");
r = crypt_pbkdf(pbkdf.type, pbkdf.hash, password, passwordLen,
salt, LUKS_SALTSIZE,
derived_key->key, derived_key->keylength,
@@ -358,7 +362,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
crypt_serialize_unlock(cd);
if (r == 0) {
log_dbg(cd, "Reading keyslot area [0x%04x].", (unsigned)area_offset);
log_dbg(cd, "Reading keyslot area [0x%04" PRIx64 "].", area_offset);
/* FIXME: sector_offset should be size_t, fix LUKS_decrypt... accordingly */
r = luks2_decrypt_from_storage(AfKey, AFEKSize, cipher, cipher_mode,
derived_key, (unsigned)(area_offset / SECTOR_SIZE), cd);
@@ -367,6 +371,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
if (r == 0)
r = AF_merge(cd, AfKey, volume_key, volume_key_len, LUKS_STRIPES, af_hash);
out:
crypt_free_volume_key(derived_key);
crypt_safe_free(AfKey);
@@ -462,7 +467,7 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
return -EINVAL;
if (keyslot == CRYPT_ANY_SLOT)
keyslot = LUKS2_keyslot_find_empty(hdr);
keyslot = LUKS2_keyslot_find_empty(cd, hdr, 0);
if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX)
return -ENOMEM;
@@ -494,8 +499,8 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
@@ -607,7 +612,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tCipher: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "key_size", &jobj1);
log_std(cd, "\tCipher key: %u bits\n", json_object_get_uint32(jobj1) * 8);
log_std(cd, "\tCipher key: %u bits\n", crypt_jobj_get_uint32(jobj1) * 8);
json_object_object_get_ex(jobj_kdf, "type", &jobj1);
log_std(cd, "\tPBKDF: %s\n", json_object_get_string(jobj1));
@@ -617,7 +622,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tHash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_kdf, "iterations", &jobj1);
log_std(cd, "\tIterations: %" PRIu64 "\n", json_object_get_uint64(jobj1));
log_std(cd, "\tIterations: %" PRIu64 "\n", crypt_jobj_get_uint64(jobj1));
} else {
json_object_object_get_ex(jobj_kdf, "time", &jobj1);
log_std(cd, "\tTime cost: %" PRIu64 "\n", json_object_get_int64(jobj1));
@@ -640,10 +645,10 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tAF hash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "offset", &jobj1);
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
json_object_object_get_ex(jobj_area, "size", &jobj1);
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
return 0;
}
@@ -735,7 +740,7 @@ static int luks2_keyslot_update(struct crypt_device *cd,
return r;
}
static void luks2_keyslot_repair(struct crypt_device *cd, json_object *jobj_keyslot)
static void luks2_keyslot_repair(struct crypt_device *cd __attribute__((unused)), json_object *jobj_keyslot)
{
const char *type;
json_object *jobj_kdf, *jobj_type;

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
*
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2018, Ondrej Kozina
* Copyright (C) 2016-2021, Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2021, Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -21,12 +21,12 @@
#include "luks2_internal.h"
static int reenc_keyslot_open(struct crypt_device *cd,
int keyslot,
const char *password,
size_t password_len,
char *volume_key,
size_t volume_key_len)
static int reenc_keyslot_open(struct crypt_device *cd __attribute__((unused)),
int keyslot __attribute__((unused)),
const char *password __attribute__((unused)),
size_t password_len __attribute__((unused)),
char *volume_key __attribute__((unused)),
size_t volume_key_len __attribute__((unused)))
{
return -ENOENT;
}
@@ -67,13 +67,13 @@ int reenc_keyslot_alloc(struct crypt_device *cd,
if (params->data_shift) {
json_object_object_add(jobj_area, "type", json_object_new_string("datashift"));
json_object_object_add(jobj_area, "shift_size", json_object_new_uint64(params->data_shift << SECTOR_SHIFT));
json_object_object_add(jobj_area, "shift_size", crypt_jobj_new_uint64(params->data_shift << SECTOR_SHIFT));
} else
/* except data shift protection, initial setting is irrelevant. Type can be changed during reencryption */
json_object_object_add(jobj_area, "type", json_object_new_string("none"));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "type", json_object_new_string("reencrypt"));
json_object_object_add(jobj_keyslot, "key_size", json_object_new_int(1)); /* useless but mandatory */
@@ -113,8 +113,8 @@ static int reenc_keyslot_store_data(struct crypt_device *cd,
!json_object_object_get_ex(jobj_area, "size", &jobj_length))
return -EINVAL;
area_offset = json_object_get_uint64(jobj_offset);
area_length = json_object_get_uint64(jobj_length);
area_offset = crypt_jobj_get_uint64(jobj_offset);
area_length = crypt_jobj_get_uint64(jobj_length);
if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
return -EINVAL;
@@ -176,42 +176,8 @@ static int reenc_keyslot_store(struct crypt_device *cd,
return r < 0 ? r : keyslot;
}
int reenc_keyslot_update(struct crypt_device *cd,
const struct luks2_reenc_context *rh)
{
json_object *jobj_keyslot, *jobj_area, *jobj_area_type;
struct luks2_hdr *hdr;
if (!(hdr = crypt_get_hdr(cd, CRYPT_LUKS2)))
return -EINVAL;
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, rh->reenc_keyslot);
if (!jobj_keyslot)
return -EINVAL;
json_object_object_get_ex(jobj_keyslot, "area", &jobj_area);
json_object_object_get_ex(jobj_area, "type", &jobj_area_type);
if (rh->rp.type == REENC_PROTECTION_CHECKSUM) {
log_dbg(cd, "Updating reencrypt keyslot for checksum protection.");
json_object_object_add(jobj_area, "type", json_object_new_string("checksum"));
json_object_object_add(jobj_area, "hash", json_object_new_string(rh->rp.p.csum.hash));
json_object_object_add(jobj_area, "sector_size", json_object_new_int64(rh->alignment));
} else if (rh->rp.type == REENC_PROTECTION_NONE) {
log_dbg(cd, "Updating reencrypt keyslot for none protection.");
json_object_object_add(jobj_area, "type", json_object_new_string("none"));
json_object_object_del(jobj_area, "hash");
} else if (rh->rp.type == REENC_PROTECTION_JOURNAL) {
log_dbg(cd, "Updating reencrypt keyslot for journal protection.");
json_object_object_add(jobj_area, "type", json_object_new_string("journal"));
json_object_object_del(jobj_area, "hash");
} else
log_dbg(cd, "No update of reencrypt keyslot needed.");
return 0;
}
static int reenc_keyslot_wipe(struct crypt_device *cd, int keyslot)
static int reenc_keyslot_wipe(struct crypt_device *cd __attribute__((unused)),
int keyslot __attribute__((unused)))
{
return 0;
}
@@ -242,14 +208,14 @@ static int reenc_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\t%-12s%d [bytes]\n", "Hash data:", json_object_get_int(jobj1));
} else if (!strcmp(json_object_get_string(jobj_resilience), "datashift")) {
json_object_object_get_ex(jobj_area, "shift_size", &jobj1);
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", json_object_get_uint64(jobj1));
log_std(cd, "\t%-12s%" PRIu64 "[bytes]\n", "Shift size:", crypt_jobj_get_uint64(jobj1));
}
json_object_object_get_ex(jobj_area, "offset", &jobj1);
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
json_object_object_get_ex(jobj_area, "size", &jobj1);
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
return 0;
}
@@ -304,7 +270,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
return -EINVAL;
if (!validate_json_uint32(jobj_sector_size))
return -EINVAL;
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (sector_size < SECTOR_SIZE || NOTPOW2(sector_size)) {
log_dbg(cd, "Invalid sector_size (%" PRIu32 ") for checksum resilience mode.", sector_size);
return -EINVAL;
@@ -313,7 +279,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
if (!(jobj_shift_size = json_contains(cd, jobj_area, "type:datashift", "Keyslot area", "shift_size", json_type_string)))
return -EINVAL;
shift_size = json_object_get_uint64(jobj_shift_size);
shift_size = crypt_jobj_get_uint64(jobj_shift_size);
if (!shift_size)
return -EINVAL;

View File

@@ -1,9 +1,9 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Ondrej Kozina
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2021 Ondrej Kozina
* Copyright (C) 2015-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -91,8 +91,8 @@ static int json_luks1_keyslot(const struct luks_phdr *hdr_v1, int keyslot, struc
}
area_size = offs_b - offs_a;
json_object_object_add(jobj_area, "key_size", json_object_new_int(hdr_v1->keyBytes));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_size));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_size));
json_object_object_add(keyslot_obj, "area", jobj_area);
*keyslot_object = keyslot_obj;
@@ -145,7 +145,7 @@ static int json_luks1_segment(const struct luks_phdr *hdr_v1, struct json_object
/* offset field */
number = (uint64_t)hdr_v1->payloadOffset * SECTOR_SIZE;
field = json_object_new_uint64(number);
field = crypt_jobj_new_uint64(number);
if (!field) {
json_object_put(segment_obj);
return -ENOMEM;
@@ -401,8 +401,9 @@ static int json_luks1_object(struct luks_phdr *hdr_v1, struct json_object **luks
json_object_object_add(luks1_obj, "config", field);
json_size = LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN;
json_object_object_add(field, "json_size", json_object_new_uint64(json_size));
json_object_object_add(field, "keyslots_size", json_object_new_uint64(keyslots_size));
json_object_object_add(field, "json_size", crypt_jobj_new_uint64(json_size));
keyslots_size -= (keyslots_size % 4096);
json_object_object_add(field, "keyslots_size", crypt_jobj_new_uint64(keyslots_size));
*luks1_object = luks1_obj;
return 0;
@@ -418,8 +419,8 @@ static void move_keyslot_offset(json_object *jobj, int offset_add)
UNUSED(key);
json_object_object_get_ex(val, "area", &jobj_area);
json_object_object_get_ex(jobj_area, "offset", &jobj2);
offset = json_object_get_uint64(jobj2) + offset_add;
json_object_object_add(jobj_area, "offset", json_object_new_uint64(offset));
offset = crypt_jobj_get_uint64(jobj2) + offset_add;
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(offset));
}
}
@@ -466,7 +467,7 @@ static int move_keyslot_areas(struct crypt_device *cd, off_t offset_from,
r = 0;
out:
device_sync(cd, device);
crypt_memzero(buf, buf_size);
crypt_safe_memzero(buf, buf_size);
free(buf);
return r;
@@ -518,7 +519,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
int r;
json_object *jobj = NULL;
size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS;
uint64_t max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
/* for detached headers max size == device size */
if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size)))
@@ -539,11 +540,18 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
log_dbg(cd, "Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu",
max_size, luks1_size, luks1_shift);
if ((max_size - luks1_size) < luks1_shift) {
required_size = luks1_size + luks1_shift;
if ((max_size < required_size) &&
device_fallocate(crypt_metadata_device(cd), required_size)) {
log_err(cd, _("Unable to move keyslot area. Not enough space."));
return -EINVAL;
}
if (max_size < required_size)
max_size = required_size;
r = json_luks1_object(hdr1, &jobj, max_size - 2 * LUKS2_HDR_16K_LEN);
if (r < 0)
return r;
@@ -565,7 +573,13 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
* It duplicates check in LUKS2_hdr_write() but we don't want to move
* keyslot areas in case it would fail later
*/
if (max_size < LUKS2_hdr_and_areas_size(hdr2->jobj)) {
if (max_size < LUKS2_hdr_and_areas_size(hdr2)) {
r = -EINVAL;
goto out;
}
/* check future LUKS2 metadata before moving keyslots area */
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
r = -EINVAL;
goto out;
}
@@ -579,6 +593,14 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
// move keyslots 4k -> 32k offset
buf_offset = 2 * LUKS2_HDR_16K_LEN;
buf_size = luks1_size - LUKS_ALIGN_KEYSLOTS;
/* check future LUKS2 keyslots area is at least as large as LUKS1 keyslots area */
if (buf_size > LUKS2_keyslots_size(hdr2)) {
log_err(cd, _("Unable to move keyslot area. LUKS2 keyslots area too small."));
r = -EINVAL;
goto out;
}
if ((r = move_keyslot_areas(cd, 8 * SECTOR_SIZE, buf_offset, buf_size)) < 0) {
log_err(cd, _("Unable to move keyslot area."));
goto out;
@@ -653,7 +675,7 @@ static int keyslot_LUKS1_compatible(struct crypt_device *cd, struct luks2_hdr *h
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-1], cipher_mode[LUKS_CIPHERMODE_L-1];
char cipher[LUKS_CIPHERNAME_L], cipher_mode[LUKS_CIPHERMODE_L];
char digest[LUKS_DIGESTSIZE], digest_salt[LUKS_SALTSIZE];
const char *hash;
size_t len;
@@ -742,7 +764,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
return -EINVAL;
if (!json_object_object_get_ex(jobj_area, "offset", &jobj1))
return -EINVAL;
offset = json_object_get_uint64(jobj1);
offset = crypt_jobj_get_uint64(jobj1);
} else {
if (LUKS2_find_area_gap(cd, hdr2, key_size, &offset, &area_length))
return -EINVAL;
@@ -774,7 +796,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_kdf, "iterations", &jobj1))
continue;
hdr1->keyblock[i].passwordIterations = json_object_get_uint32(jobj1);
hdr1->keyblock[i].passwordIterations = crypt_jobj_get_uint32(jobj1);
if (!json_object_object_get_ex(jobj_kdf, "salt", &jobj1))
continue;
@@ -802,8 +824,10 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (r < 0)
return r;
strncpy(hdr1->cipherName, cipher, sizeof(hdr1->cipherName) - 1);
strncpy(hdr1->cipherMode, cipher_mode, sizeof(hdr1->cipherMode) - 1);
strncpy(hdr1->cipherName, cipher, LUKS_CIPHERNAME_L - 1);
hdr1->cipherName[LUKS_CIPHERNAME_L-1] = '\0';
strncpy(hdr1->cipherMode, cipher_mode, LUKS_CIPHERMODE_L - 1);
hdr1->cipherMode[LUKS_CIPHERMODE_L-1] = '\0';
if (!json_object_object_get_ex(jobj_keyslot, "kdf", &jobj_kdf))
return -EINVAL;
@@ -815,7 +839,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_digest, "iterations", &jobj1))
return -EINVAL;
hdr1->mkDigestIterations = json_object_get_uint32(jobj1);
hdr1->mkDigestIterations = crypt_jobj_get_uint32(jobj1);
if (!json_object_object_get_ex(jobj_digest, "digest", &jobj1))
return -EINVAL;
@@ -840,7 +864,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
if (!json_object_object_get_ex(jobj_segment, "offset", &jobj1))
return -EINVAL;
offset = json_object_get_uint64(jobj1) / SECTOR_SIZE;
offset = crypt_jobj_get_uint64(jobj1) / SECTOR_SIZE;
if (offset > UINT32_MAX)
return -EINVAL;
/* FIXME: LUKS1 requires offset == 0 || offset >= luks1_hdr_size */
@@ -859,7 +883,7 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd, struct luks2_hdr *hdr2, struct
// move keyslots 32k -> 4k offset
buf_offset = 2 * LUKS2_HDR_16K_LEN;
buf_size = LUKS2_keyslots_size(hdr2->jobj);
buf_size = LUKS2_keyslots_size(hdr2);
r = move_keyslot_areas(cd, buf_offset, 8 * SECTOR_SIZE, buf_size);
if (r < 0) {
log_err(cd, _("Unable to move keyslot area."));

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, internal segment handling
*
* Copyright (C) 2018-2019, Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2019, Ondrej Kozina
* Copyright (C) 2018-2021, Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2021, Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -55,7 +55,7 @@ uint64_t json_segment_get_offset(json_object *jobj_segment, unsigned blockwise)
!json_object_object_get_ex(jobj_segment, "offset", &jobj))
return 0;
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
}
const char *json_segment_type(json_object *jobj_segment)
@@ -77,7 +77,7 @@ uint64_t json_segment_get_iv_offset(json_object *jobj_segment)
!json_object_object_get_ex(jobj_segment, "iv_tweak", &jobj))
return 0;
return json_object_get_uint64(jobj);
return crypt_jobj_get_uint64(jobj);
}
uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
@@ -88,7 +88,7 @@ uint64_t json_segment_get_size(json_object *jobj_segment, unsigned blockwise)
!json_object_object_get_ex(jobj_segment, "size", &jobj))
return 0;
return blockwise ? json_object_get_uint64(jobj) >> SECTOR_SHIFT : json_object_get_uint64(jobj);
return blockwise ? crypt_jobj_get_uint64(jobj) >> SECTOR_SHIFT : crypt_jobj_get_uint64(jobj);
}
const char *json_segment_get_cipher(json_object *jobj_segment)
@@ -229,8 +229,8 @@ static json_object *_segment_create_generic(const char *type, uint64_t offset, c
return NULL;
json_object_object_add(jobj, "type", json_object_new_string(type));
json_object_object_add(jobj, "offset", json_object_new_uint64(offset));
json_object_object_add(jobj, "size", length ? json_object_new_uint64(*length) : json_object_new_string("dynamic"));
json_object_object_add(jobj, "offset", crypt_jobj_new_uint64(offset));
json_object_object_add(jobj, "size", length ? crypt_jobj_new_uint64(*length) : json_object_new_string("dynamic"));
return jobj;
}
@@ -252,7 +252,7 @@ json_object *json_segment_create_crypt(uint64_t offset,
if (!jobj)
return NULL;
json_object_object_add(jobj, "iv_tweak", json_object_new_uint64(iv_offset));
json_object_object_add(jobj, "iv_tweak", crypt_jobj_new_uint64(iv_offset));
json_object_object_add(jobj, "encryption", json_object_new_string(cipher));
json_object_object_add(jobj, "sector_size", json_object_new_int(sector_size));
if (reencryption)

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, token handling
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Milan Broz
* Copyright (C) 2016-2021 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -19,39 +19,201 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <ctype.h>
#include <dlfcn.h>
#include <assert.h>
#include "luks2_internal.h"
/* Builtin tokens */
extern const crypt_token_handler keyring_handler;
#if USE_EXTERNAL_TOKENS
static bool external_tokens_enabled = true;
#else
static bool external_tokens_enabled = false;
#endif
static token_handler token_handlers[LUKS2_TOKENS_MAX] = {
static struct crypt_token_handler_internal token_handlers[LUKS2_TOKENS_MAX] = {
/* keyring builtin token */
{
.get = token_keyring_get,
.set = token_keyring_set,
.h = &keyring_handler
},
.version = 1,
.u = {
.v1 = { .name = LUKS2_TOKEN_KEYRING,
.open = keyring_open,
.validate = keyring_validate,
.dump = keyring_dump }
}
}
};
void crypt_token_external_disable(void)
{
external_tokens_enabled = false;
}
const char *crypt_token_external_path(void)
{
return external_tokens_enabled ? EXTERNAL_LUKS2_TOKENS_PATH : NULL;
}
#if USE_EXTERNAL_TOKENS
static void *token_dlvsym(struct crypt_device *cd,
void *handle,
const char *symbol,
const char *version)
{
char *error;
void *sym;
#ifdef HAVE_DLVSYM
log_dbg(cd, "Loading symbol %s@%s.", symbol, version);
sym = dlvsym(handle, symbol, version);
#else
log_dbg(cd, "Loading default version of symbol %s.", symbol);
sym = dlsym(handle, symbol);
#endif
error = dlerror();
if (error)
log_dbg(cd, "%s", error);
return sym;
}
#endif
static bool token_validate_v1(struct crypt_device *cd, const crypt_token_handler *h)
{
if (!h)
return false;
if (!h->name) {
log_dbg(cd, "Error: token handler does not provide name attribute.");
return false;
}
if (!h->open) {
log_dbg(cd, "Error: token handler does not provide open function.");
return false;
}
return true;
}
#if USE_EXTERNAL_TOKENS
static bool token_validate_v2(struct crypt_device *cd, const struct crypt_token_handler_internal *h)
{
if (!h)
return false;
if (!token_validate_v1(cd, &h->u.v1))
return false;
if (!h->u.v2.version) {
log_dbg(cd, "Error: token handler does not provide " CRYPT_TOKEN_ABI_VERSION " function.");
return false;
}
return true;
}
static bool external_token_name_valid(const char *name)
{
if (!*name || strlen(name) > LUKS2_TOKEN_NAME_MAX)
return false;
while (*name) {
if (!isalnum(*name) && *name != '-' && *name != '_')
return false;
name++;
}
return true;
}
#endif
static int
crypt_token_load_external(struct crypt_device *cd, const char *name, struct crypt_token_handler_internal *ret)
{
#if USE_EXTERNAL_TOKENS
struct crypt_token_handler_v2 *token;
void *h;
char buf[PATH_MAX];
int r;
if (!external_tokens_enabled)
return -ENOTSUP;
if (!ret || !name)
return -EINVAL;
if (!external_token_name_valid(name)) {
log_dbg(cd, "External token name (%.*s) invalid.", LUKS2_TOKEN_NAME_MAX, name);
return -EINVAL;
}
token = &ret->u.v2;
r = snprintf(buf, sizeof(buf), "%s/libcryptsetup-token-%s.so", crypt_token_external_path(), name);
if (r < 0 || (size_t)r >= sizeof(buf))
return -EINVAL;
assert(*buf == '/');
log_dbg(cd, "Trying to load %s.", buf);
h = dlopen(buf, RTLD_LAZY);
if (!h) {
log_dbg(cd, "%s", dlerror());
return -EINVAL;
}
dlerror();
token->name = strdup(name);
token->open = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_OPEN, CRYPT_TOKEN_ABI_VERSION1);
token->buffer_free = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_BUFFER_FREE, CRYPT_TOKEN_ABI_VERSION1);
token->validate = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_VALIDATE, CRYPT_TOKEN_ABI_VERSION1);
token->dump = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_DUMP, CRYPT_TOKEN_ABI_VERSION1);
token->open_pin = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_OPEN_PIN, CRYPT_TOKEN_ABI_VERSION1);
token->version = token_dlvsym(cd, h, CRYPT_TOKEN_ABI_VERSION, CRYPT_TOKEN_ABI_VERSION1);
if (!token_validate_v2(cd, ret)) {
free(CONST_CAST(void *)token->name);
dlclose(h);
memset(token, 0, sizeof(*token));
return -EINVAL;
}
/* Token loaded, possible error here means only debug message fail and can be ignored */
r = snprintf(buf, sizeof(buf), "%s", token->version() ?: "");
if (r < 0 || (size_t)r >= sizeof(buf))
*buf = '\0';
log_dbg(cd, "Token handler %s-%s loaded successfully.", token->name, buf);
token->dlhandle = h;
ret->version = 2;
return 0;
#else
return -ENOTSUP;
#endif
}
static int is_builtin_candidate(const char *type)
{
return !strncmp(type, LUKS2_BUILTIN_TOKEN_PREFIX, LUKS2_BUILTIN_TOKEN_PREFIX_LEN);
}
int crypt_token_register(const crypt_token_handler *handler)
static int crypt_token_find_free(struct crypt_device *cd, const char *name, int *index)
{
int i;
if (is_builtin_candidate(handler->name)) {
log_dbg(NULL, "'" LUKS2_BUILTIN_TOKEN_PREFIX "' is reserved prefix for builtin tokens.");
if (is_builtin_candidate(name)) {
log_dbg(cd, "'" LUKS2_BUILTIN_TOKEN_PREFIX "' is reserved prefix for builtin tokens.");
return -EINVAL;
}
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++) {
if (!strcmp(token_handlers[i].h->name, handler->name)) {
log_dbg(NULL, "Keyslot handler %s is already registered.", handler->name);
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].u.v1.name; i++) {
if (!strcmp(token_handlers[i].u.v1.name, name)) {
log_dbg(cd, "Keyslot handler %s is already registered.", name);
return -EINVAL;
}
}
@@ -59,32 +221,70 @@ int crypt_token_register(const crypt_token_handler *handler)
if (i == LUKS2_TOKENS_MAX)
return -EINVAL;
token_handlers[i].h = handler;
if (index)
*index = i;
return 0;
}
static const token_handler
*LUKS2_token_handler_type_internal(struct crypt_device *cd, const char *type)
int crypt_token_register(const crypt_token_handler *handler)
{
int i, r;
if (!token_validate_v1(NULL, handler))
return -EINVAL;
r = crypt_token_find_free(NULL, handler->name, &i);
if (r < 0)
return r;
token_handlers[i].version = 1;
token_handlers[i].u.v1 = *handler;
return 0;
}
void crypt_token_unload_external_all(struct crypt_device *cd)
{
#if USE_EXTERNAL_TOKENS
int i;
for (i = LUKS2_TOKENS_MAX - 1; i >= 0; i--) {
if (token_handlers[i].version < 2)
continue;
log_dbg(cd, "Unloading %s token handler.", token_handlers[i].u.v2.name);
free(CONST_CAST(void *)token_handlers[i].u.v2.name);
if (dlclose(CONST_CAST(void *)token_handlers[i].u.v2.dlhandle))
log_dbg(cd, "%s", dlerror());
}
#endif
}
static const void
*LUKS2_token_handler_type(struct crypt_device *cd, const char *type)
{
int i;
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].h; i++)
if (!strcmp(token_handlers[i].h->name, type))
return token_handlers + i;
for (i = 0; i < LUKS2_TOKENS_MAX && token_handlers[i].u.v1.name; i++)
if (!strcmp(token_handlers[i].u.v1.name, type))
return &token_handlers[i].u;
return NULL;
if (i >= LUKS2_TOKENS_MAX)
return NULL;
if (is_builtin_candidate(type))
return NULL;
if (crypt_token_load_external(cd, type, &token_handlers[i]))
return NULL;
return &token_handlers[i].u;
}
static const crypt_token_handler
*LUKS2_token_handler_type(struct crypt_device *cd, const char *type)
{
const token_handler *th = LUKS2_token_handler_type_internal(cd, type);
return th ? th->h : NULL;
}
static const token_handler
*LUKS2_token_handler_internal(struct crypt_device *cd, int token)
static const void
*LUKS2_token_handler(struct crypt_device *cd, int token)
{
struct luks2_hdr *hdr;
json_object *jobj1, *jobj2;
@@ -101,15 +301,7 @@ static const token_handler
if (!json_object_object_get_ex(jobj1, "type", &jobj2))
return NULL;
return LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj2));
}
static const crypt_token_handler
*LUKS2_token_handler(struct crypt_device *cd, int token)
{
const token_handler *th = LUKS2_token_handler_internal(cd, token);
return th ? th->h : NULL;
return LUKS2_token_handler_type(cd, json_object_get_string(jobj2));
}
static int LUKS2_token_find_free(struct luks2_hdr *hdr)
@@ -130,7 +322,6 @@ int LUKS2_token_create(struct crypt_device *cd,
int commit)
{
const crypt_token_handler *h;
const token_handler *th;
json_object *jobj_tokens, *jobj_type, *jobj;
enum json_tokener_error jerr;
char num[16];
@@ -147,7 +338,8 @@ int LUKS2_token_create(struct crypt_device *cd,
if (!json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens))
return -EINVAL;
snprintf(num, sizeof(num), "%d", token);
if (snprintf(num, sizeof(num), "%d", token) < 0)
return -EINVAL;
/* Remove token */
if (!json)
@@ -166,16 +358,14 @@ int LUKS2_token_create(struct crypt_device *cd,
}
json_object_object_get_ex(jobj, "type", &jobj_type);
if (is_builtin_candidate(json_object_get_string(jobj_type))) {
th = LUKS2_token_handler_type_internal(cd, json_object_get_string(jobj_type));
if (!th || !th->set) {
log_dbg(cd, "%s is builtin token candidate with missing handler", json_object_get_string(jobj_type));
json_object_put(jobj);
return -EINVAL;
}
h = th->h;
} else
h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
h = LUKS2_token_handler_type(cd, json_object_get_string(jobj_type));
if (is_builtin_candidate(json_object_get_string(jobj_type)) && !h) {
log_dbg(cd, "%s is builtin token candidate with missing handler",
json_object_get_string(jobj_type));
json_object_put(jobj);
return -EINVAL;
}
if (h && h->validate && h->validate(cd, json)) {
json_object_put(jobj);
@@ -203,7 +393,7 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
const char **type)
{
const char *tmp;
const token_handler *th;
const crypt_token_handler *th;
json_object *jobj_type, *jobj_token;
if (token < 0 || token >= LUKS2_TOKENS_MAX)
@@ -215,10 +405,10 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
json_object_object_get_ex(jobj_token, "type", &jobj_type);
tmp = json_object_get_string(jobj_type);
if ((th = LUKS2_token_handler_type_internal(cd, tmp))) {
if ((th = LUKS2_token_handler_type(cd, tmp))) {
if (type)
*type = th->h->name;
return th->set ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
*type = th->name;
return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL : CRYPT_TOKEN_EXTERNAL;
}
if (type)
@@ -227,95 +417,109 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
return is_builtin_candidate(tmp) ? CRYPT_TOKEN_INTERNAL_UNKNOWN : CRYPT_TOKEN_EXTERNAL_UNKNOWN;
}
int LUKS2_builtin_token_get(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *type,
void *params)
static const char *token_json_to_string(json_object *jobj_token)
{
const token_handler *th = LUKS2_token_handler_type_internal(cd, type);
// internal error
assert(th && th->get);
return th->get(LUKS2_get_token_jobj(hdr, token), params) ?: token;
return json_object_to_json_string_ext(jobj_token,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
}
int LUKS2_builtin_token_create(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *type,
const void *params,
int commit)
static int token_is_usable(struct luks2_hdr *hdr, json_object *jobj_token, int segment, crypt_keyslot_priority minimal_priority)
{
const token_handler *th;
int r;
json_object *jobj_token, *jobj_tokens;
crypt_keyslot_priority keyslot_priority;
json_object *jobj_array;
int i, keyslot, len, r = -ENOENT;
th = LUKS2_token_handler_type_internal(cd, type);
// at this point all builtin handlers must exist and have validate fn defined
assert(th && th->set && th->h->validate);
if (token == CRYPT_ANY_TOKEN) {
if ((token = LUKS2_token_find_free(hdr)) < 0)
log_err(cd, _("No free token slot."));
}
if (token < 0 || token >= LUKS2_TOKENS_MAX)
if (!jobj_token)
return -EINVAL;
r = th->set(&jobj_token, params);
if (r) {
log_err(cd, _("Failed to create builtin token %s."), type);
return r;
if (!json_object_object_get_ex(jobj_token, "keyslots", &jobj_array))
return -EINVAL;
if (segment < 0 && segment != CRYPT_ANY_SEGMENT)
return -EINVAL;
/* no assigned keyslot returns -ENOENT even for CRYPT_ANY_SEGMENT */
len = json_object_array_length(jobj_array);
if (len <= 0)
return -ENOENT;
for (i = 0; i < len; i++) {
keyslot = atoi(json_object_get_string(json_object_array_get_idx(jobj_array, i)));
keyslot_priority = LUKS2_keyslot_priority_get(NULL, hdr, keyslot);
if (keyslot_priority == CRYPT_SLOT_PRIORITY_INVALID)
return -EINVAL;
if (keyslot_priority < minimal_priority)
continue;
r = LUKS2_keyslot_for_segment(hdr, keyslot, segment);
if (r != -ENOENT)
return r;
}
// builtin tokens must produce valid json
r = LUKS2_token_validate(cd, hdr->jobj, jobj_token, "new");
assert(!r);
r = th->h->validate(cd, json_object_to_json_string_ext(jobj_token,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE));
assert(!r);
return r;
}
json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
json_object_object_add_by_uint(jobj_tokens, token, jobj_token);
if (LUKS2_check_json_size(cd, hdr)) {
log_dbg(cd, "Not enough space in header json area for new %s token.", type);
json_object_object_del_by_uint(jobj_tokens, token);
return -ENOSPC;
static int translate_errno(struct crypt_device *cd, int ret_val, const char *type)
{
if ((ret_val > 0 || ret_val == -EINVAL || ret_val == -EPERM) && !is_builtin_candidate(type)) {
log_dbg(cd, "%s token handler returned %d. Changing to %d.", type, ret_val, -ENOENT);
ret_val = -ENOENT;
}
if (commit)
return LUKS2_hdr_write(cd, hdr) ?: token;
return token;
return ret_val;
}
static int LUKS2_token_open(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
json_object *jobj_token,
const char *type,
int segment,
crypt_keyslot_priority priority,
const char *pin,
size_t pin_size,
char **buffer,
size_t *buffer_len,
void *usrptr)
{
const char *json;
const crypt_token_handler *h;
const struct crypt_token_handler_v2 *h;
json_object *jobj_type;
int r;
assert(token >= 0);
assert(jobj_token);
assert(priority >= 0);
if (type) {
if (!json_object_object_get_ex(jobj_token, "type", &jobj_type))
return -EINVAL;
if (strcmp(type, json_object_get_string(jobj_type)))
return -ENOENT;
}
r = token_is_usable(hdr, jobj_token, segment, priority);
if (r < 0) {
if (r == -ENOENT)
log_dbg(cd, "Token %d unusable for segment %d with desired keyslot priority %d.", token, segment, priority);
return r;
}
if (!(h = LUKS2_token_handler(cd, token)))
return -ENOENT;
if (h->validate) {
if (LUKS2_token_json_get(cd, hdr, token, &json))
return -EINVAL;
if (h->validate(cd, json)) {
log_dbg(cd, "Token %d (%s) validation failed.", token, h->name);
return -EINVAL;
}
if (h->validate && h->validate(cd, token_json_to_string(jobj_token))) {
log_dbg(cd, "Token %d (%s) validation failed.", token, h->name);
return -ENOENT;
}
r = h->open(cd, token, buffer, buffer_len, usrptr);
if (pin && !h->open_pin)
r = -ENOENT;
else if (pin)
r = translate_errno(cd, h->open_pin(cd, token, pin, pin_size, buffer, buffer_len, usrptr), h->name);
else
r = translate_errno(cd, h->open(cd, token, buffer, buffer_len, usrptr), h->name);
if (r < 0)
log_dbg(cd, "Token %d (%s) open failed with %d.", token, h->name, r);
@@ -329,129 +533,224 @@ static void LUKS2_token_buffer_free(struct crypt_device *cd,
{
const crypt_token_handler *h = LUKS2_token_handler(cd, token);
if (h->buffer_free)
if (h && h->buffer_free)
h->buffer_free(buffer, buffer_len);
else {
crypt_memzero(buffer, buffer_len);
crypt_safe_memzero(buffer, buffer_len);
free(buffer);
}
}
static bool break_loop_retval(int r)
{
if (r == -ENOENT || r == -EPERM || r == -EAGAIN || r == -ENOANO)
return false;
return true;
}
static void update_return_errno(int r, int *stored)
{
if (*stored == -ENOANO)
return;
else if (r == -ENOANO)
*stored = r;
else if (r == -EAGAIN && *stored != -ENOANO)
*stored = r;
else if (r == -EPERM && (*stored != -ENOANO && *stored != -EAGAIN))
*stored = r;
}
static int LUKS2_keyslot_open_by_token(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
int segment,
crypt_keyslot_priority priority,
const char *buffer,
size_t buffer_len,
struct volume_key **vk)
{
const crypt_token_handler *h;
json_object *jobj_token, *jobj_token_keyslots, *jobj;
crypt_keyslot_priority keyslot_priority;
json_object *jobj_token, *jobj_token_keyslots, *jobj_type, *jobj;
unsigned int num = 0;
int i, r;
if (!(h = LUKS2_token_handler(cd, token)))
return -ENOENT;
int i, r = -ENOENT, stored_retval = -ENOENT;
jobj_token = LUKS2_get_token_jobj(hdr, token);
if (!jobj_token)
return -EINVAL;
if (!json_object_object_get_ex(jobj_token, "type", &jobj_type))
return -EINVAL;
json_object_object_get_ex(jobj_token, "keyslots", &jobj_token_keyslots);
if (!jobj_token_keyslots)
return -EINVAL;
/* Try to open keyslot referenced in token */
r = -EINVAL;
for (i = 0; i < (int) json_object_array_length(jobj_token_keyslots) && r < 0; i++) {
jobj = json_object_array_get_idx(jobj_token_keyslots, i);
num = atoi(json_object_get_string(jobj));
log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).", num, token, h->name);
keyslot_priority = LUKS2_keyslot_priority_get(NULL, hdr, num);
if (keyslot_priority == CRYPT_SLOT_PRIORITY_INVALID)
return -EINVAL;
if (keyslot_priority < priority)
continue;
log_dbg(cd, "Trying to open keyslot %u with token %d (type %s).", num, token, json_object_get_string(jobj_type));
r = LUKS2_keyslot_open(cd, num, segment, buffer, buffer_len, vk);
/* short circuit on fatal error */
if (r < 0 && r != -EPERM && r != -ENOENT)
return r;
/* save -EPERM in case no other keyslot is usable */
if (r == -EPERM)
stored_retval = r;
}
if (r < 0)
return r;
return stored_retval;
return num;
}
int LUKS2_token_open_and_activate(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *name,
uint32_t flags,
void *usrptr)
static bool token_is_blocked(int token, uint32_t *block_list)
{
int keyslot, r;
char *buffer;
size_t buffer_len;
struct volume_key *vk = NULL;
/* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
r = LUKS2_token_open(cd, hdr, token, &buffer, &buffer_len, usrptr);
if (r < 0)
return r;
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
buffer, buffer_len, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
if (r < 0)
return r;
keyslot = r;
if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot)))
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
}
if (r >= 0 && name)
r = LUKS2_activate(cd, name, vk, flags);
if (r < 0)
crypt_drop_keyring_key(cd, vk);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
return (*block_list & (1 << token));
}
int LUKS2_token_open_and_activate_any(struct crypt_device *cd,
static void token_block(int token, uint32_t *block_list)
{
/* it is safe now, but have assert in case LUKS2_TOKENS_MAX grows */
assert(token >= 0 && (size_t)token < BITFIELD_SIZE(block_list));
*block_list |= (1 << token);
}
static int token_open_priority(struct crypt_device *cd,
struct luks2_hdr *hdr,
const char *name,
uint32_t flags)
json_object *jobj_tokens,
const char *type,
int segment,
crypt_keyslot_priority priority,
const char *pin,
size_t pin_size,
void *usrptr,
int *stored_retval,
uint32_t *block_list,
struct volume_key **vk)
{
char *buffer;
json_object *tokens_jobj;
size_t buffer_len;
int keyslot, token, r = -EINVAL;
size_t buffer_size;
int token, r;
assert(stored_retval);
assert(block_list);
json_object_object_foreach(jobj_tokens, slot, val) {
token = atoi(slot);
if (token_is_blocked(token, block_list))
continue;
r = LUKS2_token_open(cd, hdr, token, val, type, segment, priority, pin, pin_size, &buffer, &buffer_size, usrptr);
if (!r) {
r = LUKS2_keyslot_open_by_token(cd, hdr, token, segment, priority,
buffer, buffer_size, vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
}
if (r == -ENOANO)
token_block(token, block_list);
if (break_loop_retval(r))
return r;
update_return_errno(r, stored_retval);
}
return *stored_retval;
}
static int token_open_any(struct crypt_device *cd, struct luks2_hdr *hdr, const char *type, int segment, const char *pin, size_t pin_size, void *usrptr, struct volume_key **vk)
{
json_object *jobj_tokens;
int r, retval = -ENOENT;
uint32_t blocked = 0; /* bitmap with tokens blocked from loop by returning -ENOANO (wrong/missing pin) */
json_object_object_get_ex(hdr->jobj, "tokens", &jobj_tokens);
/* passing usrptr for CRYPT_ANY_TOKEN does not make sense without specific type */
if (!type)
usrptr = NULL;
r = token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_PREFER, pin, pin_size, usrptr, &retval, &blocked, vk);
if (break_loop_retval(r))
return r;
return token_open_priority(cd, hdr, jobj_tokens, type, segment, CRYPT_SLOT_PRIORITY_NORMAL, pin, pin_size, usrptr, &retval, &blocked, vk);
}
int LUKS2_token_open_and_activate(struct crypt_device *cd,
struct luks2_hdr *hdr,
int token,
const char *name,
const char *type,
const char *pin,
size_t pin_size,
uint32_t flags,
void *usrptr)
{
bool use_keyring;
char *buffer;
size_t buffer_size;
json_object *jobj_token;
int keyslot, segment, r = -ENOENT;
struct volume_key *vk = NULL;
json_object_object_get_ex(hdr->jobj, "tokens", &tokens_jobj);
json_object_object_foreach(tokens_jobj, slot, val) {
UNUSED(val);
token = atoi(slot);
r = LUKS2_token_open(cd, hdr, token, &buffer, &buffer_len, NULL);
if (r < 0)
continue;
r = LUKS2_keyslot_open_by_token(cd, hdr, token,
(flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ?
CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT,
buffer, buffer_len, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_len);
if (r >= 0)
break;
if (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY)
segment = CRYPT_ANY_SEGMENT;
else {
segment = LUKS2_get_default_segment(hdr);
if (segment < 0)
return -EINVAL;
}
if (token >= 0 && token < LUKS2_TOKENS_MAX) {
if ((jobj_token = LUKS2_get_token_jobj(hdr, token))) {
r = LUKS2_token_open(cd, hdr, token, jobj_token, type, segment, CRYPT_SLOT_PRIORITY_IGNORE, pin, pin_size, &buffer, &buffer_size, usrptr);
if (!r) {
r = LUKS2_keyslot_open_by_token(cd, hdr, token, segment, CRYPT_SLOT_PRIORITY_IGNORE,
buffer, buffer_size, &vk);
LUKS2_token_buffer_free(cd, token, buffer, buffer_size);
}
}
} else if (token == CRYPT_ANY_TOKEN)
/*
* return priorities (ordered form least to most significant):
* ENOENT - unusable for activation (no token handler, invalid token metadata, not assigned to volume segment, etc)
* EPERM - usable but token provided passphrase did not not unlock any assigned keyslot
* EAGAIN - usable but not ready (token HW is missing)
* ENOANO - ready, but token pin is wrong or missing
*
* success (>= 0) or any other negative errno short-circuits token activation loop
* immediately
*/
r = token_open_any(cd, hdr, type, segment, pin, pin_size, usrptr, &vk);
else
return -EINVAL;
if (r < 0)
return r;
assert(vk);
keyslot = r;
if (r >= 0 && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) && crypt_use_keyring_for_vk(cd)) {
if (!crypt_use_keyring_for_vk(cd))
use_keyring = false;
else
use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) ||
(flags & CRYPT_ACTIVATE_KEYRING_KEY));
if (use_keyring) {
if (!(r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd, hdr, vk, keyslot)))
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
}
@@ -480,7 +779,7 @@ void LUKS2_token_dump(struct crypt_device *cd, int token)
}
}
int LUKS2_token_json_get(struct crypt_device *cd, struct luks2_hdr *hdr,
int LUKS2_token_json_get(struct crypt_device *cd __attribute__((unused)), struct luks2_hdr *hdr,
int token, const char **json)
{
json_object *jobj_token;
@@ -489,8 +788,7 @@ int LUKS2_token_json_get(struct crypt_device *cd, struct luks2_hdr *hdr,
if (!jobj_token)
return -EINVAL;
*json = json_object_to_json_string_ext(jobj_token,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
*json = token_json_to_string(jobj_token);
return 0;
}
@@ -510,7 +808,9 @@ static int assign_one_keyslot(struct crypt_device *cd, struct luks2_hdr *hdr,
if (!jobj_token_keyslots)
return -EINVAL;
snprintf(num, sizeof(num), "%d", keyslot);
if (snprintf(num, sizeof(num), "%d", keyslot) < 0)
return -EINVAL;
if (assign) {
jobj1 = LUKS2_array_jobj(jobj_token_keyslots, num);
if (!jobj1)
@@ -569,23 +869,18 @@ int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
if (r < 0)
return r;
// FIXME: do not write header in nothing changed
if (commit)
return LUKS2_hdr_write(cd, hdr) ?: token;
return token;
}
int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
int keyslot, int token)
static int token_is_assigned(struct luks2_hdr *hdr, int keyslot, int token)
{
int i;
json_object *jobj_token, *jobj_token_keyslots, *jobj;
json_object *jobj, *jobj_token_keyslots,
*jobj_token = LUKS2_get_token_jobj(hdr, token);
if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
return -EINVAL;
jobj_token = LUKS2_get_token_jobj(hdr, token);
if (!jobj_token)
return -ENOENT;
@@ -600,6 +895,15 @@ int LUKS2_token_is_assigned(struct crypt_device *cd, struct luks2_hdr *hdr,
return -ENOENT;
}
int LUKS2_token_is_assigned(struct crypt_device *cd __attribute__((unused)), struct luks2_hdr *hdr,
int keyslot, int token)
{
if (keyslot < 0 || keyslot >= LUKS2_KEYSLOTS_MAX || token < 0 || token >= LUKS2_TOKENS_MAX)
return -EINVAL;
return token_is_assigned(hdr, keyslot, token);
}
int LUKS2_tokens_count(struct luks2_hdr *hdr)
{
json_object *jobj_tokens = LUKS2_get_tokens_jobj(hdr);
@@ -608,3 +912,28 @@ int LUKS2_tokens_count(struct luks2_hdr *hdr)
return json_object_object_length(jobj_tokens);
}
int LUKS2_token_assignment_copy(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot_from,
int keyslot_to,
int commit)
{
int i, r;
if (keyslot_from < 0 || keyslot_from >= LUKS2_KEYSLOTS_MAX || keyslot_to < 0 || keyslot_to >= LUKS2_KEYSLOTS_MAX)
return -EINVAL;
r = LUKS2_tokens_count(hdr);
if (r <= 0)
return r;
for (i = 0; i < LUKS2_TOKENS_MAX; i++) {
if (!token_is_assigned(hdr, keyslot_from, i)) {
if ((r = assign_one_token(cd, hdr, keyslot_to, i, 1)))
return r;
}
}
return commit ? LUKS2_hdr_write(cd, hdr) : 0;
}

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