Compare commits

...

585 Commits

Author SHA1 Message Date
Milan Broz
f95336e116 Prepare version 2.3.6.
Add Release notes.
2021-05-28 11:57:08 +02:00
Yuri Chornoivan
3753614517 po: update uk.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Yuri Kozlov
5fd96b75d3 po: update ru.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Jakub Bogusz
44aac4e5a3 po: update pl.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Hiroshi Takekawa
fbea879d1e po: update ja.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Frédéric Marchal
7012d031b6 po: update fr.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Roland Illig
a7f3065f6f po: update de.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Petr Pisar
f7fabbe141 po: update cs.po (from translationproject.org) 2021-05-28 09:59:30 +02:00
Klaus Zipfel
ac9a2c08e3 Fixing incorrect offsets for data/IV with TCRYPT system-encryption with a detached header
Related: #587
2021-05-26 09:36:32 +02:00
Milan Broz
bee77b2f35 Add note about --header use in TCRYPT format to man page.
Related: #587
2021-05-24 10:46:29 +02:00
Milan Broz
2d03ba3f4d Do not use Whirlpool hash in tests (some crypto backends do not implement it). 2021-05-23 11:13:44 +02:00
Milan Broz
29e4bca24b Increase interactive expect test timeout if runing under valgrind. 2021-05-22 10:27:00 +02:00
Milan Broz
2f9b22f5ff Update cryptsetup.pot. 2021-05-21 17:42:52 +02:00
Milan Broz
bbb6739d41 Set 2.3.6-rc0 version. 2021-05-21 17:30:40 +02:00
Мирослав Николић
d0c6eeea81 po: update sr.po (from translationproject.org) 2021-05-21 17:29:45 +02:00
Antonio Ceballos
4f982e9708 po: update es.po (from translationproject.org) 2021-05-21 17:29:28 +02:00
Milan Broz
df8135dfdf Check exit value for snprintf where it makes sense. 2021-05-21 14:54:00 +02:00
Milan Broz
280c821b9b 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-21 14:44:15 +02:00
Ondrej Kozina
28dd0f5c05 Avoid LUKS2 decryption without detached header.
This is temporary hotfix for stable 2.3.6 release. The full
fix that requires new API will be provided in later 2.4.0
release.

For more info see issue #614.
2021-05-21 14:27:24 +02:00
Milan Broz
c7789719d8 integritysetup: mention maximal allowed key size
The error message and man page should contain this information.
2021-05-19 19:44:56 +02:00
Milan Broz
97e709788e Fix description of maximum passphrase size. 2021-05-19 19:40:59 +02:00
Milan Broz
3dbbc005d3 Add test for longer integritysetup keys. 2021-05-19 19:40:51 +02:00
Milan Broz
e1e3430c2c 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-19 19:35:51 +02:00
Andrii Pravorskyi
b354cdd9ad Add a note about CRC32 and other non-cryptographic checksums 2021-05-19 13:44:28 +02:00
Milan Broz
ed24d033d4 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-05-19 13:44:25 +02:00
Milan Broz
5da8f5e710 Fix broken loopaes test.
We actually try to write file in /dev because the device is deactivated.

Broken since 2018 in 8728ba08e2
2021-05-19 13:44:21 +02:00
Milan Broz
800a8a4d5d Fix libintl detection for compiled tests.
Commit 99c4e83994 was incomplete.

See #633.
2021-05-19 13:44:19 +02:00
Milan Broz
0a06947e14 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-05-19 13:44:15 +02:00
Milan Broz
418d068470 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.
2021-05-19 13:43:37 +02:00
Milan Broz
9abe126016 Set devel 2.3.x version. 2021-05-19 13:08:46 +02:00
Milan Broz
59cf9969f9 Update cryptsetup.pot. 2021-03-11 12:56:15 +01:00
Milan Broz
98ec1e314a Prepare version 2.3.5. 2021-03-11 12:56:11 +01:00
Milan Broz
a9b327c12a Update Release notes version. 2021-03-11 12:55:25 +01:00
Milan Broz
eaa93a8116 Prepare Readme for version 2.3.5. 2021-03-11 12:55:09 +01:00
Milan Broz
018494b6b3 Add note for passwdqc change to release notes. 2021-03-11 11:38:21 +01:00
Dmitry V. Levin
3d7a0f741a 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:38:11 +01:00
Milan Broz
3858b1815c Add stdbool.h include. 2021-03-09 20:47:39 +01:00
Yuri Chornoivan
4eca4e8fce po: update uk.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Yuri Kozlov
39abe23e0e po: update ru.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Jakub Bogusz
80faafea48 po: update pl.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Hiroshi Takekawa
f658ea6ba4 po: update ja.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Frédéric Marchal
fa0a24f726 po: update fr.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Roland Illig
24abdf4e72 po: update de.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Petr Pisar
677572a425 po: update cs.po (from translationproject.org) 2021-03-09 20:40:51 +01:00
Milan Broz
30d6a8a8f9 Update 2.3.5 release notes.
And reformat it for strange problems with mail signature (line length).
2021-03-09 20:40:45 +01:00
Milan Broz
9fc40d35d3 Remove superfluous CONST_CAST.
It only confuses cppcheck.
2021-03-09 20:39:58 +01:00
Milan Broz
5a032abc33 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 20:36:44 +01:00
Milan Broz
6df6c0a363 Update Readme.md. 2021-03-04 13:16:44 +01:00
Milan Broz
e2e57e5776 Update cryptsetup.pot. 2021-03-04 11:35:50 +01:00
Milan Broz
3d8cb44c61 Fix typo. 2021-03-04 11:27:33 +01:00
Milan Broz
05dad56f75 Add release notes for 2.3.5-rc. 2021-03-03 22:21:24 +01:00
Milan Broz
69361fec1c Add a note about FEC calculation to veritysetup manual. 2021-03-03 12:20:51 +01:00
Milan Broz
4e0398aef0 Add final list of failures to valgrind-check test target. 2021-03-03 12:11:24 +01:00
Ondrej Kozina
51ab9da665 Fix reencryption recovery tests w/ cipher_null. 2021-03-02 17:25:00 +01:00
Milan Broz
855a232403 Add disappeared device test. 2021-03-02 16:44:18 +01:00
Milan Broz
96241cea6a 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-02 16:44:11 +01:00
Milan Broz
9e5c87b449 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-26 00:16:06 +01:00
Ondrej Kozina
7d1b40a3a6 Silent error messages in tests. 2021-02-26 00:16:06 +01:00
Ondrej Kozina
969be38a7a 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-26 00:16:06 +01:00
Ondrej Kozina
93382071a5 Fix luksResume when called on non-LUKS device. 2021-02-26 00:16:06 +01:00
Ondrej Kozina
426a8b9df0 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-26 00:16:06 +01:00
Ondrej Kozina
83811b5ea9 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-26 00:16:06 +01:00
Ondrej Kozina
56a01574ff Allow LUKS resume for device with cipher_null. 2021-02-26 00:16:06 +01:00
Ondrej Kozina
c68cd0a483 Unify crypt_resume_by internal code. 2021-02-26 00:16:06 +01:00
Ondrej Kozina
b2135a75e2 Do not upload VK in keyring when data cipher is null. 2021-02-26 00:16:06 +01:00
Ondrej Kozina
91e8f5ffd9 Remove redundant check.
It can't be non-LUKS2 device at this branching.
2021-02-26 00:16:06 +01:00
Ondrej Kozina
855628f796 Add tests for cipher_null suspend/resume. 2021-02-26 00:16:06 +01:00
Milan Broz
db8ce3f818 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-26 00:16:05 +01:00
Milan Broz
973474503a verity: do not process hash image if it is empty. 2021-02-26 00:16:05 +01:00
Milan Broz
4e2561df6d 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-26 00:16:05 +01:00
Milan Broz
b01ec20703 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-26 00:16:05 +01:00
Ondrej Kozina
ca1b41cf96 Extend LUKS2 reencryption tests w/ cipher_null. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
7825e0d4a6 Bypass keyring activation flag if cipher is null. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
c8c28cf6dd Use crypt_is_cipher_null check where possible. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
fb8aa6d03b 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-26 00:16:05 +01:00
Ondrej Kozina
207383782a Fix reencryption test on systems w/o keyring. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
f25a1c92ec 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-26 00:16:05 +01:00
Ondrej Kozina
44a9e7aa62 Improve key handling with cipher_null in reencryption. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
27eee9cfcb Add debug message for activated cipher_null device. 2021-02-26 00:16:05 +01:00
Ondrej Kozina
196477d194 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-26 00:16:05 +01:00
Ondrej Kozina
1e68d73bc3 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-26 00:16:05 +01:00
Ondrej Kozina
17bb1e2fdd 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-26 00:16:05 +01:00
Ondrej Kozina
ba7fd45ba6 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-26 00:16:05 +01:00
Ondrej Kozina
7058b81bb6 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-26 00:16:05 +01:00
Ondrej Kozina
b40018860b Add tests for various keyslot cipher null bugs. 2021-02-26 00:16:05 +01:00
Milan Broz
e97ac9f58c Get rid of off_t integers and use uint64_t.
Also move uint64 multiplication overflow check to internal library.
2021-02-26 00:16:05 +01:00
Milan Broz
75447d0d80 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-26 00:16:05 +01:00
Milan Broz
c760ae36ea Get rid of the long paramete list in FEC verity function.
Also params struct will be needed in following patch.
2021-02-26 00:16:05 +01:00
Milan Broz
dbd20776bc 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-26 00:16:05 +01:00
Milan Broz
3ebbceaef2 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-26 00:16:05 +01:00
Milan Broz
d733e4d0e8 Add a missing stdbool include. 2021-02-26 00:16:05 +01:00
Milan Broz
4d6d6edcff Backport device_is_identical() changes needed for following patch. 2021-02-26 00:13:48 +01:00
Milan Broz
1380efa1c6 Fix compat interactive test to run with valgrind too. 2021-02-08 21:43:40 +01:00
Milan Broz
bce9d695e3 Coverity workaround for tainted warnings.
Password can be any string and the function allocates
string properly, so mark it is as sanitized.
2021-02-07 20:05:03 +01:00
Milan Broz
bea6e0da74 Fix an error path memory leak. 2021-02-07 20:02:20 +01:00
Vojtech Trefny
e064406f85 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-07 20:02:20 +01:00
Milan Broz
3d58f480ee 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-07 20:02:20 +01:00
Milan Broz
660edf7959 Remove WARNING from the debug message. 2021-02-07 20:02:20 +01:00
Milan Broz
312efd8582 Remove redundant EOL in the previous patch. 2021-02-07 20:02:20 +01:00
Milan Broz
ec657332c6 Rephrase lockinging dir warning and move it to debug level.
System should later provide safe transition to tempdir configuration.
2021-02-07 20:02:20 +01:00
Milan Broz
e123263975 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-07 20:02:20 +01:00
Milan Broz
e8f2bb4a1a Disable alternative backends in CI build for now.
These will run in release time only.
2021-02-07 20:02:20 +01:00
Ondrej Kozina
6e71e2d6ed 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-02-07 20:02:20 +01:00
Ondrej Kozina
2f6698d1a7 Test crypt_keyslot_change_by_passphrase does not break tokens. 2021-02-07 20:02:12 +01:00
Milan Broz
d20929194f Fix previous commit error condition.
This hints actually failed even if return code was OK.
2021-02-07 20:00:16 +01:00
Milan Broz
0a6f89cfa6 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-02-07 19:58:49 +01:00
Milan Broz
c74f17c6e7 Fix copy & paste typo in integrity test. 2021-02-07 19:52:32 +01:00
Ondrej Kozina
616dd5a304 Allow bitlk tests to run with valgrind. 2021-02-07 17:37:18 +01:00
Ondrej Kozina
79442539c7 Remove bogus valgrind suppressions. 2021-02-07 17:37:06 +01:00
Ondrej Kozina
92b24fd758 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.
2021-02-07 17:36:56 +01:00
Ondrej Kozina
4a43a2773a Add utilities cleanup routine. 2021-02-07 17:36:47 +01:00
Ondrej Kozina
74c943c352 Drop unreachable code and useless conditions.
integrity_alg variable can not be NULL.
2021-02-07 17:36:38 +01:00
Ondrej Kozina
bc49c83ace Remove const from all opt_ string declarations.
Those variables contain pointers to dynamically alocated memory.
2021-02-07 17:36:24 +01:00
Ondrej Kozina
ed28583f17 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().
2021-02-07 17:36:10 +01:00
Ondrej Kozina
5345a73ca0 Group all string options variables together. 2021-02-07 17:35:23 +01:00
Ondrej Kozina
36f424ce71 Properly prefix all popt variables in veritysetup. 2021-02-07 17:28:09 +01:00
Milan Broz
a757d84b91 Update Copyright year. 2021-02-07 16:09:13 +01:00
Luca Boccassi
255464b0ae 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-02-07 16:09:13 +01:00
Luca Boccassi
4c350f4d72 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-02-07 16:09:13 +01:00
Ondrej Kozina
7cca38632f Add pedantic check for key helpers arguments. 2021-02-07 16:09:13 +01:00
Lars Wendler
d8bbfb118b 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-02-07 16:09:13 +01:00
Arno Wagner
178bc9ee39 Update FAQ: Clarified statement about block sizes in 5.16 2021-02-07 16:09:13 +01:00
Milan Broz
7d4d1baaa7 Fix some formatting and typos in man page. 2021-02-07 16:09:13 +01:00
Milan Broz
f82c1bf90f Remove obsolete tpm-luks project link from FAQ. 2021-02-07 16:09:13 +01:00
Milan Broz
8d856d4e17 Add lore.kernel.org list archive link. 2021-02-07 16:09:13 +01:00
Samanta Navarro
fb49d9630d 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.
2021-02-07 16:09:13 +01:00
Samanta Navarro
7866e71d6f Fix typos.
Typos found with codespell.
2021-02-07 16:09:13 +01:00
Samanta Navarro
d2ee949d88 lib: fix utils_safe_memory function comments. 2021-02-07 16:09:13 +01:00
Ondrej Kozina
3a29cbbf5d Add missing translation anotation. 2021-02-07 16:09:13 +01:00
Milan Broz
51bf5435f9 Enable Travis test for GOST crypto in VeraCrypt (install GOST external kernel crypto modules). 2021-02-07 16:09:13 +01:00
Vojtech Trefny
505effe085 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.
2021-02-07 16:09:12 +01:00
Vojtech Trefny
82f8fb653c bitlk: Allow running bitlk_metadata_free with NULL 2021-02-07 16:09:12 +01:00
Joerg Kastning
829a2379a1 Update cryptsetup.8
* Improved information about calling luksFormat on devices.
2021-02-07 16:09:12 +01:00
Joerg Kastning
b5894ce1ab 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
2021-02-07 16:09:12 +01:00
lixiaokeng
1bc6caceb1 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>
2021-02-07 16:09:12 +01:00
lixiaokeng
78f33946f1 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>
2021-02-07 16:09:12 +01:00
lixiaokeng
0d90efac88 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>
2021-02-07 16:09:12 +01:00
lixiaokeng
82490aaaa3 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>
2021-02-07 16:09:12 +01:00
lixiaokeng
782f4c5029 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>
2021-02-07 16:09:12 +01:00
Ondrej Kozina
d63d399c17 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.
2021-02-07 16:09:12 +01:00
dofrupisla
745c75b5b0 Fix typo 2021-02-07 16:09:12 +01:00
Samanta Navarro
1d615cf6dd fix typo in manual page 2021-02-07 16:09:12 +01:00
Vojtech Trefny
7f0ddcbed4 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.
2021-02-07 16:09:12 +01:00
Vojtech Trefny
efa7c4574c 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.
2021-02-07 16:09:12 +01:00
Milan Broz
e2b4479543 bitlk: Fix a compiler warning. 2021-02-07 16:09:12 +01:00
Vojtech Trefny
7c23bdb868 bitlk: Add support for startup key protected VMKs (keyslots)
Fixes: #588
2021-02-07 16:09:12 +01:00
Vojtech Trefny
fa5d46592e 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.
2021-02-07 16:09:12 +01:00
Joe Richey
e5e09d889b 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>
2021-02-07 16:09:12 +01:00
Milan Broz
7dbd007ac1 Print a visible error if requesting resize on unsupported format.
Fixes: #571.
2021-02-07 16:09:12 +01:00
Ondrej Kozina
dbb80e41c7 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.
2021-02-07 16:09:12 +01:00
Milan Broz
33cc4739da 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.
2021-02-07 16:09:12 +01:00
Milan Broz
5518198f97 Always store dm-verity hash algorithm in superblock in lowercase.
Fixes: #586.
2021-02-07 16:09:12 +01:00
Milan Broz
1a81925764 Fix disaplay of dm-integrity recalculating sector in dump command.
Fixes: #578.
2021-02-07 16:09:12 +01:00
Milan Broz
15df5904f2 Fix a memleak in blockwise test. 2021-02-07 16:09:12 +01:00
Milan Broz
07a06f2f40 Set 2.3.5-rc0 version. 2021-02-07 16:09:12 +01:00
Мирослав Николић
fd94f036c1 po: update sr.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Мирослав Николић
03607db1f8 po: update sr.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Josef Andersson
c2fcc7aebd po: update sv.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Josef Andersson
8dbb72e296 po: update sv.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Antonio Ceballos
513e88fd77 po: update es.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Antonio Ceballos
8360a85169 po: update es.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Roland Illig
b56a450a31 po: update de.po (from translationproject.org) 2021-02-07 16:09:12 +01:00
Milan Broz
569b485d02 Update Readme.md. 2020-09-03 20:45:35 +02:00
Milan Broz
bd888e30a6 Prepare version 2.3.4. 2020-09-03 19:11:40 +02:00
Milan Broz
b86c51afeb Add stable version release notes. 2020-09-03 19:10:45 +02:00
Yuri Chornoivan
56f47d3899 po: update uk.po (from translationproject.org) 2020-09-03 16:37:27 +02:00
Yuri Kozlov
284672c081 po: update ru.po (from translationproject.org) 2020-09-03 16:37:18 +02:00
Jakub Bogusz
6f6b54a5fd po: update pl.po (from translationproject.org) 2020-09-03 16:37:07 +02:00
Hiroshi Takekawa
154c344115 po: update ja.po (from translationproject.org) 2020-09-03 16:36:58 +02:00
Frédéric Marchal
cccb7780ec po: update fr.po (from translationproject.org) 2020-09-03 16:36:48 +02:00
Petr Pisar
aa762d5cc1 po: update cs.po (from translationproject.org) 2020-09-03 16:36:38 +02:00
Milan Broz
68cc46fc22 Update cryptsetup.pot. 2020-08-27 23:29:51 +02:00
Milan Broz
06bd23d120 Remove a gcc warning. 2020-08-27 21:24:37 +02:00
Ondrej Kozina
2f4990868e Explicitly terminate cipher strings during down conversion. 2020-08-27 14:18:17 +02:00
Ondrej Kozina
03213ac230 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:17:58 +02:00
Ondrej Kozina
fb1b287773 Add test for LUKS2 segments validation code fix. 2020-08-27 14:17:38 +02:00
Ondrej Kozina
7ceaf3f313 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:17:29 +02:00
Ondrej Kozina
3f20b04e42 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:17:20 +02:00
Milan Broz
82e6ca7202 Set devel 2.3.x version. 2020-08-26 15:45:20 +02:00
Milan Broz
8a170d0e80 Build branch v2.3.x in Travis. 2020-08-26 15:44:51 +02:00
Milan Broz
72be05c817 Fix error message in previous commit. 2020-08-26 15:41:48 +02:00
Milan Broz
b79ccb782b 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 15:41:44 +02:00
Milan Broz
9c8c636ece Print a warning if API test generates too long log. 2020-08-26 15:41:35 +02:00
Tobias Stoeckmann
63a5bd5ef6 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-26 15:41:29 +02:00
Tobias Stoeckmann
e75f5de2ed 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-26 15:41:24 +02:00
Milan Broz
6df1a69430 Add some descriptive output to device test - performance flags. 2020-08-26 15:40:23 +02:00
Milan Broz
e7ca35091c 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-26 15:39:26 +02:00
Milan Broz
03ecfe3478 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-26 15:26:01 +02:00
Ondrej Kozina
f5bf9ef9fa Add test for reencryption with --master-key-file argument. 2020-08-26 14:10:23 +02:00
Ondrej Kozina
f61eb8b427 Add API test for reencryption with specific new key. 2020-08-26 14:09:55 +02:00
Ingo Franzki
a4f78e1c98 Support online reencryption for PAES cipher.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>

(With few adjustments by Ondrej Kozina)
2020-08-26 14:03:32 +02:00
Vojtech Trefny
d1c3ad2703 bitlk: Set sector size to 512 when unknown/zero
Fixes: #584
2020-08-26 13:57:48 +02:00
Milan Broz
d7279eeda1 Use Ubuntu 20.04 in Travis CI builds. 2020-08-26 13:57:16 +02:00
Milan Broz
9c2d918474 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-26 13:55:59 +02:00
Milan Broz
16aec64d1b 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-08-26 13:54:53 +02:00
Milan Broz
04d2ff7689 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-08-26 13:54:34 +02:00
Milan Broz
0cd7cac03f 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-08-26 13:53:55 +02:00
Milan Broz
b2c1ec2f83 Use the most recent image in travis.yml. 2020-08-26 13:53:42 +02:00
Ondrej Kozina
a15008d876 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-08-26 13:52:57 +02:00
Francesco Turco
ac535923e0 fix capitalization 2020-08-26 13:52:16 +02:00
Francesco Turco
f695e155ec fix typos 2020-08-26 13:52:08 +02:00
Francesco Turco
9412d9a0f1 use HTTPS for URLs 2020-08-26 13:51:22 +02:00
Vojtech Trefny
57eba0d6f5 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-08-26 13:50:39 +02:00
Milan Broz
4a9862a666 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-08-26 13:49:54 +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
Milan Broz
686744e48e Prepare version 2.2.0. 2019-08-14 20:38:23 +02:00
Milan Broz
0f49221f57 Add ja.po translation. 2019-08-14 20:37:40 +02:00
Milan Broz
725720dfc3 Fix volume key file if no LUKS2 keyslots are present.
If all keyslots are removed, LUKS2 has no longer information about
the volume key size (there is only key digest present).

If user wants to open or add new keyslot, it must get information
about key size externally.

We do not want to guess key size from the file size (it does not
work for block devices for example), so require explicit --keyfil
option in these cases.

Fixes #470.
2019-08-14 12:31:40 +02:00
Milan Broz
96cdb8edb7 Return error if keysize is 0.
Also use read_buffer to support partial read.
2019-08-14 12:18:04 +02:00
Milan Broz
7aa197be7d Print better warning if online reencrypt is called over LUKS1. 2019-08-14 08:14:02 +02:00
Ondrej Kozina
ea1dbfe961 Fix minimal size check for device in LUKS2 reencryption.
Commit 4c73da31 exposed another bug in minimal device size check.
During reencryption initialization wrong data offset value was used
and adjusted as if device was already undergoing reencryption. The
bug fixed by commit 4c73da31 hid this bug.

This is hotfix only and following functions needs more review:

- LUKS2_reencrypt_data_offset
- LUKS2_get_data_offset
- luks2_check_device_size
- LUKS2_get_data_size
2019-08-13 20:34:14 +02:00
Milan Broz
4c73da31ba Fix bugs found by Coverity. 2019-08-13 12:20:18 +02:00
Milan Broz
5febae8ad0 Fix warnings and flock access to test file in tests. 2019-08-13 10:36:41 +02:00
Milan Broz
d06f01a7d7 Update po files. 2019-08-13 09:26:04 +02:00
Ondrej Kozina
54d757a4c7 Fix illegal access to deallocated memory.
When deallocating context with LUKS2 reencryption handle
we access data device structure after being free'd.
2019-08-09 12:43:23 +02:00
Ondrej Kozina
a23e1cf729 LUKS2 code cleanup.
- drop unused code
- drop unused function declarations
- remove local routines from internal api
2019-08-05 18:29:37 +02:00
Ondrej Kozina
91879960e6 Move most of crypt_reencrypt_status to reencryption file. 2019-08-05 18:29:37 +02:00
Ondrej Kozina
270e6959b8 Make crypt_reencrypt_status return 'none' value for non-LUKS2 devices. 2019-08-05 18:29:37 +02:00
Ondrej Kozina
cbb3ca01f4 Reencryption code cleanup.
- Remove all 'LUKS2_' name prefixes from internal routines
- Make all internal routines prefixed with 'reencrypt_' instead
- Drop few static routines by refactoring
- Rename all variables and routines containing 'pre' prefix to
  contain 'hot' prefix instead (when referring to segments
  undergoing reencryption)
- Rename all variables and routines containing 'after' prefix to
  contain 'post' prefix instead
- Rename all routines prefixed with '_' to 'reencrypt_' instead
2019-08-05 18:29:35 +02:00
Ondrej Kozina
9845d6fd40 Shorten reencryption parameters debug message. 2019-08-05 18:28:15 +02:00
Ondrej Kozina
e5a59d6925 Remove json debug reencryption metadata fragments. 2019-08-05 18:28:15 +02:00
Ondrej Kozina
574170488c Update LUKS2 reencryption api tests. 2019-08-02 16:57:03 +02:00
Ondrej Kozina
9ea99efe13 Add test for absolute path passed to --active-name parameter. 2019-08-02 16:57:03 +02:00
Ondrej Kozina
b3af88708d Change reencryption mode parameter type to enum. 2019-08-01 15:40:53 +02:00
Ondrej Kozina
b96ce0b764 Add LUKS2 reencryption test for detached header misuse. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
97ea39404a Allow reencryption to parse names prefixed with /dev. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
4054f26c4d Add dm_device_name helper.
Gets dm name from absolute device path.
2019-08-01 10:43:57 +02:00
Ondrej Kozina
7380731bf7 Do not fail reencryption silently when --active-name is not LUKS2. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
3bea349f9e Optionaly check device table before reencryption initialization. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
98e0c8d609 Extend device table check in-before reencryption. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
71f7385fcb Add support for linear segment in device comparison. 2019-08-01 10:43:57 +02:00
Ondrej Kozina
fbedf0ba6b Improve dm-crypt segments comparison function.
Check key descriptions are identical if both targets
were constructed using keys in kernel keyring service.
2019-08-01 10:40:37 +02:00
Ondrej Kozina
cf710eab13 Add internal crypt_compare_dm_devices. 2019-08-01 10:40:37 +02:00
Ondrej Kozina
b216a6a30e Introduce crypt_strcmp function (allows NULL). 2019-07-31 14:58:55 +02:00
Ondrej Kozina
b79086b3e9 Refactor assembly of multi-segment LUKS2 devices. 2019-07-31 14:58:55 +02:00
Ondrej Kozina
b551bdb0ce Make json_segments_count fn return unsigned value. 2019-07-31 14:58:55 +02:00
Ondrej Kozina
0886bc7afd Check for error sooner while assigning reencryption segments.
Also wraps function parameters definition.
2019-07-31 14:58:55 +02:00
Milan Broz
e7027e3d40 Revert back last cleanup call in api-test.
Removed by a mistake.
2019-07-31 12:15:49 +02:00
Milan Broz
243690b5ab Disalble luks2-reencryption-test in FIPE mode for now. 2019-07-31 12:03:44 +02:00
Milan Broz
5b5f76002e Fix various tests to run again in FIPS OpenSSL mode. 2019-07-31 10:27:58 +02:00
Milan Broz
fc03f1a1e6 Fix TCRYPT KDF failyure in FIPS mode.
SOme crypto backends now supports plain hash, but not PBKDF2 with
the same hash in FIPS mode.

Let's continue scanning other KDF if this error happens.
2019-07-31 10:25:54 +02:00
Milan Broz
1d59ae9aa9 Remove FIPS mode restriction for crypt_volume_key_get.
It is an application responsibility to use this API in the proper
context.
2019-07-30 14:12:50 +02:00
Milan Broz
8fde1b9f2c Mark API tests as skipped if setup phase fails. 2019-07-30 13:18:34 +02:00
Milan Broz
5e03f8c725 Always close context before failing API test.
Some devices could be still open delaying removal in cleanup.
2019-07-30 13:14:12 +02:00
Milan Broz
d6d4a50f7c Rename cd1-> cd in api test2. 2019-07-30 10:48:08 +02:00
Milan Broz
fe4e1de566 Mention limitiation of crypt_get_volume_key_size(). 2019-07-29 14:32:13 +02:00
Ondrej Kozina
e0d34b8f47 Add basic LUKS2 reencryption api test. 2019-07-26 16:20:36 +02:00
Ondrej Kozina
17c9d35449 Update reencryption flags description. 2019-07-26 16:09:38 +02:00
Ondrej Kozina
0e994265c6 Report data segment is moved in crypt_reencrypt_status. 2019-07-26 16:09:38 +02:00
Ondrej Kozina
e16319a290 Fail encryption initialization when data device too small. 2019-07-26 16:09:38 +02:00
Ondrej Kozina
c033643f07 Fix corner case bug in encryption with data shift.
If we initialized encryption with data shift and only single
segment the resulting metadata were missing
CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT flag and also segments json section was
invalid.
2019-07-26 16:06:03 +02:00
Ondrej Kozina
607e2248c8 Simplify LUKS2_reencrypt_direction function. 2019-07-26 16:06:03 +02:00
Ondrej Kozina
a1111c7aa0 Tighten reencryption direction field validation. 2019-07-26 16:06:03 +02:00
Ondrej Kozina
1b82e70fc1 Fix bug in minimal device size calculation for reencryption. 2019-07-26 16:06:03 +02:00
Ondrej Kozina
35068c2e6e Fix broken segments calculation for backward data shift reencryption. 2019-07-26 16:06:03 +02:00
Ondrej Kozina
212703edf8 crypt_get_data_offset() must always return new offset value. 2019-07-26 16:06:03 +02:00
Ondrej Kozina
7460d1a446 Fix backward reencryption with data shift.
The device has to be shrunk the data shift size during activation.
Otherwise the online reencryption would fail with incorrect device
size.
2019-07-26 16:04:27 +02:00
Ondrej Kozina
c851205f83 Fix bug in reencryption digest to segment assignement. 2019-07-23 17:28:26 +02:00
Ondrej Kozina
dd0e073159 Fill direction field in crypt_reencrypt_status. 2019-07-23 17:28:26 +02:00
Ondrej Kozina
193b477086 Report reencryption data shift value in sectors. 2019-07-23 17:28:26 +02:00
Ondrej Kozina
3f85da0098 Fix datashift calculation in reencryption initialization. 2019-07-23 17:28:25 +02:00
Ondrej Kozina
dad28f3dfe Move exclusive open for offline reencryption in initialization. 2019-07-23 17:28:25 +02:00
Ondrej Kozina
e8e1da3fb5 Do not callback progress twice in reencryption loop. 2019-07-23 17:28:25 +02:00
Ondrej Kozina
4a24311161 Extend offline reencryption test for other keyslot numbers. 2019-07-15 14:36:36 +02:00
Ondrej Kozina
4f8c6b7773 Fix offline reencryption bug in header backup phase.
If first active keyslot number was different from zero the
decryption always failed.
2019-07-15 14:36:36 +02:00
Milan Broz
26fc2c24bd Update po files. 2019-07-15 10:26:13 +02:00
Ondrej Kozina
330f9daade Pass max_hotzone_size inside reencryption parameters in sectors. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
4a232bc868 Pass device size inside reencryption parameters in sectors.
it was mistake in reencryption API. All other device sizes
related to device mapper devices are always in 512b setctors.
2019-07-12 15:37:18 +02:00
Ondrej Kozina
61dff96474 Reencryption keyslot must report as unbound. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
bda28bbf38 Fix bug in crypt_keyslot_add_by_key. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
66bedfd8e4 Fix LUKS2 reencryption recovery test.
Detect properly the case when recovery actually completed
encryption action for detached header case.
2019-07-12 15:37:18 +02:00
Ondrej Kozina
c18f968d84 Extend LUKS2 metadata size api tests. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
5dfbc57117 Move LUKS2 metadata size api tests in separate routine. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
e3fb6771d6 Re-enable mode test for LUKS2.
Since release 2.1.0 mode test for LUKS2 is skipped due to small test image.
Enforce smaller LUKS2 metadata via --offset to reenable the test.

Also detect failure for open action if format pass earlier.
2019-07-12 15:37:18 +02:00
Ondrej Kozina
f4da3c7f1b Add warning when changing explicitly requested LUKS2 metadata size. 2019-07-12 15:37:18 +02:00
Ondrej Kozina
81dbc9c070 Reduce implicit keyslots size when header device is too small.
Unless user explicitly asks for keyslots areas size
(either via --luks2-keyslots-size or --offset) reduce keyslots
size so that it fits in metadata device.
2019-07-12 15:37:08 +02:00
Ondrej Kozina
431bc87f85 Add LUKS2 error message hint when device too small.
If we format LUKS2 device with parameters unsuitable
for current metadata device size we usually fail during header areas
wipe. It was not clear what the reason actually was.
2019-07-12 15:12:46 +02:00
Milan Broz
b0e224a9f8 Update po file. 2019-07-01 10:19:14 +02:00
Ondrej Kozina
e3e6e75d40 Improvements to LUKS2 reencryption error messages.
- make error messages propagated to users more comprehensible
- drop some error messages completely
- replace many error messages with debug logs only

Fixes #458.
2019-07-01 10:18:55 +02:00
Ondrej Kozina
ed856f2ab8 Add tests for reencryption status reporting. 2019-07-01 10:18:52 +02:00
Ondrej Kozina
6425e1c52f Fix data device lookup among dm dependecies in crypt_init_by_name.
Also remove overlooked temporary debug message.
2019-07-01 10:18:49 +02:00
Ondrej Kozina
c842087cc1 Drop identical tests (already in compat-test). 2019-07-01 10:18:45 +02:00
Milan Broz
2651b381bb Update po files. 2019-06-29 10:43:28 +02:00
Yuri Chornoivan
4143d9871e Fix minor typos 2019-06-28 12:02:39 +00:00
Ondrej Kozina
fb9e467147 Add resize tests with --device-size parameter. 2019-06-27 14:40:06 +02:00
Ondrej Kozina
8b959158e3 Make resize action accept --device-size parameter (supports units).
Fixes #368.
2019-06-27 14:40:01 +02:00
Ondrej Kozina
ecb898c7ff Device size parameter must be always aligned to 512. 2019-06-27 14:39:59 +02:00
Milan Broz
c2b2b1ab5c Resync po files with the last translation.
(to be updated later)
2019-06-27 12:15:28 +02:00
Ondrej Kozina
d4682b3b38 Cleanup translated messages id.
- minimize count of almost identical message ids
- unify style for some messages
- remove some useless messages
2019-06-27 10:23:42 +02:00
Ondrej Kozina
2f4a50064f Add direction hint in reencryption hotzone device name. 2019-06-27 10:23:36 +02:00
Ondrej Kozina
6851535fe7 Add info about reencrytpion in LUKS2 status. 2019-06-27 10:23:08 +02:00
Ondrej Kozina
292a5f50b2 Allow offline reencryption on files without root privileges.
If userspace block ciphers are not available try kcapi first.
2019-06-27 10:19:23 +02:00
Ondrej Kozina
c25ce7c585 Allow disabling of reencryption locks via crypt_metadata_locking() 2019-06-27 10:19:18 +02:00
Ondrej Kozina
b22c9a86a9 Add internal crypt_zalloc routine (calloc wrapper). 2019-06-27 10:19:14 +02:00
Ondrej Kozina
767bb952a5 Enable crypt_init_by_name() for LUKS2 device on top of reencryption stack. 2019-06-27 10:19:12 +02:00
Ondrej Kozina
32e7178bbb Allow crypt_get_active_device for multi-segment devices. 2019-06-27 10:19:05 +02:00
Ondrej Kozina
614f671b92 Introduce SUBDEV internal device type.
LUKS2 and other device types allow stacking of dm devices
underneath public top level device.

The new type identifies clearly those private devices in respective
device stack so that they can be easily removed while removing
top level public device.

Switch LUKS2 reencryption device stack to use SUBDEV type immmediately
for hotzone and overlay devices. Other devices will follow in later
releases.
2019-06-27 10:19:01 +02:00
Ondrej Kozina
af62dbf3d3 Add internal limit for count of dm dependencies.
32 should be enough (+1 for terminating NULL byte)
2019-06-27 10:18:58 +02:00
Ondrej Kozina
249e6af3a6 Add LUKS2 uuid component in underlying dm-integrity device. 2019-06-27 10:18:56 +02:00
Ondrej Kozina
59bed375d0 Add type parameter to INTEGRITY_activate_dmd. 2019-06-27 10:18:54 +02:00
Ondrej Kozina
aba95b00aa Activate underlying dm-integrity privately for LUKS2 w/ auth. encryption. 2019-06-27 10:18:50 +02:00
Ondrej Kozina
011ee5b180 Introduce crypt_string_in internal helper.
And replace custom name_in_list function with new helper.
2019-06-27 10:18:47 +02:00
Ondrej Kozina
4e19719bdd Check hotzone size and device size alignment earlier.
It failed later but it was difficult to understand what went wrong.
2019-06-27 10:18:44 +02:00
Ondrej Kozina
fa469aaf41 Update struct crypt_params_reencrypt documentation. 2019-06-27 10:18:41 +02:00
Ondrej Kozina
3cabf608ca Unify reencryption context load error messages. 2019-06-27 10:18:37 +02:00
Milan Broz
2e841622f8 Print proper error message if LUKS2 slot encryption fail. 2019-06-26 17:30:30 +02:00
Milan Broz
9b5e3797b1 Fis status command to display only specific device types.
Cryptsetup, veritysetup and integrity setup should ignore other
device mappings in status command (it should display only
basic type information).
2019-06-25 15:03:04 +02:00
Seong-Joong Kim
07df177332 Fix a typo of comment 2019-06-24 22:31:52 -07:00
Milan Broz
ff364347cf Add FAIL backtrace to all bash tests. 2019-06-20 15:11:56 +02:00
Milan Broz
4c74ff5e5a Add ESSIV test in combination with AEAD data integrity protection. 2019-06-20 14:48:59 +02:00
Milan Broz
2ebd19c9bc Fix another EOL in api-test debug log. 2019-06-20 14:28:32 +02:00
Milan Broz
875ffa49b3 Fix log_dbg EOL in tools. 2019-06-19 12:12:02 +02:00
Ondrej Kozina
ff0030d74f Add missing --retry parameter in tests cleanup. 2019-06-18 13:26:20 +02:00
Ondrej Kozina
7a71feed8c Remove overlooked config scratching from reencryption tests. 2019-06-18 13:26:20 +02:00
Guilhem Moulin
70c4ce199d Fix minor spelling errors in manpage and messages.
Reported by lintian(1) - Static analysis tool for Debian packages:

accidentaly -> accidentally
trigerring -> triggering
alocate -> allocate
alignemnt -> alignment
initalize -> initialize
2019-06-18 09:42:28 +02:00
Alexander Neumann
ed0f8ccbaf Document all options for the --type parameter 2019-06-14 21:28:05 +02:00
Milan Broz
3e5ca2e168 Update readme.md. 2019-06-14 16:30:37 +02:00
192 changed files with 42916 additions and 15836 deletions

1
.gitignore vendored
View File

@@ -36,7 +36,6 @@ missing
po/Makevars.template
po/POTFILES
po/Rules-quot
po/*.pot
po/*.header
po/*.sed
po/*.sin

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

@@ -102,7 +102,13 @@ function travis_install_script
keyutils \
libjson-c-dev \
libblkid-dev \
dkms \
linux-headers-$(uname -r) \
linux-modules-extra-$(uname -r) \
|| return
# For VeraCrypt test
sudo apt-get install gost-crypto-dkms
}
function travis_before_script

View File

@@ -1,21 +1,23 @@
language: c
sudo: required
dist: xenial
os: linux
dist: focal
group: edge
compiler:
- gcc
env:
- MAKE_CHECK="gcrypt"
# MAKE_CHECK="gcrypt"
- MAKE_CHECK="openssl"
- MAKE_CHECK="kernel"
# MAKE_CHECK="kernel"
branches:
only:
- master
- wip-luks2
- v2_0_x
- v2.3.x
before_install:
- uname -a

View File

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

3102
FAQ

File diff suppressed because it is too large Load Diff

View File

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

5
README
View File

@@ -14,7 +14,8 @@ FAQ:
MAILING LIST:
E-MAIL: dm-crypt@saout.de
URL: http://www.saout.de/mailman/listinfo/dm-crypt
URL: https://www.saout.de/mailman/listinfo/dm-crypt
ARCHIVE: https://lore.kernel.org/dm-crypt/
DOWNLOAD:
@@ -28,4 +29,4 @@ SOURCE CODE:
NLS (PO TRANSLATIONS):
PO files are maintained by:
http://translationproject.org/domain/cryptsetup.html
https://translationproject.org/domain/cryptsetup.html

View File

@@ -5,8 +5,8 @@ What the ...?
**Cryptsetup** is a utility used to conveniently set up disk encryption based
on the [DMCrypt](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt) kernel module.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**
and **TrueCrypt** (including **VeraCrypt** extension) formats.
These include **plain** **dm-crypt** volumes, **LUKS** volumes, **loop-AES**,
**TrueCrypt** (including **VeraCrypt** extension) and **BitLocker** formats.
The project also includes a **veritysetup** utility used to conveniently setup
[DMVerity](https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity) block integrity checking kernel module
@@ -44,58 +44,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.3.5**
* [cryptsetup-2.3.5.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.5.tar.xz)
* Signature [cryptsetup-2.3.5.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/cryptsetup-2.3.5.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-rc0**
* [cryptsetup-2.2.0-rc0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0-rc0.tar.xz)
* Signature [cryptsetup-2.2.0-rc0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/cryptsetup-2.2.0-rc0.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.2.0-rc0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.2/v2.2.0-rc0-ReleaseNotes).
* [Cryptsetup 2.3.5 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.3/v2.3.5-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 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,7 +67,7 @@ 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).
Help!
-----
@@ -115,5 +76,5 @@ For cryptsetup and LUKS related questions, please use the dm-crypt mailing list,
If you want to subscribe just send an empty mail to [dm-crypt-subscribe@saout.de](mailto:dm-crypt-subscribe@saout.de).
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).
You can also browse [list archive](https://www.saout.de/pipermail/dm-crypt/) or read and search it through
[web interface on lore.kernel.org](https://lore.kernel.org/dm-crypt/) or alternatively on [marc.info](https://marc.info/?l=dm-crypt).

View File

@@ -9,16 +9,23 @@ 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
}
@@ -26,8 +33,7 @@ DIE=0
(libtool --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 "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-rc1])
AC_INIT([cryptsetup],[2.3.6])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=17:0:5
LIBCRYPTSETUP_VERSION_INFO=18:0:6
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c)
@@ -33,6 +33,7 @@ AC_PROG_MAKE_SET
AC_ENABLE_STATIC(no)
LT_INIT
PKG_PROG_PKG_CONFIG
AM_ICONV
dnl ==========================================================================
dnl define PKG_CHECK_VAR for old pkg-config <= 0.28
@@ -59,6 +60,12 @@ AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h malloc.h inttypes.h sys/ioctl.h sys/mman.h \
sys/sysmacros.h sys/statvfs.h ctype.h unistd.h locale.h byteswap.h endian.h stdint.h)
AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
[[
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
]])
AC_CHECK_HEADERS(uuid/uuid.h,,[AC_MSG_ERROR([You need the uuid library.])])
AC_CHECK_HEADER(libdevmapper.h,,[AC_MSG_ERROR([You need the device-mapper library.])])
@@ -169,7 +176,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 +363,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
@@ -587,7 +604,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])

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) {

View File

@@ -46,7 +46,7 @@ Side effect of reencryption is that final device will contain
only ciphertext (for all sectors) so even if device was not properly
wiped by random data, after reencryption you cannot distinguish
which sectors are used.
(Reecryption is done always for the whole device.)
(Reencryption is done always for the whole device.)
There are for sure bugs, please TEST IT IN TEST ENVIRONMENT before
use for your data.

View File

@@ -1,62 +1,13 @@
Cryptsetup 2.2.0-rc1 Release Notes
==================================
Testing release with new experimental features and bug fixes.
Cryptsetup 2.2.0 Release Notes
==============================
Stable release with new experimental features and bug fixes.
Cryptsetup 2.2 version introduces a new LUKS2 online reencryption
extension that allows reencryption of mounted LUKS2 devices
(device in use) in the background.
This testing release is intended for more extensive testing
of very complex online reencryption feature; it is expected
that it contains bugs, performance issues and that some functions
are in this testing release limited.
Please do not use this testing version in production environments.
Also, use it only if you have a full data backup.
Changes since version 2.2.0-rc0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Add integritysetup support for bitmap mode introduced in Linux kernel 5.2.
Integritysetup now supports --integrity-bitmap-mode option and
--bitmap-sector-per-bit and --bitmap-flush-time commandline options.
In the bitmap operation mode, if a bit in the bitmap is 1, the corresponding
region's data and integrity tags are not synchronized - if the machine
crashes, the unsynchronized regions will be recalculated.
The bitmap mode is faster than the journal mode because we don't have
to write the data twice, but it is also less reliable, because if data
corruption happens when the machine crashes, it may not be detected.
This can be used only for standalone devices, not with dm-crypt.
* The libcryptsetup now keeps all file descriptors to underlying device
open during the whole lifetime of crypt device context to avoid excessive
scanning in udev (udev run scan on every descriptor close).
* The luksDump command now prints more info for reencryption keyslot
(when a device is in-reencryption).
* New --device-size parameter is supported for LUKS2 reencryption.
It may be used to encrypt/reencrypt only the initial part of the data
device if the user is aware that the rest of the device is empty.
Note: This change causes API break since the last rc0 release
(crypt_params_reencrypt structure contains additional field).
* New --resume-only parameter is supported for LUKS2 reencryption.
This flag resumes reencryption process if it exists (not starting
new reencryption).
* The repair command now tries LUKS2 reencryption recovery if needed.
* If reencryption device is a file image, an interactive dialog now
asks if reencryption should be run safely in offline mode
(if autodetection of active devices failed).
* Fix activation through a token where dm-crypt volume key was not
set through keyring (but using old device-mapper table parameter mode).
* Online reencryption can now retain all keyslots (if all passphrases
are provided). Note that keyslot numbers will change in this case.
Online reencryption is a complex feature. Please be sure you
have a full data backup before using this feature.
Changes since version 2.1.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -96,7 +47,6 @@ The recovery supports three resilience modes:
These resilience modes are not available if reencryption uses data shift.
Note: until we have full documentation (both of the process and metadata),
please refer to Ondrej's slides (some slight details are no longer relevant)
https://okozina.fedorapeople.org/online-disk-reencryption-with-luks2-compact.pdf
@@ -264,3 +214,66 @@ Other changes and fixes
distinguish between a wrong passphrase and no keyslot available.
* Fix a possible segfault in detached header handling (double free).
* Add integritysetup support for bitmap mode introduced in Linux kernel 5.2.
Integritysetup now supports --integrity-bitmap-mode option and
--bitmap-sector-per-bit and --bitmap-flush-time commandline options.
In the bitmap operation mode, if a bit in the bitmap is 1, the corresponding
region's data and integrity tags are not synchronized - if the machine
crashes, the unsynchronized regions will be recalculated.
The bitmap mode is faster than the journal mode because we don't have
to write the data twice, but it is also less reliable, because if data
corruption happens when the machine crashes, it may not be detected.
This can be used only for standalone devices, not with dm-crypt.
* The libcryptsetup now keeps all file descriptors to underlying device
open during the whole lifetime of crypt device context to avoid excessive
scanning in udev (udev run scan on every descriptor close).
* The luksDump command now prints more info for reencryption keyslot
(when a device is in-reencryption).
* New --device-size parameter is supported for LUKS2 reencryption.
It may be used to encrypt/reencrypt only the initial part of the data
device if the user is aware that the rest of the device is empty.
Note: This change causes API break since the last rc0 release
(crypt_params_reencrypt structure contains additional field).
* New --resume-only parameter is supported for LUKS2 reencryption.
This flag resumes reencryption process if it exists (not starting
new reencryption).
* The repair command now tries LUKS2 reencryption recovery if needed.
* If reencryption device is a file image, an interactive dialog now
asks if reencryption should be run safely in offline mode
(if autodetection of active devices failed).
* Fix activation through a token where dm-crypt volume key was not
set through keyring (but using old device-mapper table parameter mode).
* Online reencryption can now retain all keyslots (if all passphrases
are provided). Note that keyslot numbers will change in this case.
* Allow volume key file to be used if no LUKS2 keyslots are present.
If all keyslots are removed, LUKS2 has no longer information about
the volume key size (there is only key digest present).
Please use --key-size option to open the device or add a new keyslot
in these cases.
* Print a warning if online reencrypt is called over LUKS1 (not supported).
* Fix TCRYPT KDF failure in FIPS mode.
Some crypto backends support plain hash in FIPS mode but not for PBKDF2.
* Remove FIPS mode restriction for crypt_volume_key_get.
It is an application responsibility to use this API in the proper context.
* Reduce keyslots area size in luksFormat when the header device is too small.
Unless user explicitly asks for keyslots areas size (either via
--luks2-keyslots-size or --offset) reduce keyslots size so that it fits
in metadata device.
* Make resize action accept --device-size parameter (supports units suffix).

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".

View File

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

1382
lib/bitlk/bitlk.c Normal file

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,131 @@
/*
* 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;
#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_activate(struct crypt_device *cd,
const char *name,
const char *password,
size_t passwordLen,
const struct bitlk_metadata *params,
uint32_t flags);
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek);
void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk);
void BITLK_bitlk_metadata_free(struct bitlk_metadata *params);
#endif

View File

@@ -2,8 +2,8 @@
* cryptsetup plain device helper functions
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-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.

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

View File

@@ -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(void);
void crypt_backend_destroy(void);
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
@@ -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
@@ -55,5 +55,9 @@ int crypt_cipher_decrypt_kernel(struct crypt_cipher_kernel *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length);
void crypt_cipher_destroy_kernel(struct crypt_cipher_kernel *ctx);
int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -1,8 +1,8 @@
/*
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-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,13 +167,13 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
}
len = sendmsg(ctx->opfd, &msg, 0);
if (len != (ssize_t)length) {
if (len != (ssize_t)(in_length)) {
r = -EIO;
goto bad;
}
len = read(ctx->opfd, out, length);
if (len != (ssize_t)length)
len = read(ctx->opfd, out, out_length);
if (len != (ssize_t)out_length)
r = -EIO;
bad:
crypt_backend_memzero(buffer, sizeof(buffer));
@@ -168,7 +184,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 +192,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 +233,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 +249,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 +262,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 +342,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(void)
{
int r;
if (crypto_backend_initialised)
return 0;
@@ -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;
}
@@ -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
@@ -62,6 +62,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 +118,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
return 0;
}
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
struct utsname uts;
struct sockaddr_alg sa = {
@@ -118,7 +126,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 +134,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 +265,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 +278,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);
@@ -392,3 +407,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* Nettle crypto backend implementation
*
* Copyright (C) 2011-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2019 Milan Broz
* Copyright (C) 2011-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(void)
{
return 0;
}
@@ -433,3 +433,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* NSS crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-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(void)
{
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;
}
@@ -381,3 +386,12 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return true;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
return crypt_bitlk_decrypt_key_kernel(key, key_length, in, out, length,
iv, iv_length, tag, tag_length);
}

View File

@@ -1,8 +1,8 @@
/*
* OPENSSL crypto backend implementation
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2019 Milan Broz
* Copyright (C) 2010-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
@@ -35,6 +35,8 @@
#include <openssl/rand.h>
#include "crypto_backend_internal.h"
#define CONST_CAST(x) (x)(uintptr_t)
static int crypto_backend_initialised = 0;
struct crypt_hash {
@@ -61,6 +63,11 @@ struct crypt_cipher {
} u;
};
struct hash_alg {
const char *name;
const char *openssl_name;
};
/*
* Compatible wrappers for OpenSSL < 1.1.0 and LibreSSL < 2.7.0
*/
@@ -119,7 +126,7 @@ static const char *openssl_backend_version(void)
}
#endif
int crypt_backend_init(struct crypt_device *ctx)
int crypt_backend_init(void)
{
if (crypto_backend_initialised)
return 0;
@@ -145,11 +152,36 @@ 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;
}
/* HASH */
int crypt_hash_size(const char *name)
{
const EVP_MD *hash_id = EVP_get_digestbyname(name);
const EVP_MD *hash_id;
hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name));
if (!hash_id)
return -EINVAL;
@@ -170,7 +202,7 @@ int crypt_hash_init(struct crypt_hash **ctx, const char *name)
return -ENOMEM;
}
h->hash_id = EVP_get_digestbyname(name);
h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name));
if (!h->hash_id) {
EVP_MD_CTX_free(h->md);
free(h);
@@ -255,7 +287,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return -ENOMEM;
}
h->hash_id = EVP_get_digestbyname(name);
h->hash_id = EVP_get_digestbyname(crypt_hash_compat_name(name));
if (!h->hash_id) {
HMAC_CTX_free(h->md);
free(h);
@@ -331,7 +363,7 @@ int crypt_pbkdf(const char *kdf, const char *hash,
return -EINVAL;
if (!strcmp(kdf, "pbkdf2")) {
hash_id = EVP_get_digestbyname(hash);
hash_id = EVP_get_digestbyname(crypt_hash_compat_name(hash));
if (!hash_id)
return -EINVAL;
@@ -370,7 +402,7 @@ 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);
@@ -505,3 +537,40 @@ bool crypt_cipher_kernel_only(struct crypt_cipher *ctx)
{
return ctx->use_kernel;
}
int crypt_bitlk_decrypt_key(const void *key, size_t key_length,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
const char *tag, size_t tag_length)
{
#ifdef EVP_CTRL_CCM_SET_IVLEN
EVP_CIPHER_CTX *ctx;
int len = 0, r = -EINVAL;
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
return -EINVAL;
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_ccm(), NULL, NULL, NULL) != 1)
goto out;
//EVP_CIPHER_CTX_key_length(ctx)
//EVP_CIPHER_CTX_iv_length(ctx)
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, iv_length, NULL) != 1)
goto out;
if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_length, CONST_CAST(void*)tag) != 1)
goto out;
if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, (const unsigned char*)iv) != 1)
goto out;
if (EVP_DecryptUpdate(ctx, (unsigned char*)out, &len, (const unsigned char*)in, length) == 1)
r = 0;
out:
EVP_CIPHER_CTX_free(ctx);
return r;
#else
return -ENOTSUP;
#endif
}

View File

@@ -2,7 +2,7 @@
* Generic wrapper for storage encryption modes and Initial Vectors
* (reimplementation of some functions from Linux dm-crypt kernel)
*
* Copyright (C) 2014-2019 Milan Broz
* Copyright (C) 2014-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,16 +31,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 +56,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 +89,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 +116,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 +129,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 +173,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 +196,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 +213,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 +246,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 +266,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 +296,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
@@ -151,7 +155,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 +361,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;
}

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;
}
@@ -137,6 +142,27 @@ int INTEGRITY_key_size(struct crypt_device *cd, const char *integrity)
return -EINVAL;
}
/* Return hash or hmac(hash) size, if known */
int INTEGRITY_hash_tag_size(const char *integrity)
{
char hash[MAX_CIPHER_LEN];
int r;
if (!integrity)
return 0;
if (!strcmp(integrity, "crc32") || !strcmp(integrity, "crc32c"))
return 4;
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
if (r == 1)
r = crypt_hash_size(hash);
else
r = crypt_hash_size(integrity);
return r < 0 ? 0 : r;
}
int INTEGRITY_tag_size(struct crypt_device *cd,
const char *integrity,
const char *cipher,
@@ -187,7 +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,
@@ -212,7 +242,9 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
const char *name,
struct crypt_dm_active_device *dmd)
const char *type,
struct crypt_dm_active_device *dmd,
uint32_t sb_flags)
{
int r;
uint32_t dmi_flags;
@@ -235,9 +267,24 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
return r;
}
r = dm_create_device(cd, name, "INTEGRITY", dmd);
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;
}
@@ -250,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, &dmd);
r = INTEGRITY_activate_dmd_device(cd, name, CRYPT_INTEGRITY, &dmd, sb_flags);
dm_targets_free(cd, &dmd);
return r;
}
@@ -282,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);
@@ -302,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) {
@@ -318,7 +368,7 @@ int INTEGRITY_format(struct crypt_device *cd,
}
}
r = dm_create_device(cd, tmp_name, "INTEGRITY", &dmdi);
r = dm_create_device(cd, tmp_name, CRYPT_INTEGRITY, &dmdi);
crypt_free_volume_key(vk);
dm_targets_free(cd, &dmdi);
if (r)

View File

@@ -1,7 +1,7 @@
/*
* Integrity header defitinion
* 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,7 +57,9 @@ struct superblock {
uint64_t recalc_sector; /* V2 only */
} __attribute__ ((packed));
int INTEGRITY_read_sb(struct crypt_device *cd, struct crypt_params_integrity *params);
int INTEGRITY_read_sb(struct crypt_device *cd,
struct crypt_params_integrity *params,
uint32_t *flags);
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset);
@@ -66,6 +72,7 @@ int INTEGRITY_tag_size(struct crypt_device *cd,
const char *integrity,
const char *cipher,
const char *cipher_mode);
int INTEGRITY_hash_tag_size(const char *integrity);
int INTEGRITY_format(struct crypt_device *cd,
const struct crypt_params_integrity *params,
@@ -78,7 +85,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,9 +93,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,
struct crypt_dm_active_device *dmd);
const char *type,
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
@@ -27,8 +27,10 @@
#include <stdint.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <fcntl.h>
#include "nls.h"
#include "bitops.h"
@@ -54,6 +56,9 @@
#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); })
@@ -73,6 +78,10 @@
*_py = NULL; \
} while (0)
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
struct crypt_device;
struct luks2_reenc_context;
@@ -250,4 +259,19 @@ int kernel_version(uint64_t *kversion);
int crypt_serialize_lock(struct crypt_device *cd);
void crypt_serialize_unlock(struct crypt_device *cd);
bool crypt_string_in(const char *str, char **list, size_t list_size);
int crypt_strcmp(const char *a, const char *b);
int crypt_compare_dm_devices(struct crypt_device *cd,
const struct crypt_dm_active_device *src,
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
@@ -414,6 +414,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
#define CRYPT_TCRYPT "TCRYPT"
/** INTEGRITY dm-integrity device */
#define CRYPT_INTEGRITY "INTEGRITY"
/** BITLK (BitLocker-compatible mode) */
#define CRYPT_BITLK "BITLK"
/** LUKS any version */
#define CRYPT_LUKS NULL
@@ -505,6 +507,8 @@ struct crypt_params_verity {
#define CRYPT_VERITY_CHECK_HASH (1 << 1)
/** Create hash - format hash device */
#define CRYPT_VERITY_CREATE_HASH (1 << 2)
/** Root hash signature required for activation */
#define CRYPT_VERITY_ROOT_HASH_SIGNATURE (1 << 3)
/**
*
@@ -629,6 +633,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 +856,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);
/** @} */
/**
@@ -874,10 +916,6 @@ int crypt_keyslot_add_by_passphrase(struct crypt_device *cd,
* @param new_passphrase_size size of @e new_passphrase (binary data)
*
* @return allocated key slot number or negative errno otherwise.
*
* @note This function is just internal implementation of luksChange
* command to avoid reading of volume key outside libcryptsetup boundary
* in FIPS mode.
*/
int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
int keyslot_old,
@@ -1065,6 +1103,16 @@ 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)
/**
* Active device runtime attributes
@@ -1256,6 +1304,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.
*
@@ -1326,6 +1399,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,
@@ -1415,11 +1489,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);
@@ -1429,7 +1503,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);
@@ -1461,6 +1535,8 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd);
*
* @return volume key size
*
* @note For LUKS2, this function can be used only if there is at least
* one keyslot assigned to data segment.
*/
int crypt_get_volume_key_size(struct crypt_device *cd);
@@ -1752,7 +1828,7 @@ int crypt_header_restore(struct crypt_device *cd,
/** Debug all */
#define CRYPT_DEBUG_ALL -1
/** Debug all with adidtional JSON dump (for LUKS2) */
/** Debug all with additional JSON dump (for LUKS2) */
#define CRYPT_DEBUG_JSON -2
/** Debug none */
#define CRYPT_DEBUG_NONE 0
@@ -2120,13 +2196,13 @@ int crypt_activate_by_token(struct crypt_device *cd,
* @{
*/
/** Initialize reencryption metadata but do not run reencryption yet. */
/** Initialize reencryption metadata but do not run reencryption yet. (in) */
#define CRYPT_REENCRYPT_INITIALIZE_ONLY (1 << 0)
/** Move the first segment; used only with data shift. */
/** Move the first segment, used only with data shift. (in/out) */
#define CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT (1 << 1)
/** Resume already initialized reencryption only. */
/** Resume already initialized reencryption only. (in) */
#define CRYPT_REENCRYPT_RESUME_ONLY (1 << 2)
/** Run reencryption recovery only */
/** Run reencryption recovery only. (in) */
#define CRYPT_REENCRYPT_RECOVERY (1 << 3)
/**
@@ -2137,16 +2213,25 @@ typedef enum {
CRYPT_REENCRYPT_BACKWARD /**< backward direction */
} crypt_reencrypt_direction_info;
/**
* Reencryption mode
*/
typedef enum {
CRYPT_REENCRYPT_REENCRYPT = 0, /**< Reencryption mode */
CRYPT_REENCRYPT_ENCRYPT, /**< Encryption mode */
CRYPT_REENCRYPT_DECRYPT, /**< Decryption mode */
} crypt_reencrypt_mode_info;
/**
* LUKS2 reencryption options.
*/
struct crypt_params_reencrypt {
const char *mode; /**< Mode as "encrypt" / "reencrypt" / "decrypt", immutable after first init. */
crypt_reencrypt_mode_info mode; /**< Reencryption mode, immutable after first init. */
crypt_reencrypt_direction_info direction; /**< Reencryption direction, immutable after first init. */
const char *resilience; /**< Resilience mode: "none", "checksum", "journal" or "shift" (only "shift" is immutable after init) */
const char *hash; /**< Used hash for "checksum" resilience type, ignored otherwise. */
uint64_t data_shift; /**< Used in "shift" mode, must be non-zero, immutable after first init. */
uint64_t max_hotzone_size; /**< Hotzone size for "none" mode; maximum hotzone size for "checksum" mode. */
uint64_t max_hotzone_size; /**< Exact hotzone size for "none" mode. Maximum hotzone size for "checksum" and "journal" modes. */
uint64_t device_size; /**< Reencrypt only initial part of the data device. */
const struct crypt_params_luks2 *luks2; /**< LUKS2 parameters for the final reencryption volume.*/
uint32_t flags; /**< Reencryption flags. */
@@ -2214,7 +2299,7 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
* Run data reencryption.
*
* @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.
@@ -2236,7 +2321,7 @@ typedef enum {
* LUKS2 reencryption status.
*
* @param cd crypt device handle
* @param params reecryption parameters
* @param params reencryption parameters
*
* @return reencryption status info and parameters.
*/
@@ -2244,6 +2329,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,11 @@ CRYPTSETUP_2.0 {
crypt_reencrypt_init_by_keyring;
crypt_reencrypt;
crypt_reencrypt_status;
crypt_safe_alloc;
crypt_safe_realloc;
crypt_safe_free;
crypt_safe_memzero;
local:
*;
};

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

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.

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
@@ -23,7 +23,6 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
@@ -260,7 +259,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
r = 0;
out:
crypt_memzero(&hdr, sizeof(hdr));
crypt_safe_memzero(&hdr, sizeof(hdr));
crypt_safe_free(buffer);
return r;
}
@@ -284,7 +283,7 @@ int LUKS_hdr_restore(
buffer_size = LUKS_device_sectors(&hdr_file) << SECTOR_SHIFT;
if (r || buffer_size < LUKS_ALIGN_KEYSLOTS) {
log_err(ctx, _("Backup file doesn't contain valid LUKS header."));
log_err(ctx, _("Backup file does not contain valid LUKS header."));
r = -EINVAL;
goto out;
}
@@ -376,8 +375,13 @@ 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;
}
@@ -387,6 +391,8 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
return -EINVAL;
vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
if (!vk)
return -ENOMEM;
log_verbose(ctx, _("Repairing keyslots."));
@@ -453,7 +459,7 @@ out:
if (r)
log_err(ctx, _("Repair failed."));
crypt_free_volume_key(vk);
crypt_memzero(&temp_phdr, sizeof(temp_phdr));
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
return r;
}
@@ -692,7 +698,7 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
crypt_free_volume_key(empty_key);
crypt_memzero(buf, sizeof(buf));
crypt_safe_memzero(buf, sizeof(buf));
return r;
}
@@ -787,10 +793,15 @@ int LUKS_generate_phdr(struct luks_phdr *header,
return r;
assert(pbkdf->iterations);
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (pbkdf->flags & CRYPT_PBKDF_NO_BENCHMARK && pbkdf->time_ms == 0)
PBKDF2_temp = LUKS_MKD_ITERATIONS_MIN;
else /* iterations per ms * LUKS_MKD_ITERATIONS_MS */
PBKDF2_temp = (double)pbkdf->iterations * LUKS_MKD_ITERATIONS_MS / pbkdf->time_ms;
if (PBKDF2_temp > (double)UINT32_MAX)
return -EINVAL;
header->mkDigestIterations = at_least((uint32_t)PBKDF2_temp, LUKS_MKD_ITERATIONS_MIN);
assert(header->mkDigestIterations);
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec, vk->key,vk->keylength,
header->mkDigestSalt, LUKS_SALTSIZE,
@@ -951,12 +962,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 +981,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 +998,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 +1013,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 +1042,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 +1244,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"
@@ -55,6 +57,9 @@
/* 20 MiBs */
#define LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH 0x1400000
/* 1 GiB */
#define LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH 0x40000000
struct device;
/*
@@ -157,12 +162,12 @@ struct luks2_reenc_context {
bool online;
bool fixed_length;
crypt_reencrypt_direction_info direction;
enum { REENCRYPT = 0, ENCRYPT, DECRYPT } type;
crypt_reencrypt_mode_info mode;
char *device_name;
char *hotzone_name;
char *overlay_name;
uint32_t flags;
/* reencryption window persistence attributes */
struct reenc_protection rp;
@@ -170,8 +175,8 @@ struct luks2_reenc_context {
int reenc_keyslot;
/* already running reencryption */
json_object *jobj_segs_pre;
json_object *jobj_segs_after;
json_object *jobj_segs_hot;
json_object *jobj_segs_post;
/* backup segments */
json_object *jobj_segment_new;
@@ -327,6 +332,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,
@@ -368,19 +379,15 @@ int LUKS2_tokens_count(struct luks2_hdr *hdr);
/*
* Generic LUKS2 segment
*/
json_object *json_get_segments_jobj(json_object *hdr_jobj);
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);
json_object *json_segment_get_flags(json_object *jobj_segment);
bool json_segment_is_backup(json_object *jobj_segment);
bool json_segment_is_reencrypt(json_object *jobj_segment);
json_object *json_segments_get_segment(json_object *jobj_segments, int segment);
int json_segments_count(json_object *jobj_segments);
json_object *json_segments_get_segment_by_flag(json_object *jobj_segments, const char *flag);
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);
@@ -397,8 +404,6 @@ 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);
json_object *LUKS2_get_ignored_segments(struct luks2_hdr *hdr);
int LUKS2_segments_set(struct crypt_device *cd,
struct luks2_hdr *hdr,
json_object *jobj_segments,
@@ -426,10 +431,7 @@ 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);
const char *LUKS2_reencrypt_protection_type(struct luks2_hdr *hdr);
const char *LUKS2_reencrypt_protection_hash(struct luks2_hdr *hdr);
uint64_t LUKS2_reencrypt_data_shift(struct luks2_hdr *hdr);
const char *LUKS2_reencrypt_mode(struct luks2_hdr *hdr);
int LUKS2_reencrypt_data_offset(struct luks2_hdr *hdr, bool blockwise);
/*
* Generic LUKS2 digest
@@ -493,6 +495,7 @@ int LUKS2_activate(struct crypt_device *cd,
int LUKS2_activate_multi(struct crypt_device *cd,
const char *name,
struct volume_key *vks,
uint64_t device_size,
uint32_t flags);
struct crypt_dm_active_device;
@@ -509,12 +512,6 @@ int LUKS2_reload(struct crypt_device *cd,
uint64_t device_size,
uint32_t flags);
int LUKS2_keyslot_luks2_format(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
const char *cipher,
size_t keylength);
int LUKS2_generate_hdr(
struct crypt_device *cd,
struct luks2_hdr *hdr,
@@ -534,7 +531,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);
@@ -550,7 +547,6 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr);
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);
int LUKS2_find_keyslot_for_segment(struct luks2_hdr *hdr, int segment, 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,
@@ -575,7 +571,6 @@ int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet);
char *LUKS2_key_description_by_digest(struct crypt_device *cd, int digest);
int LUKS2_key_description_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int segment);
int LUKS2_volume_key_load_in_keyring_by_keyslot(struct crypt_device *cd,
@@ -594,16 +589,6 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd,
/*
* LUKS2 reencryption
*/
int LUKS2_verify_and_upload_keys(struct crypt_device *cd,
struct luks2_hdr *hdr,
int digest_old,
int digest_new,
struct volume_key *vks);
int LUKS2_reenc_update_segments(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct luks2_reenc_context *rh);
int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
int keyslot_old,
int keyslot_new,
@@ -614,9 +599,19 @@ int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
void LUKS2_reenc_context_free(struct crypt_device *cd, struct luks2_reenc_context *rh);
int crypt_reencrypt_lock(struct crypt_device *cd, const char *uuid, struct crypt_lock_handle **reencrypt_lock);
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 crypt_device *cd,
struct crypt_params_reencrypt *params);
int crypt_reencrypt_lock(struct crypt_device *cd, struct crypt_lock_handle **reencrypt_lock);
int crypt_reencrypt_lock_by_dm_uuid(struct crypt_device *cd, const char *dm_uuid, struct crypt_lock_handle **reencrypt_lock);
void crypt_reencrypt_unlock(struct crypt_device *cd, struct crypt_lock_handle *reencrypt_lock);
int luks2_check_device_size(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t check_size, uint64_t *device_size, bool activation);
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);
#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
};
const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type)
static const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type)
{
int i;
@@ -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)
@@ -304,7 +306,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)
@@ -415,11 +419,6 @@ static char *get_key_description_by_digest(struct crypt_device *cd, int digest)
return desc;
}
char *LUKS2_key_description_by_digest(struct crypt_device *cd, int digest)
{
return get_key_description_by_digest(cd, digest);
}
int LUKS2_key_description_by_segment(struct crypt_device *cd,
struct luks2_hdr *hdr, struct volume_key *vk, int segment)
{

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
@@ -26,7 +26,7 @@
/*
* Helper functions
*/
json_object *parse_json_len(struct crypt_device *cd, const char *json_area,
static json_object *parse_json_len(struct crypt_device *cd, const char *json_area,
uint64_t max_length, int *json_len)
{
json_object *jobj;
@@ -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);
@@ -210,7 +210,7 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd,
}
if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.",
(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
return -EINVAL;
}
@@ -421,10 +421,9 @@ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr, struct
* Allocate and zero JSON area (of proper header size).
*/
json_area_len = hdr->hdr_size - LUKS2_HDR_BIN_LEN;
json_area = malloc(json_area_len);
json_area = crypt_zalloc(json_area_len);
if (!json_area)
return -ENOMEM;
memset(json_area, 0, json_area_len);
/*
* Generate text space-efficient JSON representation to json area.

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>
@@ -59,11 +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);
json_object *parse_json_len(struct crypt_device *cd, const char *json_area,
uint64_t max_length, int *json_len);
uint64_t json_object_get_uint64(json_object *jobj);
uint32_t json_object_get_uint32(json_object *jobj);
json_object *json_object_new_uint64(uint64_t value);
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);
@@ -81,8 +78,6 @@ json_object *json_contains(struct crypt_device *cd, json_object *jobj, const cha
const char *section, const char *key, json_type type);
int LUKS2_hdr_validate(struct crypt_device *cd, json_object *hdr_jobj, uint64_t json_size);
int LUKS2_keyslot_validate(struct crypt_device *cd, json_object *hdr_jobj,
json_object *hdr_keyslot, const char *key);
int LUKS2_check_json_size(struct crypt_device *cd, const struct luks2_hdr *hdr);
int LUKS2_token_validate(struct crypt_device *cd, json_object *hdr_jobj,
json_object *jobj_token, const char *key);
@@ -167,8 +162,6 @@ typedef struct {
digest_dump_func dump;
} digest_handler;
const digest_handler *LUKS2_digest_handler_type(struct crypt_device *cd, const char *type);
/**
* LUKS2 token handlers (internal use only)
*/
@@ -195,4 +188,16 @@ int LUKS2_check_cipher(struct crypt_device *cd,
size_t keylength,
const char *cipher,
const char *cipher_mode);
static inline const char *crypt_reencrypt_mode_to_str(crypt_reencrypt_mode_info mi)
{
if (mi == CRYPT_REENCRYPT_REENCRYPT)
return "reencrypt";
if (mi == CRYPT_REENCRYPT_ENCRYPT)
return "encrypt";
if (mi == CRYPT_REENCRYPT_DECRYPT)
return "decrypt";
return "<unknown>";
}
#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
@@ -216,7 +216,8 @@ 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)
metadata_size = LUKS2_HDR_16K_LEN;
@@ -240,6 +241,12 @@ int LUKS2_generate_hdr(
if (!keyslots_size) {
assert(LUKS2_DEFAULT_HDR_SIZE > 2 * LUKS2_HDR_OFFSET_MAX);
keyslots_size = LUKS2_DEFAULT_HDR_SIZE - get_min_offset(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)) &&
(get_min_offset(hdr) <= mdev_size))
keyslots_size = mdev_size - get_min_offset(hdr);
}
/* Decrease keyslots_size if we have smaller data_offset */
@@ -283,9 +290,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();
@@ -319,8 +328,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;
@@ -331,7 +340,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;
@@ -346,7 +355,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;
}
@@ -394,6 +403,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);
}
@@ -169,6 +169,16 @@ json_object *LUKS2_get_digest_jobj(struct luks2_hdr *hdr, int digest)
return jobj2;
}
static json_object *json_get_segments_jobj(json_object *hdr_jobj)
{
json_object *jobj_segments;
if (!hdr_jobj || !json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
return NULL;
return jobj_segments;
}
json_object *LUKS2_get_segment_jobj(struct luks2_hdr *hdr, int segment)
{
if (!hdr)
@@ -187,12 +197,10 @@ json_object *LUKS2_get_segments_jobj(struct luks2_hdr *hdr)
int LUKS2_segments_count(struct luks2_hdr *hdr)
{
json_object *jobj_segments;
if (!hdr || !(jobj_segments = LUKS2_get_segments_jobj(hdr)))
if (!hdr)
return -EINVAL;
return json_segments_count(jobj_segments);
return json_segments_count(LUKS2_get_segments_jobj(hdr));
}
int LUKS2_get_default_segment(struct luks2_hdr *hdr)
@@ -211,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);
}
@@ -226,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];
@@ -265,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,
@@ -292,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,
@@ -305,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,
@@ -328,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)
@@ -349,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,
@@ -364,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++) {
@@ -385,17 +393,17 @@ 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;
}
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, json_object *hdr_keyslot, const char *key)
{
json_object *jobj_key_size;
@@ -447,16 +455,16 @@ static int hdr_validate_json_size(struct crypt_device *cd, json_object *hdr_jobj
json = json_object_to_json_string_ext(hdr_jobj,
JSON_C_TO_STRING_PLAIN | JSON_C_TO_STRING_NOSLASHESCAPE);
json_area_size = json_object_get_uint64(jobj1);
json_area_size = crypt_jobj_get_uint64(jobj1);
json_size = (uint64_t)strlen(json);
if (hdr_json_size != json_area_size) {
log_dbg(cd, "JSON area size doesn't match value in binary header.");
log_dbg(cd, "JSON area size does not match value in binary header.");
return 1;
}
if (json_size > json_area_size) {
log_dbg(cd, "JSON doesn't fit in the designated area.");
log_dbg(cd, "JSON does not fit in the designated area.");
return 1;
}
@@ -535,7 +543,7 @@ static int hdr_validate_crypt_segment(struct crypt_device *cd,
return 1;
}
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (!sector_size || MISALIGNED_512(sector_size)) {
log_dbg(cd, "Illegal sector size: %" PRIu32, sector_size);
return 1;
@@ -586,9 +594,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.");
@@ -668,10 +676,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;
@@ -962,13 +978,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);
@@ -976,11 +995,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);
@@ -1151,7 +1166,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;
}
@@ -1262,8 +1277,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);
@@ -1282,6 +1297,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 }
};
@@ -1559,7 +1576,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));
@@ -1642,7 +1659,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))
@@ -1739,7 +1756,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 */
@@ -1754,16 +1771,14 @@ int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic)
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr)
{
uint64_t new = 0, old = 0;
crypt_reencrypt_info ri;
json_object *jobj;
jobj = LUKS2_get_segment_by_flag(hdr, "backup-final");
if (jobj) {
new = json_segment_get_offset(jobj, 1);
jobj = LUKS2_get_segment_by_flag(hdr, "backup-previous");
ri = LUKS2_reenc_status(hdr);
if (ri == CRYPT_REENCRYPT_CLEAN || ri == CRYPT_REENCRYPT_CRASH) {
jobj = LUKS2_get_segment_by_flag(hdr, "backup-final");
if (jobj)
old = json_segment_get_offset(jobj, 1);
return new > old ? new : old;
return json_segment_get_offset(jobj, 1);
}
return json_segments_get_minimal_offset(LUKS2_get_segments_jobj(hdr), 1);
@@ -1948,7 +1963,7 @@ int LUKS2_get_sector_size(struct luks2_hdr *hdr)
return json_segment_get_sector_size(jobj_segment) ?: SECTOR_SIZE;
}
static int _prepare_multi_dmd(struct crypt_device *cd,
int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct volume_key *vks,
json_object *jobj_segments,
@@ -1967,26 +1982,25 @@ static int _prepare_multi_dmd(struct crypt_device *cd,
else
device_check = DEV_EXCL;
/* FIXME: replace == 0 with < LUKS2_header_size() */
data_offset = json_segments_get_minimal_offset(jobj_segments, 1);
if (data_offset == 0 &&
crypt_data_device(cd) == crypt_metadata_device(cd)) {
log_dbg(cd, "Internal error. Wrong data offset");
return -EINVAL;
}
data_offset = LUKS2_reencrypt_data_offset(hdr, true);
r = device_block_adjust(cd, crypt_data_device(cd), device_check,
data_offset, &dmd->size, &dmd->flags);
if (r)
return r;
r = dm_targets_allocate(&dmd->segment, json_segments_count(jobj_segments));
if (r)
goto err;
r = -EINVAL;
while (t) {
jobj = json_segments_get_segment(jobj_segments, s);
if (!jobj) {
log_dbg(cd, "Internal error. Segment %u is null.", s);
return -EINVAL;
r = -EINVAL;
goto err;
}
segment_offset = json_segment_get_offset(jobj, 1);
@@ -1996,14 +2010,16 @@ static int _prepare_multi_dmd(struct crypt_device *cd,
segment_size = dmd->size - segment_start;
if (!segment_size) {
log_dbg(cd, "Internal error. Wrong segment size %u", s);
return -EINVAL;
r = -EINVAL;
goto err;
}
if (!strcmp(json_segment_type(jobj), "crypt")) {
vk = crypt_volume_key_by_id(vks, LUKS2_digest_by_segment(hdr, s));
if (!vk) {
log_err(cd, _("Missing key for dm-crypt segment %u"), s);
return -EINVAL;
r = -EINVAL;
goto err;
}
r = dm_crypt_target_set(t, segment_start, segment_size,
@@ -2014,22 +2030,27 @@ static int _prepare_multi_dmd(struct crypt_device *cd,
json_segment_get_sector_size(jobj));
if (r) {
log_err(cd, _("Failed to set dm-crypt segment."));
return r;
goto err;
}
} else if (!strcmp(json_segment_type(jobj), "linear")) {
r = dm_linear_target_set(t, segment_start, segment_size, crypt_data_device(cd), segment_offset);
if (r) {
log_err(cd, _("Failed to set dm-linear segment."));
return r;
goto err;
}
} else
return -EINVAL;
} else {
r = -EINVAL;
goto err;
}
segment_start += segment_size;
t = t->next;
s++;
}
return r;
err:
dm_targets_free(cd, dmd);
return r;
}
@@ -2041,16 +2062,13 @@ static int _reload_custom_multi(struct crypt_device *cd,
uint64_t device_size,
uint32_t flags)
{
int r, count = json_segments_count(jobj_segments);
int r;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
struct crypt_dm_active_device dmd = {
.uuid = crypt_get_uuid(cd),
.size = device_size >> SECTOR_SHIFT
};
if (count < 0)
return -EINVAL;
/* do not allow activation when particular requirements detected */
if ((r = LUKS2_unmet_requirements(cd, hdr, CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 0)))
return r;
@@ -2061,13 +2079,7 @@ static int _reload_custom_multi(struct crypt_device *cd,
dmd.flags |= (flags | CRYPT_ACTIVATE_SHARED);
r = dm_targets_allocate(&dmd.segment, count);
if (r) {
dm_targets_free(cd, &dmd);
return r;
}
r = _prepare_multi_dmd(cd, hdr, vks, jobj_segments, &dmd);
r = LUKS2_assembly_multisegment_dmd(cd, hdr, vks, jobj_segments, &dmd);
if (!r)
r = dm_reload_device(cd, name, &dmd, 0, 0);
@@ -2091,18 +2103,17 @@ int LUKS2_reload(struct crypt_device *cd,
int LUKS2_activate_multi(struct crypt_device *cd,
const char *name,
struct volume_key *vks,
uint64_t device_size,
uint32_t flags)
{
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
json_object *jobj_segments = LUKS2_get_segments_jobj(hdr);
int r, count = json_segments_count(jobj_segments);
int r;
struct crypt_dm_active_device dmd = {
.uuid = crypt_get_uuid(cd),
.size = device_size,
.uuid = crypt_get_uuid(cd)
};
if (count < 0)
return -EINVAL;
/* do not allow activation when particular requirements detected */
if ((r = LUKS2_unmet_requirements(cd, hdr, CRYPT_REQUIREMENT_ONLINE_REENCRYPT, 0)))
return r;
@@ -2113,13 +2124,7 @@ int LUKS2_activate_multi(struct crypt_device *cd,
dmd.flags |= flags;
r = dm_targets_allocate(&dmd.segment, count);
if (r) {
dm_targets_free(cd, &dmd);
return r;
}
r = _prepare_multi_dmd(cd, hdr, vks, jobj_segments, &dmd);
r = LUKS2_assembly_multisegment_dmd(cd, hdr, vks, jobj_segments, &dmd);
if (!r)
r = dm_create_device(cd, name, CRYPT_LUKS2, &dmd);
@@ -2135,7 +2140,7 @@ int LUKS2_activate(struct crypt_device *cd,
int r;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
struct crypt_dm_active_device dmdi = {}, dmd = {
.uuid = crypt_get_uuid(cd),
.uuid = crypt_get_uuid(cd)
};
/* do not allow activation when particular requirements detected */
@@ -2161,10 +2166,17 @@ 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;
dmdi.flags |= CRYPT_ACTIVATE_PRIVATE;
dmdi.uuid = dmd.uuid;
dmd.segment.u.crypt.offset = 0;
dmd.segment.size = dmdi.segment.size;
@@ -2186,7 +2198,7 @@ static bool is_reencryption_helper(const char *name)
return false;
len = strlen(name);
return (len >= 9 && (!strcmp(name + len - 8, "-hotzone") ||
return (len >= 9 && (!strncmp(name + len - 8, "-hotzone-", 9) ||
!strcmp(name + len - 8, "-overlay")));
}
@@ -2207,24 +2219,19 @@ 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[38], *deps[65] = { 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)
return -EINVAL;
r = snprintf(deps_uuid_prefix, sizeof(deps_uuid_prefix), "TEMP-%.32s", dmd->uuid + 6);
if (r < 0 || (size_t)r != 37)
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 != 36)
if (!dmd || !dmd->uuid || strncmp(CRYPT_LUKS2, dmd->uuid, sizeof(CRYPT_LUKS2)-1))
return -EINVAL;
/* uuid mismatch with metadata (if available) */
if (hdr && strcmp(hdr->uuid, uuid))
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;
tgt = &dmd->segment;
@@ -2238,7 +2245,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
goto out;
if (contains_reencryption_helper(deps)) {
r = crypt_reencrypt_lock(cd, uuid, &reencrypt_lock);
r = crypt_reencrypt_lock_by_dm_uuid(cd, dmd->uuid, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot deactivate device."));
@@ -2252,7 +2259,7 @@ int LUKS2_deactivate(struct crypt_device *cd, const char *name, struct luks2_hdr
while (*dep) {
if (is_reencryption_helper(*dep) && (dm_status_suspended(cd, *dep) > 0)) {
if (dm_error_device(cd, *dep))
log_err(cd, _("Failed to error suspended device %s."), *dep);
log_err(cd, _("Failed to replace suspended device %s with dm-error target."), *dep);
}
dep++;
}
@@ -2347,9 +2354,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;
@@ -2402,7 +2409,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
@@ -76,22 +76,21 @@ int LUKS2_keyslot_find_empty(struct luks2_hdr *hdr)
return -EINVAL;
}
/* Check if a keyslot is asssigned to specific segment */
/* 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 +148,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)
@@ -271,7 +270,8 @@ crypt_keyslot_info LUKS2_keyslot_info(struct luks2_hdr *hdr, int keyslot)
if (!LUKS2_get_keyslot_jobj(hdr, keyslot))
return CRYPT_SLOT_INACTIVE;
if (LUKS2_keyslot_unbound(hdr, keyslot))
if (LUKS2_digest_by_keyslot(hdr, keyslot) < 0 ||
LUKS2_keyslot_unbound(hdr, keyslot))
return CRYPT_SLOT_UNBOUND;
if (LUKS2_keyslot_active_count(hdr, CRYPT_DEFAULT_SEGMENT) == 1 &&
@@ -300,37 +300,25 @@ int LUKS2_keyslot_area(struct luks2_hdr *hdr,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj))
return -EINVAL;
*offset = json_object_get_uint64(jobj);
*offset = crypt_jobj_get_uint64(jobj);
if (!json_object_object_get_ex(jobj_area, "size", &jobj))
return -EINVAL;
*length = json_object_get_uint64(jobj);
*length = crypt_jobj_get_uint64(jobj);
return 0;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
static int _open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
const keyslot_handler *h,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r, key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
@@ -349,9 +337,41 @@ static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
*vk = NULL;
}
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
}
static int LUKS2_open_and_verify_by_digest(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int digest,
const char *password,
size_t password_len,
struct volume_key **vk)
{
const keyslot_handler *h;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
r = h->validate(cd, LUKS2_get_keyslot_jobj(hdr, keyslot));
if (r) {
log_dbg(cd, "Keyslot %d validation failed.", keyslot);
return r;
}
r = _keyslot_for_digest(hdr, keyslot, digest);
if (r) {
if (r == -ENOENT)
log_dbg(cd, "Keyslot %d unusable for digest %d.", keyslot, digest);
return r;
}
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_open_and_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -361,7 +381,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
struct volume_key **vk)
{
const keyslot_handler *h;
int key_size, r;
int r;
if (!(h = LUKS2_keyslot_handler(cd, keyslot)))
return -ENOENT;
@@ -379,29 +399,7 @@ static int LUKS2_open_and_verify(struct crypt_device *cd,
return r;
}
key_size = LUKS2_get_volume_key_size(hdr, segment);
if (key_size < 0)
key_size = LUKS2_get_keyslot_stored_key_size(hdr, keyslot);
if (key_size < 0)
return -EINVAL;
*vk = crypt_alloc_volume_key(key_size, NULL);
if (!*vk)
return -ENOMEM;
r = h->open(cd, keyslot, password, password_len, (*vk)->key, (*vk)->keylength);
if (r < 0)
log_dbg(cd, "Keyslot %d (%s) open failed with %d.", keyslot, h->name, r);
else
r = LUKS2_digest_verify(cd, hdr, *vk, keyslot);
if (r < 0) {
crypt_free_volume_key(*vk);
*vk = NULL;
} else
crypt_volume_key_set_id(*vk, r);
return r < 0 ? r : keyslot;
return _open_and_verify(cd, hdr, h, keyslot, password, password_len, vk);
}
static int LUKS2_keyslot_open_priority_digest(struct crypt_device *cd,
@@ -519,7 +517,7 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
size_t password_len,
struct volume_key **vks)
{
struct volume_key *vk;
struct volume_key *vk = NULL;
int digest_old, digest_new, r = -EINVAL;
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
@@ -529,7 +527,6 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_old, digest_old, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_old);
crypt_volume_key_add_next(vks, vk);
}
@@ -539,13 +536,17 @@ int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
r = LUKS2_keyslot_open_by_digest(cd, hdr, keyslot_new, digest_new, password, password_len, &vk);
if (r < 0)
goto out;
crypt_volume_key_set_id(vk, digest_new);
crypt_volume_key_add_next(vks, vk);
}
out:
if (r < 0) {
crypt_free_volume_key(*vks);
*vks = NULL;
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -578,6 +579,13 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
} else
r = LUKS2_open_and_verify(cd, hdr, keyslot, segment, password, password_len, vk);
if (r < 0) {
if (r == -ENOMEM)
log_err(cd, _("Not enough available memory to open a keyslot."));
else if (r != -EPERM)
log_err(cd, _("Keyslot open failed."));
}
return r;
}
@@ -827,8 +835,8 @@ int placeholder_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
@@ -927,24 +935,3 @@ int LUKS2_find_keyslot(struct luks2_hdr *hdr, const char *type)
return -ENOENT;
}
int LUKS2_find_keyslot_for_segment(struct luks2_hdr *hdr, int segment, const char *type)
{
int i;
json_object *jobj_keyslot, *jobj_type;
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++) {
jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, i);
if (!jobj_keyslot)
continue;
json_object_object_get_ex(jobj_keyslot, "type", &jobj_type);
if (strcmp(json_object_get_string(jobj_type), type))
continue;
if (!LUKS2_keyslot_for_segment(hdr, i, segment))
return i;
}
return -EINVAL;
}

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
@@ -28,7 +28,7 @@
#define LUKS_SLOT_ITERATIONS_MIN 1000
#define LUKS_STRIPES 4000
/* Serialize memory-hard keyslot access: opttional workaround for parallel processing */
/* Serialize memory-hard keyslot access: optional workaround for parallel processing */
#define MIN_MEMORY_FOR_SERIALIZE_LOCK_KB 32*1024 /* 32MB */
static int luks2_encrypt_to_storage(char *src, size_t srcLength,
@@ -48,17 +48,18 @@ 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_dbg(cd, "Userspace crypto wrapper cannot use %s-%s (%d).",
cipher, cipher_mode, r);
log_err(cd, _("Cannot use %s-%s cipher for keyslot encryption."), cipher, cipher_mode);
return r;
}
r = crypt_storage_encrypt(s, 0, srcLength, src);
crypt_storage_destroy(s);
if (r)
if (r) {
log_err(cd, _("IO error while encrypting keyslot."));
return r;
}
devfd = device_open_locked(cd, device, O_RDWR);
if (devfd >= 0) {
@@ -102,10 +103,9 @@ 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_dbg(cd, "Userspace crypto wrapper cannot use %s-%s (%d).",
cipher, cipher_mode, 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;
@@ -313,7 +313,7 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
if (!json_object_object_get_ex(jobj_area, "offset", &jobj2))
return -EINVAL;
area_offset = json_object_get_uint64(jobj2);
area_offset = crypt_jobj_get_uint64(jobj2);
if (!json_object_object_get_ex(jobj_area, "encryption", &jobj2))
return -EINVAL;
@@ -494,8 +494,8 @@ static int luks2_keyslot_alloc(struct crypt_device *cd,
/* Area object */
jobj_area = json_object_new_object();
json_object_object_add(jobj_area, "type", json_object_new_string("raw"));
json_object_object_add(jobj_area, "offset", json_object_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", json_object_new_uint64(area_length));
json_object_object_add(jobj_area, "offset", crypt_jobj_new_uint64(area_offset));
json_object_object_add(jobj_area, "size", crypt_jobj_new_uint64(area_length));
json_object_object_add(jobj_keyslot, "area", jobj_area);
json_object_object_add_by_uint(jobj_keyslots, keyslot, jobj_keyslot);
@@ -607,7 +607,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tCipher: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "key_size", &jobj1);
log_std(cd, "\tCipher key: %u bits\n", json_object_get_uint32(jobj1) * 8);
log_std(cd, "\tCipher key: %u bits\n", crypt_jobj_get_uint32(jobj1) * 8);
json_object_object_get_ex(jobj_kdf, "type", &jobj1);
log_std(cd, "\tPBKDF: %s\n", json_object_get_string(jobj1));
@@ -617,7 +617,7 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tHash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_kdf, "iterations", &jobj1);
log_std(cd, "\tIterations: %" PRIu64 "\n", json_object_get_uint64(jobj1));
log_std(cd, "\tIterations: %" PRIu64 "\n", crypt_jobj_get_uint64(jobj1));
} else {
json_object_object_get_ex(jobj_kdf, "time", &jobj1);
log_std(cd, "\tTime cost: %" PRIu64 "\n", json_object_get_int64(jobj1));
@@ -640,10 +640,10 @@ static int luks2_keyslot_dump(struct crypt_device *cd, int keyslot)
log_std(cd, "\tAF hash: %s\n", json_object_get_string(jobj1));
json_object_object_get_ex(jobj_area, "offset", &jobj1);
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea offset:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
json_object_object_get_ex(jobj_area, "size", &jobj1);
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", json_object_get_uint64(jobj1));
log_std(cd, "\tArea length:%" PRIu64 " [bytes]\n", crypt_jobj_get_uint64(jobj1));
return 0;
}

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, reencryption keyslot handler
*
* Copyright (C) 2016-2018, Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2018, Ondrej Kozina
* Copyright (C) 2016-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
@@ -67,17 +67,17 @@ 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 */
json_object_object_add(jobj_keyslot, "mode", json_object_new_string(params->mode));
json_object_object_add(jobj_keyslot, "mode", json_object_new_string(crypt_reencrypt_mode_to_str(params->mode)));
if (params->direction == CRYPT_REENCRYPT_FORWARD)
json_object_object_add(jobj_keyslot, "direction", json_object_new_string("forward"));
else if (params->direction == CRYPT_REENCRYPT_BACKWARD)
@@ -113,8 +113,8 @@ static int reenc_keyslot_store_data(struct crypt_device *cd,
!json_object_object_get_ex(jobj_area, "size", &jobj_length))
return -EINVAL;
area_offset = json_object_get_uint64(jobj_offset);
area_length = json_object_get_uint64(jobj_length);
area_offset = crypt_jobj_get_uint64(jobj_offset);
area_length = crypt_jobj_get_uint64(jobj_length);
if (!area_offset || !area_length || ((uint64_t)buffer_len > area_length))
return -EINVAL;
@@ -242,22 +242,22 @@ 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;
}
static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_keyslot)
{
json_object *jobj_mode, *jobj_area, *jobj_type, *jobj_shift_size, *jobj_hash, *jobj_sector_size;
const char *mode, *type;
json_object *jobj_mode, *jobj_area, *jobj_type, *jobj_shift_size, *jobj_hash, *jobj_sector_size, *jobj_direction;
const char *mode, *type, *direction;
uint32_t sector_size;
uint64_t shift_size;
@@ -277,12 +277,14 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
return -EINVAL;
jobj_mode = json_contains(cd, jobj_keyslot, "", "reencrypt keyslot", "mode", json_type_string);
jobj_direction = json_contains(cd, jobj_keyslot, "", "reencrypt keyslot", "direction", json_type_string);
if (!jobj_mode || !json_contains(cd, jobj_keyslot, "", "reencrypt keyslot", "direction", json_type_string))
if (!jobj_mode || !jobj_direction)
return -EINVAL;
mode = json_object_get_string(jobj_mode);
type = json_object_get_string(jobj_type);
direction = json_object_get_string(jobj_direction);
if (strcmp(mode, "reencrypt") && strcmp(mode, "encrypt") &&
strcmp(mode, "decrypt")) {
@@ -290,6 +292,11 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
return -EINVAL;
}
if (strcmp(direction, "forward") && strcmp(direction, "backward")) {
log_dbg(cd, "Illegal reencrypt direction %s.", direction);
return -EINVAL;
}
if (!strcmp(type, "checksum")) {
jobj_hash = json_contains(cd, jobj_area, "type:checksum", "Keyslot area", "hash", json_type_string);
jobj_sector_size = json_contains(cd, jobj_area, "type:checksum", "Keyslot area", "sector_size", json_type_int);
@@ -297,7 +304,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
return -EINVAL;
if (!validate_json_uint32(jobj_sector_size))
return -EINVAL;
sector_size = json_object_get_uint32(jobj_sector_size);
sector_size = crypt_jobj_get_uint32(jobj_sector_size);
if (sector_size < SECTOR_SIZE || NOTPOW2(sector_size)) {
log_dbg(cd, "Invalid sector_size (%" PRIu32 ") for checksum resilience mode.", sector_size);
return -EINVAL;
@@ -306,7 +313,7 @@ static int reenc_keyslot_validate(struct crypt_device *cd, json_object *jobj_key
if (!(jobj_shift_size = json_contains(cd, jobj_area, "type:datashift", "Keyslot area", "shift_size", json_type_string)))
return -EINVAL;
shift_size = json_object_get_uint64(jobj_shift_size);
shift_size = crypt_jobj_get_uint64(jobj_shift_size);
if (!shift_size)
return -EINVAL;

View File

@@ -1,9 +1,9 @@
/*
* LUKS - Linux Unified Key Setup v2, LUKS1 conversion code
*
* Copyright (C) 2015-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2019 Ondrej Kozina
* Copyright (C) 2015-2019 Milan Broz
* Copyright (C) 2015-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;
@@ -478,7 +479,7 @@ static int luks_header_in_use(struct crypt_device *cd)
r = lookup_dm_dev_by_uuid(cd, crypt_get_uuid(cd), crypt_get_type(cd));
if (r < 0)
log_err(cd, _("Can not check status of device with uuid: %s."), crypt_get_uuid(cd));
log_err(cd, _("Cannot check status of device with uuid: %s."), crypt_get_uuid(cd));
return r;
}
@@ -518,7 +519,7 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
int r;
json_object *jobj = NULL;
size_t buf_size, buf_offset, luks1_size, luks1_shift = 2 * LUKS2_HDR_16K_LEN - LUKS_ALIGN_KEYSLOTS;
uint64_t max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
uint64_t required_size, max_size = crypt_get_data_offset(cd) * SECTOR_SIZE;
/* for detached headers max size == device size */
if (!max_size && (r = device_size(crypt_metadata_device(cd), &max_size)))
@@ -539,11 +540,18 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
log_dbg(cd, "Max size: %" PRIu64 ", LUKS1 (full) header size %zu , required shift: %zu",
max_size, luks1_size, luks1_shift);
if ((max_size - luks1_size) < luks1_shift) {
required_size = luks1_size + luks1_shift;
if ((max_size < required_size) &&
device_fallocate(crypt_metadata_device(cd), required_size)) {
log_err(cd, _("Unable to move keyslot area. Not enough space."));
return -EINVAL;
}
if (max_size < required_size)
max_size = required_size;
r = json_luks1_object(hdr1, &jobj, max_size - 2 * LUKS2_HDR_16K_LEN);
if (r < 0)
return r;
@@ -570,6 +578,12 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
goto out;
}
/* check future LUKS2 metadata before moving keyslots area */
if (LUKS2_hdr_validate(cd, hdr2->jobj, hdr2->hdr_size - LUKS2_HDR_BIN_LEN)) {
r = -EINVAL;
goto out;
}
if ((r = luks_header_in_use(cd))) {
if (r > 0)
r = -EBUSY;
@@ -579,6 +593,14 @@ int LUKS2_luks1_to_luks2(struct crypt_device *cd, struct luks_phdr *hdr1, struct
// move keyslots 4k -> 32k offset
buf_offset = 2 * LUKS2_HDR_16K_LEN;
buf_size = luks1_size - LUKS_ALIGN_KEYSLOTS;
/* check future LUKS2 keyslots area is at least as large as LUKS1 keyslots area */
if (buf_size > LUKS2_keyslots_size(hdr2->jobj)) {
log_err(cd, _("Unable to move keyslot area. LUKS2 keyslots area too small."));
r = -EINVAL;
goto out;
}
if ((r = move_keyslot_areas(cd, 8 * SECTOR_SIZE, buf_offset, buf_size)) < 0) {
log_err(cd, _("Unable to move keyslot area."));
goto out;
@@ -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 */

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
@@ -21,16 +21,6 @@
#include "luks2_internal.h"
json_object *json_get_segments_jobj(json_object *hdr_jobj)
{
json_object *jobj_segments;
if (!hdr_jobj || !json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
return NULL;
return jobj_segments;
}
/* use only on already validated 'segments' object */
uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned blockwise)
{
@@ -65,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)
@@ -87,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)
@@ -98,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)
@@ -124,7 +114,7 @@ int json_segment_get_sector_size(json_object *jobj_segment)
return json_object_get_int(jobj);
}
json_object *json_segment_get_flags(json_object *jobj_segment)
static json_object *json_segment_get_flags(json_object *jobj_segment)
{
json_object *jobj;
@@ -159,11 +149,6 @@ bool json_segment_is_backup(json_object *jobj_segment)
return json_segment_contains_flag(jobj_segment, "backup-", 7);
}
bool json_segment_is_reencrypt(json_object *jobj_segment)
{
return json_segment_contains_flag(jobj_segment, "in-reencryption", 0);
}
json_object *json_segments_get_segment(json_object *jobj_segments, int segment)
{
json_object *jobj;
@@ -178,12 +163,12 @@ json_object *json_segments_get_segment(json_object *jobj_segments, int segment)
return jobj;
}
int json_segments_count(json_object *jobj_segments)
unsigned json_segments_count(json_object *jobj_segments)
{
int count = 0;
unsigned count = 0;
if (!jobj_segments)
return -EINVAL;
return 0;
json_object_object_foreach(jobj_segments, slot, val) {
UNUSED(slot);
@@ -215,16 +200,6 @@ static void _get_segment_or_id_by_flag(json_object *jobj_segments, const char *f
}
}
json_object *json_segments_get_segment_by_flag(json_object *jobj_segments, const char *flag)
{
json_object *jobj_segment = NULL;
if (jobj_segments)
_get_segment_or_id_by_flag(jobj_segments, flag, 0, &jobj_segment);
return jobj_segment;
}
void json_segment_remove_flag(json_object *jobj_segment, const char *flag)
{
json_object *jobj_flags, *jobj_flags_new;
@@ -254,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;
}
@@ -277,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)
@@ -435,20 +410,3 @@ json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag)
return jobj_segment;
}
json_object *LUKS2_get_ignored_segments(struct luks2_hdr *hdr)
{
json_object *jobj_segments, *jobj = json_object_new_object();
int i = 0;
if (!jobj || !json_object_object_get_ex(hdr->jobj, "segments", &jobj_segments))
return NULL;
json_object_object_foreach(jobj_segments, key, value) {
UNUSED(key);
if (json_segment_is_backup(value))
json_object_object_add_by_uint(jobj, i++, json_object_get(value));
}
return jobj;
}

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
@@ -147,7 +147,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)
@@ -329,10 +330,10 @@ 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);
}
}
@@ -383,6 +384,7 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
uint32_t flags,
void *usrptr)
{
bool use_keyring;
int keyslot, r;
char *buffer;
size_t buffer_len;
@@ -404,7 +406,13 @@ int LUKS2_token_open_and_activate(struct crypt_device *cd,
keyslot = r;
if ((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;
}
@@ -510,7 +518,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)
@@ -576,16 +586,12 @@ int LUKS2_token_assign(struct crypt_device *cd, struct luks2_hdr *hdr,
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 +606,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, 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 +623,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;
}

View File

@@ -1,8 +1,8 @@
/*
* LUKS - Linux Unified Key Setup v2, kernel keyring token
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-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

View File

@@ -1,7 +1,7 @@
/*
* cryptsetup kernel RNG access functions
*
* Copyright (C) 2010-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-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
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
#include <sys/select.h>
@@ -28,10 +27,6 @@
#include "libcryptsetup.h"
#include "internal.h"
#ifndef O_CLOEXEC
#define O_CLOEXEC 0
#endif
static int random_initialised = 0;
#define URANDOM_DEVICE "/dev/urandom"

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
/*
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-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
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>
#include "libcryptsetup.h"
@@ -301,8 +300,8 @@ static int decrypt_blowfish_le_cbc(struct tcrypt_alg *alg,
}
crypt_cipher_destroy(cipher);
crypt_memzero(iv, bs);
crypt_memzero(iv_old, bs);
crypt_safe_memzero(iv, bs);
crypt_safe_memzero(iv_old, bs);
return r;
}
@@ -369,8 +368,8 @@ static int TCRYPT_decrypt_hdr_one(struct tcrypt_alg *alg, const char *mode,
crypt_cipher_destroy(cipher);
}
crypt_memzero(backend_key, sizeof(backend_key));
crypt_memzero(iv, TCRYPT_HDR_IV_LEN);
crypt_safe_memzero(backend_key, sizeof(backend_key));
crypt_safe_memzero(iv, TCRYPT_HDR_IV_LEN);
return r;
}
@@ -420,8 +419,8 @@ out:
if (cipher[j])
crypt_cipher_destroy(cipher[j]);
crypt_memzero(iv, bs);
crypt_memzero(iv_old, bs);
crypt_safe_memzero(iv, bs);
crypt_safe_memzero(iv_old, bs);
return r;
}
@@ -474,13 +473,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
r = -EPERM;
}
crypt_memzero(&hdr2, sizeof(hdr2));
crypt_safe_memzero(&hdr2, sizeof(hdr2));
return r;
}
static int TCRYPT_pool_keyfile(struct crypt_device *cd,
unsigned char pool[TCRYPT_KEY_POOL_LEN],
const char *keyfile)
unsigned char pool[VCRYPT_KEY_POOL_LEN],
const char *keyfile, int keyfiles_pool_length)
{
unsigned char *data;
int i, j, fd, data_size, r = -EIO;
@@ -512,12 +511,12 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
pool[j++] += (unsigned char)(crc >> 16);
pool[j++] += (unsigned char)(crc >> 8);
pool[j++] += (unsigned char)(crc);
j %= TCRYPT_KEY_POOL_LEN;
j %= keyfiles_pool_length;
}
r = 0;
out:
crypt_memzero(&crc, sizeof(crc));
crypt_memzero(data, TCRYPT_KEYFILE_LEN);
crypt_safe_memzero(&crc, sizeof(crc));
crypt_safe_memzero(data, TCRYPT_KEYFILE_LEN);
free(data);
return r;
@@ -527,29 +526,39 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
struct tcrypt_phdr *hdr,
struct crypt_params_tcrypt *params)
{
unsigned char pwd[TCRYPT_KEY_POOL_LEN] = {};
size_t passphrase_size;
unsigned char pwd[VCRYPT_KEY_POOL_LEN] = {};
size_t passphrase_size, max_passphrase_size;
char *key;
unsigned int i, skipped = 0, iterations;
int r = -EPERM;
int r = -EPERM, keyfiles_pool_length;
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
return -ENOMEM;
if (params->flags & CRYPT_TCRYPT_VERA_MODES &&
params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
/* Really. Keyfile pool length depends on passphrase size in Veracrypt. */
max_passphrase_size = VCRYPT_KEY_POOL_LEN;
keyfiles_pool_length = VCRYPT_KEY_POOL_LEN;
} else {
max_passphrase_size = TCRYPT_KEY_POOL_LEN;
keyfiles_pool_length = TCRYPT_KEY_POOL_LEN;
}
if (params->keyfiles_count)
passphrase_size = TCRYPT_KEY_POOL_LEN;
passphrase_size = max_passphrase_size;
else
passphrase_size = params->passphrase_size;
if (params->passphrase_size > TCRYPT_KEY_POOL_LEN) {
log_err(cd, _("Maximum TCRYPT passphrase length (%d) exceeded."),
TCRYPT_KEY_POOL_LEN);
if (params->passphrase_size > max_passphrase_size) {
log_err(cd, _("Maximum TCRYPT passphrase length (%zu) exceeded."),
max_passphrase_size);
goto out;
}
/* Calculate pool content from keyfiles */
for (i = 0; i < params->keyfiles_count; i++) {
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i]);
r = TCRYPT_pool_keyfile(cd, pwd, params->keyfiles[i], keyfiles_pool_length);
if (r < 0)
goto out;
}
@@ -582,13 +591,11 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
hdr->salt, TCRYPT_HDR_SALT_LEN,
key, TCRYPT_HDR_KEY_LEN,
iterations, 0, 0);
if (r < 0 && crypt_hash_size(tcrypt_kdf[i].hash) < 0) {
if (r < 0) {
log_verbose(cd, _("PBKDF2 hash algorithm %s not available, skipping."),
tcrypt_kdf[i].hash);
continue;
}
if (r < 0)
break;
/* Decrypt header */
r = TCRYPT_decrypt_hdr(cd, hdr, key, params->flags);
@@ -621,9 +628,9 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
params->cipher, params->mode, params->key_size);
}
out:
crypt_memzero(pwd, TCRYPT_KEY_POOL_LEN);
crypt_safe_memzero(pwd, TCRYPT_KEY_POOL_LEN);
if (key)
crypt_memzero(key, TCRYPT_HDR_KEY_LEN);
crypt_safe_memzero(key, TCRYPT_HDR_KEY_LEN);
free(key);
return r;
}
@@ -632,7 +639,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
struct tcrypt_phdr *hdr,
struct crypt_params_tcrypt *params)
{
struct device *base_device, *device = crypt_metadata_device(cd);
struct device *base_device = NULL, *device = crypt_metadata_device(cd);
ssize_t hdr_size = sizeof(struct tcrypt_phdr);
char *base_device_path;
int devfd, r;
@@ -655,11 +662,11 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
if (r < 0)
return r;
devfd = device_open(cd, base_device, O_RDONLY);
device_free(cd, base_device);
} else
devfd = device_open(cd, device, O_RDONLY);
if (devfd < 0) {
device_free(cd, base_device);
log_err(cd, _("Cannot open device %s."), device_path(device));
return -EINVAL;
}
@@ -696,6 +703,7 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
device_alignment(device), hdr, hdr_size, 0) == hdr_size)
r = TCRYPT_init_hdr(cd, hdr, params);
device_free(cd, base_device);
if (r < 0)
memset(hdr, 0, sizeof (*hdr));
return r;
@@ -741,14 +749,14 @@ int TCRYPT_activate(struct crypt_device *cd,
return -ENOTSUP;
}
if (hdr->d.sector_size && hdr->d.sector_size != SECTOR_SIZE) {
if (hdr->d.sector_size % SECTOR_SIZE) {
log_err(cd, _("Activation is not supported for %d sector size."),
hdr->d.sector_size);
return -ENOTSUP;
}
if (strstr(params->mode, "-tcrypt")) {
log_err(cd, _("Kernel doesn't support activation for this TCRYPT legacy mode."));
log_err(cd, _("Kernel does not support activation for this TCRYPT legacy mode."));
return -ENOTSUP;
}
@@ -761,15 +769,12 @@ int TCRYPT_activate(struct crypt_device *cd,
if (!algs)
return -EINVAL;
if (hdr->d.sector_size == 0)
return -EINVAL;
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
dmd.size = 0;
else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER)
dmd.size = hdr->d.hidden_volume_size / hdr->d.sector_size;
dmd.size = hdr->d.hidden_volume_size / SECTOR_SIZE;
else
dmd.size = hdr->d.volume_size / hdr->d.sector_size;
dmd.size = hdr->d.volume_size / SECTOR_SIZE;
if (dmd.flags & CRYPT_ACTIVATE_SHARED)
device_check = DEV_OK;
@@ -860,7 +865,7 @@ int TCRYPT_activate(struct crypt_device *cd,
if (r < 0 &&
(dm_flags(cd, DM_CRYPT, &dmc_flags) || ((dmc_flags & req_flags) != req_flags))) {
log_err(cd, _("Kernel doesn't support TCRYPT compatible mapping."));
log_err(cd, _("Kernel does not support TCRYPT compatible mapping."));
r = -ENOTSUP;
}
@@ -1023,7 +1028,7 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
/* Mapping through whole device, not partition! */
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
if (crypt_dev_is_partition(device_path(crypt_metadata_device(cd))))
if (crypt_dev_is_partition(device_path(crypt_data_device(cd))))
return 0;
goto hdr_offset;
}
@@ -1034,11 +1039,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
if (hdr->d.version > 3)
return (hdr->d.mk_offset / hdr->d.sector_size);
return (hdr->d.mk_offset / SECTOR_SIZE);
if (device_size(crypt_metadata_device(cd), &size) < 0)
return 0;
return (size - hdr->d.hidden_volume_size +
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
}
goto hdr_offset;
}
@@ -1047,11 +1052,11 @@ uint64_t TCRYPT_get_data_offset(struct crypt_device *cd,
if (device_size(crypt_metadata_device(cd), &size) < 0)
return 0;
return (size - hdr->d.hidden_volume_size +
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / hdr->d.sector_size;
(TCRYPT_HDR_HIDDEN_OFFSET_OLD)) / SECTOR_SIZE;
}
hdr_offset:
return hdr->d.mk_offset / hdr->d.sector_size;
return hdr->d.mk_offset / SECTOR_SIZE;
}
uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
@@ -1065,10 +1070,10 @@ uint64_t TCRYPT_get_iv_offset(struct crypt_device *cd,
else if (params->mode && !strncmp(params->mode, "lrw", 3))
iv_offset = 0;
else
iv_offset = hdr->d.mk_offset / hdr->d.sector_size;
iv_offset = hdr->d.mk_offset / SECTOR_SIZE;
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
iv_offset += crypt_dev_partition_offset(device_path(crypt_metadata_device(cd)));
iv_offset += crypt_dev_partition_offset(device_path(crypt_data_device(cd)));
return iv_offset;
}

View File

@@ -1,8 +1,8 @@
/*
* TCRYPT (TrueCrypt-compatible) header defitinion
* TCRYPT (TrueCrypt-compatible) header definition
*
* 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
@@ -42,6 +42,7 @@
#define TCRYPT_LRW_IKEY_LEN 16
#define TCRYPT_KEY_POOL_LEN 64
#define VCRYPT_KEY_POOL_LEN 128
#define TCRYPT_KEYFILE_LEN 1048576
#define TCRYPT_HDR_FLAG_SYSTEM (1 << 0)

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-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
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
@@ -130,7 +129,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
if (errno == EINTR)
continue;
crypt_memzero(tmp, sizeof(tmp));
crypt_safe_memzero(tmp, sizeof(tmp));
/* read error */
return -1;
}
@@ -142,7 +141,7 @@ static int keyfile_seek(int fd, uint64_t bytes)
bytes -= bytes_r;
}
crypt_memzero(tmp, sizeof(tmp));
crypt_safe_memzero(tmp, sizeof(tmp));
return bytes == 0 ? 0 : -1;
}
@@ -181,7 +180,7 @@ int crypt_keyfile_device_read(struct crypt_device *cd, const char *keyfile,
key_size = DEFAULT_KEYFILE_SIZE_MAXKB * 1024 + 1;
unlimited_read = 1;
/* use 4k for buffer (page divisor but avoid huge pages) */
buflen = 4096 - sizeof(struct safe_allocation);
buflen = 4096 - sizeof(size_t); // sizeof(struct safe_allocation);
} else
buflen = key_size;
@@ -323,3 +322,24 @@ int kernel_version(uint64_t *kversion)
return r;
}
bool crypt_string_in(const char *str, char **list, size_t list_size)
{
size_t i;
for (i = 0; *list && i < list_size; i++, list++)
if (!strcmp(str, *list))
return true;
return false;
}
/* compare two strings (allows NULL values) */
int crypt_strcmp(const char *a, const char *b)
{
if (!a && !b)
return 0;
else if (!a || !b)
return 1;
return strcmp(a, b);
}

View File

@@ -1,8 +1,8 @@
/*
* libcryptsetup - cryptsetup library, cipher benchmark
*
* Copyright (C) 2012-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2019 Milan Broz
* Copyright (C) 2012-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
@@ -48,6 +48,12 @@ int crypt_benchmark(struct crypt_device *cd,
if (posix_memalign(&buffer, crypt_getpagesize(), buffer_size))
goto out;
r = crypt_cipher_ivsize(cipher, cipher_mode);
if (r >= 0 && iv_size != (size_t)r) {
log_dbg(cd, "IV length for benchmark adjusted to %i bytes (requested %zu).", r, iv_size);
iv_size = r;
}
if (iv_size) {
iv = malloc(iv_size);
if (!iv)
@@ -71,9 +77,9 @@ int crypt_benchmark(struct crypt_device *cd,
if (r == -ERANGE)
log_dbg(cd, "Measured cipher runtime is too low.");
else if (r == -ENOTSUP || r == -ENOENT)
log_dbg(cd, "Cannot initialise cipher %s, mode %s.", cipher, cipher_mode);
else if (r)
log_dbg(cd, "Cannot initialize cipher %s, mode %s, key size %zu, IV size %zu.",
cipher, cipher_mode, volume_key_size, iv_size);
out:
free(buffer);
free(key);

View File

@@ -1,7 +1,7 @@
/*
* blkid probe utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-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
@@ -307,3 +307,17 @@ int blk_supported(void)
#endif
return r;
}
off_t blk_get_offset(struct blkid_handle *h)
{
off_t offset_value = -1;
#ifdef HAVE_BLKID
const char *offset;
if (blk_is_superblock(h)) {
if (!blkid_probe_lookup_value(h->pr, "SBMAGIC_OFFSET", &offset, NULL))
offset_value = strtoll(offset, NULL, 10);
} else if (blk_is_partition(h) && !blkid_probe_lookup_value(h->pr, "PTMAGIC_OFFSET", &offset, NULL))
offset_value = strtoll(offset, NULL, 10);
#endif
return offset_value;
}

View File

@@ -1,7 +1,7 @@
/*
* blkid probe utilities
*
* Copyright (C) 2018-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-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
@@ -21,6 +21,8 @@
#ifndef _UTILS_BLKID_H
#define _UTILS_BLKID_H
#include <sys/types.h>
struct blkid_handle;
typedef enum { PRB_OK = 0, PRB_EMPTY, PRB_AMBIGUOUS, PRB_FAIL } blk_probe_status;
@@ -59,4 +61,6 @@ int blk_do_wipe(struct blkid_handle *h);
int blk_supported(void);
off_t blk_get_offset(struct blkid_handle *h);
#endif

View File

@@ -2,8 +2,8 @@
* utils_crypt - cipher utilities for cryptsetup
*
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-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
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "libcryptsetup.h"
@@ -76,14 +77,16 @@ int crypt_parse_hash_integrity_mode(const char *s, char *integrity)
return -EINVAL;
r = sscanf(s, "%" MAX_CIPHER_LEN_STR "[^-]-%" MAX_CIPHER_LEN_STR "s", mode, hash);
if (r == 2)
if (r == 2 && !isdigit(hash[0]))
r = snprintf(integrity, MAX_CIPHER_LEN, "%s(%s)", mode, hash);
else if (r == 2)
r = snprintf(integrity, MAX_CIPHER_LEN, "%s-%s", mode, hash);
else if (r == 1)
r = snprintf(integrity, MAX_CIPHER_LEN, "%s", mode);
else
return -EINVAL;
if (r < 0 || r == MAX_CIPHER_LEN)
if (r < 0 || r >= MAX_CIPHER_LEN)
return -EINVAL;
return 0;
@@ -149,79 +152,6 @@ int crypt_parse_pbkdf(const char *s, const char **pbkdf)
return 0;
}
/*
* Replacement for memset(s, 0, n) on stack that can be optimized out
* Also used in safe allocations for explicit memory wipe.
*/
void crypt_memzero(void *s, size_t n)
{
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(s, n);
#else
volatile uint8_t *p = (volatile uint8_t *)s;
while(n--)
*p++ = 0;
#endif
}
/* safe allocations */
void *crypt_safe_alloc(size_t size)
{
struct safe_allocation *alloc;
if (!size || size > (SIZE_MAX - offsetof(struct safe_allocation, data)))
return NULL;
alloc = malloc(size + offsetof(struct safe_allocation, data));
if (!alloc)
return NULL;
alloc->size = size;
crypt_memzero(&alloc->data, size);
/* coverity[leaked_storage] */
return &alloc->data;
}
void crypt_safe_free(void *data)
{
struct safe_allocation *alloc;
if (!data)
return;
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
crypt_memzero(data, alloc->size);
alloc->size = 0x55aa55aa;
free(alloc);
}
void *crypt_safe_realloc(void *data, size_t size)
{
struct safe_allocation *alloc;
void *new_data;
new_data = crypt_safe_alloc(size);
if (new_data && data) {
alloc = (struct safe_allocation *)
((char *)data - offsetof(struct safe_allocation, data));
if (size > alloc->size)
size = alloc->size;
memcpy(new_data, data, size);
}
crypt_safe_free(data);
return new_data;
}
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
{
char buf[3] = "xx\0", *endp, *bytes;
@@ -247,3 +177,10 @@ ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc)
*result = bytes;
return i;
}
bool crypt_is_cipher_null(const char *cipher_spec)
{
if (!cipher_spec)
return false;
return (strstr(cipher_spec, "cipher_null") || !strcmp(cipher_spec, "null"));
}

View File

@@ -2,8 +2,8 @@
* utils_crypt - cipher utilities for cryptsetup
*
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-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
@@ -23,20 +23,13 @@
#ifndef _UTILS_CRYPT_H
#define _UTILS_CRYPT_H
#include <stdbool.h>
#include <unistd.h>
#define MAX_CIPHER_LEN 32
#define MAX_CIPHER_LEN_STR "31"
#define MAX_KEYFILES 32
struct crypt_device;
/* Not to be used directly */
struct safe_allocation {
size_t size;
char data[0];
};
int crypt_parse_name_and_mode(const char *s, char *cipher,
int *key_nums, char *cipher_mode);
int crypt_parse_hash_integrity_mode(const char *s, char *integrity);
@@ -44,12 +37,8 @@ int crypt_parse_integrity_mode(const char *s, char *integrity,
int *integrity_key_size);
int crypt_parse_pbkdf(const char *s, const char **pbkdf);
void *crypt_safe_alloc(size_t size);
void crypt_safe_free(void *data);
void *crypt_safe_realloc(void *data, size_t size);
void crypt_memzero(void *s, size_t n);
ssize_t crypt_hex_to_bytes(const char *hex, char **result, int safe_alloc);
bool crypt_is_cipher_null(const char *cipher_spec);
#endif /* _UTILS_CRYPT_H */

View File

@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2019 Milan Broz
* Copyright (C) 2009-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
@@ -24,7 +24,6 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -145,14 +144,14 @@ static int device_read_test(int devfd)
if (read_blockwise(devfd, blocksize, alignment, buffer, minsize) == (ssize_t)minsize)
r = 0;
crypt_memzero(buffer, sizeof(buffer));
crypt_safe_memzero(buffer, sizeof(buffer));
return r;
}
/*
* The direct-io is always preferred. The header is usually mapped to the same
* device and can be accessed when the rest of device is mapped to data device.
* Using dirct-io encsures that we do not mess with data in cache.
* Using direct-io ensures that we do not mess with data in cache.
* (But proper alignment should prevent this in the first place.)
* The read test is needed to detect broken configurations (seen with remote
* block devices) that allow open with direct-io but then fails on read.
@@ -163,6 +162,9 @@ static int device_ready(struct crypt_device *cd, struct device *device)
struct stat st;
size_t tmp_size;
if (!device)
return -EINVAL;
if (device->o_direct) {
log_dbg(cd, "Trying to open and read device %s with direct-io.",
device_path(device));
@@ -185,7 +187,7 @@ static int device_ready(struct crypt_device *cd, struct device *device)
}
if (devfd < 0) {
log_err(cd, _("Device %s doesn't exist or access denied."),
log_err(cd, _("Device %s does not exist or access denied."),
device_path(device));
return -EINVAL;
}
@@ -218,10 +220,13 @@ static int _open_locked(struct crypt_device *cd, struct device *device, int flag
{
int fd;
if (!device)
return -EINVAL;
log_dbg(cd, "Opening locked device %s", device_path(device));
if ((flags & O_ACCMODE) != O_RDONLY && device_locked_readonly(device->lh)) {
log_dbg(cd, "Can not open locked device %s in write mode. Read lock held.", device_path(device));
log_dbg(cd, "Cannot open locked device %s in write mode. Read lock held.", device_path(device));
return -EAGAIN;
}
@@ -301,6 +306,9 @@ static int device_open_internal(struct crypt_device *cd, struct device *device,
int device_open(struct crypt_device *cd, struct device *device, int flags)
{
if (!device)
return -EINVAL;
assert(!device_locked(device->lh));
return device_open_internal(cd, device, flags);
}
@@ -355,6 +363,9 @@ void device_release_excl(struct crypt_device *cd, struct device *device)
int device_open_locked(struct crypt_device *cd, struct device *device, int flags)
{
if (!device)
return -EINVAL;
assert(!crypt_metadata_locking_enabled() || device_locked(device->lh));
return device_open_internal(cd, device, flags);
}
@@ -521,10 +532,16 @@ void device_topology_alignment(struct crypt_device *cd,
temp_alignment = (unsigned long)min_io_size;
/* Ignore bogus opt-io that could break alignment */
/*
* Ignore bogus opt-io that could break alignment.
* Also real opt_io_size should be aligned to minimal page size (4k).
* Some bogus USB enclosures reports wrong data here.
*/
if ((temp_alignment < (unsigned long)opt_io_size) &&
!((unsigned long)opt_io_size % temp_alignment))
!((unsigned long)opt_io_size % temp_alignment) && !MISALIGNED_4K(opt_io_size))
temp_alignment = (unsigned long)opt_io_size;
else if (opt_io_size && (opt_io_size != min_io_size))
log_err(cd, _("Ignoring bogus optimal-io size for data device (%u bytes)."), opt_io_size);
/* If calculated alignment is multiple of default, keep default */
if (temp_alignment && (default_alignment % temp_alignment))
@@ -584,8 +601,11 @@ int device_size(struct device *device, uint64_t *size)
struct stat st;
int devfd, r = -EINVAL;
if (!device)
return -EINVAL;
devfd = open(device->path, O_RDONLY);
if(devfd == -1)
if (devfd == -1)
return -EINVAL;
if (fstat(devfd, &st) < 0)
@@ -607,6 +627,9 @@ int device_fallocate(struct device *device, uint64_t size)
struct stat st;
int devfd, r = -EINVAL;
if (!device)
return -EINVAL;
devfd = open(device_path(device), O_RDWR);
if (devfd == -1)
return -EINVAL;
@@ -758,7 +781,7 @@ static int device_internal_prepare(struct crypt_device *cd, struct device *devic
log_dbg(cd, "Allocating a free loop device.");
/* Keep the loop open, dettached on last close. */
/* Keep the loop open, detached on last close. */
loop_fd = crypt_loop_attach(&loop_device, device->path, 0, 1, &readonly);
if (loop_fd == -1) {
log_err(cd, _("Attaching loopback device failed "
@@ -847,22 +870,30 @@ size_t size_round_up(size_t size, size_t block)
void device_disable_direct_io(struct device *device)
{
device->o_direct = 0;
if (device)
device->o_direct = 0;
}
int device_direct_io(const struct device *device)
{
return device->o_direct;
return device ? device->o_direct : 0;
}
static dev_t device_devno(const struct device *device)
static int device_compare_path(const char *path1, const char *path2)
{
struct stat st;
struct stat st_path1, st_path2;
if (stat(device->path, &st) || !S_ISBLK(st.st_mode))
return 0;
if (stat(path1, &st_path1 ) < 0 || stat(path2, &st_path2 ) < 0)
return -EINVAL;
return st.st_rdev;
if (S_ISBLK(st_path1.st_mode) && S_ISBLK(st_path2.st_mode))
return (st_path1.st_rdev == st_path2.st_rdev) ? 1 : 0;
if (S_ISREG(st_path1.st_mode) && S_ISREG(st_path2.st_mode))
return (st_path1.st_ino == st_path2.st_ino &&
st_path1.st_dev == st_path2.st_dev) ? 1 : 0;
return 0;
}
int device_is_identical(struct device *device1, struct device *device2)
@@ -873,21 +904,19 @@ int device_is_identical(struct device *device1, struct device *device2)
if (device1 == device2)
return 1;
if (device1->init_done && device2->init_done)
return (device_devno(device1) == device_devno(device2));
else if (device1->init_done || device2->init_done)
return 0;
if (!strcmp(device_path(device1), device_path(device2)))
return 1;
return 0;
return device_compare_path(device_path(device1), device_path(device2));
}
int device_is_rotational(struct device *device)
{
struct stat st;
if (!device)
return -EINVAL;
if (stat(device_path(device), &st) < 0)
return -EINVAL;
@@ -901,6 +930,9 @@ size_t device_alignment(struct device *device)
{
int devfd;
if (!device)
return -EINVAL;
if (!device->alignment) {
devfd = open(device_path(device), O_RDONLY);
if (devfd != -1) {
@@ -914,17 +946,18 @@ size_t device_alignment(struct device *device)
void device_set_lock_handle(struct device *device, struct crypt_lock_handle *h)
{
device->lh = h;
if (device)
device->lh = h;
}
struct crypt_lock_handle *device_get_lock_handle(struct device *device)
{
return device->lh;
return device ? device->lh : NULL;
}
int device_read_lock(struct crypt_device *cd, struct device *device)
{
if (!crypt_metadata_locking_enabled())
if (!device || !crypt_metadata_locking_enabled())
return 0;
if (device_read_lock_internal(cd, device))
@@ -935,7 +968,7 @@ int device_read_lock(struct crypt_device *cd, struct device *device)
int device_write_lock(struct crypt_device *cd, struct device *device)
{
if (!crypt_metadata_locking_enabled())
if (!device || !crypt_metadata_locking_enabled())
return 0;
assert(!device_locked(device->lh) || !device_locked_readonly(device->lh));
@@ -945,7 +978,7 @@ int device_write_lock(struct crypt_device *cd, struct device *device)
void device_read_unlock(struct crypt_device *cd, struct device *device)
{
if (!crypt_metadata_locking_enabled())
if (!device || !crypt_metadata_locking_enabled())
return;
assert(device_locked(device->lh));
@@ -955,7 +988,7 @@ void device_read_unlock(struct crypt_device *cd, struct device *device)
void device_write_unlock(struct crypt_device *cd, struct device *device)
{
if (!crypt_metadata_locking_enabled())
if (!device || !crypt_metadata_locking_enabled())
return;
assert(device_locked(device->lh) && !device_locked_readonly(device->lh));

View File

@@ -1,8 +1,8 @@
/*
* Metadata on-disk locking for processes serialization
*
* Copyright (C) 2016-2019 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2019 Ondrej Kozina
* Copyright (C) 2016-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
@@ -20,7 +20,6 @@
*/
#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
@@ -107,7 +106,7 @@ static int open_lock_dir(struct crypt_device *cd, const char *dir, const char *b
lockdfd = openat(dirfd, base, O_RDONLY | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
if (lockdfd < 0) {
if (errno == ENOENT) {
log_std(cd, _("WARNING: Locking directory %s/%s is missing!\n"), dir, base);
log_dbg(cd, _("Locking directory %s/%s will be created with default compiled-in permissions."), dir, base);
/* success or failure w/ errno == EEXIST either way just try to open the 'base' directory again */
if (mkdirat(dirfd, base, DEFAULT_LUKS2_LOCK_DIR_PERMS) && errno != EEXIST)

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