Compare commits

...

626 Commits

Author SHA1 Message Date
Kristína Hanicová
ffe169aa48 Merge branch 'add_debian_unstable' into 'main'
ci: Add debian unstable (sid)

See merge request cryptsetup/cryptsetup!851
2025-11-28 19:46:58 +00:00
Kristina Hanicova
f1ba606c28 ci: Add debian unstable (sid) 2025-11-28 20:46:56 +01:00
Ondrej Kozina
5d69c34f59 Reinstate pbkdf serialization flag in device activation.
crypt_activate_by_keyslot_context never respected pbkdf serialation
flag (CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF).

In fact it worked only when device was activated via passphrase or via
passphrase file. It was never respected when device was activated
by a token for example.

When the internal code was fully switched to activation via keyslot
context the legacy code for passphrase based activation was dropped
and we lost track of serialization flag completely.

This fixes all of the issues so now the serialization flag will be
respected also with tokens (and all other activation methods unlocking
LUKS2 keyslot with memory hard pbkdf).

Fixes: 58385d68d8 (Allow activation via keyslot context)
Fixes: #968.
2025-11-27 14:51:44 +01:00
Ondrej Kozina
e1cbd4ecba tests: add simple verification test for --serialize-memory-hard-pbkdf 2025-11-27 14:51:32 +01:00
Kfir Kahanov
9ea9af1bcd tests: Add Bitlocker images for clearkey 2025-11-21 22:07:01 +02:00
Kfir Kahanov
4fe1601d9c bitlocker: Open bitlocker devices with clearkey
Always trying to open with clearkey when available
2025-11-21 22:07:01 +02:00
Kfir Kahanov
72173b2777 bitlocker: Handle getting NULL passwords 2025-11-21 22:07:01 +02:00
Kfir Kahanov
f304132b2b bitlocker: Support clearkey
Clearkey does not mean partially encrypted, and may be on fully
encrypted volumes.
2025-11-21 22:07:01 +02:00
Milan Broz
0779c8ceed Explicitly mention units (bytes) for volume key in header. 2025-11-21 16:34:47 +01:00
Milan Broz
153aed3d16 Fix key-size descriptions
For compatibility reasons, cryptsetup uses key size in BITS
while integritysetup in BYTES.

The help is confusing here, this patch fixes it.

Thanks Daniel Tang for notification.
2025-11-21 16:34:47 +01:00
Milan Broz
8a3e16fa25 tests: Avoid verity concurrent test failure on device node check
This regularly crashes on Alpine Linux that use some strange
configuration.
Udev settle seems to help, despite it should be noop on recent systems...
2025-11-21 14:29:38 +01:00
Milan Broz
8da66c3066 verity: Support status info about FEC repaired events
Kernel 6.19 will support additional info on dm-verity status
line that contains number of FEC successful repair events.

This patch adds support to libcryptsetup and veritysetup status command.

Ref. https://lore.kernel.org/dm-devel/074e1ecc-6690-1c22-0dba-454e191e1b6f@redhat.com/T/#m1af31c9c4263fe2b1fb58dee2fd7f0bdf045c463
2025-11-20 17:18:37 +01:00
Milan Broz
11a4fc6790 tests: use utility to detect FIPS mode
Also try to use crypto lib/kernel check where appropriate.

This can be useful for local testing (non-FIPS kernel) byt
should not break real FIPS systems.
2025-11-19 22:09:27 +01:00
Milan Broz
e4c498d15b Remove fips argument from crypt_backend_init()
It is really not needed, as it is detected automagically.
2025-11-19 22:09:27 +01:00
Milan Broz
e609c47916 tests: Add fips mode detection to crypt check tool 2025-11-19 22:09:27 +01:00
Milan Broz
ccc0c69cd7 Add fips_mode check for kernel.
Akso add a separate function so we can detect that kernel and crypto
lib is in different FIPS state (only for testing).
2025-11-19 22:09:27 +01:00
Milan Broz
7fba92260a ci: Fix Alpine runner dependences
gettext-dev install asli gettext.
argp-standalone is needed for with musl
This ensures that we can later use simplified package mappings.
2025-11-19 18:16:17 +01:00
Milan Broz
76ea8f13cf tests: Fix coding style (tabs) 2025-11-18 19:39:18 +01:00
Ondrej Kozina
bbc053682a Do not read test hotzone device repeatadly.
While allocating internal data structure for a device
overlaying reencryption hotzone we accidentally read
tested the device in each reencryption step. This
was suboptimal so now the device is read only once
while initializing the reencryption device-mapper stack.
2025-11-17 13:56:39 +01:00
Milan Broz
c9fd8b5ed4 Set devel version. 2025-11-17 13:55:40 +01:00
Kristina Hanicova
fbd295259c ci: remove ubuntu 2025-11-14 15:47:28 +01:00
Ondrej Kozina
5490d28aa4 Drop never used code in storage wrapper utils.
It was never used...
2025-11-13 15:24:12 +01:00
Ingo Franzki
296eb39c60 Changes to support PHMAC with integritysetup and cryptsetup
Make the PHMAC integrity algorithm know to libcryptsetup.

The size of a key for PHMAC is not known, because PHMAC gets an opaque
blob as key, who's physical size has nothing to do with the cryptographic
size. Thus, let INTEGRITY_key_size() and crypt_parse_integrity_mode()
return the required_key_size as key size for PHMAC, or -EINVAL if
required_key_size is zero, to indicate that the size is unknown.

Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
2025-11-13 09:21:40 +01:00
Ondrej Kozina
917b6836a9 Always use json-c types in internal code.
Sometimes we used "struct json_foo_bar" and sometimes "json_foo_bar"
json-c defined type. Stick with one notation in internal code.
2025-11-12 13:13:02 +01:00
Ondrej Kozina
b36d4be8fa opal: supress confusing debug messages.
Do not print sed-opal spefic debug messages with confusing
error codes if ioctl() call failed with -1. Usually that means
the kernel does not support sed-opal interface or the requested
ioctl number is not implemented.
2025-11-06 11:14:56 +01:00
Ondrej Kozina
0a8e7da7ae opal: fix debug message on failed sed-opal ioctl.
ioctl syscall always returns -1 on error (see ioctl(2)).
On error the actual reason is reported via errno varible.
Let's store the original errno code in the variable
so that it can be printed out in debug mode.

Before this fix the debug message always reported "Operation not
permited" (the translation of errno EPERM (1)).
2025-11-06 11:09:43 +01:00
Ondrej Kozina
83a7310ca2 opal: do not initialize LRs array in activation.
The lr member in opal_lr_act kernel structure is
ingnored unless the device is being activated in SUM
mode.

See kernel implementation of IOC_OPAL_ACTIVATE_LSP
in block/sed-opal.c
2025-11-03 16:05:08 +01:00
Ondrej Kozina
441802773f opal: simplify User setup routine.
Reduce memory copying by reusing nested structure in opal_lock.
2025-11-03 16:05:08 +01:00
Ondrej Kozina
cc66b1fa52 opal: pull User setup in separate function. 2025-11-03 16:05:08 +01:00
Ondrej Kozina
a0d5d2bf5e opal: pull individual range setup in separate function. 2025-11-03 16:05:08 +01:00
Ondrej Kozina
61dbb69319 opal: pull reuse of active device in separate function. 2025-11-03 16:05:08 +01:00
Ondrej Kozina
32b33541a8 opal: pull LSP activation in separate function. 2025-11-03 16:05:08 +01:00
Ondrej Kozina
346db2e42a opal: add a named constant for TCG FAIL status.
Will be checked upon later when we add support
for OPAL2 SUM Reactivate method.
2025-11-03 16:05:08 +01:00
Milan Broz
0d07e80077 Fix typo in volume-key-file help.
Fixes: #966
2025-11-03 10:58:15 +01:00
Milan Broz
dc2251b88d man: Fix typo in integritysetup man page. 2025-10-31 08:31:21 +01:00
Ondrej Kozina
a8e8e39007 Fix possible use of uninitialized variable.
device_tag_size variable was not initialized and used
when device_is_nop_dif returned negative error code.
2025-10-30 13:59:54 +01:00
Kristina Hanicova
bcef385346 ci: Add Centos Stream 10 runner 2025-10-19 22:20:47 +02:00
Ondrej Kozina
9810c6fb2f Read integrity profile info from top level device.
When formating device with --integrity-inline option
there's a check if underlying device properly advertise
integrity profile support. The check did not work
properly for partition device nodes. We have to read
integrity profile info from top level block device.

Fixes: #964.
2025-10-17 15:25:32 +02:00
Ondrej Kozina
4d98add260 opal: Submit PSID reset command to R/W file descriptor.
The PSID reset erases the block device it's submitted to
succesfully.

By submitting the command to read-only fd previously
there were partition device nodes still visible in
the /dev directory because kernel does not trigger rescan
after OPAL2 PSID reset. Even though all the partition were
actually erased (including the partition table).

We workaround the issue by submitting the PSID reset
to R/W fd so that it triggers rescan event on close.
2025-10-06 10:37:37 +02:00
Milan Broz
0eaaa4553e Fix handling of too long label and subsystem fields
These LUKS2 labels are stored in the binary header area that has limited size.

While we have been silently truncating strings here, it is something that
is not expected, as the final label is then different than expected.

Let's fix the code to explicitly print and return error here.

Also remove the comment about duplicate check. It is incorrect  optimization,
as some users will expect a real write on disk, we should no skip it.

Fixes: #958
2025-10-01 21:41:55 +02:00
Ondrej Kozina
3a8feb8be7 Improve check for a function attribute support.
The compiler may advertise function attribute support
with __has_attribute operator even though it does
not implement the feature on some architecture.

This fixes the issue with  GCC 11 on ppc64le with
__attribute__((zero_call_used_regs("used"))).

Fixes: #959.
2025-09-11 14:18:39 +02:00
Kristina Hanicova
2b9523a1ef ci: Remove rhel runner 2025-08-29 15:21:26 +02:00
Maxim Suhanov
68d4749d8a bitlk: implement validation of FVE metadata
This commit implements FVE metadata block validation based on:
* CRC-32 (to detect random corruption);
* AES-CCM-encrypted SHA-256 (to detect malicious manipulations).

The hash-based validation requires us to decrypt the VMK first, so
it's only performed when obtaining the volume key.

This allows us to detect corrupted/altered FVE metadata blocks and
pick the valid one (before this commit: the first FVE metadata block
is always selected).

Fixes: #953

tests: add BitLocker image with corrupted headers

The image contains 2 manually corrupted metadata blocks (out of 3),
the library should use the third one to correctly load the volume.

Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
2025-08-29 15:16:36 +02:00
Milan Broz
9cfdd6ba06 Version 2.8.1. 2025-08-19 10:57:12 +02:00
Marián Haburaj
4749473c39 po: update sk.po (from translationproject.org) 2025-08-18 20:02:14 +02:00
Milan Broz
4a1384452c Add release notes for 2.8.1. 2025-08-18 16:38:45 +02:00
Milan Broz
b0821b11a5 Add the same cipher_null restriction to LUKS2 keyslot as in LUKS1.
LUKS2 keyslot cannot be created with cipher_null using standard
tools, but activation of such a keyslot is allowed.

As this can be confusing and create a false sense of security,
let's apply the same restriction as in LUKS1 - such a keyslot
is used only with an empty passphrase.

This will reject activation with a real password, avoiding
possible activation of insecure LUKS containers.

Fixes: #954
2025-08-18 08:22:51 +02:00
Milan Broz
098d2122e5 Remove redundant test in LUKS2 keyslot cipher incompatible test.
The null_cipher is tested twice there.
2025-08-18 08:22:51 +02:00
Jakub Bogusz
df58aa5aee po: update pl.po (from translationproject.org) 2025-08-18 08:21:53 +02:00
Antonio Ceballos
9e9f6bcb5b po: update es.po (from translationproject.org) 2025-08-18 08:21:53 +02:00
Roland Illig
c8166fc696 po: update de.po (from translationproject.org) 2025-08-18 08:21:53 +02:00
Petr Pisar
c48cac6c65 po: update cs.po (from translationproject.org) 2025-08-18 08:21:53 +02:00
Yuri Chornoivan
c9d32b7462 po: update uk.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Мирослав Николић
c91d641e0c po: update sr.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Remus-Gabriel Chelu
5ac42f98bd po: update ro.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Temuri Doghonadze
d825083baa po: update ka.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Hiroshi Takekawa
79b09a897f po: update ja.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Frédéric Marchal
a42083e6c8 po: update fr.po (from translationproject.org) 2025-08-14 17:23:28 +02:00
Milan Broz
b8d3ff3b1a Version 2.8.1-rc0 (for translation). 2025-08-13 15:25:39 +02:00
Milan Broz
b7ec4a9d9b test: fix warning about missing NUL terminator
Both gcc-15 and clang-22 now warn if there is no space for null character.

As we use this as binary buffer, just do not use fixed char array here.
2025-08-13 11:03:30 +02:00
Milan Broz
10e5ab1a87 tcrypt: Fix detecting status of chained modes
The function dm_uuid_cmp cannot be used for TCRYPT, it expects
LUKS UUID, not a device name.

Fixes: #952
2025-08-08 11:15:32 +02:00
Milan Broz
57a8837879 ci: Disable fd leak detection for gcc analyzer on Alpine
This generates false positives, probably another system header
incompatibility in musl.
2025-08-01 16:48:08 +02:00
Milan Broz
b0d38f932f Add (ugly) wrorkaround for musl broken macro
Nobody fixes this for years, there are multiple discussions.
Let's just ignore it.
2025-08-01 16:48:08 +02:00
Milan Broz
b7e3ea592b Avoid warning about unused parameter.
This fixes compilation warning:
   error: unused parameter 'version' [-Werror=unused-parameter]
2025-08-01 16:48:08 +02:00
Milan Broz
c618a50de8 Avoid truncatted NULL ternminator gcc warning
This prevents gcc warnings:
  warning: initializer-string for array of 'unsigned char' truncates
  NUL terminator but destination lacks 'nonstring' attribute

While there is "nonstring" attribute, clang does not support it,
so this is the simplest solution.
2025-08-01 16:48:08 +02:00
Milan Broz
7b43c6a784 ci: Add stringop-overread warning to compilations test 2025-08-01 16:47:25 +02:00
Milan Broz
149a414c93 ci: Add Apline shared runner test for gcc/clang compilation
Alpine is continuously updated in GitLab; we get new errors automatically
once a new version is deployed.
2025-08-01 16:47:25 +02:00
Milan Broz
e33a315776 ci: Update clang version
And remove unneeded variable, we do not run test in shared runners.
2025-08-01 16:47:25 +02:00
Milan Broz
8546260a49 ci: Move compiler version report to script
Preparation for Alpine jobs.
2025-08-01 16:47:25 +02:00
Milan Broz
fa5ab78837 Support --prefix also in Meson for tmpfilesdir 2025-08-01 15:27:27 +02:00
Milan Broz
80a1ebe93e Define EXTERNAL_LUKS2_TOKENS_PATH even for autoconf
Meson already uses config.h here, do the seame instead of commandline
define option.

Expanding the variable is tricky, though...
2025-08-01 15:27:27 +02:00
Milan Broz
70a69b5059 Fix luks2-external-tokens-path option for meson
The variable was never called default-* in autoconf,
name is the same.

Morever, it defines unneeded DEFAULT_* entry in config.h.
2025-08-01 15:27:27 +02:00
Milan Broz
32e9bed060 Fix wrongly generated config.h paths
For some reason, external token path and tmpfilesdir uses a macro
that generates entry in config.h, producing these #defines:
  DEFAULT_LUKS2_EXTERNAL_TOKENS_PATH
  DEFAULT_TMPFILESDIR

Neiter one is used in C code, moreover, definitions are wrong,
as variables are modified after entry is pushed to config.

Remove the macro call and use AC_ARG_WITH directly.
2025-08-01 15:27:27 +02:00
Milan Broz
12eaacaaaf Do not try to install tmpfiles in system path if $prefix is set
If cryptsetup is being installed to different directory using --prefix
configure switch, it tyries to use absolute system path (and fails).

Let's instruct pkgconfig to return proper prefixed tmpfiles variable.
2025-08-01 15:27:27 +02:00
Milan Broz
d0312d6c34 man: Install fvault2Open man page in Meson. 2025-08-01 15:27:27 +02:00
Milan Broz
4a67af439e Do not silently decrease PBKDF parallel cost (threads)
The maximum parallel cost is set since the introduction of Argon2 to 4.

Do not silently decrease the value (if explicitly set by the option)
but fail instead.
2025-08-01 12:31:02 +02:00
Vojtech Trefny
d77ece493d tests: Add BitLocker image with multibyte character in passphrase 2025-07-30 13:43:14 +02:00
Vojtech Trefny
04d307d9c0 bitlk: Fix unlocking bitlocker with multibyte utf8 characters
Fixes: #950

Co-authored-by: Thomas Lidén
2025-07-30 13:43:14 +02:00
Ondrej Kozina
6c7c8d36bb Fix bug in parsing of tcrypt device in crypt_init_by_name.
When TCRYPT subdevices was moved to use SUBDEV dm uuid prefix
we did not correctly modified the TCRYPT_status_one routine
to correctly expect the SUBDEV uuid prefix.

Fixes: cf630f578d
Fixes: #952.
2025-07-29 13:49:37 +02:00
Ondrej Kozina
b6ddaa40bf Refactor tcrypt subdev check in a helper routine.
Add comments what parts will be removed later.
2025-07-29 13:49:37 +02:00
Funda Wang
1c75cd0dc4 meson: install binaries 2025-07-29 12:23:22 +02:00
Milan Broz
267de08586 man: Try to explain PBKDF hardcoded limits. 2025-07-29 09:14:56 +02:00
Milan Broz
e0a5fb2c25 man: Add better explanation for automatic integrity tag recalculation. 2025-07-29 09:14:56 +02:00
Milan Broz
b995ab243c man: Mention crypt/verity/integritytab. 2025-07-29 09:14:56 +02:00
Milan Broz
a498757fd4 man: Use *WARNING* only for serious issues.
Use highlighted warning only for possibility of data loss or serious security issues.

No need to scary people everywhere :)
2025-07-29 09:14:56 +02:00
Milan Broz
349912fec2 man: Do not use *NOTE*, it is just a normal description. 2025-07-29 09:14:56 +02:00
Milan Broz
b0e3b94839 man: Remove mentions about archeologic kernel 2.6 and kernel 4.x 2025-07-29 09:14:56 +02:00
Milan Broz
c66c520e26 man: Always mention <options> as the last paragraph.
Move all notes and warnings to description text.
Refine some small clarification.

Do not use NOTE/WARNING unless there is a serious reason (data loss).
2025-07-29 09:14:56 +02:00
Milan Broz
2c95933bb5 man: Clarify that commands do not wipes data, unify OPAL reset wording. 2025-07-29 09:14:56 +02:00
Milan Broz
bc1b149ee4 man: Better mark option --align-payload as deprecated. 2025-07-29 09:14:56 +02:00
Milan Broz
55272bee98 man: Make --sector-size option description more clear. 2025-07-29 09:14:56 +02:00
Milan Broz
9590d6fe62 man: Clarify --label option. 2025-07-29 09:14:56 +02:00
Milan Broz
5af06cb6cc man: Weaken warning about /dev/urandom as recent kernels behave much better. 2025-07-29 09:14:56 +02:00
Milan Broz
a9e245f68c man: Update and clarify cryptsetup man page notes. 2025-07-29 09:14:56 +02:00
Milan Broz
74a4de9fdd man: Unify tools description and add some context. 2025-07-29 09:14:56 +02:00
Milan Broz
2d4c40e627 CI: update gcc explicitly on Alpine Linux 2025-07-28 22:27:07 +02:00
Milan Broz
2cf4c9a360 man: Avoid forced line breaks where not necessary. 2025-07-17 15:18:21 +02:00
Milan Broz
360f85dde7 man: Grammar and simple stylistic fixes.
This is based mainly on Grammarly.

It unifies man pages to at least some level of grammar,
so later we can focus on adding more readable content.
2025-07-17 15:01:39 +02:00
Milan Broz
1438140ce3 man: Do not wrap sentences in man pages.
This helps to use external tools for language checking.
2025-07-17 12:38:17 +02:00
Milan Broz
a52e1aadca man: unify formatting of options
- do not use bold if option is the text
- unify argument format
- do not highlight obsolete syntax
2025-07-17 11:51:18 +02:00
Milan Broz
19a4f53c07 man: Do not use bold font in text/URL to avoid format issues. 2025-07-17 11:39:57 +02:00
Milan Broz
8a73750ba9 doc: Mention Asciidoctor in Readme required packages. 2025-07-14 10:55:56 +02:00
Ondrej Kozina
db720abcc3 ci: enable systemd-test-plugin on Rawhide. 2025-06-26 16:24:04 +02:00
Ondrej Kozina
ebbecb6df0 Drop unused variable in systemd-test-plugin. 2025-06-26 14:38:08 +02:00
Ondrej Kozina
830bd02160 tests: enable systemd-tpm2 test to run with default system path.
If run in Makefile.localtest there was unset CRYPTSETUP_TOKENS_PATH.
It's valid test case to run with systemd-tpm2 plugin installed on
the system (integration tests).
2025-06-26 14:34:23 +02:00
Milan Broz
ea96360efc Include fuzz/meson.build in release
Fixes: #949
2025-06-25 21:10:27 +02:00
Milan Broz
eb9f0a63b8 Set devel version. 2025-06-25 21:09:33 +02:00
Milan Broz
13306948c8 Version 2.8.0. 2025-06-24 09:30:17 +02:00
Vojtech Trefny
cdc451a61a Fix expected keyslot context for LUKS1 activate_by_keyring 2025-06-23 14:22:13 +02:00
Ondrej Kozina
04ca5087f8 man: Add cryptsetup-reencrypt token usage examples. 2025-06-23 14:10:16 +02:00
Milan Broz
2262641c74 tests: Reinitialize integrity device after inline test 2025-06-22 09:35:39 +02:00
Milan Broz
232ba8dd3a Add missing crypto backend init in crypt_format_inline.
This triggers abort() in various crypto backends.
2025-06-22 09:35:18 +02:00
Antonio Ceballos
3490944c27 po: update es.po (from translationproject.org) 2025-06-18 11:53:22 +02:00
Petr Pisar
e8c32e5c41 po: update cs.po (from translationproject.org) 2025-06-18 11:53:22 +02:00
Milan Broz
ccc9a977f7 tests: Use truncate and detect failure.
The fallocate can fail, while it has -x option,
we user truncate in different tests, so switch to it.

Also fail early if truncate fails.
2025-06-18 10:10:52 +02:00
Yuri Chornoivan
a0929f67f1 po: update uk.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Marián Haburaj
e57f1b3dd8 po: update sk.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Remus-Gabriel Chelu
e9a20ad3dc po: update ro.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Jakub Bogusz
f3d348776d po: update pl.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Hiroshi Takekawa
e9c626cccd po: update ja.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Frédéric Marchal
ef592405dd po: update fr.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Roland Illig
5ce481a8c2 po: update de.po (from translationproject.org) 2025-06-17 14:46:59 +02:00
Guilhem Moulin
9b5ed35078 bitlk-compat-test: Use eval in load_vars().
It that appears using the `source` builtin with process substitution
yields a race condition:

	./tests$ ./bitlk-compat-test; echo RV=$?
	HEADER CHECK
	 bitlk-images/bitlk-aes-cbc-128-4k.img [OK]
	 bitlk-images/bitlk-aes-cbc-128.img [OK]
	 bitlk-images/bitlk-aes-cbc-256.img [OK]
	 bitlk-images/bitlk-aes-cbc-elephant-128.img [OK]
	 bitlk-images/bitlk-aes-cbc-elephant-256.img [OK]
	 bitlk-images/bitlk-aes-xts-128-4k.img [OK]
	 bitlk-images/bitlk-aes-xts-128-eow.img./bitlk-compat-test: trap: line 2: unexpected EOF while looking for matching `)'
	./bitlk-compat-test: command substitution: line 70: syntax error near unexpected token `)'
	./bitlk-compat-test: command substitution: line 70: `echo "$dump" | grep "Volume size:" | cut -d: -f2 | tr -d "\t\n ")'
	WARNING: You must be root to run activation part of test, test skipped.
	RV=0

This is with bash 5.2.37 on a Debian sid system.  It doesn't fail the
test, but affects coverage as subsequent images are not tested.
`eval`'ing the output of a pipe solves the race condition.

It's arguably not robust code, but load_vars() appears to make
assumption about images.conf's content and didn't account for edge cases
either.
2025-06-16 17:34:12 +02:00
Milan Broz
bf7d2c5a3b Use CDN in release links. 2025-06-16 14:40:42 +02:00
Milan Broz
a8105ef9bb Version 2.8.0-rc1. 2025-06-16 14:10:18 +02:00
Milan Broz
96787457e1 Add 2.8.0-rc1 Release notes. 2025-06-16 11:38:13 +02:00
Antonio Ceballos
849bd0d2f3 po: update es.po (from translationproject.org) 2025-06-15 10:47:31 +02:00
Petr Pisar
f866a663b0 po: update cs.po (from translationproject.org) 2025-06-15 10:47:31 +02:00
Milan Broz
bac868b392 Fix message translation (missing macro). 2025-06-09 10:13:26 +02:00
Marián Haburaj
7ed0934892 po: add sk.po (from translationproject.org) 2025-06-05 14:23:13 +02:00
Yuri Chornoivan
6db3fa33e1 po: update uk.po (from translationproject.org) 2025-06-05 14:20:44 +02:00
Remus-Gabriel Chelu
255336b309 po: update ro.po (from translationproject.org) 2025-06-05 14:20:44 +02:00
Hiroshi Takekawa
084b1d2984 po: update ja.po (from translationproject.org) 2025-06-05 14:20:44 +02:00
Frédéric Marchal
d0b582bbd6 po: update fr.po (from translationproject.org) 2025-06-05 14:20:44 +02:00
Roland Illig
b84ffc4ff4 po: update de.po (from translationproject.org) 2025-06-05 14:20:44 +02:00
Milan Broz
c7f3f32ec9 Avoid zero-length read in read_lseek_blockwise
Found by Valgrind. Similar fix already exists
for write_lseek_blockwise.
2025-06-04 14:07:24 +02:00
Milan Broz
f221de22b6 Fix libcryptsetup version. 2025-06-03 11:41:30 +02:00
Milan Broz
ff4aa8e5e7 Fix typo in Readme. 2025-06-03 10:17:28 +02:00
Milan Broz
efc6f847ee Update kernel.org links to use CDN. 2025-06-03 09:54:49 +02:00
Milan Broz
30ede1be36 Test version 2.8.0-rc0. 2025-06-03 09:21:07 +02:00
Josef Andersson
98323a93a8 po: update sv.po (from translationproject.org) 2025-06-03 09:06:31 +02:00
Yuri Kozlov
700047c84f po: update ru.po (from translationproject.org) 2025-06-03 09:06:31 +02:00
Ondrej Kozina
10ab6be262 Allow --reduce-device-size and --device-size in encrypt action.
Fixes: #822
2025-06-02 17:10:02 +02:00
Ondrej Kozina
ad30673dc5 Clarify structure assignement in tests.
Makes code more obvious.
2025-06-02 17:09:08 +02:00
Ondrej Kozina
773ac1ce55 Support encryption with reduced device size and data shift.
The only mising bit in library is a check if reduced data
size is smaller than real device size minus data shift.
2025-06-02 17:08:43 +02:00
Ondrej Kozina
ed50d30e7e Decouple data device size from reencryption operation data size.
Encryption with data shift and moved segment used to change
data size attribute later than necessary. Make it obvious in
upper layers.
2025-06-02 17:05:38 +02:00
Ondrej Kozina
5973694311 Correctly suffix device related variables.
We introduced _bytes and _sectors variables some time ago.
2025-06-02 17:05:03 +02:00
Milan Broz
b81c84bd8f Do not allow null cipher for LUKS2 keyslot even in conversion. 2025-06-02 13:58:33 +02:00
Milan Broz
8d7ee84006 tests: Silence repair warning on intentionally wiped image 2025-05-29 13:55:56 +02:00
Milan Broz
21e0680abf Disallow conversion to LUKS1 if capi string is specified.
While it works, it is a bug and we block it already in luksFormat.
2025-05-29 13:55:56 +02:00
Milan Broz
bd03054c38 tests: Add capi LUKS1 non-root test.
note: there should be much larger coverage of non-root operations.
2025-05-29 13:55:56 +02:00
Milan Broz
e136a0a40a Support capi format in crypt_storage wrapper.
Fixes: #944
2025-05-29 13:55:56 +02:00
Milan Broz
5b3ff3c0a7 Explicitly disallow capi format for LUKS2 keyslot encryption
NO functional change as it fails in IV check anyway, but the
code should not reach this funtion at all.
2025-05-29 13:55:56 +02:00
Milan Broz
c3414b8221 tests: detect failure of crypt_decode_key 2025-05-28 15:09:44 +02:00
Milan Broz
9f8667922c tests: Fix length of decoded key
As the following patch would detect a failure here.
2025-05-28 15:09:44 +02:00
Milan Broz
949c4ad0f1 tests: Fix typo in test key definition.
Code used a partially uninitialized key here.
2025-05-28 15:09:44 +02:00
Milan Broz
55c44cd3fd Fix warning for hidden global variable
The requirements_flags is a global array, do not
name a local variable the same (CodeQL fix).
2025-05-28 14:05:30 +02:00
Ondrej Kozina
ca7c4c8b15 test: Fix KeyslotContextAndKeyringLink test
The test was wrongly expecting results based on a mistake
in keyring utilities. The internal function extracting
volume key from kernel keyring was by mistake returning
-ENOENT (error code internaly used to signal the keyslot
context can not be used for unlocking key) even though
the kernel key was in fact unreachable and therefor
the volume key could not be read.

In short never expect device activation will pass
when one of passed keyslot contexts is invalid. The fact
that sometimes only one keyslot context is needed and
the invalid second context should not be needed is not
good practice.
2025-05-27 16:25:22 +02:00
Ondrej Kozina
a6c9c28208 Return -EINVAL if keyslot context can not access keyring key. 2025-05-27 16:24:27 +02:00
Ondrej Kozina
b6f43890f2 Add better errno hint in debug message. 2025-05-27 14:27:14 +02:00
Ondrej Kozina
c735c71ca1 keyring_find_key_id_by_name does not return negative values on error.
It returns 0 on error even if keyring support is compiled out.

There are valid negative constants for thread keyring, process keyring,
etc.
2025-05-27 14:27:14 +02:00
Ondrej Kozina
f3557f0765 find_key_by_type_and_desc must return 0 on error. 2025-05-27 14:27:14 +02:00
Milan Broz
5a2ca129b9 tests: Fix interactive query
In some situations (like under valgrind) test interactively asks
for confirmation, avoid it by using batch mode.
2025-05-27 13:43:20 +02:00
Milan Broz
5755f210ac doc: Do not wrap line for packages list and suggest netcat-openbsd for Debian.
The netcat package no longer exists in Debian.
2025-05-27 13:42:44 +02:00
Milan Broz
ccf7d6b197 tests: Do not use --key-size for --hw-opal-only format
This option is ignored and only produces warning
"OPAL hw-only encryption does not support --cipher and --key-size, options ignored."
2025-05-27 13:42:08 +02:00
Milan Broz
19d67d3c62 Fix integer and double types in keyslot checker.
To avoid theoretical overflows detected by Coverity.
2025-05-27 11:41:42 +02:00
Ondrej Kozina
cf630f578d Create underlying TCRYPT devices with CRYPT_SUBDEV prefix.
Create lower level TCRYPT device (underneath the toplevel one)
with CRYPT_SUBDEV prefix so that in later release we
can use general dependecies deactivation code.

The newly activated stacked TCRYPT devices will not correctly
deactivate with older pre 2.8.0 release.
2025-05-26 15:41:41 +02:00
Ondrej Kozina
12eb040943 Create dm-integrity with CRYPT_SUBDEV prefix.
When activating dm-integrity device underneath dm-crypt
with LUKS2 authenticated encryption mode, annotate the
device correctly with CRYPT_SUBDEV prefix. This will help
us to clearly identify dependent device underneath LUKS2 top
level device and we can unify the deactivation code in future
releases.

We have general code deactivating dependent devices already for
LUKS2 reencrytion.

Deactivating newly created devices with pre 2.8.0 cryptsetup
will issue warning about missing devices but the deactivation
will succeed.
2025-05-26 15:35:41 +02:00
Milan Broz
880bbfab4d Use free physical memory check for pbkdf only on small systems.
This hack tries to workaround situation when small VMs without swap
causes OOM. This hack will be removed one day completely...

Also remove confusing warning about possible crash.
With OpenSSL Argon2 backend this behaves much better, but it still
can cause OOM instead od returning ENOMEM.
Anyway, the warning message causes more problems that it solves.

Fixes: #896
2025-05-26 12:45:09 +02:00
Milan Broz
e6f6ee9291 Do not allow PBKDF benchmark over maximum allowed threads.
Unfortunatelly the benchmark function cannot return
corrected parallel cost, so it must fail.

Note that some backends (like OpenSSL) also limits maximal thread count,
so currently it was clapped at 4 for luksFormat and 8 for benchmark.

This patch set it all to PBKDF internal parallel limit.
2025-05-26 11:30:37 +02:00
Milan Broz
6b832b8d03 Add keyslot check code.
This patch adds keyslot randomness analysis to cryptsetup repair command
to check for a detectable corruption of binary area.

It uses Chi2 analysis. This check basically replaces external keyslot
checker program.
2025-05-22 16:09:50 +02:00
Milan Broz
f29337aa9f Define opaques crypt_device struct in local header. 2025-05-22 16:09:50 +02:00
Milan Broz
f5bbc499d4 Move LUKS_STRIPES definition to macros definitions.
To be used in repair code later.
2025-05-22 16:09:50 +02:00
Milan Broz
4fd3db5e93 Fix cryptsetup repair to use header device and UUID spec. 2025-05-22 16:09:50 +02:00
Milan Broz
cbf6fa9d07 Fix external slot checker to work with LUKS2. 2025-05-22 16:09:50 +02:00
Milan Broz
9e4a31887e ci: retry update for Ubuntu repos 2025-05-22 16:08:45 +02:00
Milan Broz
680567615a tests: add LUKS2 integrity tests 2025-05-22 14:53:27 +02:00
Milan Broz
24b126252b tests: add integritysetup inline tags tests 2025-05-22 14:53:21 +02:00
Milan Broz
324926e2d8 LUKS2: support Inline tags format and activation for integrity protection 2025-05-22 14:53:16 +02:00
Milan Broz
3ec14c8668 Move (and rename) UUID helpers to libdevmapper source. 2025-05-22 14:53:12 +02:00
Milan Broz
d967c9aaf0 Unify checking for LUKS2 intermediate device.
Use dm_get_active_iname that should be used on all places.

This function return integrioty device name if it shoudl be
maintained by LUKS2 context directly.

Code must not touch other devices that it does not own.
2025-05-22 14:53:03 +02:00
Milan Broz
352cda0302 integrity: Detect PI/DIF capable devices in inline mode.
And print better error if not.
2025-05-22 14:48:56 +02:00
Milan Broz
006ebd832f integrity: support Inline tags format and activation
Support inline format in API with crypt_format_inline().

Add --integrity-inline option to integritysetup.
2025-05-22 14:48:56 +02:00
Milan Broz
49ccafe38a integrity: Add inline flag to API
Process new dm-integrity flag (hw inline mode).
2025-05-22 14:48:56 +02:00
Milan Broz
29fcd88d86 integrity: Support superblock V6
This one include inline flag support.
2025-05-22 14:48:56 +02:00
Milan Broz
c4ce270568 Avoid false positive for static scan (integer overflow).
Avoid adding signed type to unsigned one.
2025-05-22 10:31:22 +02:00
Milan Broz
8440e59b7b Fix possible integer overflow (for unused variable). 2025-05-22 10:31:22 +02:00
Milan Broz
465043300d Check for unbound keyslot in convert.
The type cannot be converted to LUKS1 if there is an unbound keyslot.

It is already covered by digest count check, but in some specific
use cases the explicit check can catch a new problem.
2025-05-20 18:24:01 +02:00
Milan Broz
50b762ab94 Add note to man page for LUKS convert requirements. 2025-05-20 18:23:55 +02:00
Milan Broz
11dd8d318c Add debug messages for incompatible LUKS1 conversion.
If LUKS2 keyslot is not compatible, print debug message with more
specific info.

Fixes: #850
2025-05-20 18:23:48 +02:00
Milan Broz
e5c2892cd5 cryptsetup: Adjust XTS keys size also if cipher is specified with capi: prefix.
Fixes: #776
2025-05-20 16:58:14 +02:00
Ondrej Kozina
bd2f7eb671 Harden digest verification when adding new unbound key.
While adding new unbound key there is a check whether the
passed key parameter matches current volume key or not. If it
matches the existing volume key we handle the LUKS2 keyslot
addition as an ordinary LUKS2 keyslot (not unbound).

If the check failed we continued with the operation of adding
LUKS2 unbound keyslot. But we did not check if the error
was not a more general issue for example with in-memory metadata.

Let's contine with the operation only if the return code is
expected -EPERM (not matching digest) or -ENOENT (not matching any
existing unbound key).
2025-05-20 16:57:45 +02:00
Milan Broz
a39a0d00e5 Do not use pagesize as fallback for block size.
Device must process MAX_SECTOR_SIZE as it is encryption
block size, so if it does not work with this value, it will
fail anyway.

Fixes: #943
2025-05-20 16:44:06 +02:00
Milan Broz
9484eee48a Move wipe debug message and add alignment info. 2025-05-20 16:44:06 +02:00
Ondrej Kozina
5689fb46e7 Add error message for missing volume key.
Add specific error message when user does not provide
all necessary volume keys via --volume-key-file or
--volume-key-keyring parameters.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
4d5aa29955 Add tests for reencryption by keyslot context in CLI. 2025-05-20 15:29:14 +02:00
Ondrej Kozina
ad21502d06 Extend options for initializing reencrypiton from cli.
This patch extends available options for LUKS2 reencryption
initialization.

When no specific keyslot is selected by --key-slot option, all active
keyslots needs to be refreshed. With current patch user does not
have to provide passphrase via interactive prompt when token is
available and can unlock assigned keyslot. Only keyslots not assigned
to tokens (and unlocked by tokens) must be provided with passphrase.

Furthermore user may directly narrow down selection of keyslots
suitable for reencryption by specifying either --token-id, --token-type
or --token-only option. In that case only keyslots associated to the
specific token (--token-id) or specific type (--token-type) or any token
specified in LUKS2 metadata (--token-only) will be used for
reencryption and refreshed with new volume key. All other keyslots will
not be refreshed and will be erased after reencryption is finished. The token
association will be carried over to refreshed keyslots.

The third new method available in this patch is support for reencryption
by passing volume keys directly. The LUKS2 device may be reencrypted
by passing volume keys by --volume-key-file, --new-volume-key-file,
--volume-key-keyring or --new-volume-key-keyring options. With this
options user may reencrypt device with no active keyslots. If there's
any active keyslot and volume keys are passed directly user may enforce
volume key based reencryption by passing --force-no-keyslots option.
If --force-no-keyslots option is passed all active keyslots will be
erased after reencryption operation is finished and the device may be
unlocked only by passing new volume key directly.

Fixes: #774, #780.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
0dc630b911 Allow reencryption resume by new methods.
The reencryption operation can now be resumed
using tokens or by specifying volume keys
directly.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
cbcb8c6ee3 Allow device in reencryption to be activated by volume keys in files.
Allow to use up to two --volume-key-file options (paired with
two --key-size options) for device in-reencryption activation.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
5a84dc87e3 Return -ENOENT if digest is missing.
If there is no digest associated with segment,
for example during reencryption mode encrypt initialization,
return -ENOENT in LUKS2_digest_verify_by_segment.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
1a7e89c55d Allow crypt_reencrypt_init_by_keyslot_contexts with no active keyslots.
With this commit reencryption can run without any active
keyslot containing current (or optional future) volume key.

In such case new volume key must be provided via CRYPT_KC_TYPE_KEY
keyslot context and by adding CRYPT_REENCRYPT_CREATE_NEW_DIGEST flag in
reencryption parameters during reencryption initialization in
crypt_reencrypt_init_by_keyslot_contexts.

The new flag can not be combined with CRYPT_REENCRYPT_RESUME_ONLY
flag.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
804ee74a46 Reduce memory allocations in vk keyring keyslot context. 2025-05-20 15:29:14 +02:00
Ondrej Kozina
b497306934 Add method in keyslot_context to get stored key size.
Only applicable for CRYPT_KC_TYPE_KEY and
CRYPT_KC_TYPE_VK_KEYRING.
2025-05-20 15:29:14 +02:00
Ondrej Kozina
6c74b6f9c8 Update crypt_keyring_get_key_by_name debug message. 2025-05-20 15:29:14 +02:00
Ondrej Kozina
548de244c5 Add internal helper to get key size by key description. 2025-05-20 15:29:14 +02:00
Ondrej Kozina
0363ea7c57 Add utils keyring helper to get keyring key size by id. 2025-05-20 15:29:14 +02:00
Ondrej Kozina
ae2a7cfc33 Use crypt_get_old_volume_key_size in action reencrypt. 2025-05-20 15:21:44 +02:00
Ondrej Kozina
4e94c8d809 Add crypt_get_old_volume_key_size API.
It allows to get former (old) volume key size
from LUKS2 device in reencryption state when
there's at least one keyslot containing encrypted
volume key.
2025-05-20 15:21:44 +02:00
Milan Broz
3dcb532bd3 verity: Check hash device size in advance
Let's check block device size required for Merkle tree and superblock.
If it is a file, allocate the size in advance with fallocate.

This should print better error message if hash device is too small.

Fixes: #808
2025-05-20 14:59:09 +02:00
Milan Broz
02a48caf7e Print better error message for unsupported LUKS2 AEAD device resize.
Fixes: #804
2025-05-15 15:49:28 +02:00
Milan Broz
bc6c3092fa ci: call dnf clean all before install 2025-05-12 14:30:36 +02:00
Ondrej Kozina
0cf87a4151 Add support for --decrypt init by keyslot contexts. 2025-05-12 11:46:16 +02:00
Ondrej Kozina
cf29d51589 Refactor activation by volume key(s) in helper routine. 2025-05-12 11:46:16 +02:00
Ondrej Kozina
8fcd8a78d8 Make changes in token unlock for further changes in reencrypt action.
The token preference condition is moved outside the
try_token_unlock routine body.
2025-05-12 11:46:16 +02:00
Ondrej Kozina
5f48657f4d Move try_token_unlock to luks utils.
and rename it to luks_try_token_unlock.
2025-05-12 11:46:16 +02:00
Ondrej Kozina
4493d9ad3e Switch reencrypt --encrypt initialization to keyslot context.
This allows to simplify init_keyslot_context and we can only
pass single pointer from luksFormat routine.
2025-05-12 11:46:16 +02:00
Ondrej Kozina
9f0dd9cc4c Move init_keyslot_context in luks utils.
and rename it to luks_init_keyslot_context.
2025-05-12 11:46:16 +02:00
Ondrej Kozina
261bef3409 Fix mistake in reencryption change detection logic.
There's no reason to have bool variable for
key size change specifically.
2025-05-12 11:46:16 +02:00
Ondrej Kozina
ff7a21eb94 Refactor get_adjusted_key_size. 2025-05-12 11:46:16 +02:00
Ondrej Kozina
48683f7316 Fix memory leak on error path in luksAddKey. 2025-05-12 10:25:01 +02:00
Ondrej Kozina
e48d5b6d19 Verify volume key passed by kernel keyring.
Verify volume key passed by --volume-key-keyring before
trying to add new keyslot.
2025-05-12 10:25:01 +02:00
Ondrej Kozina
723ad6afdf Print error message in cryptetup cli.
Prints "Volume key does not match the volume" when
passed VK's digest does match the stored one.
2025-05-12 10:25:01 +02:00
Ondrej Kozina
79d8a8b840 Drop error message about mismatching volume key.
crypt_activate_by_keyslot_context() returns -EPERM
when key was passed either by CRYPT_KC_TYPE_KEY or
CRYPT_KC_TYPE_VK_KEYRING and does not match the digest
stored in metadata.

Sometimes caller might want to verify if the passed
keyslot contexts matches the effective volume key
or not without the error message. It can be
printed from command line tools when needed.
2025-05-12 10:25:01 +02:00
Milan Broz
5f8cab5d4a FAQ: add volume key example.
And remove requests for private mails.
2025-05-11 21:20:44 +02:00
Milan Broz
dd68e53082 ci: check FIPS mode without fips-mode-setup 2025-05-01 17:27:36 +02:00
Milan Broz
9153c9c3c0 Fix unused PIM query actions list. 2025-04-29 08:16:26 +02:00
Ondrej Kozina
c1b5e412c9 Drop unreachable error message.
LUKS2_reencrypt_status can not return CRYPT_REENCRYPT_INVALID.
2025-04-27 14:14:13 +02:00
Ondrej Kozina
fa84cb8a55 Fix LUKS2_config_get_requirements prototype.
It never returns any error. Make it void.
2025-04-27 14:14:13 +02:00
Milan Broz
221d6ac345 ci: disable rhel10-fips job
Someone decided to remove fips-mode-setup instead
of providing backward compatibility (and just set fips=1).

Upstream is not a RH testbed, remove this job.
2025-04-27 14:09:45 +02:00
Milan Broz
d2fc31da28 ci: update compiler versions 2025-04-27 11:21:30 +02:00
Milan Broz
8b14558b94 ci: Run lintian and codespell. 2025-04-27 11:21:30 +02:00
Milan Broz
e936d4395b Opal: limit PSID keyfile read if not set otherwise
PSID length is de-facto always 32 alphanumeric characters.

Limit the read of PSID from keyfile to this limit
(if not set by explicit size option).

This eliminates mistakes when the keyfile contains EOL characters.

Also, some OPAL drives accepts PSID with any suffix, this patch
unifies processing (it works everywhere the same).
2025-04-22 15:30:38 +02:00
Milan Broz
b166747fee ci: Run rawhide csmock.
Switch to rawhide version of csmock.
2025-03-25 22:54:16 +01:00
Milan Broz
3e114bcb1e Fix warning about NULL argument in setsockopt()
This should fix a warning produced by scan-build-20

warning: The 4th argument to 'setsockopt' is NULL but should
not be NULL [unix.StdCLibraryFunctions]
2025-03-24 13:46:59 +01:00
Milan Broz
1df9a4c566 Fix dirfd() handling.
Detected by scan-build-20.
2025-03-24 13:46:59 +01:00
Milan Broz
7f0724f46c Opal2: Do not use IOC_OPAL_ERASE_LR
The IOC_OPAL_ERASE_LR uses Erase method, that is defined only
in Single user mode (SUM) and works only on SUM-enabled LRs.

As we do not use SUM yet, this always fails.

Moreover, Erase has many side effects - it resets user password to ""
and disables locking for LR.

We already use fallback to IOC_OPAL_SECURE_ERASE_LR, which is GenKey
method (defined in Core spec) that must be always available.
It effectively regenerates the LR encryption key.
2025-03-24 12:34:43 +01:00
Milan Broz
c8420de4d6 tests: Disable csmock jobs
We have to switch to an open alternative, cmsock update no longer works.
Disable it for now.
2025-03-24 12:34:11 +01:00
Mingye Wang (Artoria2e5)
a0b4ae7e27 po: update zh_CN.po (from translationproject.org) 2025-03-23 14:42:57 +01:00
Мирослав Николић
4b39379c5b po: update sr.po (from translationproject.org) 2025-03-23 14:42:57 +01:00
Milan Broz
70f0938fff tests: disable broken OPAL HW
This NVMe is crashing kernel now.
2025-03-20 14:04:16 +01:00
Ondrej Kozina
fbb8d2e910 Revert "Add temporary workaround for broken kernels since 6.14-rc3."
This reverts commit b2da80909a.

The kernel 6.14-rc7 was already release including the proper fix.
2025-03-20 10:03:41 +01:00
Milan Broz
9e6fcefefc Remove redundant --verify-passphrase in man.
Fixes: #938
2025-03-09 20:23:12 +01:00
Vojtech Trefny
bf5d56d804 tests: Add a BITLK test image with two recovery passphrases
It is possible to add multiple recovery passphrases to a BitLocker
device so we should make sure we check both key slots when trying
to activate the device.
2025-03-09 11:23:48 +01:00
Ondrej Kozina
c1b7ad8979 Fix the debug message for too large json data during write. 2025-03-07 15:44:41 +01:00
Ondrej Kozina
fcf266667b Add validation tests for json area in non compact version.
The non compact json area may contiain whitespace characters
in between json object key and value (e.g.: {"key":   "the_value"}).

For LUKS2 write optimization we need to check and do regression testing
for the case where LUKS2 metadata would contain valid LUKS2 json area in
non compact format. The test is meant to verify if the write optimization
does not leave invalid characters beyond valid and properly terminated
LUKS2 json area.
2025-03-07 15:44:41 +01:00
Ondrej Kozina
cb0f568932 Optimize LUKS2 metadata writes.
LUKS2 supports several jsom area length configurations. With
the largest size supported in megabytes we do not want to write full
metadata area unconditionaly (current code) with every metadata
update. This might generate noticeble overhead with LUKS2
reencryption.

With this patch we write only the real used json area
length plus necessary padding to overwrite remaining previous
metadata stored on the disk.

During LUKS2 format and LUKS2 autorecovery we always overwrite
whole json metadata area no matter the used size.
2025-03-07 15:44:41 +01:00
Ondrej Kozina
000f03ad31 Switch to crypt_jobj_to_string_on_disk().
Use single function when we require json format
string representation for on disk format.
2025-03-07 15:44:41 +01:00
Ondrej Kozina
07e8628940 Add helper to unify json string format.
Add a single function to use when generating
json format string representation for on disk
storage purposes so that it can be easily
reused when needed.
2025-03-07 15:44:41 +01:00
Milan Broz
fdb179ea8b verity: Avoid false positive unititialized warning. 2025-03-07 14:43:57 +01:00
Ondrej Kozina
b91aee46c1 Use lower level code for droping signature from kernel keyring.
We do not need to used crypt_unlink_key_by_description_from_thread_keyring
since it also sets some additional parameters unrelated to dm-verity
signatures.

Also it's useless to search kernel key by description when
we have the key id.
2025-03-06 17:17:36 +01:00
Ondrej Kozina
eccccfd9b5 Fix drop of volume key from kernel keyring on crypt_suspend.
We do not have to query device-mapper subsystem
twice in order to get volume key description in kernel keyring.

Also there was a bug that wrongly used kernel key type set by function
supposed to set custom user key type used only when linking volume key
in arbitrary kernel keyring on caller demand.
2025-03-06 17:17:36 +01:00
Ondrej Kozina
2dc886053f Drop unused temporary volume key helpers. 2025-03-06 17:17:36 +01:00
Ondrej Kozina
0a6ee8633a Switch to volume key keyring helpers.
And do not access volume key internals bearing
information whether the key payload was uploaded
in kernel keyring or not.
2025-03-06 17:17:36 +01:00
Ondrej Kozina
15c4a410fd Add volume key helpers for manipulating kernel keys. 2025-03-06 17:17:36 +01:00
Ondrej Kozina
5615488196 Refactor and unify naming conventions for internal keyring helpers.
Functions related to uploading/unlinking volume keys in user
requested kernel keyrings are named as follows:

crypt_single_volume_key_load_in_custom_keyring
crypt_volume_key_load_in_custom_keyring
crypt_unlink_key_from_custom_keyring

helpers for unlinking LUKS2 volume keys from thread keyring:

crypt_unlink_key_from_thread_keyring
crypt_unlink_key_by_description_from_thread_keyring
2025-03-06 17:17:36 +01:00
Ondrej Kozina
c9edd942e8 Remove keyring_add_key_to_custom_keyring function.
The was identical function in keyring utilities already,
except the function name.
2025-03-06 17:17:36 +01:00
Milan Broz
d792de66d5 Fix typo in comment. 2025-03-06 17:16:25 +01:00
Vojtech Trefny
848f16bb5e man: Fix link for --allow-discards option explanation
--allow-discards is documented only in open and refresh man pages
not in luksFormat.
2025-03-06 17:15:41 +01:00
Vojtech Trefny
8573eb515d Fix docstring for crypt_persistent_flags_set
Add all persistent flags and use full name of the flags.
2025-03-06 17:14:11 +01:00
Ondrej Kozina
b2da80909a Add temporary workaround for broken kernels since 6.14-rc3.
The kernel 6.14-rc3 introduced regretion with 1f47ed294a2bd577d5a

The commit changed how errors are propagated and with it OPAL2 devices
no longer returns -EIO on IO to locker region.

Revert this patch after the kernel gets fixed.
2025-03-06 14:23:46 +01:00
Ondrej Kozina
db57571906 Test invalid --luks2-keyslots-size value.
The test was supposed to check if invalid --luks2-keyslots-size
metadata value will trigger failure.

The 128MiB was valid value and the test failed only due to smaller
test device size.

(In case of OPAL2 device it spanned into locked region.)
2025-03-06 14:23:22 +01:00
Milan Broz
93bc8997ea tests: Fix targets/kernel version detection
It is really not a good idea to check minor version without
checking major version is not lower first.

Also try to prepare for situation when major target versions
increases.
2025-02-19 13:50:24 +01:00
nl6720
52c63b5de1 Note the need to omit separator characters from the PSID 2025-02-19 12:42:27 +02:00
Milan Broz
dded9b3305 veritysetup: Support --error-as-corruption option.
The panic/restart_on_error options were introduces in kernel 6.12.

As it does not make sense to set these flags without
data corruption handling, only one option error-as-corruption
is implemented that must be used in combination with
panic/restart on corruption.
2025-02-16 20:53:35 +01:00
Milan Broz
41b8b02ccf verity: Add support for restart/panic on error flag.
Introduced in kernel 6.12.
2025-02-16 20:53:35 +01:00
Milan Broz
7ee0b02967 Make test libdevmapper flags 64bit. 2025-02-16 20:52:37 +01:00
Milan Broz
a3455befe7 Sync libdevmapper flags in tests. 2025-02-16 20:52:37 +01:00
Milan Broz
f07854ab4f Make libdevmapper internal flags 64bit. 2025-02-16 20:52:37 +01:00
Milan Broz
c497945ab3 Make internal dm_flags 64bit. 2025-02-16 20:52:37 +01:00
Ondrej Kozina
036ed52999 Remove volume key internals from internal API. 2025-02-16 18:00:20 +00:00
Ondrej Kozina
1bec71dbe1 Add temporary helpers to indicate uploaded volume key.
To be removed later when we add clear implementation
to hide access to volume key uploaded attribute.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
9e0bcedbaa Harden LUKS2 volume key compare helper. 2025-02-16 18:00:20 +00:00
Milan Broz
6123ea2e0b Add strict compare volume key comparison for non-LUKS2 devices.
[Modified by Ondrej Kozina]
2025-02-16 18:00:20 +00:00
Ondrej Kozina
f421ec0800 Simplify volume key compare helper.
Since we can now identify volume key not containing
real key data we can make _compare_volume_key more
comprehensible.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
843fac813f Indicate volume key with initialized key content.
volume key does not have to always contain properly
initialized key content (binary buffer). Add helper
to notify callers about it.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
6ee76934fa Harden and limit access to volume key internals.
The volume key structure may often be in configuration
where 'key' member does not contain real data. Some
examples:

- volume key acquired by querring device-mapper where key
  was originaly passed by kernel keyring reference.

- volume key allocated by crypt_alloc_volume_key(size, NULL)

With this patch access to internal 'uninitialized' data result
in failed assert().

For use cases where key data are not needed (keyring reference wrapper,
key length info only) we do not have to allocate and lock the safe
buffer in memory.

Further improvements might to completely hide the volume key internals
and access only via setter and getter functions.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
f86ab28ad6 Add crypt_safe_alloc_size helper.
Returns size of the payload. Zero means error.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
54d937dfc7 Switch away from accessing volume key internals directly.
Switch current code to use following volume key helpers
for accessing internal properties:

crypt_volume_key_length(), crypt_volume_key_get_key(),
crypt_volume_key_description() and crypt_volume_key_kernel_key_type()

Remaining direct access to volume key internals will be dealt with in
later commits since it requires some further changes.
2025-02-16 18:00:20 +00:00
Ondrej Kozina
fd9be9e777 Add severeal helpers (get methods) for volume key.
crypt_volume_key_length() for key length
crypt_volume_key_get_key() to access key data (if initialized)
crypt_volume_key_description() for kernel key description
crypt_volume_key_kernel_key_type() for kernel keyring key type
2025-02-16 18:00:20 +00:00
Milan Broz
63f7dc739b fuzz: Better log from installation script
Print last commit from each git repo.
Also use master branch for zlib.
2025-02-15 14:57:19 +01:00
Milan Broz
a2b2c6a8ae Add workaround for memory sanitizer that cannot recognize explicit_bzero.
Otherwise it produces a lot of false positives in OSS-Fuzz.
2025-02-08 15:06:36 +01:00
Milan Broz
3899484be8 fuzz: Fix use of PWD variable.
The PWD variable is set by bash itself on every cd command,
rename it so it works as expected.
2025-02-08 15:06:33 +01:00
Ondrej Kozina
a965a88992 Add const to pointer in blob_serialize() function.
the data is read-only in this context.
2025-02-06 11:41:30 +01:00
Ondrej Kozina
88b3da6042 Use new crypt_generate_volume_key to generate weaker keys.
There were two different use cases for weaker keys:

1) empty keys (zero filled buffer)
2) weak 'random' keys not sucking entropy while being generated

Those key types must not be used to encrypt real data. It's used either
to check cipher can be configured sucessfully on the system or as
a fake envelope during metadata repair.
2025-02-06 11:41:26 +01:00
Ondrej Kozina
1326dfbac1 Add generic crypt_generate_volume_key function.
So that we can generate keys with different 'quality'
attribute at one place.
2025-02-06 11:37:04 +01:00
Ondrej Kozina
4f90213a5b Drop redundant member initialization in volume key.
The memory is already initialized to zeroes after allocation.
2025-02-06 11:30:18 +01:00
Ondrej Kozina
5ee549de1e Remove volume_key struct from fvault2 code.
No volume_key feature is used in the code and it
will make further changes easier.
2025-02-06 11:30:18 +01:00
Ondrej Kozina
e9073e6b19 Add keyring key type in volume key comparison function. 2025-02-06 11:30:18 +01:00
Ondrej Kozina
dc75deff51 Drop bogus usage of vk->uploaded.
The volume key uploaded attribute is respected only with
regard to volume keys uploaded in the thread keyring in logon key type.

Here the uploaded attribute was set for volume keys uploaded in
custom user keyrings in custome key descriptions.
2025-02-06 11:21:42 +01:00
Ondrej Kozina
ab9d4fec3b Do not parse emtpy '-' key string with null ciphers.
The loop is not entered but for later patche lets make
it obvious it is not needed.
2025-02-06 11:21:42 +01:00
Ondrej Kozina
da84c79a5b Use crypt_volume_key_next helper in bitlk. 2025-02-06 11:21:42 +01:00
Ondrej Kozina
a321068e8d Add compile_commands.json file to .gitignore.
The file is used to describe project compilation independent
of build system in use.

It can also help LSP servers to improve code suggestions since
it can see how the project is configured and respect, for example,
content of config.h file.
2025-02-04 16:13:08 +01:00
Milan Broz
e257def910 Remove redundant check for dm-integrity mapping table params section.
The dm-integrity table always contains number of feature arguments
(since introduction in kernel 4.12).

Moreover, the code already dereferences params field, so the test
make no sense.

Found by CodeQL check.
2025-01-28 13:03:10 +00:00
Milan Broz
c9008528f9 tests: Remove function xx() bashism.
Posix does not use function keyword, moreover, we use it inconsistently.
2025-01-27 20:43:33 +01:00
Milan Broz
3d535dcf31 tests: Add trap for segfault and sigabrt
If bash test script uses a pattern that test that command should fail
  command && fail
(IOW fail function is called only if command exited successfully),
it can mask potential segfault, as it return non-zero exit code.

Fix it by using trap for scripts that uses this pattern.

The same applies for SIGABRT (abort() call).
2025-01-27 20:42:25 +01:00
Milan Broz
a45fb0a90d Do not include dlfcn.h if external token support is disabled.
Fixes: #925
2025-01-27 12:33:52 +00:00
Milan Broz
06c0f03c9f Add a note regarding use of #if for config.h processing. 2025-01-27 11:05:08 +00:00
Milan Broz
c6a7849090 Use #if for password quality libs defines. 2025-01-27 11:05:08 +00:00
Milan Broz
29741d91e6 Use #if in bitops.h. 2025-01-27 11:05:08 +00:00
Milan Broz
1e441bf75c Use #if for rest of defines. 2025-01-27 11:05:08 +00:00
Milan Broz
d9404821a6 Use #if for HAVE_BLKID_* defines. 2025-01-27 11:05:08 +00:00
Milan Broz
e5405f2fd8 Use #if for HAVE*_H defines. 2025-01-27 11:05:08 +00:00
Milan Broz
37d52876b9 Use #if for other ENABLE* options. 2025-01-27 11:05:08 +00:00
Milan Broz
ff81791308 Use #if for ENABLE_AF_ALG. 2025-01-27 11:05:08 +00:00
Milan Broz
c21c746eff Use #if for USE_UDEV. 2025-01-27 11:05:08 +00:00
Milan Broz
bb304f45bd Use #if for KERNEL_KEYRING. 2025-01-27 11:05:08 +00:00
Milan Broz
f64f6fb9e8 opal: Fix error table offset
The error table was partially wrong (for codes >0x0b)

Let's use exact enum codes according to TCG Core spec (5.1.5).

This also fixes CodeQL warning.
2025-01-27 11:04:25 +00:00
Milan Broz
5c795885c5 opal: update copyright 2025-01-27 11:04:25 +00:00
Milan Broz
6a8f88ea99 Fix leaks detected by Coverity. 2025-01-27 09:11:40 +00:00
Milan Broz
7ffa8ee28a Fix integer cast for sector_size.
Found by Coverity scan.
2025-01-27 09:11:40 +00:00
Milan Broz
2691514547 Print message about reaching maximal interactive passphrase to error output.
Reaching maximal keyfile size is already reported as error.

Note that interactive really means user entering password.

For all other us there is keyfile processing.

Related: #933
2025-01-26 10:10:27 +01:00
Milan Broz
36574dd114 Avoid if (not NULL) free().
This fixes some COdeQL warnings.
2025-01-16 15:54:09 +01:00
Milan Broz
8364178b38 Update copyright year. 2025-01-15 23:09:36 +01:00
Milan Broz
2a880f838a ci: Update and fix GitHub actions 2025-01-15 17:07:18 +01:00
Milan Broz
e6208a12b5 ci: Update CodeQL GitHub CI config 2025-01-15 15:06:06 +01:00
Milan Broz
b54e5ce9f0 ci: Fix GitHub CI build 2025-01-15 15:03:10 +01:00
Milan Broz
bfae421c52 bitlk: Clarify activation error message if clear key is present.
Fixes: #929
2025-01-15 13:35:29 +01:00
Milan Broz
33ebb36f71 tests: check for xxd binary in validation test 2024-12-23 22:07:09 +01:00
Gabi Falk
64fb1c1b26 tests/compat-test: Adjust test for compatibility with passwdqc
Unlike libpwquality, passwdqc does not consider 'compatkey' a strong
password and rejects 512 character long passwords.

Closes: https://gitlab.com/cryptsetup/cryptsetup/-/issues/928
Signed-off-by: Gabi Falk <gabifalk@gmx.com>
2024-12-22 16:00:00 +00:00
Milan Broz
b18cefcc71 Detect out of memory in KDF in keyslot derivation.
For OpenSSL and gcrypt we can detect that Argon2 failed on malloc,
report it to user (and return ENOMEM instead of EINVAL).
2024-12-12 22:45:21 +00:00
Milan Broz
7cabaa5d70 pbkdf: Do not allow memory cost that cannot be used in size_t
For 32bit platforms size_t is 32bit integer and unfortunately
our maximum hard limit overflows by 1.

Stop validation if this happens (it cannot be passed to malloc()
and similar functions anyway).

There should be no compatibility change, as such memory
is not allocatable on 32bit anyway.
Other platforms have 64bit size_t.
2024-12-12 22:45:21 +00:00
Milan Broz
b201a62987 Add a note about OPAL PSID sensitivity to manual pages. 2024-12-12 22:44:35 +00:00
Milan Broz
f8788f347e Mark all sizes in status and dump output in the correct units.
NOTE: This is possibly an incompatible change as it changes text output.

Since the support of --sector-size option, the description "sectors"
became ambiguous as it usually means 512-byte sectors (device-mapper unit).

Major confusion occurs when the sector size is 4096 bytes while units display
is in 512-bytes.

Unfortunately, there is no clear compatible way, so this patch adds
[512-byte units] marker and also additional byte size value.

All other fields that display units are changed to use the "[units]" format.

The integrity format is also unified with the common style with ':' as a separator.

Fixes: #884.
2024-12-12 15:56:00 +00:00
Milan Broz
ea39aecba3 Add integrity key tests. 2024-12-03 20:28:07 +01:00
Milan Broz
5eda5f6a38 Fix compatibility for older dmcrypt without integrity_key_size
For older kernel an default HMAC key size we must not set
integrity_key_size option.
2024-12-03 20:28:00 +01:00
Milan Broz
b5672053f5 Use real integrity key size in format operation.
For now, we used zeroed key for dm-integrity format, as there was not
data area. In future, there can be wrapped key scheme, that will require
to setup real key even in this situation.

This patch modifies the integrity format flow that the real key is used
during format.

Mostly based on code from Ingo Franzki <ifranzki@linux.ibm.com>
2024-12-03 20:27:16 +01:00
Milan Broz
491f31c4d4 Add --integrity-key-size option to cryptsetup.
This patch adds support for --integrity-key-size option that can be used
to setup non-standard HMAC integrity key size.
2024-12-03 20:25:54 +01:00
Milan Broz
7b5ac650e5 Allow specific integrity key size.
This patch add support for setting of integrity key size
for LUKS2 devices.

It adds new (optional) JSON "key_size" attribute in segment.integrity JSON object.
If not set, the code use hash length size (backward compatible).

For LUKS2, we do not allow smaller keys than 128 bits.

Mostly based on code from Ingo Franzki <ifranzki@linux.ibm.com>
2024-12-03 20:25:54 +01:00
Milan Broz
ff3e2c6a43 libdevmapper: Support dm-crypt integrity_key_size option
This patch implement support for setting specific integrity key size
option in dm-crypt, available since dm-crypt version 1.28.0.

This can be used for setting non-standard HMAC key length.

Mostly based on code from Ingo Franzki <ifranzki@linux.ibm.com>
2024-12-03 20:25:54 +01:00
Ondrej Kozina
1bea029cef Lock volume key structure in memory.
This was probably oversight in original commit
introducing support for selective memory locking
on sensitive data only.

Fixes: db65a5ceac
2024-12-03 13:33:59 +01:00
Milan Broz
ecb1326e0e CI: Disable annocheck run.
It is currently broken.
2024-11-29 10:18:45 +01:00
Milan Broz
690c22ac7b Switch isLUKS() testing order to avoid static analysis scan confusion.
There is no functional change in this patch except it avoids
strange confusion during some static tests.

The cd->type must be set in this function anyway.
2024-11-28 10:41:18 +01:00
Ondrej Kozina
9f1aee46d5 Rename 'keyring' member to 'keyring_key_type' in volume_key.
The keyring field is misleading since the
field indeed contains the type identification
id.
2024-11-27 12:24:59 +01:00
Milan Broz
82bee1c52d test: Skip trusted test if keyctl cannot load user key.
Some very old systems do not support -x option for keyctl,
skip the test in this case.
2024-11-26 12:20:00 +01:00
Milan Broz
0805cc025d test: Run keyring trusted/encrypted test in CI.
And install dependencies unconditionally.
2024-11-25 14:56:00 +01:00
Milan Broz
9d03e5987c Add trusted/encrypted keyring test (for plain format). 2024-11-25 14:55:55 +01:00
Milan Broz
768bca1df5 Support plain resize with keyring key. 2024-11-25 14:55:51 +01:00
Milan Broz
4b7920975c Support trusted & encrypted keyring for plain device. 2024-11-25 14:55:47 +01:00
Milan Broz
42e85571df Move keyring utilities to separate file. 2024-11-25 14:55:43 +01:00
Milan Broz
ae4b4ff4d7 Unlink only volume keys that were previously stored in keyring.
This is only preparation for an extension later, however, the volume
keys should not be unloaded unconditionally from keyring.

Note that all other places dropping keys already check that keys
were uploaded through key ID setting.
(And for suspend unconditional unlink make sense too.)
2024-11-25 13:20:36 +01:00
Milan Broz
9575dadc8b Store keyring type in volume key.
The key_decripion always contains only a key name,
keyring then contains type of keyring as defned un keyring utils.

For now, only LOGON type is used in commands, it will be extended later.
2024-11-25 13:19:42 +01:00
Milan Broz
6be70a0157 Do not include luks2/luks2_internal.h ouside of LUKS2 internal implementation.
The luks2_internal.h contains specific JSON implementations while
luks2.h is generic. Code outside of luks2/ dir should not use internals.

Also luks2.h includes functions prototypes that are used from setup.c.
2024-11-23 20:52:24 +01:00
Milan Broz
3acac6f8fc Print warning if some options were ignored for OPAL hw-only encryption.
As OPAL without sw encryption bupesses dm-crypt, many activation
options are ignored. Print at least message for user here.

Fixes: #920
2024-11-23 20:52:22 +01:00
Milan Broz
609277d957 Add a comment about wiping derived key in benchmark.
Fixes: #916
2024-11-23 20:52:19 +01:00
Ondrej Kozina
fb021bac3d Fix token assignement API.
There was a bug in both crypt_token_assign_keyslot and
crypt_token_unsassign_keyslot where CRYPT_ANY_TOKEN
special value could be passed in token parameter.

It would correctly assign/unassign all tokens to/from
the specified keyslot (or from any in case of CRYPT_ANY_SLOT),
but it returned -1 (CRYPT_ANY_TOKEN) which fited error return
values as per API documentation.

We fixed that by not supporting CRYPT_ANY_TOKEN since it does
not make much sense. It can be workarounded by iterating over
all available tokens and calling crypt_token_assign_keyslot or
crypt_token_unassign_keyslot accodingly.

Fixes: #914.
2024-11-15 15:24:14 +01:00
Milan Broz
c3972372b1 argon2: Avoid unitialized warning in cppcheck
Thsi patch avoids this cppcheck warning:

Error: CPPCHECK_WARNING (CWE-457): [#def1]
cryptsetup-main/lib/crypto_backend/argon2/blake2/blake2b.c:369: warning[uninitvar]: Uninitialized variable: out_buffer

It is a false positive, but wiping buffer is cheap a and similar approach is used
in other Argon2 implementations (OpenSSL).
2024-11-08 19:51:14 +00:00
Milan Broz
46289f92ff argon2: Avoid cppcheck integer oveflow warning
This patch avoid warning in constant-time base64 function:

Error: CPPCHECK_WARNING (CWE-190): [#def2]
cryptsetup-main/lib/crypto_backend/argon2/encoding.c:86: error[integerOverflow]: Signed integer overflow for expression ''0'-52'.

The (x + ('0' - 52)) can be rewritten to (x - (52 - '0')) with the same effect.
Similar solution used in https://github.com/pornin/CTTK/blob/master/src/base64.c
2024-11-08 19:51:14 +00:00
Ondrej Kozina
3c5aa4ef59 Remove unused code.
Due to complete shift to device activation via keyslot context,
remove all remaining internal code activating device by passphrase
or by token.
2024-11-08 15:46:28 +01:00
Ondrej Kozina
5e950924c3 Clarify unbound key parameter in verification routine. 2024-11-08 15:46:09 +01:00
Ondrej Kozina
76d66d6a01 Better name internal activation function. 2024-11-08 15:46:09 +01:00
Ondrej Kozina
ccbc53c169 Do not repeat volume keys upload in custom kernel keyring.
It is uploaded before call in to activation code.
2024-11-08 15:46:09 +01:00
Ondrej Kozina
61aaeaff5a On error drop crypt_key from kernel keyring. 2024-11-08 15:46:09 +01:00
Ondrej Kozina
dd3441621a Fix reencryption keys loading in kernel keyring.
Manage keys upload in kernel keyring (internal logon type for dm-crypt
segments) in single location in-before device activation.
2024-11-08 15:46:09 +01:00
Ondrej Kozina
d7512d738f Force reencryption keys verification after metadata reload.
After switching to reencryption by keyslot context,
the digest was not properly verified before crash recovery.
We need to reverify reencryption digest after metadata
reloads unconditionally.
2024-11-08 15:46:07 +01:00
Ondrej Kozina
6506d324ee Better name routine verifying any available digest.
also drop unused parameter from internal routine.
2024-11-08 14:09:08 +01:00
Ondrej Kozina
a93921c226 Avoid dereferencing NULL pointer. 2024-11-04 12:24:27 +01:00
Ondrej Kozina
f5b7a576b3 Do not dereference the context pointer before assert. 2024-11-04 12:24:20 +01:00
Milan Broz
c0449fc24e Revert "Do not call safe erase on benchmark data."
This reverts commit 17f0261024.

The password can be set by user through expeorted API, we should
not keep traces of derived key from a real password.
2024-11-01 12:59:25 +01:00
Ondrej Kozina
17f0261024 Do not call safe erase on benchmark data.
In both pbkdf2 and argon2* benchmark key variable
is pointer to benchmark data and does not need to be erased
safely as regular key data would need to.
2024-11-01 10:27:24 +01:00
Ondrej Kozina
6daefa8222 api-test: Use minimal key size 14 bytes (112 bits).
As per SP800-132 minimal key length is 112 bits. Use it
while testing unbound keys stored in LUKS2 keyslots.
Otherwise the test fails in FIPS mode.
2024-10-31 17:26:38 +00:00
Milan Broz
33ed0d587e Fix typos found by lintian. 2024-10-30 19:11:29 +01:00
Ondrej Kozina
f85c31677c Simplify bitlk activation by volume key.
Let's not copy volume key again when not necessary.
2024-10-30 16:13:49 +01:00
Ondrej Kozina
5b83ae8ec2 Enable fvault activation by keyslot context. 2024-10-30 13:28:56 +00:00
Ondrej Kozina
7db83f8fb3 Simplify fvault activation by volume key. 2024-10-30 13:28:56 +00:00
Ondrej Kozina
652835a1f8 Verify fvault2 key size in before activation by volume key. 2024-10-30 13:28:56 +00:00
Ondrej Kozina
00b89c4862 Export expected fvault2 volume key size. 2024-10-30 13:28:56 +00:00
Ondrej Kozina
305aa376b6 Add crypt_reencrypt_init_by_keyslot_context API test. 2024-10-30 13:25:57 +01:00
Ondrej Kozina
651a089f38 Add crypt_reencrypt_init_by_keyslot_context.
It allows initializing reencryption operation by
providing access to volume keys via keyslot context.
2024-10-30 13:25:57 +01:00
Ondrej Kozina
45af8de034 Allow shared activation of device in reencryption.
This would be regression when we later switch all internal
implementation to keyslot context.
2024-10-30 13:25:57 +01:00
Ondrej Kozina
0eccd6e194 Check also CRYPT_ANY_SLOT in LUKS2_keyslot_for_segment.
The function did not work properly if keyslot parameter
was set to CRYPT_ANY_SLOT and returned always error.

But it will be used later when we need to find if there's
at least one keyslot asigned to a specific segment.
2024-10-30 13:25:55 +01:00
Ondrej Kozina
4de453d6a5 Retain original error code when reading data from keyring.
If key description is not available we expect -ENOENT.
-EINVAL usually aborts all following effort to unlock
device/keyslot.
2024-10-29 13:26:35 +01:00
Milan Broz
66c1523163 ci: Make unreleased RHEL distro build optional. 2024-10-26 10:51:43 +02:00
Milan Broz
5f066777a1 ci: Print output for RHEL packages install. 2024-10-26 10:38:34 +02:00
Michal Privoznik
fb04611ff7 crypto_backend.h: Wrap APIs in extern C
It's a good practice to mark public APIs as extern "C" so that
projects written in C++ can use our library.

[mbroz] It is not public API in cryptsetup, but we use this backend
in other projects, this aligns the code changes.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2024-10-18 20:40:50 +02:00
Ondrej Kozina
b7cf60f229 Add regression test for decryption with datashift.
Test if decryption works when default segment
is assigned to volume key with digest id set
to non zero value.
2024-10-11 15:06:48 +02:00
Ondrej Kozina
81d8c12cbe Fix LUKS2 decryption when volume key digest id not zero.
During the initialization phase future moved data segments
were incorrectly assigned (hardcoded) to digest with id 0.

When the default segment was assigned to a different value,
the initialization failed and was aborted.

This patch fixes the issue by assigning intermediary segments
to corect digest id.

Reported-by: 谢致邦 (XIE Zhibang) <Yeking@Red54.com>
2024-10-11 14:55:08 +02:00
Ondrej Kozina
e19030915b Unify integer format parameter in prompt.
There was only single occurence of the prompt
message with %u. Let's use %d as anywhere else.
2024-10-09 11:15:56 +00:00
Ondrej Kozina
e4bf1f91b9 Properly block opal devices from deferred deactivation.
The check did not work properly for stacked dm_crypt over
hw opal devices.

Also it did not work at all for active dm mappings with
missing (or detached) LUKS2 metadata.
2024-10-09 09:57:49 +00:00
Ondrej Kozina
7c83d4e639 Simplify internal crypt_get_hdr for LUKS2 type. 2024-10-09 08:04:19 +00:00
Yiyuan Zhong
939b7c0a9e Mbed-TLS: implement PBKDF2
PBKDF2 has been implemented since 2.0.0 and a new API was introduced in 3.3.0
deprecating the old one. This implementation will use the new API if detected.
2024-10-08 20:21:21 +00:00
Milan Broz
443a555559 integrity: print debug message if superblock metadata read fails. 2024-10-08 12:22:46 +00:00
Milan Broz
79ef5bee86 Do not run direct-io read check on block devices.
Block devices must support direct-io. This check causes more problems
than it solves - for Opal locked device it disables direct-io
and we can later possible read wrong data (if kernel does not flush
cache).
2024-10-08 12:22:46 +00:00
Milan Broz
cd818156f6 Do not print debug message if device read check fails.
It really should not print "direct-io works" when it just failed :)
2024-10-08 12:22:46 +00:00
Milan Broz
faeb0c3483 Fix a possible segfault in deferred deactivation.
For device without a type code shoud not try to use
strcmp function.

This can happen for example if deferref flag is used
for device without proper DM-UUID where init_by_name
does not set know device type.

Thanks Clément Guérin for the report.

Fixes: #910
2024-10-08 13:08:18 +02:00
Milan Broz
d35fb1e671 ci: run vectors test when compiling crypto backends.
This should cost only few seconds but will verify
basic crypto backend operations as we do not run full testsuite
with all backends.
2024-10-04 21:57:09 +02:00
Ondrej Kozina
8ad28547ee Simplify keyslot context initialization code. 2024-09-29 19:14:56 +00:00
Jan Zerebecki
3c00305156 add warning to order luksChangeKey and reencrypt 2024-09-29 19:13:02 +00:00
Ondrej Kozina
31bf986084 Adapt cryptsetup to self-contained keyslot contexts. 2024-09-29 16:10:44 +00:00
Ondrej Kozina
6ef0650332 Rename internal keyslot context functions. 2024-09-29 16:10:44 +00:00
Ondrej Kozina
9311c923ca Make all keyslot context types fully self-contained.
Duplicate all dynamically allocated memory passed
keyslot context during initialization and make it
self contained.

Before current patch all pointers passed in keyslot
context initialization routines have to remain valid
for the duration of the keyslot context. Otherwise
memory violation could occur.

This patch fixes the issue in backward compatible
way so that we do not have to change API for all
keyslot contexts. As of now all dynamically allocated
memory can be freed right after keyslot context
initialization.
2024-09-29 16:10:44 +00:00
Eric Biggers
209e6167b5 Exclude cipher allocation time from benchmark
For each 1 MiB of data en/decrypted, 'cryptsetup benchmark' is setting
up a new AF_ALG socket, which involves 4 system calls and is included in
the data en/decryption time.  With high-speed ciphers (e.g. VAES
optimized AES-XTS) this can measure well over 10000 AF_ALG socket setups
per second.  This is not representative of dm-crypt, which only
allocates a cipher when the dm-crypt device is created.

Therefore, allocate the AF_ALG socket once, before doing the benchmark.

On AMD Ryzen 9 9950X this increases the 'cryptsetup benchmark' result of
AES-256-XTS slightly, from 14000 MiB/s to 14600 MiB/s.

Note that an in-kernel benchmark of the crypto API with the same block
size (65536 bytes) gives 34100 MiB/s, so AF_ALG still takes more time
than the en/decryption itself -- this cannot easily be addressed though.

Signed-off-by: Eric Biggers <ebiggers@google.com>
2024-09-17 10:31:10 -07:00
Milan Broz
b5f7176af1 CI: Install scsi_debug and other kernel modules for Ubuntu CI. 2024-09-12 10:20:21 +00:00
Ondrej Kozina
c0bf271bef Add crypt_safe_memcpy in reencrypt digest routine.
We copy volume keys for purpose of calculating LUKS2
reencryption digest. Add crypt_safe_memcpy in serialization
function as well.
2024-09-12 11:08:16 +02:00
Ondrej Kozina
41c72eaa65 Fix a bug in keyring keyslot context.
It always returned zero upon successful keyslot unlock
instead expected unlocked keyslot id.
2024-09-12 08:07:23 +00:00
Milan Broz
e48c74b77f Update Readme.md. 2024-09-03 11:54:48 +02:00
Milan Broz
46b8275ad9 Add 2.7.5 release notes. 2024-09-02 15:38:59 +02:00
Milan Broz
beef8e325a Fix clang undefined version error for ssh token
We use common libcryptsetup-token.sym version script that contain
all symbols, but some of them are optional.

As clang linker treats missing symbols as errors, the linker
phase for ssh token fails as optional cryptsetup_token_buffer_free
is not defined.
(Most of distros has this option still disabled, though).

As the sym file is also example for token authors, removing symbols
there is not an option. For clang, we can use --undefined-version option,
but it is not supported by other linkers, so it requires non-trivial
checks for usable LDFLAGS (for both autoconf and meson).

Instead, fix it by simply defining the symbol in ssh token, which
duplicates the internal libcryptsetup functionality.

Fixes: #830
2024-09-01 00:38:57 +02:00
Ondrej Kozina
63bb997b41 Abort online reencryption for misconfigured devices.
Hard abort is justified here. The online reencryption on
data devices that do not support O_DIRECT io flag is
dangerous and leads to data corruption. This should be
impossible to hit due to a patch that handles it
in initialization phase. Better safe than sorry.
2024-08-27 14:00:41 +00:00
Ondrej Kozina
9991cbc306 Harden online reencryption checks in initialization phase.
Verify the data device supports O_DIRECT io flag in
the initialization phase. Online reencryption is not
safe unless we can read and write the data in direct
mode.
2024-08-27 14:00:41 +00:00
Milan Broz
4cdd022ba4 Fix detection of direct-io with suspended devices.
Currently, direct-io is disabled if underlying device is suspended.

This was an unfortunate change, as it is part of data corruption
problem in online reenryption.

Let's relax the test to assume that suspended device
(suspended =>  must be a device-mapper device) supports direct-io.

The read test is still needed as some network based devices
misbehaves if opened with direct-io flag.
2024-08-27 12:13:54 +02:00
Ondrej Kozina
e4d25d18eb Remove needless double statements. 2024-08-26 17:40:04 +00:00
Milan Broz
3d89faca18 Fix return code for ssize_t.
The ssize_t must be defined in the range [-1, SSIZE_MAX].

The return value is overwritten to -EINVAL later anyway,
return -1 here to be on the safe side.

Fixes: #900
2024-08-26 16:39:10 +00:00
Ondrej Kozina
a42bd088b5 Add Ubuntu 24.04 runner. 2024-08-22 14:06:21 +00:00
Ondrej Kozina
aeada055d1 Return suspended status also for unknow target types.
This patch allows dm_status_suspended() to report if device
is suspended or not also for unknown target types from
libcryptsetup perspective (e.g.: dm-cache).
2024-08-22 13:53:23 +02:00
Ondrej Kozina
53198bdea9 Do not handle device as suspended on error.
Consider device is suspended only if dm_status_suspended return code
is true.

This function returned -EEXIST for dm devices with target types unknown
to libcryptsetup (for example dm-cache) and turned off O_DIRECT flag
for devices unexpectedly.

Turned out ignoring direct-io was a problem after all :).

Fixes: 0f51b5bacb (Do not run sector read check on suspended device.)
2024-08-22 13:42:13 +02:00
Milan Broz
da09835b6c Document reencryption process status callbak return code. 2024-08-13 09:14:00 +02:00
Vojtech Trefny
42f4a68705 Initialize crypto in crypt_format_luks2_opal
Without this random isn't initialized and crypt_format_luks2_opal
is aborted.
2024-08-07 10:28:17 +00:00
Milan Broz
d5fb76a3b4 CI: Fix backend test after change in previous commit
The same CFLAGS change need to be applied to backend test.
2024-08-04 12:29:02 +02:00
Daniel Zatovic
7c992fa09e CI: update Ubuntu container image and set compiler version 2024-07-31 14:07:13 +02:00
Milan Broz
35bf791e85 Version 2.7.4. 2024-07-30 14:14:22 +02:00
Milan Broz
0d4027291a Add Release notes for stable 2.7.4 version. 2024-07-30 12:38:28 +02:00
Milan Broz
e0852d21dd tests: workaround valgrind SIGPIPE
Parsing --debug output with quiet flag can produce SIGPIPE output
if running with valgrind wrapper, just workaround it with another
grep as used elsewhere.
2024-07-30 10:34:41 +02:00
Milan Broz
3a7794795f Always set cipher_mode even in crypt_parse_name_and_mode.
Othewrwise some tools like valgrind can see unitialized string.
2024-07-29 16:00:01 +02:00
Frédéric Marchal
8be7b01ba8 po: update fr.po (from translationproject.org) 2024-07-24 12:29:27 +02:00
Antonio Ceballos
2bcdb5127a po: update es.po (from translationproject.org) 2024-07-24 12:29:26 +02:00
Ondrej Kozina
002f73b360 Add --shared option in veritysetup open action.
The option allows data device to be used in multiple
DM table mappings and exclusive access is not checked
anymore in-before device activation.

It also allows correct concurrent verity device activation.
With --shared option if multiple processes compete for same DM
verity name using same underlying data device we can now guarantee
one process succeeds and all other fails with -EEXIST.
2024-07-24 09:39:21 +00:00
Ondrej Kozina
ec9b97a731 Fix shared activation for dm-verity devices.
CRYPT_ACTIVATE_SHARED flag was silently ignored
while activating dm-verity devices by libcryptsetup.
This was a bug.

DM verity shared activation is generaly safe (single mapped data device
in multiple DM verity tables) since all verity devices are
read only.

The CRYPT_ACTIVATE_SHARED flag also fixes a race condition
when multiple processes compete for the same DM device name
(all dm-verity) while using same backing data device.

The exclusive open check in-before verity activation could
fail DM table load for a process that otherwise successfully acquired
DM device name (succeed in creating the DM device). This could (in some
cases) result in all processes competening for the DM verity device
to fail and none would activate the DM verity device.
2024-07-24 09:39:21 +00:00
Milan Broz
5873a65183 Do not use O_EXCL for allocated backing loop device.
Exclusive flag is defined only when creating a file,
for opening existing file it is undefinded operation.

Remove it from crypt_loop_attach as it was wrong since
the initial commit.
2024-07-24 08:28:32 +00:00
Milan Broz
d88a97b1a0 libdevmapper: properly detect device busy failure for dm table devices
Due to internal retry-overengineering in libdevmapper, some dm-ioctl
failures can disappear. One such case is when there is a device
creation race and DM device is created but reload fails.
this can heppen because some block device used in table mapping is
already claimed (it needs exclusive access for bdev_open in kernel).

The kernel ioctl properly returns EBUSY, this errno is lost
in libdevmapper (dm_task_get_errno returns 0).

While this should be solved by libdevampper, we need some reliable
way on older systems to properly report "busy" error instead of
overloaded "invalid" error.

With modified reproducer (see check_concurrent in very compat test),
this situation can happen quite often.

This patch modifies dm_create_device to return ENODEV only if
dm-ioctl also reports no device (ENXIO); following dm status reports ENODEV
and also some referenced device is no longer accesible through stat().

In all other cases we return EBUSY. Command line translates EBUSY and EEXIST
to the same return vaules, for API users it now returns EBUSY instead
of generic EINVAL.

IOW, if device activation returns EEXIST or EBUSY, device-mapper
cannot create the device because it already exits (EEXIST) or some referenced
device is claimed by other subystem (EBUSY) and mapping table cannot be created.
2024-07-23 11:15:06 +00:00
Milan Broz
3dc5d50918 fuzz: Fix build as upstream xz repo has disabled cloning 2024-07-23 08:41:53 +02:00
Milan Broz
021e5c31fd Check for bad device-mapper name early
There is no need to unlock keyslot if the provided name
has wrong format. Let's check for length and '/' in name early.

Note that other commands could accept path to the device
as libdevmapper translate it to the name (status /dev/mapper/xxx).
Add early check only to activate commands.

It still can fail later because of mangled characters.

Fixes: #893
2024-07-16 08:05:13 +00:00
Milan Broz
624b7087b0 ci: fix backends job logic 2024-07-15 14:44:31 +02:00
Yiyuan Zhong
cb7b7fd863 Add Mbed-TLS crypto backend
Mbed-TLS is a tiny TLS implementation designed for embedded environment which
can greatly reduce the disk space requirement compared to OpenSSL. While we
already have crypto_kernel for this purpose and Mbed-TLS lacking hash/cipher
support can cause reduced functionality, there're situations where AF_ALG is
not available but we're fine with limited scenarios like LUKS2 only.
2024-07-14 17:12:03 +08:00
Milan Broz
4daf8ef0dc tests: skip reencryption test if non-AES ciphers fails in luksFormat 2024-07-12 21:08:05 +02:00
Milan Broz
2d041439bc tests: Print N/A visible in mode_test (LUKS2 userspace crypto) 2024-07-12 21:07:59 +02:00
Milan Broz
7fa19da140 tests: use crypto check tool in tests 2024-07-12 21:07:15 +02:00
Milan Broz
a9617c7c4a tests: Add crypto check program for crypto backend.
We use benchmark, but backend can implement different
set of ciphers than kernel crypto API.
2024-07-12 21:04:37 +02:00
Milan Broz
ce38d82025 Fix crypt_cipher_check_kernel to work with length-preserving modes too.
The check is currently used only with AEAD, but whould work also
with common block ciphers and modes.
2024-07-12 18:02:37 +00:00
Milan Broz
5e04a82e53 Fix wiping of hash struct in nss and nettle backend. 2024-07-12 16:38:56 +00:00
Milan Broz
3839e2bf98 Fix scan-build warnings in gcrypt backend 2024-07-12 16:38:56 +00:00
Milan Broz
8accd612a3 CI: Add fanalyzer and scan-build test for crypto backends 2024-07-12 16:38:56 +00:00
Frank Rehberger
fddec0f2d7 doc: build dependency update 2024-07-12 16:05:52 +00:00
Milan Broz
7a816abf82 TCRYPT: fix system encryption test if kernel does not support EFI partition
If kernel is mising CONFIG_EFI_PARTITION, the required partitons
are missing too.
Just skip the test if loop block device is not available.
2024-07-12 11:58:06 +00:00
Milan Broz
94f37efb57 Remove obsolete AC_PROG_GCC_TRADITIONAL macro.
As it causes warnings and does nothing for many years already.
2024-07-10 10:32:27 +02:00
Milan Broz
5fb6d711c1 Fix clang possible rh NULL dereference warning. 2024-07-10 09:48:10 +02:00
Milan Broz
b0be186f9e Fix leaked fd gcc analyzer warning.
These are actually false positives (fd 0 is always open as stdin),
but code is even more readable with this fix.
2024-07-10 09:48:08 +02:00
Milan Broz
b1cc660df3 Do not use assert() that depends on external data.
Just fail function. Also fixed gcc analyzer warning (leaked fd).
2024-07-10 09:48:05 +02:00
Milan Broz
35a9f08062 Fix warning about unitialized passwordLen.
THis is false positive, but fix is trivial.
2024-07-10 09:48:02 +02:00
Milan Broz
9c47812904 Use buffer functions and fix potential fd leak.
Use read/write buffer functions to avoid partial operation.

This also fixed leaked fd warning. Also fix error path
for context failure - if initialize_context() fails,
rc->log_fd is closed in context destructor, no need to close
it in open_log/parse_log.

Another fixed bug is in parse_log, where immediatelly after
creation we have to seek to the beginning of the file first.
2024-07-10 09:47:59 +02:00
Milan Broz
8b21b4b2ee Fix "allocated buffer size is not a multiple of the pointee's size" warning
No need to play games with void pointers, two separate functions are
much more readable.
2024-07-10 09:47:56 +02:00
Milan Broz
bf088de00f Update CI shared runner compiler versions. 2024-07-10 09:43:33 +02:00
Milan Broz
1423c6eac2 TCRYPT: make algorithms definitions static 2024-07-02 13:04:30 +00:00
Milan Broz
e5b430cdc1 TCRYPT: use bool instead of one bit integer 2024-07-02 13:04:30 +00:00
Milan Broz
a5e409c186 TCRYPT: update system encryption images and test. 2024-07-02 13:04:30 +00:00
Milan Broz
0cc686af59 TCRYPT: Clear mapping of system encrypted partitions.
TrueCrypt/VeraCrypt supports full system encryption (only a partition
table is not encrypted) or system partition encryption
(only a system partition is encrypted).
The metadata header then contains the offset and size of the encrypted area.
Cryptsetup needs to know the specific partition offset to calculate encryption parameters.
To properly map a partition, you must specify a real partition device so cryptsetup can calculate this offset.

As user can specify various combination, we need to determine the proper
IV and data offsets.

The logic for CRYPT_TCRYPT_SYSTEM_HEADER flag should be (in this order):
- if data device is a real partition, calculate offset from it.
- if --header is a real partition , calculate offset from it.
- if device is a real disk, try to search for partition using decrypted offset and size
(works only for system partition-only encryption).
- if data and metadata (header) device is the same, map whole encrypted area
(this is the ost confusing for user)
- if data and metadata (header) divice differs, expect data image contains
only partition (setting offset to 0, but using IV offset from header).

There are still situation that can end with wrong mapping, but user now has the option
to setup it properly.

Also this patch fixes use of stored encryption size in header,
so we do not map larger area.

Fixes:#889
2024-07-02 13:04:30 +00:00
Milan Broz
14fd0b5fc1 TCRYPT: Print all information from decrypted header.
Print also volume sizes (if present) and flags.
This inforamtion is useful mainly for setting systemd encryption
where size determines encrypted region.
2024-07-02 13:04:30 +00:00
Ondrej Kozina
9651d1f376 Fix a typo in valgrind test parameter. 2024-07-02 13:03:01 +00:00
Milan Broz
98b4243432 Add support for high-priority dm-crypt flag.
This patch add new --perf-high_priority cryptsetup option
for flga added in Linux kernel 6.10, dm-crypt target version 1.26.
2024-06-18 11:00:38 +00:00
Milan Broz
e32ea56b59 Update README for version 2.7.3. 2024-06-17 14:39:42 +02:00
Milan Broz
afee503e34 Add CONTRIBUTING.md file. 2024-06-17 11:52:56 +00:00
Milan Broz
7019f42ff1 Add release notes for 2.7.3. 2024-06-12 17:20:56 +02:00
Yuri Chornoivan
647b24f706 po: update uk.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Remus-Gabriel Chelu
0cff233af1 po: update ro.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Jakub Bogusz
8cb3b32070 po: update pl.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Hiroshi Takekawa
8109b10ea4 po: update ja.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Roland Illig
d9660cf221 po: update de.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Petr Pisar
29f1f71c67 po: update cs.po (from translationproject.org) 2024-06-11 12:31:53 +02:00
Daniel Zatovic
1d9a362113 CI: don't run parallel OPAL jobs 2024-06-07 13:56:46 +02:00
Daniel Zatovic
e92763a61c CI: run fips-mode-setup --check as a root 2024-06-07 13:52:50 +02:00
Daniel Zatovic
9bdb7fee34 CI: add RHEL10 runner 2024-06-07 12:21:32 +02:00
Milan Broz
51c672ea62 tests: Fix test numbers in compat-test2 again 2024-06-06 17:24:51 +00:00
Milan Broz
b19170e8fe Fix warning for printf argument. 2024-06-06 13:09:23 +02:00
Ondrej Kozina
97c5f47c94 Add opal test for detached header erase command. 2024-06-05 11:02:38 +02:00
Ondrej Kozina
494c510c34 Simplify LUKS2_wipe_header_areas.
For LUKS2 headers with non zero data offset LUKS2_wipe_header_areas
will always erase the smallest from following:

- metadata device size
- data offset value
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
binary keyslot areas) even with detached header.

For zero value data offset (LUKS2 header can not be restored back to
data device), we erase up to smallest from the following values:

- metadata device size
- maximal LUKS2 metadata size (twice 2 MiBs json area including 128 MiB for
2024-06-05 10:49:08 +02:00
Milan Broz
2a13ef5dd8 Fix interactive query retry if LUKS2 unbound keyslot is present
If an unbound keyslot is present (e.g.. slot 0 usual slot, slot 1 unbound),
the query loop could return ENOENT (keyslot not valid for segment) and this
will stop epxected retry for slot quewry (--tries option).

If any previous slot rerutned EPERM (no valid passphrase), prefer
this return code.
2024-06-03 16:40:55 +00:00
Milan Broz
4708884d8c Allow "capi:" cipher format for benchmark command.
Note, currently AEAD modes are not supported.
2024-06-03 16:40:01 +00:00
Milan Broz
8f4a149ed3 Fix bad parsing of capi:xts(aes)-plain
Corrent logic confuses it with aes-plain (capi:xts(aes)-plain
does not work in luksFormat).
For CAPI format we need to skip this test.
2024-06-03 16:40:01 +00:00
Milan Broz
d590c74a0e Support aes-hctr2 mode.
The HCTR2 encryption was added to Linux kernel for fscrypt,
but as it is length-preserving mode (with sector tweak) it
can be easily used for disk encryption too.

As it need larger IV of size 32 bytes, we need to add exception
for aes-hctr2[-plain64] to be accepted in cryptsetup commands.

Fixes: #883
2024-06-03 16:39:06 +00:00
Milan Broz
1a6a611dff Reorganize license files.
This patch adds README.licensing describing used licenses.
The license text files are now in dosc/licenses.

The main COPYING document in root is the default license,
this also forces GitHub to properly identify default license.
2024-06-03 16:38:15 +00:00
Milan Broz
661f57def4 Use SPDX license identifiers.
This patch switches code to SPDX one-line license identifiers according to
https://spdx.dev/learn/handling-license-info/
and replacing long license text headers.

I used C++ format on the first line in style
// SPDX-License-Identifier: <id>
except exported libcryptsetup.h, when only C comments are used.

The only additional changes are:
- switch backend utf8.c from LGPL2+ to LGPL2.1+ (as in systemd)
- add some additional formatting lines.
2024-06-03 16:38:15 +00:00
Milan Broz
8448448aa2 Opal: Check for bogus logical size also in activation
For existing devices we only print warning, but the device is
probably completely misconfigured.
2024-06-03 11:14:27 +00:00
Milan Broz
329fa3c54e Opal: Require locking range attributes in range check function.
The check will be required mandatory in the next patch.
2024-06-03 11:14:27 +00:00
Milan Broz
1eb3df45dd Opal: Do not allow format if device and Opal logical block size disagrees
Some Opal devices contain a bug that device reports different logical
size for block device and Opal SED layer.

This can happen for NVMe after reformatting with different LBAF (512/4096).

We will not support such configuration as Opal then calculates sizes
differently for locking range (that could lead to data corruption or
a partially unecrypted area).
2024-06-03 11:14:27 +00:00
Daniel Zatovic
af99b9b9d9 CI: Add Samsung 980 PRO OPAL test on trantor machine 2024-05-30 16:30:01 +02:00
Milan Broz
6859993ea7 Fix string.h, strings.h and stdio.h include in crypto backend.
String.h and stdbool.h are already included in main backend header,
no need to include them again.

Stdio.h is missing for OpenSSL and NSS backed (for sprintf).

Strings.h is missing for cipher_generic, gcrypt and OpoenSSL (strcasecmp).

Fixes: #885
2024-05-23 06:29:47 +00:00
Milan Broz
bd8cfe1efb Mention need for possible PSID reset for some OPAL drives in man page.
Fixes: #879
2024-05-23 06:29:20 +00:00
Milan Broz
c2c1d59ff2 bitlk: Ignore TPM key metadata
Using TPM entry on Linux is impossible, as we will never have
the same PCRs, so we can quietly ignore these entries without
warnings.
2024-05-21 11:27:14 +02:00
Milan Broz
dca99f7dc1 bitlk: Ignore unknown VMK entry 24
This VMK value looks like a password hint (masked email?)
we can safely ignore it.

Fixes: #886
2024-05-21 11:25:06 +02:00
Milan Broz
9b822800b3 tests: Use only PBKDF2 in api-test-2 images (FIPS with OpenSSL 3.2+)
For compatimage2 also add keyslot 1 that uses Argon2id PBKDF2 to keep
check for compatibility on non-fips system.
2024-05-13 10:22:02 +00:00
Milan Broz
0d6d4e4255 tests: Use only PBKDF2 in luks2_keyslot_unassigned.img (FIPS with OpenSSL 3.2+) 2024-05-13 10:22:02 +00:00
Milan Broz
a8e5bb0ebe tests: Fix redundant test number in compat-test2 2024-05-13 10:22:02 +00:00
Milan Broz
aa69fc342a tests: Skip zoned test if kernel does not support it
Zoned block device support can be disabled (as in RHEL8),
skip particular test if scsi_Debug does not create device.
(Modprobe does not return any error code, just kernel message
as parameter is actually supported, but block layer lack
support for zoned device.)
2024-05-13 10:22:02 +00:00
Milan Broz
d0678c208d tests: Remove leftover debug parameter. 2024-05-13 10:22:02 +00:00
Milan Broz
c21ccd89e3 Add tests for --key-description and --new-key-description. 2024-05-10 10:56:20 +02:00
Milan Broz
0f20e14c67 Rename TOKEN to KEY_DESC to be used in different context later. 2024-05-10 10:55:03 +02:00
Milan Broz
1e58ad570e Add --key-description and --new-key-description for luksAddKey command. 2024-05-10 10:54:59 +02:00
Milan Broz
73975857a3 Add --key-description for luksResume command. 2024-05-10 10:54:55 +02:00
Milan Broz
3c79fd6c4b Add --key-description for open command. 2024-05-10 10:54:50 +02:00
Milan Broz
82118bdd5f Add --key-description for resize command. 2024-05-10 10:54:47 +02:00
Milan Broz
3e01e151f8 Add --key-description for luksFormat command. 2024-05-10 10:54:43 +02:00
Milan Broz
e085ae461f Add --key-description for luksDump command. 2024-05-10 10:54:37 +02:00
Milan Broz
4a40d79322 Fix --key-description actions and define --new-key-description. 2024-05-10 10:54:32 +02:00
Daniel Zatovic
ea32731e5b CI: make OPAL tests run at the end
Once OPAL tests run, the whole pipeline gets marked as uninterruptible
(because of the uninterruptible OPAL job). Therefore a duplicate
pipeline gets started on e.g. MR change. Move OPAL jobs to test-opal
stage which runs at the end.
2024-05-07 14:32:41 +00:00
Ondrej Kozina
42a073c0cb Use crypt_wipe to zero rest of data device. 2024-05-07 12:30:05 +00:00
Ondrej Kozina
738b9ee645 Use proper write_buffer in LUKS1 reencryption code.
The raw write() syscal may write less bytes than requested. We
have write_buffer in utils_io.c that handles it properly.
2024-05-07 12:30:05 +00:00
Ondrej Kozina
94ef8a7610 Use proper read_buffer function from utils.
Legacy LUKS1 reencryption used custom read buffer
function. Use implementation from utils_io instead.
2024-05-07 12:30:05 +00:00
Milan Broz
410a586284 Detect unsupported zoned devices for LUKS header device.
Zoned device cannot be written with direct-io
and cannot be used for LUKS header logic without
significant changes. Do not allow to use them for LUKS header
but allow it for data device, as dm-crypt supports it.

Fixes: #877
2024-05-03 14:03:47 +00:00
Milan Broz
40e5c7d095 Use crypt_safe_memcpy for operations with key. 2024-05-03 11:52:09 +00:00
Milan Broz
4322ddbcb3 Add crypt_safe_memcpy to libcryptsetup.h. 2024-05-03 11:52:09 +00:00
Milan Broz
7b3a341809 Use crypt_backend_memcpy in crypt backend for sensitive data. 2024-05-03 11:52:09 +00:00
Milan Broz
40e56e969c Use backend memory utils in safe memory functions. 2024-05-03 11:52:09 +00:00
Milan Broz
c5d4b845df Use zero_call_used_regs and noinline for backend memory utils and introduce crypt_backend_memcpy. 2024-05-03 11:52:09 +00:00
Milan Broz
aae5cba2b9 Add memutils.c for backend and move existing mem helpers there.
Also remove inline definitions.
2024-05-03 11:52:09 +00:00
Ondrej Kozina
bede116926 Fix various coverity issues.
Mostly INTEGER_OVERFLOW (CWE-190).
2024-05-03 11:58:35 +02:00
Milan Broz
33e26be58b Avoid divide by zero in uint64_mult_overflow.
This function is used with block size, where 0 does
not make sense, so failing the check is the simple way
to avoid sividion by zero.

In reality, this should never happen, but it was seen
in (unreproducible) fuzzing input.
2024-04-18 08:39:52 +02:00
Milan Broz
842d9e6e6e Update README for version 2.7.2. 2024-04-09 12:12:56 +02:00
Milan Broz
bc62204a41 Add warning about OPAL admin PIN to man page and release notes. 2024-04-09 10:46:13 +02:00
Milan Broz
4bd64eed82 Add 2.7.2 release notes. 2024-04-04 18:34:49 +00:00
Milan Broz
4b0ae54379 tests: print OPAL device parameters in test envirenment if specified 2024-04-04 18:34:19 +00:00
Daniel Zatovic
69920581a3 CI: add WD PC SN740 OPAL drive job 2024-04-04 14:49:27 +02:00
Antonio Ceballos
4bf6db5ce8 po: update es.po (from translationproject.org) 2024-04-04 14:08:50 +02:00
Ondrej Kozina
a89485924c Compile --disable-hw-opal variant. 2024-04-03 16:26:02 +00:00
Ondrej Kozina
0cbeb35a93 Do not check passphrase quality in-before erase.
The passphrase (Admin PIN) already exists and there's no
reason to check quiality of it.
2024-04-03 11:51:35 +00:00
Milan Broz
e17ec37341 Relicense older script to LGPL fro GPL2.0 only.
(As I am sole author here.)
2024-04-03 11:49:33 +00:00
Milan Broz
1ba758cde1 FAQ: update license version to CC BY-SA 4.0.
With email approval from Arno Wagner dated March 29, 2024:

 From: Arno Wagner
 To: Milan Broz
 Subject: Re: cryuptsetup FAQ license

  Hi Milan,

  fine for me. You can change it directly.

  Arno

  On Wed, Mar 27, 2024 at 13:38:36 CET, Milan Broz wrote:
  > Hi Arno,
  >
  > the FAQ in cryptsetup is licensed under CC-BY-SA-3.0 that is no longer a recent version - https://creativecommons.org/licenses/by-sa/3.0/
  >
  > I use CC-BY-SA-4.0 (https://creativecommons.org/licenses/by-sa/4.0/deed.en) for LUKS2 docs and think it is the best option for docs.
  >
  > Do you agree with updating the license to CC-BY-SA-4.0 for the FAQ.md file? (I, as coauthor, obviously agree :-)
  >
  > Thanks,
  > Milan
2024-04-03 11:49:33 +00:00
Ondrej Kozina
87bf39f71e Fix invalid assert for hw-opal data segment keys.
hw-opal segment does not receive volume key for data
encryption, unlike crypt segment or hw-opal-crypt segment.
It gets key encryption key that is passed to device fw which
later unlocks the locking range key sealed in the device.

The assert may be skipped while volume key is not set.

Fixes: #875.
2024-04-03 11:48:56 +00:00
Ondrej Kozina
1ae70b8c16 Fix data segment length compensation on misaligned partitions.
While properly calculated data segment needed compensation due to
misaligned partition (locking range had to be truncated),
we passed wrong value (original partition size) to LUKS2 metadata.

It has to use calculated locking range length in bytes.

Fixes: #873.
2024-04-02 14:21:01 +02:00
Daniel Zatovic
3d82771418 CI: make OPAL jobs uninterruptible 2024-03-26 16:09:22 +01:00
Ondrej Kozina
3e29dbe6f2 Add --hw-opal-factory-reset switch in erase options explicitly. 2024-03-26 12:01:27 +00:00
Ondrej Kozina
a462dbeb4e Check HW OPAL range parameters in proper units.
The opal_range_check_attributes_fd function expected both
offset and length parameters of a LR to be passed in sectors (512B).
During format we passed it wrongly in OPAL blocks which caused
bogus check provided OPAL block size was not 512B.

Fixes: #871.
2024-03-26 11:55:31 +01:00
Daniel Zatovic
8655093cb7 tests: run systemd tests using meson only when requested 2024-03-21 16:42:06 +01:00
Milan Broz
25b543d371 Update Readme for 2.7.1. 2024-03-07 15:53:23 +01:00
Milan Broz
6b3f9cd4bc tests: Fix Makefile * Meson to include all fs images. 2024-03-07 15:32:17 +01:00
Milan Broz
608e42c574 Update LUKS2 spec. 2024-03-07 15:26:54 +01:00
Milan Broz
143a76a5fa Add 2.7.1 release notes. 2024-03-07 15:23:15 +01:00
Milan Broz
9906bc40e1 test: Fix tests on RHEL7 clones (no keyring in dm-crypt). 2024-03-07 13:18:05 +00:00
Milan Broz
dc669a14d3 Add xfs V5 image to tests.
XFS V4 can be disabled in kernel, add image V5.

Minimal 300M xfs size avoided by using QA variables magic in format:
export TEST_DIR=1 TEST_DEV=1 QA_CHECK_FS=1 ; mkfs -t xfs ...
2024-03-07 11:30:21 +00:00
Ondrej Kozina
8819194281 tests: fix compat-test-opal bug for empty LUKS2 passphrase.
The bug was hidden due to previously contradicting condition.
2024-03-06 14:23:02 +01:00
Ondrej Kozina
5d6fbf7b53 tests: move luks1 decryption resume test.
It cannot be run in fips mode due to empty passphrase
is no longer allowed.
2024-03-06 13:10:34 +01:00
Ondrej Kozina
4347a01cce tests: fix fips mode detection contradiction in various tests. 2024-03-06 13:08:50 +01:00
Yuri Chornoivan
6525b40a7b po: update uk.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Remus-Gabriel Chelu
31573693a0 po: update ro.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Jakub Bogusz
accc9c0ee9 po: update pl.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Hiroshi Takekawa
5ec40f98ac po: update ja.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Frédéric Marchal
5eb9c8b27a po: update fr.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Roland Illig
eccd46206d po: update de.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Petr Pisar
8d6fc937da po: update cs.po (from translationproject.org) 2024-03-06 09:51:20 +01:00
Milan Broz
41755b71b6 Set devel version. 2024-03-06 09:51:10 +01:00
Ondrej Kozina
201a4b7d8b Add regression test for resuming LUKS1 decryption. 2024-03-05 14:58:02 +01:00
Ondrej Kozina
33b9a51fa8 Fix regression in LUKS1 decryption.
With removal of cryptsetup-reencrypt there was
a bug introduced that broke resuming interrupted
LUKS1 decryption operation. LUKS2 code was not
affected.
2024-03-05 14:58:02 +01:00
Milan Broz
9d38ea70e2 Require --debug log in bug report issue template. 2024-02-29 17:07:41 +00:00
Milan Broz
2cd0be9501 Allow all stable branches in GitHub actions. 2024-02-29 17:07:41 +00:00
Ondrej Kozina
5a0208cd06 Allow --link-vk-to-keyring with --test-passphrase option.
To make it possible to upload volume key in user specified kernel
keyring without need to (re)activate the device.
2024-02-29 16:25:17 +01:00
Ondrej Kozina
db635c428b Fix abort triggered by initializing decryption via --active-name.
The invalid test unfortunately hid an error in processing
of --active-name command line option.
2024-02-28 17:11:46 +01:00
Milan Broz
678b28989b Fix indentation in integritysetup man page and crypt description. 2024-02-22 20:58:35 +00:00
Milan Broz
82f37d7a10 Sort options in man pages alphabetically. 2024-02-22 20:58:35 +00:00
Milan Broz
cbf818a660 Fix JSON exampe in progress-frequency option. 2024-02-22 20:58:35 +00:00
Milan Broz
3ff8d55a8b Fix veritysetup man page typo. 2024-02-22 20:58:35 +00:00
Sergei Ilinykh
349572e69e Fix compilation with libargon2 argon when internal disabled
This fixes a regression introduced somewhere on the way to 2.7.0.
A specific set of options led to complete lack of Argon2
regardless of --enable-libargon2 option.
2024-02-22 20:43:35 +03:00
Daniel Zatovic
0725efefa7 CI: fix improper distro specification for 32-bit Debian.
The `variables` section is repeated for 32-bit Debian job. Therefore the
`DISTRO` environment variable is ignored and 64-bit distro name is
inherited from the `.debian-prep` job.
2024-02-22 16:50:46 +01:00
Daniel Zatovic
af35c93332 CI: don't store kernel log, only check for coredumps.
The kernel log is uploaded automatically by the custom executor, no need
to upload it from inside the VM (and /mnt/artifacts is not mounted in
the new CI scripts).
2024-02-22 11:41:37 +00:00
Daniel Zatovic
193f8ff595 CI: increase disk size for csmock job. 2024-02-22 11:41:37 +00:00
Daniel Zatovic
f91524dc63 CI: add OPAL jobs. 2024-02-22 11:41:37 +00:00
Daniel Zatovic
f8e79cdbe6 CI: update jobs for new CI infrastrucure 2024-02-22 11:41:37 +00:00
Ondrej Kozina
35cd898c63 Fix crypto vectors test in meson.
Otherwise it gets skipped in meson everytime.
2024-02-21 15:56:14 +01:00
Tobias Rosenkranz
91c1d2202a Skip test if keyctl is missing 2024-02-18 14:46:37 +01:00
Milan Broz
a6d9dc0a16 Do not require argon2.h if implemented natively in crypto library. 2024-02-13 12:38:00 +01:00
Ondrej Kozina
f681194b57 Fix mistake in crypt_set_keyring_to_link documentation.
The keyring_to_link_vk parameter must be prefixed by
either "%:" or "%keyring:" substrings provided caller
opted for text description of the target keyring.
2024-02-13 11:40:13 +01:00
Ondrej Kozina
fdac0d7ee2 cryptsetup.spec: drop libargon2 in favour of openssl implementation. 2024-02-12 10:43:47 +00:00
Milan Broz
b417154e71 Fix configure Argon2 OpenSSL detection to not compile internal Argon2.
Code is not called anyway, but should be completely disabled.
Note: there is intentionally no way to disable OpenSSL Argon2 if present.
2024-02-09 12:51:34 +01:00
Milan Broz
4dde8f078f Version 2.7.0. 2024-01-24 10:47:32 +01:00
Milan Broz
f11af15cd0 Fix local variable name that hides global one.
Found by CodeQL.
2024-01-23 20:22:11 +01:00
Milan Broz
bd0ef58b3a Update copyright notice to include 2024 year. 2024-01-23 16:10:44 +01:00
Ondrej Kozina
cbc7253400 Unify error code for missing key description.
Use -ESRCH for similar error code as with
crypt_activate_by_keyslot_context. Here it's not
confliciting with previous use for the very code but
let's make it easier and use same code for similar case.
2024-01-23 12:08:43 +01:00
Ondrej Kozina
35ec935cc2 Update API documentation for crypt_set_keyring_to_link.
The section about placeholder API no longer applies.
2024-01-23 12:03:39 +01:00
Ondrej Kozina
7eca077490 Replace code for missing key error in API.
While trying to activate device in LUKS2 reencryption
we originally used -ENOKEY error code for case
where one or more volume keys could not be unlocked or
were not provided direclty by (CRYPT_KC_TYPE_KEY or
CRYPT_KC_TYPE_VK_KEYRING) keyslot contexts.

We missed the fact the error code was already previously
used for signaling case when dm subsystem could not load
device table due to key in kernel keyring could not be
read from kernel. It's propagated by libdevmapper.

For it we replace -ENOKEY with -ESRCH for signaling the missing
keyslot context or volume key for devices in LUKS2 reencryption.
2024-01-23 11:55:12 +01:00
Ondrej Kozina
8dd3266599 tests: use per-test keyring for caching VKs. 2024-01-22 17:28:19 +01:00
Ondrej Kozina
135ed491d1 Do not drop keys from keyring on successfull reencryption recovery.
The key might be needed in activation of ordinary LUKS2 device
provided the recovery took place in before device activation
and actually finished LUKS2 device reencryption.

Fixes: #863.
2024-01-22 12:13:40 +01:00
Milan Broz
de1cd97fde Fix typo in verity test. 2024-01-20 19:01:25 +01:00
Milan Broz
f040f74f46 Fix autoconf valgrind test.
All environment variables are predefined in make run,
use it in $(VAR) from, as shell variables processing does not work here.
2024-01-20 10:56:22 +01:00
Daniel Zatovic
136ba21c65 Add tests for device activation using multiple VKs. 2024-01-19 16:26:30 +00:00
Daniel Zatovic
7fb98caa79 Allow activating multi key devices using VKs in keyring.
We already support activation of a device using a volume key in keyring.
However, in case of multi-key devices (i.e. device with reencryption
running) we need to supply two volume keys.
2024-01-19 16:26:30 +00:00
Daniel Zatovic
4321992561 Add tests for storing VK in keyring during resume. 2024-01-19 16:26:30 +00:00
Daniel Zatovic
f354a0b038 Add tests for storing multiple VKs in a custom keyring. 2024-01-19 16:26:30 +00:00
Daniel Zatovic
5814b39cdd Allow linking multiple VKs (also in reencryption).
If the device is in reencryption, it has two active volume keys. Linking
the VK to keyring is not supported for such devices, because the API
only counts with one key. This commit modifies the API
crypt_set_keyring_to_link to allow passing multiple keyring key names.
2024-01-19 16:26:30 +00:00
Milan Broz
e0eb4dad95 Fix tests to support --disable-keyring option.
Also remove unused function in test.
2024-01-19 13:40:25 +00:00
Antonio Ceballos
0ba3e3077c po: update es.po (from translationproject.org) 2024-01-19 12:59:50 +01:00
Petr Pisar
dfe241dc24 po: update cs.po (from translationproject.org) 2024-01-19 12:59:50 +01:00
Milan Broz
001f228059 LUKS2: add more sanity assignments to header code.
Ensure we do not return partial binary header and also
explicitly set header size to zero to silnce stupid
cppcheck warnings.
2024-01-17 21:25:30 +01:00
Milan Broz
89ee1ed656 LUKS2: add sanity check for hdr_size.
Simplify code a little bit for static analysis and also
ensure that even second LUKS2 header with wrong hdr_size is
always detected.
2024-01-17 21:25:27 +01:00
Milan Broz
cac3184da3 Add a few tainted data info for coverity to avoid warnings.
If sysconf is lying, then anything can happen.
But check for overflow anyway.

Device/partition offset overflow for IV can only cause
bad decryption (expected).
2024-01-17 21:25:00 +01:00
Milan Broz
b048a417b7 Silence false positive cppcheck warning. 2024-01-17 12:20:00 +01:00
Milan Broz
cfdb1b93af Fix signed (error) return from read in loop utils. 2024-01-17 12:19:55 +01:00
Milan Broz
d15447814a Use gcc 13 for GitHub actions. 2024-01-17 12:19:48 +01:00
Ondrej Kozina
912d410458 Fix some grammar issues suggested by auto-correction tools. 2024-01-16 09:55:06 +00:00
Ondrej Kozina
d730f45201 Update kernel keyring usage documentation. 2024-01-16 09:55:06 +00:00
Ondrej Kozina
605acab31a Fix some grammar issues suggested by auto-correction tools. 2024-01-15 12:30:32 +01:00
Ondrej Kozina
ebca40640d docs: Describe additional LUKS2 locks. 2024-01-15 12:22:43 +01:00
Ondrej Kozina
a50a39a192 tests: add in-place LUKS2 encryption api test.
Simple test for plaintext data placed at specified offset
(non zero offset relative to head of data device).
2024-01-05 14:22:07 +01:00
Ondrej Kozina
adc83f6dca tests: add helper for creating arbitrary linear mapping. 2024-01-05 14:22:07 +01:00
Ondrej Kozina
bd0768a42a Respect CRYPT_ACTIVATE_SHARED in reencryption. 2024-01-05 14:22:07 +01:00
Yuri Chornoivan
543d220bd4 po: update uk.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Remus-Gabriel Chelu
44490e3ee1 po: update ro.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Jakub Bogusz
4b2015eafd po: update pl.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Hiroshi Takekawa
65005b4cd3 po: update ja.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Frédéric Marchal
fae0d2c1f2 po: update fr.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Roland Illig
2c16a80113 po: update de.po (from translationproject.org) 2024-01-05 09:48:54 +01:00
Milan Broz
44c6a76b09 Add note for luksSuspend to man page.
It should not be expected that suspend operation wipes
possible plaintext data from memory.

Related: #855
2023-12-22 12:17:55 +01:00
Milan Broz
37a2750e4f Update cryptsetup.spec. 2023-12-20 18:25:51 +01:00
Krassy Boykinov
b5006a5404 man: Update authenticated encryption trim description and add references
790666ff (Add support for allow_discrads for dm-integrity., 2020-04-09)
added TRIM support for standalone dm-integrity volumes.
This change is now reflected in the cryptsetup(8) man page.
2023-12-20 14:56:08 +00:00
Milan Broz
3323690cbc Version 2.7.0-rc1. 2023-12-20 15:21:01 +01:00
Milan Broz
1a50de508c Fix doxygen tags for API docs. 2023-12-20 15:12:30 +01:00
Milan Broz
b47f423907 Update release notes for 2.7.0-rc1 and LUKS2 doc. 2023-12-20 15:12:24 +01:00
Daniel Zatovic
d1b32a3b64 Add keyring linking API placeholders for multi-key scenarios. 2023-12-20 14:02:07 +01:00
Milan Broz
f87f6226aa opal: Fix benign gcc warning for possible uninitialized value. 2023-12-19 13:40:29 +01:00
Milan Broz
cd576666fc opal: Do not verify passphrase by default on luksErase.
Verify passphrase should be default only when creatng
a new passphrase, here it will fail if the passphrase
is wrong.
2023-12-19 12:35:50 +01:00
Ondrej Kozina
6b1f13fd0f opal: add comments to all lockless opal calls. 2023-12-18 17:26:47 +00:00
Milan Broz
7db221e47e Report Argon2 crypto backend version in debug output
For Argon2 native code (gcrypt, OpenSSL) a flag in debug output is printed.

If libargon is used, then [cryptsetup libargon2] is printed
(embedded code) or [external libargon2] for dynamic external library.

 # Crypto backend (OpenSSL 3.0.11 19 Sep 2023 [default][legacy] [external libargon2])
or
 # Crypto backend (OpenSSL 3.0.11 19 Sep 2023 [default][legacy] [cryptsetup libargon2])

Fixes: #851
2023-12-17 11:53:38 +00:00
Milan Broz
e5511b1920 Use uppercase OPAL in messages. 2023-12-17 12:52:39 +01:00
Ondrej Kozina
0ca1e680db opal: add exclusive lock to avoid race.
Activating LUKS2 device with OPAL support is multistep process.

1) read LR state
2) unlock LR
3) activate dm device
4) in case step 3) failed lock the device
   if in step 1) the device was locked.

Otherwise, in case parallel activation happened on one device
the process that failed to map dm device (device already active)
could relock the LR afterwards and effectively break already active
device.

To avoid that we do steps 1) through 4) protected by exclusive
opal lock unique per data block device configured for use with
LUKS2 OPAL support.
2023-12-13 20:59:14 +00:00
Ondrej Kozina
2e978c8776 opal: do not always re-lock range on failed activation.
If activation fails due to already active dm mapping
we must not automatically re-lock the OPAL range since
it would break the original active device.
2023-12-13 20:59:14 +00:00
Ondrej Kozina
31027b9240 test: check if device remains usable after failed attempt to double activation. 2023-12-13 20:59:14 +00:00
Ondrej Kozina
1d0680ce95 Drop unused crypt_read_lock helper. 2023-12-13 20:58:13 +00:00
Ondrej Kozina
997ef242a2 opal: no need to export internal opal_enabled function. 2023-12-13 15:16:02 +01:00
Ondrej Kozina
b869822c8b opal: erase key cached in kernel when LR gets locked.
It affects only HW OPAL locking range KEK.

After unlocking opal locking range we cache the key in kernel
so that we do not have to pass the key again for locking the
range later (the OPAL std requires key for lock command).

Unfortunately the key remains cached in kernel even after we
lock the range on purpose during crypt_deactivate* or crypt_suspend.

This had 2 side effects:

1) key remained in system memory even though the LUKS device was
   inactive (and all keys should be erased from memory).

2) when system gets suspended the locking range got automatically
   unlocked later after system resume because the key caching is used
   primarly to automatically unlock locking ranges that got locked
   after system suspend (due to power cut off on storage device).

Since kernel does not directly support dropping cached keys we achieve
that by overwritting the original key structure with empty one.
2023-12-04 19:02:11 +00:00
Boyuan Yang
2d080580bd po: update zh_CN.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Yuri Chornoivan
e3c65d9a34 po: update uk.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Remus-Gabriel Chelu
818e35e71c po: update ro.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Jakub Bogusz
ba751970af po: update pl.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Hiroshi Takekawa
13fcbe139d po: update ja.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Frédéric Marchal
5ea325afcc po: update fr.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Roland Illig
cf523b95be po: update de.po (from translationproject.org) 2023-12-04 20:01:31 +01:00
Ondrej Kozina
0f642a8397 Add missing vectors tests in valgrind setup. 2023-12-04 09:33:21 +00:00
Ondrej Kozina
b653567e3e Simplify meson tests.
Valgrind tests is now run with:

meson test -C <build_dir> --setup=valgrind
2023-12-04 09:33:21 +00:00
Milan Broz
85d23dde79 Revert "tests: Temporarily disable veritysetup tasklet option test."
This reverts commit 0e44494aba.

Kernel fix is in mainline and on the way to stable kernels.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/md?id=2a695062a5a42aead8c539a344168d4806b3fda2
2023-11-30 14:53:42 +00:00
Milan Broz
5e7bd7a36b fuzz: Try to limit image size in crypt2_load_proto_plain_json_fuzz
It seems that we see a lot of out of space in fuzzer run,
so try to avoid writing excessive big images here.
2023-11-30 15:01:04 +01:00
392 changed files with 43520 additions and 25439 deletions

View File

@@ -5,9 +5,9 @@ set -ex
PACKAGES=(
git make autoconf automake autopoint pkg-config libtool libtool-bin
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
asciidoctor meson ninja-build
libjson-c-dev libssh-dev libblkid-dev tar libargon2-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
sshpass asciidoctor meson ninja-build
)
COMPILER="${COMPILER:?}"

View File

@@ -4,8 +4,7 @@ on:
branches:
- 'main'
- 'wip-luks2'
- 'v2.3.x'
- 'v2.4.x'
- 'v2.*.x'
paths-ignore:
- 'docs/**'
@@ -17,11 +16,11 @@ jobs:
fail-fast: false
matrix:
env:
- { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
- { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
env: ${{ matrix.env }}
steps:
- name: Repository checkout
uses: actions/checkout@v1
uses: actions/checkout@v4
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
- name: Configure & Make

View File

@@ -5,8 +5,7 @@ on:
branches:
- 'main'
- 'wip-luks2'
- 'v2.3.x'
- 'v2.4.x'
- 'v2.*.x'
permissions:
contents: read
@@ -30,21 +29,25 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-extended,security-and-quality
config-file: .codeql-config.yml
- name: Install dependencies
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
env: { COMPILER: "gcc", COMPILER_VERSION: "11", RUN_SSH_PLUGIN_TEST: "1" }
run: |
sudo -E .github/workflows/cibuild-setup-ubuntu.sh
# Force autoconf for now, meson is broken in analysis step
rm meson.build
env: { COMPILER: "gcc", COMPILER_VERSION: "14", RUN_SSH_PLUGIN_TEST: "1" }
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

View File

@@ -12,12 +12,12 @@ jobs:
if: github.repository == 'mbroz/cryptsetup'
steps:
- name: Repository checkout
uses: actions/checkout@v1
uses: actions/checkout@v4
- name: Ubuntu setup
run: sudo -E .github/workflows/cibuild-setup-ubuntu.sh
env:
COMPILER: "gcc"
COMPILER_VERSION: "11"
COMPILER_VERSION: "14"
- name: Install Coverity
run: |
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=mbroz/cryptsetup" -O cov-analysis-linux64.tar.gz

1
.gitignore vendored
View File

@@ -17,6 +17,7 @@ ABOUT-NLS
aclocal.m4
autom4te.cache/
compile
compile_commands.json
config.guess
config.h
config.h.in

View File

@@ -1,23 +1,23 @@
stages:
- test
- test-opal
.dump_kernel_log:
.fail_if_coredump_generated:
after_script:
- sudo dmesg > /mnt/artifacts/dmesg.log
- sudo journalctl > /mnt/artifacts/journalctl.log
- '[ "$(ls -A /var/coredumps)" ] && exit 1 || true'
include:
- local: .gitlab/ci/debian.yml
- local: .gitlab/ci/fedora.yml
- local: .gitlab/ci/rhel.yml
- local: .gitlab/ci/fedora-opal.yml
- local: .gitlab/ci/centos.yml
- local: .gitlab/ci/annocheck.yml
# - local: .gitlab/ci/annocheck.yml
- local: .gitlab/ci/csmock.yml
- local: .gitlab/ci/gitlab-shared-docker.yml
- local: .gitlab/ci/compilation-various-disables.yml
- local: .gitlab/ci/compilation-gcc.gitlab-ci.yml
- local: .gitlab/ci/compilation-clang.gitlab-ci.yml
- local: .gitlab/ci/compilation-spellcheck.yml
- local: .gitlab/ci/alpinelinux.yml
- local: .gitlab/ci/ubuntu-32bit.yml
- local: .gitlab/ci/debian-i686.yml
- local: .gitlab/ci/cifuzz.yml

View File

@@ -1,14 +1,16 @@
.alpinelinux-dependencies:
after_script:
- sudo dmesg > /mnt/artifacts/dmesg.log
- sudo cp /var/log/messages /mnt/artifacts/
- '[ "$(ls -A /var/coredumps)" ] && exit 1 || true'
variables:
DISTRO: cryptsetup-alpine-edge
extends:
- .fail_if_coredump_generated
before_script:
- >
sudo apk add
lvm2-dev openssl1.1-compat-dev popt-dev util-linux-dev json-c-dev
argon2-dev device-mapper which sharutils gettext gettext-dev automake
lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev
argon2-dev device-mapper which sharutils gettext-dev argp-standalone automake
autoconf libtool build-base keyutils tar jq expect git asciidoctor
# Be sure we have updated basic tools and system
- sudo apk upgrade gcc binutils build-base musl
- ./autogen.sh
- ./configure --prefix=/usr --libdir=/lib --sbindir=/sbin --disable-static --enable-libargon2 --with-crypto_backend=openssl --disable-external-tokens --disable-ssh-token --enable-asciidoc
@@ -17,7 +19,7 @@ test-main-commit-job-alpinelinux:
- .alpinelinux-dependencies
tags:
- libvirt
- alpinelinux
- cryptsetup-alpine-edge
stage: test
interruptible: true
variables:
@@ -38,7 +40,7 @@ test-mergerq-job-alpinelinux:
- .alpinelinux-dependencies
tags:
- libvirt
- alpinelinux
- cryptsetup-alpine-edge
stage: test
interruptible: true
variables:

View File

@@ -1,13 +1,14 @@
test-main-commit-job-annocheck:
extends:
- .dump_kernel_log
- .fail_if_coredump_generated
tags:
- libvirt
- rhel9-annocheck
- cryptsetup-rhel-9
stage: test
interruptible: true
allow_failure: true
variables:
DISTRO: cryptsetup-rhel-9
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"

32
.gitlab/ci/build_srpm Executable file
View File

@@ -0,0 +1,32 @@
#!/bin/bash
set -e
SAVED_PWD=$(pwd)
GIT_DIR="$SAVED_PWD/upstream_git"
SPEC="$GIT_DIR/misc/fedora/cryptsetup.spec"
rm -fr $GIT_DIR
git clone -q --depth 1 https://gitlab.com/cryptsetup/cryptsetup.git $GIT_DIR
cd $GIT_DIR
GIT_COMMIT=$(git rev-parse --short=8 HEAD)
[ -z "$GIT_COMMIT" ] && exit 1
sed -i "s/^AC_INIT.*/AC_INIT([cryptsetup],[$GIT_COMMIT])/" $GIT_DIR/configure.ac
sed -i "s/^Version:.*/Version: $GIT_COMMIT/" $SPEC
sed -i "s/%{version_no_tilde}/$GIT_COMMIT/" $SPEC
sed -i "2i %global source_date_epoch_from_changelog 0" $SPEC
sed -i "3i %define _unpackaged_files_terminate_build 0" $SPEC
./autogen.sh
./configure
make -j dist
rpmbuild --define "_sourcedir $GIT_DIR" --define "_srcrpmdir $SAVED_PWD" -bs $SPEC
cd $SAVED_PWD
rm -fr $GIT_DIR
exit 0

View File

@@ -1,14 +1,16 @@
.centos-openssl-backend:
extends:
- .dump_kernel_log
- .fail_if_coredump_generated
before_script:
- sudo dnf clean all
- >
sudo dnf -y -q install
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool
libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd
pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper
expect gettext git jq keyutils openssl-devel openssl gem
expect gettext git jq keyutils openssl-devel openssl gem swtpm swtpm-tools
tpm2-tools
- sudo gem install asciidoctor
- sudo -E git clean -xdf
- ./autogen.sh
@@ -21,11 +23,13 @@ test-main-commit-centos-stream9:
- .centos-openssl-backend
tags:
- libvirt
- centos-stream9
- cryptsetup-centos-stream-9
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-centos-stream-9
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
@@ -42,11 +46,59 @@ test-mergerq-centos-stream9:
- .centos-openssl-backend
tags:
- libvirt
- centos-stream9
- cryptsetup-centos-stream-9
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-centos-stream-9
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-centos-stream10:
extends:
- .centos-openssl-backend
tags:
- libvirt
- cryptsetup-centos-stream-10
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-centos-stream-10
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-mergerq-centos-stream10:
extends:
- .centos-openssl-backend
tags:
- libvirt
- cryptsetup-centos-stream-10
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-centos-stream-10
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never

View File

@@ -5,7 +5,7 @@ set -ex
PACKAGES=(
git make autoconf automake autopoint pkg-config libtool libtool-bin
gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-0-dev libpwquality-dev
libjson-c-dev libssh-dev libblkid-dev tar libargon2-dev libpwquality-dev
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client
sshpass asciidoctor
)
@@ -13,9 +13,12 @@ PACKAGES=(
COMPILER="${COMPILER:?}"
COMPILER_VERSION="${COMPILER_VERSION:?}"
grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~
sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~
cat /etc/apt/sources.list~ >> /etc/apt/sources.list
sed -i 's/^Types: deb$/Types: deb deb-src/' /etc/apt/sources.list.d/ubuntu.sources
# use this on older Ubuntu
# grep -E '^deb' /etc/apt/sources.list > /etc/apt/sources.list~
# sed -Ei 's/^deb /deb-src /' /etc/apt/sources.list~
# cat /etc/apt/sources.list~ >> /etc/apt/sources.list
apt-get -y update --fix-missing
DEBIAN_FRONTEND=noninteractive apt-get -yq install software-properties-common wget lsb-release
@@ -28,7 +31,7 @@ if [[ $COMPILER == "gcc" ]]; then
PACKAGES+=(gcc-$COMPILER_VERSION)
elif [[ $COMPILER == "clang" ]]; then
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
add-apt-repository "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main"
add-apt-repository -n "deb http://apt.llvm.org/${RELEASE}/ llvm-toolchain-${RELEASE}-${COMPILER_VERSION} main"
# scan-build
PACKAGES+=(clang-tools-$COMPILER_VERSION clang-$COMPILER_VERSION lldb-$COMPILER_VERSION lld-$COMPILER_VERSION clangd-$COMPILER_VERSION)
@@ -37,14 +40,8 @@ else
exit 1
fi
apt-get -y update --fix-missing
#apt-get -y update --fix-missing
(r=3;while ! apt-get -y update --fix-missing ; do ((--r))||exit;sleep 5;echo "Retrying";done)
DEBIAN_FRONTEND=noninteractive apt-get -yq install "${PACKAGES[@]}"
apt-get -y build-dep cryptsetup
echo "====================== VERSIONS ==================="
if [[ $COMPILER == "clang" ]]; then
echo "Using scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
fi
${COMPILER}-$COMPILER_VERSION -v
echo "====================== END VERSIONS ==================="

View File

@@ -4,27 +4,85 @@ test-clang-compilation:
script:
- export CFLAGS="-Wall -Werror"
- ./autogen.sh
- $CC --version
- ./configure
- make -j
- make -j check-programs
test-clang-Wall-script:
test-clang-Wall-script-ubuntu:
extends:
- .gitlab-shared-clang
script:
- export CFLAGS="-g -O0"
- export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall"
- ./autogen.sh
- $CC --version
- ./configure
- make -j CFLAGS="-g -O0 -Werror"
- make -j CFLAGS="-g -O0 -Werror" check-programs
test-scan-build:
test-clang-Wall-script-alpine:
extends:
- .gitlab-shared-clang-alpine
allow_failure: true
script:
- export CFLAGS="-g -O0"
- export CC="$CI_PROJECT_DIR/.gitlab/ci/clang-Wall"
- ./autogen.sh
- $CC --version
- ./configure
- make -j CFLAGS="-g -O0 -Werror"
- make -j CFLAGS="-g -O0 -Werror" check-programs
test-scan-build-ubuntu:
extends:
- .gitlab-shared-clang
script:
- ./autogen.sh
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0"
- make clean
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
test-scan-build-alpine:
extends:
- .gitlab-shared-clang-alpine
allow_failure: true
script:
- ./autogen.sh
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0"
- make clean
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
test-scan-build-backends:
extends:
- .gitlab-shared-clang
parallel:
matrix:
- BACKENDS: [
"openssl",
"gcrypt",
"nss",
"kernel",
"nettle",
"mbedtls"
]
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
changes:
- lib/crypto_backend/*
script:
- DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev
- ./autogen.sh
- echo "Configuring with crypto backend $BACKENDS"
- echo "scan-build${COMPILER_VERSION:+-$COMPILER_VERSION}"
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} -V ./configure CFLAGS="-g -O0" --with-crypto_backend=$BACKENDS
- make clean
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j
- scan-build${COMPILER_VERSION:+-$COMPILER_VERSION} --status-bugs -maxloop 10 make -j check-programs
- ./tests/vectors-test

View File

@@ -4,27 +4,82 @@ test-gcc-compilation:
script:
- export CFLAGS="-Wall -Werror"
- ./autogen.sh
- $CC --version
- ./configure
- make -j
- make -j check-programs
test-gcc-Wall-script:
test-gcc-Wall-script-ubuntu:
extends:
- .gitlab-shared-gcc
script:
- export CFLAGS="-g -O0"
- export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall"
- ./autogen.sh
- $CC --version
- ./configure
- make -j CFLAGS="-g -O0 -Werror"
- make -j CFLAGS="-g -O0 -Werror" check-programs
test-gcc-fanalyzer:
test-gcc-Wall-script-alpine:
extends:
- .gitlab-shared-gcc-alpine
allow_failure: true
script:
- export CFLAGS="-g -O0"
- export CC="$CI_PROJECT_DIR/.gitlab/ci/gcc-Wall"
- ./autogen.sh
- $CC --version
- ./configure
- make -j CFLAGS="-g -O0 -Werror"
- make -j CFLAGS="-g -O0 -Werror" check-programs
test-gcc-fanalyzer-ubuntu:
extends:
- .gitlab-shared-gcc
script:
- export CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events"
- ./autogen.sh
- ./configure
- $CC --version
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64
- make -j
- make -j check-programs
test-gcc-fanalyzer-alpine:
extends:
- .gitlab-shared-gcc-alpine
allow_failure: true
script:
- ./autogen.sh
- $CC --version
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events -Wno-analyzer-fd-leak" --host=x86_64
- make -j
- make -j check-programs
test-gcc-fanalyzer-backends:
extends:
- .gitlab-shared-gcc
parallel:
matrix:
- BACKENDS: [
"openssl",
"gcrypt",
"nss",
"kernel",
"nettle",
"mbedtls"
]
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
changes:
- lib/crypto_backend/*
script:
- DEBIAN_FRONTEND=noninteractive apt-get -yq install libgcrypt20-dev libnss3-dev nettle-dev libmbedtls-dev
- ./autogen.sh
- $CC --version
- echo "Configuring with crypto backend $BACKENDS"
- ./configure CFLAGS="-Wall -Werror -g -O0 -fanalyzer -fdiagnostics-path-format=separate-events" --host=x86_64 --with-crypto_backend=$BACKENDS
- make -j
- make -j check-programs
- ./tests/vectors-test

View File

@@ -0,0 +1,20 @@
test-run-spellcheck:
image: ubuntu:noble
tags:
- gitlab-org-docker
stage: test
interruptible: true
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
artifacts:
name: "spellcheck-$CI_COMMIT_REF_NAME"
paths:
- _spellcheck
before_script:
- apt-get -y update --fix-missing
- apt-get -y install git lintian codespell
script:
- echo "Running spellcheck"
- .gitlab/ci/spellcheck

View File

@@ -11,7 +11,8 @@ test-gcc-disable-compiles:
"kernel_crypto",
"udev",
"internal-argon2",
"blkid"
"blkid",
"hw-opal"
]
artifacts:
name: "meson-build-logs-$CI_COMMIT_REF_NAME"

View File

@@ -1,23 +1,36 @@
.dnf-csmock:
variables:
DISTRO: cryptsetup-fedora-rawhide
DISK_SIZE: 20
extends:
- .fail_if_coredump_generated
before_script:
- >
sudo dnf -y -q install
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libblkid-devel libpwquality-devel libselinux-devel
libssh-devel libtool libuuid-devel make popt-devel
libsepol-devel.x86_64 pkgconfig tar uuid-devel git
openssl-devel asciidoctor meson ninja-build
rpm-build csmock
test-commit-job-csmock:
extends:
- .dump_kernel_log
- .dnf-csmock
tags:
- libvirt
- rhel9-csmock
- cryptsetup-fedora-rawhide
stage: test
interruptible: true
allow_failure: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/ || $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- sudo /opt/run-csmock.sh
- .gitlab/ci/build_srpm
- .gitlab/ci/run_csmock
artifacts:
# Upload artifacts when a crash makes the job fail.
when: always
paths:
- cryptsetup-csmock-results.tar.xz
- cryptsetup-csmock-results

View File

@@ -1,12 +1,13 @@
test-mergerq-job-ubuntu-32bit:
test-mergerq-job-debian-i686:
extends:
- .debian-prep
tags:
- libvirt
- ubuntu-bionic-32bit
- cryptsetup-debian-12i686
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12i686
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
@@ -19,15 +20,16 @@ test-mergerq-job-ubuntu-32bit:
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-job-ubuntu-32bit:
test-main-commit-job-debian-i686:
extends:
- .debian-prep
tags:
- libvirt
- ubuntu-bionic-32bit
- cryptsetup-debian-12i686
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12i686
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null

View File

@@ -1,18 +1,16 @@
.debian-prep:
extends:
- .dump_kernel_log
- .fail_if_coredump_generated
before_script:
- sudo apt-get -y update
- >
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
sudo apt-get -y install -y -qq swtpm meson ninja-build python3-jinja2
gperf libcap-dev libtss2-dev libmount-dev swtpm-tools
- >
sudo apt-get -y install -y -qq git gcc make autoconf automake autopoint
pkgconf libtool libtool-bin gettext libssl-dev libdevmapper-dev
libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev
tar libargon2-0-dev libpwquality-dev sharutils dmsetup jq xxd expect
tar libargon2-dev libpwquality-dev sharutils dmsetup jq xxd expect
keyutils netcat-openbsd passwd openssh-client sshpass asciidoctor
swtpm meson ninja-build python3-jinja2 gperf libcap-dev libtss2-dev
libmount-dev swtpm-tools tpm2-tools
- sudo apt-get -y build-dep cryptsetup
- sudo -E git clean -xdf
- ./autogen.sh
@@ -23,11 +21,13 @@ test-mergerq-job-debian:
- .debian-prep
tags:
- libvirt
- debian12
- cryptsetup-debian-unstable
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-unstable
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
@@ -42,11 +42,55 @@ test-main-commit-job-debian:
- .debian-prep
tags:
- libvirt
- debian12
- cryptsetup-debian-unstable
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-unstable
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-mergerq-job-debian12:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-job-debian12:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
@@ -62,11 +106,13 @@ test-mergerq-job-debian-meson:
- .debian-prep
tags:
- libvirt
- debian12
- cryptsetup-debian-unstable
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-unstable
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
@@ -82,11 +128,57 @@ test-main-commit-job-debian-meson:
- .debian-prep
tags:
- libvirt
- debian12
- cryptsetup-debian-unstable
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-unstable
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- sudo apt-get -y install -y -qq meson ninja-build
- meson setup build
- ninja -C build
- cd build && sudo -E meson test --verbose --print-errorlogs
test-mergerq-job-debian12-meson:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
script:
- sudo apt-get -y install -y -qq meson ninja-build
- meson setup build
- ninja -C build
- cd build && sudo -E meson test --verbose --print-errorlogs
test-main-commit-job-debian12-meson:
extends:
- .debian-prep
tags:
- libvirt
- cryptsetup-debian-12
stage: test
interruptible: true
variables:
DISTRO: cryptsetup-debian-12
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never

145
.gitlab/ci/fedora-opal.yml Normal file
View File

@@ -0,0 +1,145 @@
.opal-template-fedora:
extends:
- .dnf-openssl-backend
tags:
- libvirt
- cryptsetup-fedora-rawhide
stage: test-opal
interruptible: false
variables:
OPAL2_DEV: "/dev/nvme0n1"
OPAL2_PSID_FILE: "/home/gitlab-runner/psid.txt"
VOLATILE: 1
script:
- sudo dnf install -y -q nvme-cli
- sudo nvme list
- make -j
- make -j -C tests check-programs
- sudo -E make check TESTS="00modules-test compat-test-opal"
# Samsung SSD 980 500GB (on tiber machine)
test-commit-rawhide-samsung980:
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
extends:
- .opal-template-fedora
tags:
- tiber
resource_group: samsung980-on-tiber
interruptible: false
variables:
PCI_PASSTHROUGH_VENDOR_ID: "144d"
PCI_PASSTHROUGH_DEVICE_ID: "a809"
test-mergerq-rawhide-samsung980:
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .opal-template-fedora
tags:
- tiber
resource_group: samsung980-on-tiber
interruptible: false
variables:
PCI_PASSTHROUGH_VENDOR_ID: "144d"
PCI_PASSTHROUGH_DEVICE_ID: "a809"
# WD PC SN740 SDDQNQD-512G-1014 (on tiber machine)
# Disabled on 2025-03-20, seems broken
#test-commit-rawhide-sn740:
# rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
# extends:
# - .opal-template-fedora
# tags:
# - tiber
# resource_group: sn740-on-tiber
# interruptible: false
# variables:
# PCI_PASSTHROUGH_VENDOR_ID: "15b7"
# PCI_PASSTHROUGH_DEVICE_ID: "5017"
#
#test-mergerq-rawhide-sn740:
# rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
# extends:
# - .opal-template-fedora
# tags:
# - tiber
# resource_group: sn740-on-tiber
# interruptible: false
# variables:
# PCI_PASSTHROUGH_VENDOR_ID: "15b7"
# PCI_PASSTHROUGH_DEVICE_ID: "5017"
# Samsung SSD 980 PRO 1TB (on trantor machine)
test-commit-rawhide-samsung980pro:
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
extends:
- .opal-template-fedora
tags:
- trantor
resource_group: samsung980pro-on-trantor
interruptible: false
variables:
PCI_PASSTHROUGH_VENDOR_ID: "144d"
PCI_PASSTHROUGH_DEVICE_ID: "a80a"
test-mergerq-rawhide-samsung980pro:
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
extends:
- .opal-template-fedora
tags:
- trantor
resource_group: samsung980pro-on-trantor
interruptible: false
variables:
PCI_PASSTHROUGH_VENDOR_ID: "144d"
PCI_PASSTHROUGH_DEVICE_ID: "a80a"
# # UMIS RPETJ256MGE2MDQ (on tiber machine)
# test-commit-rawhide-umis:
# rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
# extends:
# - .opal-template-fedora
# tags:
# - tiber
# resource_group: umis-on-tiber
# stage: test
# interruptible: false
# variables:
# PCI_PASSTHROUGH_VENDOR_ID: "1cc4"
# PCI_PASSTHROUGH_DEVICE_ID: "6302"
#
# test-mergerq-rawhide-umis:
# rules:
# - if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
# when: never
# - if: $CI_PIPELINE_SOURCE == "merge_request_event"
# extends:
# - .opal-template-fedora
# tags:
# - tiber
# resource_group: umis-on-tiber
# stage: test
# interruptible: false
# variables:
# PCI_PASSTHROUGH_VENDOR_ID: "1cc4"
# PCI_PASSTHROUGH_DEVICE_ID: "6302"

View File

@@ -1,20 +1,19 @@
.dnf-openssl-backend:
extends:
- .dump_kernel_log
before_script:
- >
[ -z "$RUN_SYSTEMD_PLUGIN_TEST" ] ||
sudo dnf -y -q install
swtpm meson ninja-build python3-jinja2 gperf libcap-devel tpm2-tss-devel
libmount-devel swtpm-tools
- >
sudo dnf -y -q install
variables:
DISTRO: cryptsetup-fedora-rawhide
PKGS: >-
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libargon2-devel libblkid-devel libpwquality-devel libselinux-devel
libssh-devel libtool libuuid-devel make popt-devel
libsepol-devel.x86_64 netcat openssh-clients passwd pkgconfig sharutils
sshpass tar uuid-devel vim-common device-mapper expect gettext git jq
keyutils openssl-devel openssl asciidoctor
keyutils openssl-devel openssl asciidoctor swtpm meson ninja-build
python3-jinja2 gperf libcap-devel tpm2-tss-devel libmount-devel swtpm-tools
extends:
- .fail_if_coredump_generated
before_script:
- sudo dnf clean all
- (r=3;while ! sudo dnf -y -q install $PKGS ; do ((--r))||exit;sleep 5;echo "Retrying";done)
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-fips --enable-pwquality --enable-libargon2 --with-crypto_backend=openssl --enable-asciidoc
@@ -24,12 +23,14 @@ test-main-commit-job-rawhide:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
- cryptsetup-fedora-rawhide
stage: test
interruptible: true
allow_failure: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
RUN_SYSTEMD_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
@@ -44,12 +45,14 @@ test-mergerq-job-rawhide:
- .dnf-openssl-backend
tags:
- libvirt
- fedora-rawhide
- cryptsetup-fedora-rawhide
stage: test
interruptible: true
allow_failure: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
RUN_KEYRING_TRUSTED_TEST: "1"
RUN_SYSTEMD_PLUGIN_TEST: "1"
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never

View File

@@ -36,7 +36,8 @@ EXTRA="-Wextra \
-Wmaybe-uninitialized \
-Wvla \
-Wformat-overflow \
-Wformat-truncation"
-Wformat-truncation \
-Wstringop-overread"
exec $GCC $PEDANTIC $CONVERSION \
-Wall $Wuninitialized \

View File

@@ -1,5 +1,6 @@
.gitlab-shared-docker:
image: ubuntu:lunar
# Ubuntu
.gitlab-shared-docker-ubuntu:
image: ubuntu:noble
tags:
- gitlab-org-docker
stage: test
@@ -13,18 +14,48 @@
- export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}"
- export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}"
# Alpine
.gitlab-shared-docker-alpine:
image: alpine:latest
tags:
- gitlab-org-docker
stage: test
interruptible: true
rules:
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_PIPELINE_SOURCE == "merge_request_event" || $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
before_script:
- apk add bash build-base clang clang-analyzer argp-standalone lvm2-dev openssl-dev popt-dev util-linux-dev json-c-dev device-mapper gettext-dev libssh-dev automake autoconf libtool tar asciidoctor
- export CC="${COMPILER}${COMPILER_VERSION:+-$COMPILER_VERSION}"
- export CXX="${COMPILER}++${COMPILER_VERSION:+-$COMPILER_VERSION}"
.gitlab-shared-gcc:
extends:
- .gitlab-shared-docker
- .gitlab-shared-docker-ubuntu
variables:
COMPILER: "gcc"
COMPILER_VERSION: "11"
RUN_SSH_PLUGIN_TEST: "1"
COMPILER_VERSION: "14"
CC: "gcc-14"
.gitlab-shared-clang:
extends:
- .gitlab-shared-docker
- .gitlab-shared-docker-ubuntu
variables:
COMPILER: "clang"
COMPILER_VERSION: "17"
RUN_SSH_PLUGIN_TEST: "1"
COMPILER_VERSION: "20"
CC: "clang-20"
.gitlab-shared-gcc-alpine:
extends:
- .gitlab-shared-docker-alpine
variables:
COMPILER: "gcc"
CC: "gcc"
.gitlab-shared-clang-alpine:
extends:
- .gitlab-shared-docker-alpine
variables:
COMPILER: "clang"
CC: "clang"

View File

@@ -1,106 +0,0 @@
.rhel-openssl-backend:
extends:
- .dump_kernel_log
before_script:
- >
sudo yum -y -q install
autoconf automake device-mapper-devel gcc gettext-devel json-c-devel
libblkid-devel libpwquality-devel libselinux-devel libssh-devel libtool
libuuid-devel make popt-devel libsepol-devel nc openssh-clients passwd
pkgconfig sharutils sshpass tar uuid-devel vim-common device-mapper
expect gettext git jq keyutils openssl-devel openssl gem > /dev/null 2>&1
- sudo gem install asciidoctor
- sudo -E git clean -xdf
- ./autogen.sh
- ./configure --enable-fips --enable-pwquality --with-crypto_backend=openssl --enable-asciidoc
# non-FIPS jobs
test-main-commit-rhel8:
extends:
- .rhel-openssl-backend
tags:
- libvirt
- rhel8
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-rhel9:
extends:
- .rhel-openssl-backend
tags:
- libvirt
- rhel9
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- make -j
- make -j -C tests check-programs
- sudo -E make check
# FIPS jobs
test-main-commit-rhel8-fips:
extends:
- .rhel-openssl-backend
tags:
- libvirt
- rhel8-fips
stage: test
interruptible: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- fips-mode-setup --check || exit 1
- make -j
- make -j -C tests check-programs
- sudo -E make check
test-main-commit-rhel9-fips:
extends:
- .rhel-openssl-backend
tags:
- libvirt
- rhel9-fips
stage: test
interruptible: true
allow_failure: true
variables:
RUN_SSH_PLUGIN_TEST: "1"
rules:
- if: $RUN_SYSTEMD_PLUGIN_TEST != null
when: never
- if: $CI_PROJECT_PATH != "cryptsetup/cryptsetup"
when: never
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH =~ /v2\..\.x$/
script:
- fips-mode-setup --check || exit 1
- make -j
- make -j -C tests check-programs
- sudo -E make check

22
.gitlab/ci/run_csmock Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
CSMOCK="sudo /usr/bin/csmock"
CSMOCK_TOOLS="gcc,clang,cppcheck,shellcheck"
CSMOCK_TXZ="cryptsetup-csmock-results.tar.xz"
CSMOCK_ERR="cryptsetup-csmock-results/scan-results.err"
$CSMOCK cryptsetup-*.src.rpm \
--keep-going --force \
--cswrap-timeout 300 \
--skip-patches \
--tools $CSMOCK_TOOLS \
--output $CSMOCK_TXZ \
--gcc-analyze \
--cppcheck-add-flag=--check-level=exhaustive \
|| { echo "csmock command failed"; exit 2; }
tar xJf $CSMOCK_TXZ $CSMOCK_ERR --strip-components 1 \
&& test -s $CSMOCK_ERR \
&& { echo "csmock discovered important errors"; echo 3; }
exit 0

31
.gitlab/ci/spellcheck Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
set -e
DIR="_spellcheck"
[ ! -d $DIR ] && mkdir $DIR
echo "[SPELLINTIAN]"
git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \
xargs -r0 spellintian | \
grep -v "(duplicate word)" | \
grep -v "docs/" | tee $DIR/spell1.txt
echo "[CODESPELL]"
git ls-tree -rz --name-only HEAD | grep -Evz -e '\.(pdf|xz)$' -e ^po/ | \
xargs -r0 codespell | \
grep -v "EXPCT" | \
grep -v "params, prams" | \
grep -v "pad, padded" | \
grep -v "CIPHER, CHIP" | \
grep -v "gost" | \
grep -v "userA" | \
grep -v "re-use" | \
grep -v "fo ==" | \
grep -v "docs/" | tee $DIR/spell2.txt
[ -s $DIR/spell1.txt ] && exit 1
[ -s $DIR/spell2.txt ] && exit 2
exit 0

View File

@@ -9,7 +9,10 @@
### Debug log
<!-- Paste a debug log of the failing command (add --debug option) between the markers below (to keep raw debug format).-->
<!-- We need a lot of information from the debug log; without it, we cannot process your report. -->
<!-- Debug log does not contain any private information. Do not paste private data; we'll ask you for more information if needed. -->
```
Output with --debug option:
```
<!-- NOTE: WITHOUT DEBUG LOG, THE BUG REPORT WILL BE CLOSED. ALSO, PLEASE DO NOT TRY TO REMOVE PARTS OF THE DEBUG LOG! -->

158
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,158 @@
Contributing to cryptsetup
==========================
For basic information about the cryptsetup project, please read [README](README.md).
The Cryptsetup project uses free, open-source licenses; details are described in [licensing](README.licensing).
For contribution code or documentation to the cryptsetup project, you must have the necessary rights to the content, and your contribution must be provided under the required license.
We welcome contributions from everyone.
Cryptsetup is an independent project with much volunteer effort, and our resources are limited.
Following the guidelines specified in this file makes it easier for us to process your issue.
Project maintainers can remove or reject abusive or otherwise unacceptable comments or code.
Git repository
--------------
The primary repository is located at [gitlab.com/cryptsetup/cryptsetup](https://gitlab.com/cryptsetup/cryptsetup).
The development branch is ``main``; minor stable releases can use their branches with cherry-picked or backported patches.
There are backup mirrors located at [github.com/mbroz/cryptsetup](https://github.com/mbroz/cryptsetup) and [git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git](https://git.kernel.org/pub/scm/utils/cryptsetup/cryptsetup.git).
How to make a bug report
------------------------
To report an issue or feature request, please use GitLab [cryptsetup issue tracker](https://gitlab.com/cryptsetup/cryptsetup/-/issues).
Before reporting an issue, please try to search documentation and existing issues. Always try to reproduce the problem on the latest supported release.
Please *always* collect and attach ``--debug`` log and other information as instructed in the issue template.
Even if you think the problem is obvious, we need logged information about the environment (like versions of kernel modules, etc.).
Please do not report distribution-specific issues if they are not present in the latest upstream release.
For such reports, please use downstream distribution-specific trackers.
If the issue is related to upstream, downstream maintainers will redirect you here, or upstream maintainers will join the discussion.
If you think that you found some security bug, please follow the instructions in the [SECURITY](SECURITY.md) file.
How to contribute changes to cryptsetup
---------------------------------------
The following notes are a very short introduction to cryptsetup internal processes and an overview of generic rules that should be followed for all changes.
Changes from developers and external contributors should go through the GitLab repository [merge reguests](https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests).
Alternatively (for trivial changes), you can send a patch to [cryptsetup mailing list](mailto:cryptsetup@lists.linux.dev).
Please do not write personal emails with questions or patches to maintainers and developers.
### Project structure
Cryptsetup projects include a libcryptsetup library, tools, token plugins, documentation, and a test suite.
Cryptsetup library (libcryptsetup) exports [versioned symbols](lib/libcryptsetup.sym).
Tools (cryptsetup, veritysetup, integritysetup) use libcryptsetup shared library.
Some isolated parts in the lib directory can be reused for tools (the source is recompiled).
The basic directory structure in the repository is
```
├── docs - Documentation and release notes.
├── lib - libcryptsetup implementation
│   ├── bitlk - Bitlocker format
│   ├── crypto_backend - Cryptography backend
│   ├── fvault2 - FileVault2 format
│   ├── integrity - Linux dm-integrity interface
│   ├── loopaes - Linux LoopAES format
│   ├── luks1 - LUKS1 format
│   ├── luks2 - LUKS2 format including OPAL2 SED
│   ├── tcrypt - TrueCrypt / VeraCrypt format
│   └── verity - Linux dm-verity interface
├── man - Manual pages (in AsciiDoc format)
├── misc - Miscellaneous additions
├── po - Translation files
├── scripts - Scripts for system configuration
├── src - Tools implementation
├── tests - Testsuite (test units, regression tests, fuzzing)
└── tokens - Token plugins
```
### Coordination with other projects
The cryptsetup tools and library use low-level functions that depend on many other subsystems.
Currently, the project is supported only for Linux (it will not work on Android or other systems).
Cryptsetup project requires some parts of the Linux kernel, notably the *Device Mapper* (dm-crypt, dm-integrity, dm-verity, dm-zero modules) and kernel *userspace cryptographic interface*.
Missing kernel interface can significantly limit (or even disallow) cryptsetup functionality.
Integration in operating systems also depends on several other projects, most notably *systemd* (that implements its own tooling using libcryptsetup) and *util-Linux* (*blkid* parsing of supported format metadata). Some changes must be synchronized in all needed places (kernel, blkid, libcryptsetup).
Several other projects implement their own token metadata (either through binary token plugins or through generic libcryptsetup JSON token access functions).
### Used cryptography algorithms
Cryptsetup avoids implementing cryptographic primitives but uses cryptographic libraries.
Exceptions were PBKDF internal implementations - PBKDF2 and Argon2 until these were integrated into major cryptographic libraries.
Cryptsetup can be compiled with several cryptographic libraries backend (OpenSSL, libgcrypt, Nettle, NSS, and Linux kernel userspace API).
OpenSSL is the default and strongly recommended configuration.
If the cryptographic library does not implement some cryptographic primitive (for example, if running in a FIPS-140 environment or just
because it does not include it at all), functionality could be limited.
### Configuration and versioning
Cryptsetup can be configured using *Autoconf* or *Meson*. Autoconf support is being deprecated in the long term.
Currently, all new configuration options must be implemented in both systems.
Cryptsetup intentionally does not use a system configuration file (located in /etc).
All functionality must be determined dynamically.
All related /etc configuration files (crypttab, fstab and others) are maintained by systemd (in some legacy distributions by cryptsetup downstream).
Cryptsetup uses [semantic versioning](https://semver.org/).
Major and minor releases are always based on the main git branch; the minor stable (patch) versions can have some specific branch with backported or cherry-picked patches (from the main branch).
Usually, minor releases happen twice per year and stable patch updates according to reported bugs (in 1-3 month intervals).
### Compilation and debugging
The library and tools are written in C language; we require C99 and support gcc and Clang compilers.
Manual pages are generated from AsciiDoc sources and libcryptsetup API documentation by Doxygen (from libcryptsetup.h comments).
Testsuite is a combination of local C utilities, fuzzing implementation in C++, bash scripts, and uses many other system utilities.
All tools contain compiled-in debug messages that are available through --debug options.
With Autoconf and libtool, you can run the cryptsetup tool in the debugger without installation using this one-line script:
```
libtool --mode=execute gdb --args ./cryptsetup --debug $@
```
This will ensure that a properly compiled libcryptsetup file is used.
### Coding style
Cryptsetup uses [Linux kernel coding style](https://cdn.kernel.org/doc/html/latest/process/coding-style.html) for libcryptsetup and tools (where applicable) with some additional notes:
- Use tabulators for indentation; the line should not exceed 100 characters with an 8-character tabulator. Otherwise, use a tab of any length. :-).
- The minimal C standard required is C99.
- The ``goto`` use is allowed only for error path (``goto out`` for common code path, ``goto err`` for specific error code path).
- Split patches per change; do not submit huge patches combining several changes.
- Use an elaborative description in the patch header.
- No need to use sign-off-by lines.
- Use name prefixes (``crypt_``, ``LUKS2_`` and similar).
- Avoid extensive preprocessor use (specifically conditional ``#if`` or ``#ifdef`` sections).
- To check detected configuration options stored in config.h, always use ``#if SOMETHING`` (do NOT use ``#ifdef``).
- Use output only through ``log_err, log_std, log_verbose, log_dbg`` macros.
The ``log_dbg`` is always in English; the others should be wrapped in the ``_()`` macro for translation.
- Use ``assert()`` but only for simple invariants and variables (avoid calling functions).
Do not use assert for user-defined input (this should be a normal error path).
- The code style is quite relaxed in testing scripts (code there is not intended for production use).
### General rules and testing
- Cryptsetup should work on all architectures supported by the Linux kernel.
Only very few functionalities require specific hardware (notably Opal SED support).
If you want to introduce some specific hardware support, please discuss it with the maintainers first.
- All code changes should go through merge requests and reviews.
Code can be merged after review approval (done by someone with the commit right to the development repository), but reviews from external people are very welcome, too.
- All new functionality must come with at least rudimentary coverage in the test suite.
Always run the test suite before opening the merge request (``make check`` with root privilege).
- We have continuous integration (CI) that runs many tests automatically, but the output is not directly visible for external merge request authors (for security reasons).
All CI scripts are available in .gitlab and .github folders in the project repository.
Maintainers will provide you log files if anything fails. Your code must produce no warnings before it is merged.
- We run compilation with many extended [gcc](.gitlab/ci/gcc-Wall) and [Clang](.gitlab/ci/clang-Wall) warnings and include some analyzers, notably
- [Coverity](https://scan.coverity.com), GitHub CodeQL, Clang scan-build, and gcc static analyzer, and
- fuzzing integrated in [OSS-fuzz project](https://github.com/google/oss-fuzz/tree/master/projects/cryptsetup).
- Testsuite can also partially run under Valgrind dynamic analyzer with ``make valgrind-check``.

34
FAQ.md
View File

@@ -38,7 +38,7 @@
LUKS1 and LUKS2.
The LUKS1 on-disk format specification is at
https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf
https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf
The LUKS2 on-disk format specification is at
https://gitlab.com/cryptsetup/LUKS2-docs
@@ -169,17 +169,12 @@
me write the section. Please note that by contributing to this FAQ,
you accept the license described below.
This work is under the "Attribution-Share Alike 3.0 Unported" license,
which means distribution is unlimited, you may create derived works, but
This work is licensed under a Creative Commons CC-BY-SA-4.0
"Attribution-ShareAlike 4.0 International" license which means
distribution is unlimited, you may create derived works, but
attributions to original authors and this license statement must be
retained and the derived work must be under the same license. See
https://creativecommons.org/licenses/by-sa/3.0/ for more details of the
license.
Side note: I did text license research some time ago and I think this
license is best suited for the purpose at hand and creates the least
problems.
retained and the derived work must be under the same license.
See https://creativecommons.org/licenses/by-sa/4.0/ for more details.
* **1.6 Where is the project website?**
@@ -710,9 +705,12 @@
this. The only legitimate reason I can think of is if you want to have
two LUKS devices with the same volume key. Even then, I think it would
be preferable to just use key-slots with the same passphrase, or to use
plain dm-crypt instead. If you really have a good reason, please tell
me. If I am convinced, I will add how to do this here.
plain dm-crypt instead.
Use the --volume-key-file option, like this:
```
cryptsetup luksFormat --volume-key-file keyfile /dev/loop0
```
* **2.12 What are the security requirements for a key read from file?**
@@ -1928,10 +1926,6 @@
Hence, LUKS has no kill option because it would do much more harm than
good.
Still, if you have a good use-case (i.e. non-abstract real-world
situation) where a Nuke-Option would actually be beneficial, please let
me know.
* **5.22 Does cryptsetup open network connections to websites, etc. ?**
@@ -2685,8 +2679,7 @@ can be converted to the raw volume key for example via:
Note that at the time this FAQ item was written, 1.5.4 was the latest
1.5.x version and it has the flaw, i.e. works with the old Whirlpool
version. Possibly later 1.5.x versions will work as well. If not,
please let me know.
version. Possibly later 1.5.x versions will work as well.
The only two ways to access older LUKS containers created with Whirlpool
are to either decrypt with an old gcrypt version that has the flaw or to
@@ -2802,8 +2795,7 @@ can be converted to the raw volume key for example via:
03) Creating your own initrd
The two examples below should give you most of what is needed. This is
tested with LUKS1 and should work with LUKS2 as well. If not, please
let me know.
tested with LUKS1 and should work with LUKS2 as well.
Here is a really minimal example. It does nothing but set up some
things and then drop to an interactive shell. It is perfect to try out

View File

@@ -1,4 +1,4 @@
EXTRA_DIST = README.md SECURITY.md COPYING.LGPL FAQ.md docs misc autogen.sh
EXTRA_DIST = README.md SECURITY.md README.licensing CONTRIBUTING.md FAQ.md docs misc autogen.sh
EXTRA_DIST += meson_options.txt \
meson.build \
lib/crypto_backend/argon2/meson.build \
@@ -9,6 +9,7 @@ EXTRA_DIST += meson_options.txt \
scripts/meson.build \
src/meson.build \
tests/meson.build \
tests/fuzz/meson.build \
tokens/meson.build \
tokens/ssh/meson.build
@@ -24,8 +25,7 @@ AM_CPPFLAGS = \
-DLIBDIR=\""$(libdir)"\" \
-DPREFIX=\""$(prefix)"\" \
-DSYSCONFDIR=\""$(sysconfdir)"\" \
-DVERSION=\""$(VERSION)"\" \
-DEXTERNAL_LUKS2_TOKENS_PATH=\"${EXTERNAL_LUKS2_TOKENS_PATH}\"
-DVERSION=\""$(VERSION)"\"
AM_CFLAGS = -Wall
AM_CXXFLAGS = -Wall
AM_LDFLAGS =

20
README.licensing Normal file
View File

@@ -0,0 +1,20 @@
The cryptsetup project does not use the same license for all of the code and documentation.
There is code and documentation under:
* GPL-2.0-or-later - GNU General Public License version 2, or any later version
* LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception
* LGPL-2.1-or-later - GNU Lesser General Public License 2.1 or any later version,
(with cryptsetup-OpenSSL-exception where applicable)
* Apache-2.0 - Apache License 2.0
* CC-BY-SA-4.0 - Creative Commons Attribution Share Alike 4.0 International
* Public Domain
Please, check the source code for more details.
The ./COPYING file (GPL-2.0-or-later) is the default license for code without
an explicitly defined license.

View File

@@ -30,34 +30,22 @@ which enables users to transport or migrate data seamlessly.
* The latest version of the
[LUKS2 format specification](https://gitlab.com/cryptsetup/LUKS2-docs).
* The latest version of the
[LUKS1 format specification](https://www.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
[LUKS1 format specification](https://cdn.kernel.org/pub/linux/utils/cryptsetup/LUKS_docs/on-disk-format.pdf).
* [Project home page](https://gitlab.com/cryptsetup/cryptsetup/).
* [Frequently asked questions (FAQ)](https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions)
Download
--------
Release notes and tarballs are available at
[kernel.org](https://www.kernel.org/pub/linux/utils/cryptsetup/).
[kernel.org](https://cdn.kernel.org/pub/linux/utils/cryptsetup/).
**The latest stable cryptsetup release candidate version is 2.7.0-rc0**
* [cryptsetup-2.7.0-rc0.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.0-rc0.tar.xz)
* Signature [cryptsetup-2.7.0-rc0.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/cryptsetup-2.7.0-rc0.tar.sign)
**The latest stable cryptsetup release version is 2.8.1**
* [cryptsetup-2.8.1.tar.xz](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.xz)
* Signature [cryptsetup-2.8.1.tar.sign](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/cryptsetup-2.8.1.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.7.0-rc0 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.7/v2.7.0-rc0-ReleaseNotes).
* [Cryptsetup 2.8.1 Release Notes](https://cdn.kernel.org/pub/linux/utils/cryptsetup/v2.8/v2.8.1-ReleaseNotes).
**The latest stable cryptsetup release version is 2.6.1**
* [cryptsetup-2.6.1.tar.xz](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.xz)
* Signature [cryptsetup-2.6.1.tar.sign](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/cryptsetup-2.6.1.tar.sign)
_(You need to decompress file first to check signature.)_
* [Cryptsetup 2.6.1 Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.6/v2.6.1-ReleaseNotes).
Previous versions
* [Version 2.5.0](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.xz) -
[Signature](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/cryptsetup-2.5.0.tar.sign) -
[Release Notes](https://www.kernel.org/pub/linux/utils/cryptsetup/v2.5/v2.5.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).
[Previous versions](https://cdn.kernel.org/pub/linux/utils/cryptsetup)
Source and API documentation
----------------------------
@@ -82,8 +70,7 @@ Below are the packages needed to build for certain Linux distributions:
**For Fedora**:
```
git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel
libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar
git gcc make autoconf automake gettext-devel pkgconfig openssl-devel popt-devel device-mapper-devel libuuid-devel json-c-devel libblkid-devel findutils libtool libssh-devel tar rubygem-asciidoctor
Optionally: libargon2-devel libpwquality-devel
```
@@ -94,14 +81,13 @@ sharutils device-mapper jq vim-common expect keyutils netcat shadow-utils openss
**For Debian and Ubuntu**:
```
git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev
libpopt-dev uuid-dev libsepol1-dev libjson-c-dev libssh-dev libblkid-dev tar
git gcc make autoconf automake autopoint pkg-config libtool gettext libssl-dev libdevmapper-dev libpopt-dev uuid-dev libsepol-dev libjson-c-dev libssh-dev libblkid-dev tar asciidoctor
Optionally: libargon2-0-dev libpwquality-dev
```
To run the internal testsuite (make check) you also need to install
```
sharutils dmsetup jq xxd expect keyutils netcat passwd openssh-client sshpass
sharutils dmsetup jq xxd expect keyutils netcat-openbsd passwd openssh-client sshpass
```
Note that the list may change as Linux distributions evolve.

View File

@@ -1,9 +1,9 @@
AC_PREREQ([2.67])
AC_INIT([cryptsetup],[2.7.0-rc0])
AC_INIT([cryptsetup],[2.9.0-git])
dnl library version from <major>.<minor>.<release>[-<suffix>]
LIBCRYPTSETUP_VERSION=$(echo $PACKAGE_VERSION | cut -f1 -d-)
LIBCRYPTSETUP_VERSION_INFO=22:0:10
LIBCRYPTSETUP_VERSION_INFO=23:0:11
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR(src/cryptsetup.c)
@@ -132,7 +132,6 @@ AC_C_BIGENDIAN
AC_TYPE_OFF_T
AC_SYS_LARGEFILE
AC_FUNC_FSEEKO
AC_PROG_GCC_TRADITIONAL
AC_FUNC_STRERROR_R
dnl ==========================================================================
@@ -346,7 +345,7 @@ AC_DEFUN([CONFIGURE_OPENSSL], [
saved_LIBS=$LIBS
AC_CHECK_DECLS([OSSL_get_max_threads], [], [], [#include <openssl/thread.h>])
AC_CHECK_DECLS([OSSL_KDF_PARAM_ARGON2_VERSION], [], [], [#include <openssl/core_names.h>])
AC_CHECK_DECLS([OSSL_KDF_PARAM_ARGON2_VERSION], [use_internal_argon2=0], [], [#include <openssl/core_names.h>])
LIBS=$saved_LIBS
])
@@ -400,6 +399,23 @@ AC_DEFUN([CONFIGURE_NETTLE], [
NO_FIPS([])
])
AC_DEFUN([CONFIGURE_MBEDTLS], [
AC_CHECK_HEADERS(mbedtls/version.h,,
[AC_MSG_ERROR([You need mbedTLS cryptographic library.])])
saved_LIBS=$LIBS
AC_CHECK_LIB(mbedcrypto, mbedtls_md_init,,
[AC_MSG_ERROR([You need mbedTLS cryptographic library.])])
AC_CHECK_FUNCS(mbedtls_pkcs5_pbkdf2_hmac_ext)
CRYPTO_LIBS=$LIBS
LIBS=$saved_LIBS
CRYPTO_STATIC_LIBS=$CRYPTO_LIBS
use_internal_pbkdf2=0
use_internal_argon2=1
NO_FIPS([])
])
dnl ==========================================================================
saved_LIBS=$LIBS
@@ -482,7 +498,7 @@ fi
dnl Crypto backend configuration.
AC_ARG_WITH([crypto_backend],
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle) [openssl]]),
AS_HELP_STRING([--with-crypto_backend=BACKEND], [crypto backend (gcrypt/openssl/nss/kernel/nettle/mbedtls) [openssl]]),
[], [with_crypto_backend=openssl])
dnl Kernel crypto API backend needed for benchmark and tcrypt
@@ -502,6 +518,7 @@ case $with_crypto_backend in
nss) CONFIGURE_NSS([]) ;;
kernel) CONFIGURE_KERNEL([]) ;;
nettle) CONFIGURE_NETTLE([]) ;;
mbedtls) CONFIGURE_MBEDTLS([]) ;;
*) AC_MSG_ERROR([Unknown crypto backend.]) ;;
esac
AM_CONDITIONAL(CRYPTO_BACKEND_GCRYPT, test "$with_crypto_backend" = "gcrypt")
@@ -509,6 +526,7 @@ AM_CONDITIONAL(CRYPTO_BACKEND_OPENSSL, test "$with_crypto_backend" = "openssl")
AM_CONDITIONAL(CRYPTO_BACKEND_NSS, test "$with_crypto_backend" = "nss")
AM_CONDITIONAL(CRYPTO_BACKEND_KERNEL, test "$with_crypto_backend" = "kernel")
AM_CONDITIONAL(CRYPTO_BACKEND_NETTLE, test "$with_crypto_backend" = "nettle")
AM_CONDITIONAL(CRYPTO_BACKEND_MBEDTLS, test "$with_crypto_backend" = "mbedtls")
AM_CONDITIONAL(CRYPTO_INTERNAL_PBKDF2, test $use_internal_pbkdf2 = 1)
AC_DEFINE_UNQUOTED(USE_INTERNAL_PBKDF2, [$use_internal_pbkdf2], [Use internal PBKDF2])
@@ -521,9 +539,9 @@ AC_ARG_ENABLE([internal-argon2],
AC_ARG_ENABLE([libargon2],
AS_HELP_STRING([--enable-libargon2], [enable external libargon2 (PHC) library (disables internal bundled version)]))
if test $use_internal_argon2 = 0 -o "x$enable_internal_argon2" = "xno" ; then
if test "x$enable_internal_argon2" = "xyes" -o "x$enable_libargon" = "xyes"; then
AC_MSG_WARN([Argon2 in $with_crypto_backend lib is used; internal Argon2 options are ignored.])
if test $use_internal_argon2 = 0 || ( test "x$enable_internal_argon2" = "xno" && test "x$enable_libargon2" != "xyes" ); then
if test "x$enable_internal_argon2" = "xyes" || test "x$enable_libargon2" = "xyes"; then
AC_MSG_NOTICE([Argon2 in $with_crypto_backend lib is used; internal Argon2 options are ignored.])
fi
enable_internal_argon2=no
enable_internal_sse_argon2=no
@@ -535,6 +553,7 @@ elif test "x$enable_libargon2" = "xyes" ; then
AC_CHECK_DECL(Argon2_id,,[AC_MSG_ERROR([You need more recent Argon2 library with support for Argon2id.])], [#include <argon2.h>])
PKG_CHECK_MODULES([LIBARGON2], [libargon2],,[LIBARGON2_LIBS="-largon2"])
enable_internal_argon2=no
use_internal_argon2=0
else
AC_MSG_WARN([Argon2 bundled (slow) reference implementation will be used, please consider to use system library with --enable-libargon2.])
@@ -661,8 +680,36 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
])
CFLAGS=$saved_CFLAGS
dnl Force compiler to use zero_call_used_regs("used") to check for the function attribute support.
dnl Otherwise the compiler may falsely advertise it with __has_attribute operator, even though
dnl it does not implement it on some archs.
AC_MSG_CHECKING([for zero_call_used_regs(user)])
saved_CFLAGS=$CFLAGS
CFLAGS="-O0 -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
void _test_function(void);
__attribute__((zero_call_used_regs("used"))) void _test_function(void) {
volatile int *i; volatile int j = 0; if (j) *i = 0;
}
]],
[[ _test_function() ]]
)],[
AC_DEFINE([HAVE_ATTRIBUTE_ZEROCALLUSEDREGS], 1, [Define to 1 to use __attribute__((zero_call_used_regs("used")))])
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
CFLAGS=$saved_CFLAGS
AC_MSG_CHECKING([for systemd tmpfiles config directory])
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
if test "x$prefix" != "xNONE"; then
saved_PKG_CONFIG=$PKG_CONFIG
PKG_CONFIG="$PKG_CONFIG --define-variable=prefix='${prefix}'"
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
PKG_CONFIG=$saved_PKG_CONFIG
else
PKG_CHECK_VAR([systemd_tmpfilesdir], [systemd], [tmpfilesdir], [], [systemd_tmpfilesdir=no])
fi
AC_MSG_RESULT([$systemd_tmpfilesdir])
AC_SUBST([DEVMAPPER_LIBS])
@@ -776,8 +823,9 @@ CS_NUM_WITH([verity-hash-block], [hash block size for verity mode], [4096])
CS_NUM_WITH([verity-salt-size], [salt size for verity mode], [32])
CS_NUM_WITH([verity-fec-roots], [parity bytes for verity FEC], [2])
CS_STR_WITH([tmpfilesdir], [override default path to directory with systemd temporary files], [])
test -z "$with_tmpfilesdir" && with_tmpfilesdir=$systemd_tmpfilesdir
AC_ARG_WITH([tmpfilesdir],
AS_HELP_STRING([--with-tmpfilesdir=DIR], [override default path to directory with systemd temporary files]),
[], [with_tmpfilesdir=$systemd_tmpfilesdir])
test "x$with_tmpfilesdir" = "xno" || {
CS_ABSPATH([${with_tmpfilesdir}],[with-tmpfilesdir])
DEFAULT_TMPFILESDIR=$with_tmpfilesdir
@@ -796,7 +844,9 @@ test -z "$with_luks2_lock_dir_perms" && with_luks2_lock_dir_perms=0700
DEFAULT_LUKS2_LOCK_DIR_PERMS=$with_luks2_lock_dir_perms
AC_SUBST(DEFAULT_LUKS2_LOCK_DIR_PERMS)
CS_STR_WITH([luks2-external-tokens-path], [path to directory with LUKSv2 external token handlers (plugins)], [LIBDIR/cryptsetup])
AC_ARG_WITH([luks2-external-tokens-path],
AS_HELP_STRING([--with-luks2-external-tokens-path=DIR], [path to directory with LUKSv2 external token handlers (plugins)]),
[], [with_luks2_external_tokens_path=""])
if test -n "$with_luks2_external_tokens_path"; then
CS_ABSPATH([${with_luks2_external_tokens_path}],[with-luks2-external-tokens-path])
EXTERNAL_LUKS2_TOKENS_PATH=$with_luks2_external_tokens_path
@@ -804,6 +854,17 @@ else
EXTERNAL_LUKS2_TOKENS_PATH="\${libdir}/cryptsetup"
fi
AC_SUBST(EXTERNAL_LUKS2_TOKENS_PATH)
dnl We need to define expanded EXTERNAL_LUKS2_TOKENS_PATH, but some other code can depend on prefix=NONE.
dnl Pretend you do not see this hack :-)
saved_prefix=$prefix
saved_exec_prefix=$exec_prefix
test "x$prefix" = "xNONE" && prefix="$ac_default_prefix"
test "x$exec_prefix" = "xNONE" && exec_prefix="$prefix"
expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$EXTERNAL_LUKS2_TOKENS_PATH")
expanded_EXTERNAL_LUKS2_TOKENS_PATH=$(eval echo "$expanded_EXTERNAL_LUKS2_TOKENS_PATH")
AC_DEFINE_UNQUOTED([EXTERNAL_LUKS2_TOKENS_PATH], ["$expanded_EXTERNAL_LUKS2_TOKENS_PATH"], [path to directory with LUKSv2 external token handlers (plugins)])
prefix=$saved_prefix
exec_prefix=$saved_exec_prefix
dnl Override default LUKS format version (for cryptsetup or cryptsetup-reencrypt format actions only).
AC_ARG_WITH([default_luks_format],

View File

@@ -12,30 +12,53 @@ no longer stored directly in dm-crypt target. Starting with cryptsetup 2.0 we
load VK in kernel keyring by default for LUKSv2 devices (when dm-crypt with the
feature is available).
Currently cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
the kernel and can't be read from userspace afterward. Also cryptsetup loads VK in
thread keyring (before passing the reference to dm-crypt target) so that the key
Currently, cryptsetup loads VK in 'logon' type kernel key so that VK is passed in
the kernel and can't be read from userspace afterwards. Also, cryptsetup loads VK in
the thread keyring (before passing the reference to dm-crypt target) so that the key
lifetime is directly bound to the process that performs the dm-crypt setup. When
cryptsetup process exits (for whatever reason) the key gets unlinked in kernel
cryptsetup process exits (for whatever reason) the key gets unlinked in the kernel
automatically. In summary, the key description visible in dm-crypt table line is
a reference to VK that usually no longer exists in kernel keyring service if you
used cryptsetup to for device activation.
used cryptsetup for device activation.
Using this feature dm-crypt no longer maintains a direct key copy (but there's
always at least one copy in kernel crypto layer).
always at least one copy in the kernel crypto layer).
Additionally, libcryptsetup supports the linking of volume keys to
user-specified kernel keyring with crypt_set_keyring_to_link(). The user may
specify keyring name, key type ('user' or 'logon') and key description where
libcryptsetup should link the verified volume key upon subsequent device
activation (or key verification alone).
The volume key(s) (provided the key type is 'user') linked in the user keyring
can be later used to activate the device via crypt_activate_by_keyslot_context()
with CRYPT_KC_TYPE_VK_KEYRING type keyslot context
(acquired by crypt_keyslot_context_init_by_vk_in_keyring()).
Example of how to use volume key linked in custom user keyring from cryptsetup
utility:
1) Open the device and store the volume key to the session keyring:
# cryptsetup open <device> --link-vk-to-keyring "@s::%user:testkey" tst
2) Add a keyslot using the stored volume key in a keyring:
# cryptsetup luksAddKey <device> --volume-key-keyring "%user:testkey"
3) Activate the device using the volume key cached in a keyring ('user' type key)
# cryptsetup open <device> <active_name> --volume-key-keyring "testkey"
II) Keyslot passphrase
The second use case for kernel keyring is to allow cryptsetup reading the keyslot
passphrase stored in kernel keyring instead. The user may load passphrase in kernel
passphrase stored in kernel keyring instead. The user may load the passphrase in the kernel
keyring and notify cryptsetup to read it from there later. Currently, cryptsetup
cli supports kernel keyring for passphrase only via LUKS2 internal token
(luks2-keyring). Library also provides a general method for device activation by
reading passphrase from keyring: crypt_activate_by_keyring(). The key type
(luks2-keyring). The library also provides a general method for device activation by
reading the passphrase from the keyring: crypt_activate_by_keyring(). The key type
for use case II) must always be 'user' since we need to read the actual key
data from userspace unlike with VK in I). Ability to read keyslot passphrase
from kernel keyring also allows easily auto-activate LUKS2 devices.
data from userspace unlike with VK in I). The ability to read keyslot passphrases
from kernel keyring also allows easy auto-activate LUKS2 devices.
Simple example how to use kernel keyring for keyslot passphrase:
Simple example of how to use kernel keyring for keyslot passphrase:
1) create LUKS2 keyring token for keyslot 0 (in LUKS2 device/image)
cryptsetup token add --key-description my:key -S 0 /dev/device
@@ -43,7 +66,7 @@ cryptsetup token add --key-description my:key -S 0 /dev/device
2) Load keyslot passphrase in user keyring
read -s -p "Keyslot passphrase: "; echo -n $REPLY | keyctl padd user my:key @u
3) Activate device using passphrase stored in kernel keyring
3) Activate the device using the passphrase stored in the kernel keyring
cryptsetup open /dev/device my_unlocked_device
4a) unlink the key when no longer needed by
@@ -52,5 +75,5 @@ keyctl unlink %user:my:key @u
4b) or revoke it immediately by
keyctl revoke %user:my:key
If cryptsetup asks for passphrase in step 3) something went wrong with keyring
If cryptsetup asks for a passphrase in step 3) something went wrong with keyring
activation. See --debug output then.

View File

@@ -5,7 +5,7 @@ Why
~~~
LUKS2 format keeps two identical copies of metadata stored consecutively
at the head of metadata device (file or bdev). The metadata
at the head of the metadata device (file or bdev). The metadata
area (both copies) must be updated in a single atomic operation to avoid
header corruption during concurrent write.
@@ -15,17 +15,17 @@ locking with legacy format was not so obvious as it is with the LUKSv2 format.
With LUKS2 the boundary between read-only and read-write is blurry and what
used to be the exclusively read-only operation (i.e., cryptsetup open command) may
easily become read-update operation silently without user's knowledge.
Major feature of LUKS2 format is resilience against accidental
easily become read-update operation silently without the user's knowledge.
A major feature of the LUKS2 format is resilience against accidental
corruption of metadata (i.e., partial header overwrite by parted or cfdisk
while creating partition on mistaken block device).
Such header corruption is detected early on header read and auto-recovery
while creating a partition on a mistaken block device).
Such header corruption is detected early on the header read and the auto-recovery
procedure takes place (the corrupted header with checksum mismatch is being
replaced by the secondary one if that one is intact).
On current Linux systems header load operation may be triggered without user
direct intervention for example by udev rule or from systemd service.
Such clash of header read and auto-recovery procedure could have severe
consequences with the worst case of having LUKS2 device unaccessible or being
On current Linux systems header load operation may be triggered without the user
direct intervention for example by an udev rule or from a systemd service.
Such a clash of header read and auto-recovery procedure could have severe
consequences with the worst case of having a LUKS2 device inaccessible or being
broken beyond repair.
The whole locking of LUKSv2 device headers split into two categories depending
@@ -36,17 +36,17 @@ I) block device
We perform flock() on file descriptors of files stored in a private
directory (by default /run/lock/cryptsetup). The file name is derived
from major:minor couple of affected block device. Note we recommend
that access to private locking directory is supposed to be limited
to superuser only. For this method to work the distribution needs
from major:minor couple of the affected block device. Note we recommend
that access to the private locking directory is supposed to be limited
to the superuser only. For this method to work the distribution needs
to install the locking directory with appropriate access rights.
II) regular files
~~~~~~~~~~~~~~~~~
First notable difference between headers stored in a file
A first notable difference between headers stored in a file
vs. headers stored in a block device is that headers in a file may be
manipulated by the regular user unlike headers on block devices. Therefore
manipulated by the regular user, unlike headers on block devices. Therefore
we perform flock() protection on file with the luks2 header directly.
Limitations
@@ -58,4 +58,40 @@ while locking is enabled.
We do not suppress any other negative effect that two or more concurrent
writers of the same header may cause.
b) The locking is not cluster aware in any way.
b) The locking is not cluster-aware in any way.
Additional LUKS2 locks
======================
LUKS2 reencryption device lock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Device in LUKS2 reencryption is protected by an exclusive lock placed in the default
locking directory. The lock's purpose is to exclude multiple processes from
performing reencryption on the same device (identified by LUKS uuid). The lock
is taken no matter the LUKS2 reencryption mode (online or offline).
LUKS2 memory hard global lock
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An optional global lock that makes libcryptsetup serialize memory hard
pbkdf function when deriving a key encryption key from passphrase on unlocking
LUKS2 keyslot. The lock has to be enabled via the CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
flag. The lock is placed in the default locking directory.
LUKS2 OPAL lock
~~~~~~~~~~~~~~~
Exclusive per device lock taken when manipulating LUKS2 device configured for use with
SED OPAL2 locking range.
Lock ordering
=============
To avoid a deadlock following rules must apply:
- LUKS2 reencrytpion lock must be taken before LUKS2 OPAL lock.
- LUKS2 OPAL lock must be taken before LUKS2 metadata lock.
- LUKS2 memory hard global lock can not be used with other locks.

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.9.1
# Doxyfile 1.9.8
#---------------------------------------------------------------------------
# Project related configuration options
@@ -10,9 +10,9 @@ PROJECT_BRIEF = "Public cryptsetup API"
PROJECT_LOGO =
OUTPUT_DIRECTORY = doxygen_api_docs
CREATE_SUBDIRS = NO
CREATE_SUBDIRS_LEVEL = 8
ALLOW_UNICODE_NAMES = NO
OUTPUT_LANGUAGE = English
OUTPUT_TEXT_DIRECTION = None
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
@@ -39,6 +39,7 @@ OPTIMIZE_OUTPUT_SLICE = NO
EXTENSION_MAPPING =
MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
MARKDOWN_ID_STYLE = DOXYGEN
AUTOLINK_SUPPORT = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
@@ -52,6 +53,7 @@ INLINE_SIMPLE_STRUCTS = NO
TYPEDEF_HIDES_STRUCT = YES
LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 1
TIMESTAMP = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -72,6 +74,7 @@ INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
HIDE_COMPOUND_REFERENCE= NO
SHOW_HEADERFILE = YES
SHOW_INCLUDE_FILES = YES
SHOW_GROUPED_MEMB_INC = NO
FORCE_LOCAL_INCLUDES = NO
@@ -101,9 +104,12 @@ QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_IF_INCOMPLETE_DOC = YES
WARN_NO_PARAMDOC = NO
WARN_IF_UNDOC_ENUM_VAL = NO
WARN_AS_ERROR = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LINE_FORMAT = "at line $line of file $file"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
@@ -111,6 +117,7 @@ WARN_LOGFILE =
INPUT = doxygen_index.h \
../lib/libcryptsetup.h
INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING =
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
@@ -126,6 +133,7 @@ FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
FORTRAN_COMMENT_AFTER = 72
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -158,15 +166,17 @@ HTML_FOOTER =
HTML_STYLESHEET =
HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
HTML_COLORSTYLE = AUTO_LIGHT
HTML_COLORSTYLE_HUE = 220
HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
HTML_TIMESTAMP = YES
HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
HTML_CODE_FOLDING = YES
HTML_INDEX_NUM_ENTRIES = 100
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_FEEDURL =
DOCSET_BUNDLE_ID = org.doxygen.Project
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
DOCSET_PUBLISHER_NAME = Publisher
@@ -177,6 +187,7 @@ GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = NO
SITEMAP_URL =
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE = org.doxygen.Project
@@ -189,14 +200,16 @@ GENERATE_ECLIPSEHELP = NO
ECLIPSE_DOC_ID = org.doxygen.Project
DISABLE_INDEX = NO
GENERATE_TREEVIEW = NO
FULL_SIDEBAR = NO
ENUM_VALUES_PER_LINE = 4
TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
OBFUSCATE_EMAILS = YES
HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
FORMULA_MACROFILE =
USE_MATHJAX = NO
MATHJAX_VERSION = MathJax_2
MATHJAX_FORMAT = HTML-CSS
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
MATHJAX_EXTENSIONS =
@@ -227,9 +240,7 @@ PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
LATEX_BIB_STYLE = plain
LATEX_TIMESTAMP = NO
LATEX_EMOJI_DIRECTORY =
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
@@ -240,7 +251,6 @@ COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
@@ -261,12 +271,17 @@ XML_NS_MEMB_FILE_SCOPE = NO
#---------------------------------------------------------------------------
GENERATE_DOCBOOK = NO
DOCBOOK_OUTPUT = docbook
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
GENERATE_SQLITE3 = NO
SQLITE3_OUTPUT = sqlite3
SQLITE3_RECREATE_DB = YES
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
@@ -294,15 +309,14 @@ ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
# Configuration options related to diagram generator tools
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
DIA_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
DOT_NUM_THREADS = 0
DOT_FONTNAME = Helvetica
DOT_FONTSIZE = 10
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
@@ -318,18 +332,20 @@ CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DIR_GRAPH_MAX_DEPTH = 1
DOT_IMAGE_FORMAT = png
INTERACTIVE_SVG = NO
DOT_PATH =
DOTFILE_DIRS =
MSCFILE_DIRS =
DIA_PATH =
DIAFILE_DIRS =
PLANTUML_JAR_PATH =
PLANTUML_CFG_FILE =
PLANTUML_INCLUDE_PATH =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
MSCGEN_TOOL =
MSCFILE_DIRS =

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libcryptsetup API log example
*
* Copyright (C) 2011-2023 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
* 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.
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
*/
#include <stdio.h>

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* libcryptsetup API - using LUKS device example
*
* Copyright (C) 2011-2023 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
* 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.
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
*/
#include <stdio.h>

View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,428 @@
Attribution-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-ShareAlike 4.0 International Public
License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-ShareAlike 4.0 International Public License ("Public
License"). To the extent this Public License may be interpreted as a
contract, You are granted the Licensed Rights in consideration of Your
acceptance of these terms and conditions, and the Licensor grants You
such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and
conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
l. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
m. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.

View File

@@ -0,0 +1,354 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
-----
In addition, as a special exception, the copyright holders give
permission to link the code of portions of this program with the
OpenSSL library under certain conditions as described in each
individual source file, and distribute linked combinations
including the two.
You must obey the GNU General Public License in all respects
for all of the code used other than OpenSSL. If you modify
file(s) with this exception, you may extend this exception to your
version of the file(s), but you are not obligated to do so. If you
do not wish to do so, delete this exception statement from your
version. If you delete this exception statement from all source
files in the program, then also delete it here.

Binary file not shown.

View File

@@ -1,6 +1,6 @@
Cryptsetup 2.7.0-rc0 Release Notes
==================================
Stable release candidate with new features and bug fixes.
Cryptsetup 2.7.0 Release Notes
==============================
Stable release with new features and bug fixes.
Changes since version 2.6.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -47,15 +47,14 @@ Changes since version 2.6.1
encryption (--hw-opal option) or without the software layer
(--hw-opal-only option).
You can see the configured segment parameters in the luksDump command.
Note: formal specification of OPAL LUKS2 segment metadata will be added
in the next release candidate. LUKS2 devices with OPAL segments set
a new requirement flag in the LUKS2 header to prevent older cryptsetup
metadata manipulation. Do not use hardware-only encryption if you do
not fully trust your hardware vendor.
LUKS2 devices with OPAL segments set a new requirement flag in
the LUKS2 header to prevent older cryptsetup metadata manipulation.
Do not use hardware-only encryption if you do not fully trust your
hardware vendor.
Compatibility notes:
- Linux kernel SED interface does NOT work through USB external
adapters due to the mising compatibility layer in Linux USB storage
adapters due to the missing compatibility layer in Linux USB storage
drivers (even if USB hardware itself can support OPAL commands).
- other TCG security subsystems like Ruby or Pyrite are not
supported. Note that many drives support only Pyrite subsystem that
@@ -63,7 +62,6 @@ Changes since version 2.6.1
- compatibility among OPAL-enabled drives is often very problematic,
specifically for older drives. Many drives have bugs in the firmware
that make the Linux kernel interface unusable.
- unlocking key for OPAL remains in memory even after luksSuspend
- if you forget the OPAL admin password, the only way to recover is
the full drive factory reset through the PSID key (usually printed
on the drive itself) that wipes all data on the drive (not only the
@@ -186,9 +184,6 @@ Changes since version 2.6.1
These options are intended to be used for integration with other
systems for automation.
Note: the API will slightly change in the next release candidate
(active reencryption will need to setup old and new keys together).
Users can now use the volume key (not passphrase) stored in arbitrary
kernel keyring and directly use it in particular cryptsetup commands
with --volume-key-keyring option. The keyring can use various policies
@@ -205,7 +200,7 @@ Changes since version 2.6.1
<keyring_description>::<key_description>.
The <keyring_description> contains the existing kernel keyring
description (numeric id or keyctl format). The <keyring_description>
may be optionaly prefixed with "%:" or "%keyring:". The string "::" is
may be optionally prefixed with "%:" or "%keyring:". The string "::" is
a delimiter that separates keyring and key descriptions.
The <key_description> has the same syntax as used in the
--volume-key-keyring option.
@@ -264,9 +259,7 @@ Changes since version 2.6.1
option is specified.
* Properly report if the dm-verity device cannot be activated due to
the inability to verify the signed root hash.
If the kernel returns ENOKEY, it is properly propagated.
the inability to verify the signed root hash (ENOKEY).
* Fix to check passphrase for selected keyslot only when adding
new keyslot.
@@ -305,9 +298,9 @@ Changes since version 2.6.1
* Fix wipe operation that overwrites the whole device if used for LUKS2
header with no keyslot area.
Formatting a LUKS2 device with no defined keyslots area is a very
specific operation, and the code now properly recognizes such
configuration.
Formatting a LUKS2 device with no defined keyslots area is a very
specific operation, and the code now properly recognizes such
configuration.
* Fix luksErase to work with detached LUKS header.
@@ -376,6 +369,12 @@ Changes since version 2.6.1
Argon2 has been available since version 1.10, but we need version 1.11,
which will allow empty passwords.
* Used Argon2 PBKDF implementation is now reported in debug mode
in the cryptographic backend version. For native support in
OpenSSL 3.2 or libgcrypt 1.11, "argon2" is displayed.
If libargon2 is used, "cryptsetup libargon2" (for embedded
library) or "external libargon2" is displayed.
* Link only libcrypto from OpenSSL.
This reduces dependencies as other OpenSSL libraries are not needed.
@@ -404,6 +403,9 @@ Changes since version 2.6.1
and possibly corrupt data if the user also tries to modify the
underlying device.
* Update keyring and locking documentation and LUKS2 specification
for OPAL2 support.
Libcryptsetup API extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The libcryptsetup API is backward compatible for all existing symbols.

30
docs/v2.7.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,30 @@
Cryptsetup 2.7.1 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.7.0 should upgrade to this version.
Changes since version 2.7.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix interrupted LUKS1 decryption resume.
With the replacement of the cryptsetup-reencrypt tool by the cryptsetup
reencrypt command, resuming the interrupted LUKS1 decryption operation
could fail. LUKS2 was not affected.
* Allow --link-vk-to-keyring with --test-passphrase option.
This option allows uploading the volume key in a user-specified kernel
keyring without activating the device.
* Fix crash when --active-name was used in decryption initialization.
* Updates and changes to man pages, including indentation, sorting options
alphabetically, fixing mistakes in crypt_set_keyring_to_link, and fixing
some typos.
* Fix compilation with libargon2 when --disable-internal-argon2 was used.
* Do not require installed argon2.h header and never compile internal
libargon2 code if the crypto library directly supports Argon2.
* Fixes to regression tests to support older Linux distributions.

31
docs/v2.7.2-ReleaseNotes Normal file
View File

@@ -0,0 +1,31 @@
Cryptsetup 2.7.2 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 should upgrade to this version.
Changes since version 2.7.1
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix activation of OPAL-only encrypted LUKS device with tokens.
The issue was caused by an invalid volume key check (assert)
that is impossible without software encryption.
* Fix formatting of OPAL devices with 4096-byte sector size.
* Fix incorrect OPAL locking range alignment calculation if used
over an unaligned device partition.
* Add --hw-opal-factory-reset option description to the manual page.
* Do not check the passphrase quality for OPAL Admin PIN,
as this passphrase already exists.
* Update license for FAQ document to CC BY-SA 4.0.
NOTE: Please note that with OPAL-only (--hw-opal-only) encryption,
the configured OPAL administrator PIN (passphrase) allows unlocking
all configured locking ranges without LUKS keyslot decryption
(without knowledge of LUKS passphrase).
Because of many observed problems with compatibility, cryptsetup
currently DOES NOT use OPAL single-user mode, which would allow such
decoupling of OPAL admin PIN access.

114
docs/v2.7.3-ReleaseNotes Normal file
View File

@@ -0,0 +1,114 @@
Cryptsetup 2.7.3 Release Notes
==============================
Stable bug-fix release with security fixes.
All users of cryptsetup 2.7 must upgrade to this version.
Changes since version 2.7.2
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Do not allow formatting LUKS2 with Opal SED (hardware encryption)
if the reported logical sector size for the block device and Opal
encryption logical block differs.
Such a configuration can lead to a partially encrypted Opal locking
range or data destruction following the expected locking range.
Some NVMe drives support multiple LBAF profiles (typically supporting
512-byte and 4096-byte sector size). Some broken Opal NVMe firmware can
report bogus encryption size that disagrees with real used sector size.
This usually happens after low-level NVMe reformatting (LBAF profile
change with nvme utility) to different sector size.
Moreover, some firmware versions do not properly reset this even after
explicit PSID revert.
Cryptsetup calculates the Opal locking range using the reported block
size in Opal geometry ioctl. Unfortunately, the broken firmware drive
internally uses the logical block size of the block device, which can
differ. This can lead to two possible situations:
- Opal reports a smaller block size (512-byte) while the drive uses
a 4096-byte sector. The configured locking range is then much larger,
destroying data following the expected locking range setting.
- Opal reports a larger block size (4096-byte) while the drive uses
a 512-byte sector. The configured locking range is then much smaller,
leaving the remaining space in the locking range unencrypted (violating
the confidentiality of data).
Cryptsetup now detects this discrepancy and disallows LUKS2 format with
Opal hardware encryption in such a case.
For already formatted devices, you will see this warning:
"Bogus OPAL logical block size differs from device block size."
If you also used software encryption (dm-crypt over Opal), data will
still be fully encrypted with software dm-crypt.
With hw-only encryption, your configuration is probably already broken
(insecure or accessing data beyond the assigned area).
Note that this is caused by bad firmware (seen with multiple vendors),
and the problem was reported, at least for drives we have access to.
* Fixes to wiping LUKS2 headers after Opal locking area erase.
As the hardware locking range is destroyed (cryptsetup erase command),
the LUKS2 header is no longer usable and was partially wiped.
Now the code fully wipes also the secondary header, as the previous
code wiped only the primary LUKS area.
Note that this is an exception, as the normal erase command wipes only
the keyslots, keeping the LUKS2 header in place. With Opal encryption,
the data segment is no longer valid, so the whole LUKS2 header is no
longer usable.
* Mention the need for possible PSID revert before Opal format for some
drives (man page).
* Fix Bitlocker-compatible code to ignore newly seen metadata entries.
Recent Windows OS versions started to include new (undocumented)
metadata entries in Bitlocker. These entries are now quietly ignored,
allowing Bitlocker images to open with cryptsetup again.
* Fix interactive query retry if LUKS2 unbound keyslot is present.
If an unbound keyslot is present, the password query retry count is
now properly applied.
* Detect unsupported zoned devices for LUKS header devices.
Zoned devices cannot be written with direct-io and used for LUKS header
logic in general. Code now rejects placing the LUKS header on a zoned
device, while you can still create a detached header and use a zoned
device for encrypted data.
* Allow "capi" cipher format for benchmark command and fix parsing
of plain IV in "capi" format.
Some ciphers can be specified only in Linux kernel crypto notation
(in short, "capi"). Code now allows this format also for benchmark,
for example, "benchmark -c capi:xts\(aes\)-plain64"
(that is equivalent to -c aes-xts-plain64).
* Add support for HCTR2 encryption mode.
The HCTR2 encryption mode was added to the Linux kernel for fscrypt,
but as it is a length-preserving mode (with sector tweak), it can be
easily used for disk encryption, too.
The mode has the same property as wide modes (any change is propagated
to the whole sector instead of only one block as in XTS mode).
As it needs a larger initialization vector (32 bytes), we need to add
an exception in the userspace format code.
You can now use --cipher aes-hctr2-plain64 for the format operation.
* Source code now uses SPDX license identifiers instead of full
license preambles.
* Fix missing includes for cryptographic backend that could cause
compilation errors for some systems.
* Fix tests to work correctly in FIPS mode with recent OpenSSL 3.2.
* Fix various (mostly false positive) issues detected by Coverity.

62
docs/v2.7.4-ReleaseNotes Normal file
View File

@@ -0,0 +1,62 @@
Cryptsetup 2.7.4 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 should upgrade to this version.
Changes since version 2.7.3
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Detect device busy failure for device-mapper table-referenced devices.
Some device-mapper ioctl failures can disappear in libdevmapper,
causing the libcryptsetup wrapper to return an invalid error (EINVAL)
instead of EEXIST or EBUSY. One such case is when there is a device
creation race, and the device-mapper device name is created, but
the following mapping table load fails. This can happen because some
block devices used in table mapping have already been claimed by
another process (the kernel needs exclusive access).
The kernel ioctl properly returns EBUSY; this errno is lost in
libdevmapper (dm_task_get_errno returns 0). It should be fixed by
libdevmapper in the future.
Such behavior was seen in the systemd way of handling dm-verity
devices. With these changes, the code should react for EEXIST and
EBUSY, as another process has already activated the device.
Code calling libcryptsetup also must not check the underlying device
with an exclusive open flag (O_EXCL). Otherwise, it could cause a race
in the kernel device-mapper, resulting in no process succeeding device
activation (see also CRYPT_ACTIVATE_SHARED flag below).
* Fix shared activation for dm-verity devices.
The CRYPT_ACTIVATE_SHARED flag was silently ignored when activating
dm-verity devices. Dm-verity shared activation is generally safe
since all verity devices are read-only.
The shared flag is a way to skip the exclusive access check for the
device, allowing it to create multiple mappings with the same device or
properly handle a racy concurrent activation of devices with the same
name from different processes.
* Add --shared option for veritysetup open action.
The option allows the data device to be used in multiple device-mapper
table mappings (skip exclusive access check) or to allow concurrent
dm-verity device activation of the same device (only one process
succeeds in this case; the other will return EEXIST or EBUSY).
* Do not use exclusive flag for the allocated backing loop files.
Using this flag is an undefined operation for opening an existing file.
The flag should be used only for allocated loop (block) devices.
* Fixes for problems found by static analyzers and Valgrind.
These include fixes for non-default libgcrypt, NSS, and Nettle
cryptographic backends, buffer operations to avoid partial read/write,
and several other workarounds for mostly false positive warnings.
* Fixes to tests and CI scripts.

23
docs/v2.7.5-ReleaseNotes Normal file
View File

@@ -0,0 +1,23 @@
Cryptsetup 2.7.5 Release Notes
==============================
Stable bug-fix release.
All users of cryptsetup 2.7 must upgrade to this version.
Changes since version 2.7.4
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix possible online reencryption data corruption (only in 2.7.x).
In some situations (initializing a suspended device-mapper device),
cryptsetup disabled direct-io device access. This caused unsafe
online reencryption operations that could lead to data corruption.
The code now adds strict checks (and aborts the operation) and
changes direct-io detection code to prevent data corruption.
* Fix a clang compilation error in SSH token plugin.
As clang linker treats missing symbols as errors, the linker phase
for the SSH token failed as the optional cryptsetup_token_buffer_free
was not defined.
* Fix crypto backend initialization in crypt_format_luks2_opal API call.

328
docs/v2.8.0-ReleaseNotes Normal file
View File

@@ -0,0 +1,328 @@
Cryptsetup 2.8.0 Release Notes
==============================
Stable release with new features and bug fixes
All users of cryptsetup 2.7 must upgrade to this version.
Changes since version 2.7.5
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Introduce support for inline mode (use HW sectors with additional hardware metadata space).
Some enterprise NVMe drives allow formatting sector size with additional metadata space,
for example, sector size 4096 bytes + 64 bytes for metadata.
We hope common firmware will soon support such features in more recent models.
If this metadata space is available (not internally used by a data integrity profile),
it removes the need to use the dm-integrity layer for sector metadata allocation.
This means that the performance bottleneck caused by the dm-integrity journal is eliminated.
Note: such drive must be reformatted with an external nvme tool.
You can check for support (reported as LBA format) by running the command
"nvme id-ns -H <nvme device>" and then you can reformat to the selected profile
(with complete data loss) with "nvme format -l <lbaf>.
This way, you can also reformat NVMe drive to 4096-byte sectors,which is strongly recommended
for encryption performance.
The required device mapper for inline mode was introduced in Linux kernel version 6.11.
The inline mode can be used with the new --integrity-inline option.
For integritysetup, the kernel dm-integrity layer is still used, but it directly maps metadata
to the hardware (eliminating the journal).
For cryptsetup, the dm-integrity layer is eliminated, and only the dm-crypt kernel driver is used.
The libcryptsetup exports a new crypt_format_inline API call.
Examples (underlying device must provide inline HW metadata space):
Use integritysetup format with inline mode with default CRC32 checksums:
# integritysetup format --sector-size 4096 --integrity-inline <device> [--no-wipe]
# integritysetup open <device> test
# integritysetup status test
/dev/mapper/test is active.
type: INTEGRITY
tag size: 4 [bytes]
integrity: crc32c
device: <device>
sector size: 4096 [bytes]
...
inline mode
journal: not active
Use LUKS2 with authenticated encryption (here with AEGIS AEAD cipher):
# cryptsetup luksFormat --integrity-inline --integrity aead --sector-size 4096 \
-c aegis128-random --key-size 128 <device> [--integrity-no-wipe]
# cryptsetup open <device> test
# cryptsetup luksDump <device>
...
Requirements: inline-hw-tags
After format, the inline mode is used automatically, and no special options are needed.
Please check the manual pages for more details about used options.
Note that the LUKS2 authenticated encryption is still an experimental feature.
The inline mode only improves performance by removing the dm-integrity layer.
* Finalize use of keyslot context API.
Keyslot context is a generic abstraction over keyslot manipulation.
It extends many exiting commands by additional functions like tokens in activation, resume,
reencryption and similar commands without introducing new specific API functions.
* Make all keyslot context types fully self-contained.
In the previous version, the caller is responsible for releasing of some allocated memory.
In this version, all memory is allocated internally. The existing keyslot context API function
provides backward compatibility through versioned symbols.
* Add --key-description and --new-key-description cryptsetup options.
These can be used for the specification of the keyring with passphrase retrieval in the open,
resize, luksResume, luksFormat, luksAddKey and luksDump.
* Support more precise keyslot selection in reencryption initialization.
Reencryption must update stored keys in keyslots, so it needs to unlock all keyslots first.
When no specific keyslot is selected by the --key-slot option, all active keyslots are updated.
Users may narrow down the selection of keyslots by specifying either --token-id, --token-type
or --token-only option. Only keyslots associated with the specific token (--token-id) or
a specific type (--token-type) or any token (--token-only) will be updated.
All other keyslots will be erased after reencryption is finished.
During reencryption, there are two volume keys (old and new).
For very specific use cases, reencryption can also be initialized by providing
volume keys directly by --volume-key-file, --new-volume-key-file, --volume-key-keyring
or --new-volume-key-keyring options. These options allow reencryption of the device with
no active keyslots (these can be added later).
If the --force-no-keyslots option is specified, all active keyslots will be erased after
the reencryption operation is finished.
* Allow reencryption to resume using token and volume keys.
The reencryption can be resumed using tokens (similar to initialization described above).
For very specific use cases, reencryption can be resumed by providing volume keys.
* Cryptsetup repair command now tries to check LUKS keyslot areas for corruption.
A keyslot binary area contains an encrypted volume key diffused to a larger area by
the anti-forensic splitter. If this area is corrupted, the keyslot can no longer be unlocked,
even with the correct password.
Active keyslot area should look like random data, so some specific corruption can be detected
by randomness analysis.
Cryptsetup repair command now tries to analyze the area expecting a uniform distribution
of bytes in 4096-byte blocks. If a problem is detected, it tries to localize corruption
in a smaller block (using the expected bit count).
Both tests are based on the Chi-squared statistical test.
This analysis can replace the external keyslot check program and usually is more sensitive.
However, it cannot detect all corruptions and can produce false positives.
Please use it as a hint when your password is no longer accepted, and you suspect
header corruption. This is the example output of the analysis:
# cryptsetup repair <device>
Keyslot 2 binary data could be corrupted.
Suspected offset: 0x88000
You can use hexdump -v -C -n 128 -s <offset_0xXXXX> <device> to inspect the data.
The test does not modify the header. A keyslot corruption cannot be repaired.
You have to use a backup header.
* Opal2 SED: PSID keyfile is now expected to be 32 alphanumeric characters.
If the keyfile size is not explicitly set, it uses only first 32 bytes.
All Opal2 manufacturers seem to use PSID of this length.
* Opal2: Avoid the Erase method and use Secure Erase for locking range.
The Erase method is defined for Single-user mode (SUM) and works on SUM-enabled locking ranges.
As we do not use SUM yet, this always fails and falls back to Secure erase anyway.
* Opal2: Fix some error description (in debug only).
Some Opal error messages were incorrect.
Cryptsetup now use all codes according to TCG specifications.
* Opal2: Do not allow deferred deactivation.
The self-encrypting drive must be locked immediately; deferred deactivation is not supported.
* Allow --reduce-device-size and --device-size combination for reencryption (encrypt) action.
For some very specific cases, this can be used to encrypt only part of the device together
with allocation a new space for the LUKS header.
* Fix the userspace storage backend to support kernel "capi:" cipher specification format.
This avoids unnecessary fallback to the device-mapper instead of the userspace crypto library
in luksFormat. The "capi:" is Linux kernel cryptographic format.
For example, capi:xts(aes)-plain64 is equivalent of aes-xts-plain64.
* Disallow conversion from LUKS2 to LUKS1 if kernel "capi:" cipher specification is used.
LUKS1 never officially supported this cipher specification format.
Such devices cannot be converted to LUKS1 (while existing devices can still be activated).
* Explicitly disallow kernel "capi:" cipher specification format for LUKS2 keyslot encryption.
This specification is intended to be used for data encryption, not for keyslots.
* Do not allow conversion of LUKS2 to LUKS1 if an unbound keyslot is present.
LUKS1 does not support unbound keyslots. Such devices cannot be converted.
* cryptsetup: Adjust the XTS key size for kernel "capi:" cipher specification.
Double key size as there are two keys the same way as for dm-crypt format.
* Remove keyslot warning about possible failure due to low memory.
This check was intended to warn users about possible out-of-memory situations
but produced many false positives.
* Do not limit Argon2 KDF memory cost on systems with more than 4GB of available memory.
The memory cost is intended to be limited only in low-memory situations (like virtual machines
without swap), not on systems with plenty of RAM.
* Properly report out of memory error for cryptographic backends implementing Argon2.
* Avoid KDF2 memory cost overflow on 32-bit platforms.
* Do not use page size as a fallback for device block size.
This check produced wrong values if used on platforms with larger page sizes (64kB)
and specific underlying storage (like ZFS).
* veritysetup: Check hash device size in advance.
If hashes are stored in a file image, allocate the size in advance.
For a block device, check if hashes (Merkle tree) fits the device.
* Print a better error message for unsupported LUKS2 AEAD device resize.
* Optimize LUKS2 metadata writes.
LUKS2 supports several JSON area length configurations. Do not write full metadata
(including padding), as it may generate noticeable overhead with LUKS2.
* veritysetup: support --error-as-corruption option.
The panic/restart_on_error options were introduced in Linux kernel 6.12 and process errors
(like media read error) the same way as data corruption.
Use this flag in combination with --panic-on-corruption or --restart-on-corruption.
* Report all sizes in status and dump command output in the correct units.
Since the support of --sector-size option, the meaning of "sectors" became ambiguous as it
usually means 512-byte sectors (device-mapper unit). Confusion occurs when the sector size
is 4096 bytes while units used for display are 512-byte sectors.
All status commands in tools now display units explicitly to avoid confusion.
For example:
# cryptsetup status test
...
sector size: 4096 [bytes]
offset: 32768 [512-byte units] (134217728 [bytes])
size: 7501443760 [512-byte units] (30725913640960 [bytes])
If you parse the output of status commands, please check your scripts to ensure they work
with the new output properly.
* Add --integrity-key-size option to cryptsetup.
This option can be used to set up non-standard integrity key size (e.g. for HMAC).
It adds a new (optional) JSON "key_size" attribute in the segment.integrity JSON object
(see updated LUKS2 specification). If not set, the code uses selected hash length size.
* Support trusted & encrypted keyrings for plain devices.
* Support plain format resize with a keyring key.
If a plain dm-crypt device references the keyring, cryptsetup now allows resizing.
The user must ensure that the key in the keyring is unchanged since activation.
Otherwise, reloading the key can cause data corruption after an unexpected key change.
* TCRYPT: Clear mapping of system-encrypted partitions.
TrueCrypt/VeraCrypt supports full system encryption (only a partition table is not encrypted)
or system partition encryption (only a system partition is encrypted).
The metadata header then contains the offset and size of the encrypted area.
Cryptsetup needs to know the specific partition offset to calculate encryption parameters.
To properly map a partition, the user must specify a real partition device so cryptsetup
can calculate this offset. As the partition can be an image in a file, cryptsetup now tries
to determine proper parameters and use device size stored in VeraCrypt metadata.
Please see the manual page description (TCRYPT section) for a detailed description.
* TCRYPT: Print all information from the decrypted metadata header in the tcryptDump command.
Print also volume sizes (if present) and flags.
* Always lock the volume key structure in memory.
Some memory for safe allocation was not allocated from locked (unswappable) memory.
Older cryptsetup locked all memory. Selective locking was introduced in version 2.6.0.
* Do not run direct-io read check on block devices.
Block devices always support direct-io.
This check produced unnecessary error with locked Opal2 devices.
* Fix a possible segfault in deferred deactivation.
Thanks Clément Guérin for the report.
* Exclude cipher allocation time from the cryptsetup benchmark.
* Add Mbed-TLS optional crypto backend.
Mbed-TLS is a tiny TLS implementation designed for embedded environments.
The backend can be enabled with the --with-crypto_backend=mbedtls configure option.
* Fix the wrong preprocessor use of #ifdef for config.h processed by Meson.
Cryptsetup supports Autoconf and, optionally, Meson configuration.
Part of the code wrongly used #ifdef instead of #if conditional sections.
This caused problems with Meson-generated config.h.
* Reorganize license files.
The license text files are now in docs/licenses.
The COPYING file in the root directory is the default license.
Libcryptsetup API extensions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The libcryptsetup API is backward compatible with all existing symbols.
Due to the self-contained memory allocation, these symbols have the new version
crypt_keyslot_context_init_by_passphrase;
crypt_keyslot_context_init_by_keyfile;
crypt_keyslot_context_init_by_token;
crypt_keyslot_context_init_by_volume_key;
crypt_keyslot_context_init_by_signed_key;
crypt_keyslot_context_init_by_keyring;
crypt_keyslot_context_init_by_vk_in_keyring;
New symbols:
crypt_format_inline
crypt_get_old_volume_key_size
crypt_reencrypt_init_by_keyslot_context
crypt_safe_memcpy
New defines:
CRYPT_ACTIVATE_HIGH_PRIORITY
CRYPT_ACTIVATE_ERROR_AS_CORRUPTION
CRYPT_ACTIVATE_INLINE_MODE
CRYPT_REENCRYPT_CREATE_NEW_DIGEST
New requirement flag:
CRYPT_REQUIREMENT_INLINE_HW_TAGS

40
docs/v2.8.1-ReleaseNotes Normal file
View File

@@ -0,0 +1,40 @@
Cryptsetup 2.8.1 Release Notes
==============================
Stable bug-fix release with minor extensions.
All users of cryptsetup 2.8.0 must upgrade to this version.
Changes since version 2.8.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Fix status and deactivation of TCRYPT (VeraCrypt compatible) devices that use chained ciphers.
* Fix unlocking BITLK (BitLocker compatible) devices with multibyte UTF8 characters in the passphrase.
* Do not allow activation of the LUKS2 device if the used keyslot is not encrypted (it uses a null cipher).
Such a configuration cannot be created by cryptsetup, but can be crafted outside of it.
Null cipher is sometimes used to create an empty container for later reencryption.
Only an empty passphrase can activate such a container (the same as in LUKS1).
* Do not silently decrease PBKDF parallel cost (threads) if set by an option.
The maximum parallel cost is limited to 4 threads.
* Fixes to configuration and installation scripts.
Meson and autoconf tools now properly support --prefix option for temporary directory installation.
Multiple fixes and cleanups to config.h for compatibility between Meson and autoconf.
Fix the luks2-external-tokens-path Meson option to work the same as in autoconf.
Fix Meson install for tool binaries, install fvault2Open man page and include test/fuzz/meson.build in release.
* Major update to manual pages.
Try to explain the PBKDF hardcoded limits.
Add a better explanation for automatic integrity tag recalculation.
Mention crypt/verity/integritytab.
Remove or reformulate some misleading warnings present only with old and no longer supported kernels.
Clarify that some commands do not wipe data and unify OPAL reset wording.
Clarify the --label option.
There are also many other grammar and stylistic fixes to unify the man-page style.
* Fixes for false-positive and annoying (optional) warnings added in recent compilers.

View File

@@ -1,23 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* BITLK (BitLocker-compatible) volume handling
*
* Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2023 Milan Broz
* Copyright (C) 2019-2023 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.
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2025 Milan Broz
* Copyright (C) 2019-2025 Vojtech Trefny
*/
#include <errno.h>
@@ -124,6 +111,7 @@ struct bitlk_superblock {
struct bitlk_fve_metadata {
/* FVE metadata block header */
uint8_t signature[8];
/* size of this block (in 16-byte units) */
uint16_t fve_size;
uint16_t fve_version;
uint16_t curr_state;
@@ -145,6 +133,32 @@ struct bitlk_fve_metadata {
uint64_t creation_time;
} __attribute__ ((packed));
struct bitlk_validation_hash {
uint16_t size;
uint16_t role;
uint16_t type;
uint16_t flags;
/* likely a hash type code, anything other than 0x2005 isn't supported */
uint16_t hash_type;
uint16_t unknown1;
/* SHA-256 */
uint8_t hash[32];
} __attribute__ ((packed));
struct bitlk_fve_metadata_validation {
/* FVE metadata validation block header */
uint16_t validation_size;
uint16_t validation_version;
uint32_t fve_crc32;
/* this is a single nested structure's header defined here for simplicity */
uint16_t nested_struct_size;
uint16_t nested_struct_role;
uint16_t nested_struct_type;
uint16_t nested_struct_flags;
/* datum containing a similar nested structure (encrypted using VMK) with hash (SHA256) */
uint8_t nested_struct_data[BITLK_VALIDATION_VMK_DATA_SIZE];
} __attribute__ ((packed));
struct bitlk_entry_header_block {
uint64_t offset;
uint64_t size;
@@ -250,10 +264,11 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
bool supported = false;
int r = 0;
/* only passphrase or recovery passphrase vmks are supported (can be used to activate) */
/* only passphrase, recovery passphrase, startup key and clearkey vmks are supported (can be used to activate) */
supported = (*vmk)->protection == BITLK_PROTECTION_PASSPHRASE ||
(*vmk)->protection == BITLK_PROTECTION_RECOVERY_PASSPHRASE ||
(*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY;
(*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY ||
(*vmk)->protection == BITLK_PROTECTION_CLEAR_KEY;
while ((end - start) >= (ssize_t)(sizeof(key_entry_size) + sizeof(key_entry_type) + sizeof(key_entry_value))) {
/* size of this entry */
@@ -310,20 +325,19 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
crypt_volume_key_add_next(&((*vmk)->vk), vk);
/* clear key for a partially decrypted volume */
} else if (key_entry_value == BITLK_ENTRY_VALUE_KEY) {
/* We currently don't want to support opening a partially decrypted
* device so we don't need to store this key.
*
* key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
* key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
* vk = crypt_alloc_volume_key(key_size, key);
* if (vk == NULL)
* return -ENOMEM;
* crypt_volume_key_add_next(&((*vmk)->vk), vk);
*/
log_dbg(cd, "Skipping clear key metadata entry.");
/* For clearkey protection, we need to store this key */
key_size = key_entry_size - (BITLK_ENTRY_HEADER_LEN + 4);
key = (const char *) data + start + BITLK_ENTRY_HEADER_LEN + 4;
vk = crypt_alloc_volume_key(key_size, key);
if (vk == NULL)
return -ENOMEM;
crypt_volume_key_add_next(&((*vmk)->vk), vk);
/* unknown timestamps in recovery protected VMK */
} else if (key_entry_value == BITLK_ENTRY_VALUE_RECOVERY_TIME) {
;
/* optional hint (?) string (masked email?), we can safely ignore it */
} else if (key_entry_value == BITLK_ENTRY_VALUE_HINT) {
;
} else if (key_entry_value == BITLK_ENTRY_VALUE_STRING) {
if (key_entry_size < BITLK_ENTRY_HEADER_LEN)
return -EINVAL;
@@ -353,6 +367,9 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
/* no idea what this is, lets hope it's not important */
} else if (key_entry_value == BITLK_ENTRY_VALUE_USE_KEY && (*vmk)->protection == BITLK_PROTECTION_STARTUP_KEY) {
;
/* quietly ignore unsupported TPM key */
} else if (key_entry_value == BITLK_ENTRY_VALUE_TPM_KEY && (*vmk)->protection == BITLK_PROTECTION_TPM) {
;
} else {
if (supported) {
log_err(cd, _("Unexpected metadata entry value '%u' found when parsing supported Volume Master Key."), key_entry_value);
@@ -368,6 +385,54 @@ static int parse_vmk_entry(struct crypt_device *cd, uint8_t *data, int start, in
return 0;
}
static bool check_fve_metadata(struct bitlk_fve_metadata *fve)
{
if (memcmp(fve->signature, BITLK_SIGNATURE, sizeof(fve->signature)) || le16_to_cpu(fve->fve_version) != 2 ||
(fve->fve_size << 4) > BITLK_FVE_METADATA_SIZE)
return false;
return true;
}
static bool check_fve_metadata_validation(struct bitlk_fve_metadata_validation *validation)
{
/* only check if there is room for CRC-32, the actual size must be larger */
if (le16_to_cpu(validation->validation_size) < 8 || le16_to_cpu(validation->validation_version > 2))
return false;
return true;
}
static bool parse_fve_metadata_validation(struct bitlk_metadata *params, struct bitlk_fve_metadata_validation *validation)
{
/* extra checks for a nested structure (MAC) and BITLK FVE metadata */
if (le16_to_cpu(validation->validation_size) < sizeof(struct bitlk_fve_metadata_validation))
return false;
if (le16_to_cpu(validation->nested_struct_size != BITLK_VALIDATION_VMK_HEADER_SIZE + BITLK_VALIDATION_VMK_DATA_SIZE) ||
le16_to_cpu(validation->nested_struct_role) != 0 ||
le16_to_cpu(validation->nested_struct_type) != 5)
return false;
/* nonce */
memcpy(params->validation->nonce,
validation->nested_struct_data,
BITLK_NONCE_SIZE);
/* MAC tag */
memcpy(params->validation->mac_tag,
validation->nested_struct_data + BITLK_NONCE_SIZE,
BITLK_VMK_MAC_TAG_SIZE);
/* AES-CCM encrypted datum with SHA256 hash */
memcpy(params->validation->enc_datum,
validation->nested_struct_data + BITLK_NONCE_SIZE + BITLK_VMK_MAC_TAG_SIZE,
BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE);
return true;
}
void BITLK_bitlk_fvek_free(struct bitlk_fvek *fvek)
{
if (!fvek)
@@ -382,10 +447,8 @@ void BITLK_bitlk_vmk_free(struct bitlk_vmk *vmk)
struct bitlk_vmk *vmk_next = NULL;
while (vmk) {
if (vmk->guid)
free(vmk->guid);
if (vmk->name)
free(vmk->name);
free(vmk->guid);
free(vmk->name);
crypt_free_volume_key(vmk->vk);
vmk_next = vmk->next;
free(vmk);
@@ -399,8 +462,8 @@ void BITLK_bitlk_metadata_free(struct bitlk_metadata *metadata)
return;
free(metadata->guid);
if (metadata->description)
free(metadata->description);
free(metadata->description);
free(metadata->validation);
BITLK_bitlk_vmk_free(metadata->vmks);
BITLK_bitlk_fvek_free(metadata->fvek);
}
@@ -412,20 +475,25 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
struct bitlk_signature sig = {};
struct bitlk_superblock sb = {};
struct bitlk_fve_metadata fve = {};
struct bitlk_fve_metadata_validation validation = {};
struct bitlk_entry_vmk entry_vmk = {};
uint8_t *fve_entries = NULL;
uint8_t *fve_validated_block = NULL;
size_t fve_entries_size = 0;
uint32_t fve_metadata_size = 0;
uint32_t fve_size_real = 0;
int fve_offset = 0;
char guid_buf[UUID_STR_LEN] = {0};
uint16_t entry_size = 0;
uint16_t entry_type = 0;
int i = 0;
int r = 0;
int valid_fve_metadata_idx = -1;
int start = 0;
size_t key_size = 0;
const char *key = NULL;
char *description = NULL;
struct crypt_hash *hash;
struct bitlk_vmk *vmk = NULL;
struct bitlk_vmk *vmk_p = params->vmks;
@@ -500,15 +568,80 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
for (i = 0; i < 3; i++)
params->metadata_offset[i] = le64_to_cpu(sb.fve_offset[i]);
log_dbg(cd, "Reading BITLK FVE metadata of size %zu on device %s, offset %" PRIu64 ".",
sizeof(fve), device_path(device), params->metadata_offset[0]);
fve_validated_block = malloc(BITLK_FVE_METADATA_SIZE);
if (fve_validated_block == NULL) {
r = -ENOMEM;
goto out;
}
/* read FVE metadata from the first metadata area */
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &fve, sizeof(fve), params->metadata_offset[0]) != sizeof(fve) ||
memcmp(fve.signature, BITLK_SIGNATURE, sizeof(fve.signature)) ||
le16_to_cpu(fve.fve_version) != 2) {
log_err(cd, _("Failed to read BITLK FVE metadata from %s."), device_path(device));
for (i = 0; i < 3; i++) {
/* iterate over FVE metadata copies and pick the valid one */
log_dbg(cd, "Reading BITLK FVE metadata copy #%d of size %zu on device %s, offset %" PRIu64 ".",
i, sizeof(fve), device_path(device), params->metadata_offset[i]);
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &fve, sizeof(fve), params->metadata_offset[i]) != sizeof(fve) ||
!check_fve_metadata(&fve) ||
(fve_size_real = le16_to_cpu(fve.fve_size) << 4, read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), &validation, sizeof(validation), params->metadata_offset[i] + fve_size_real) != sizeof(validation)) ||
!check_fve_metadata_validation(&validation) ||
/* double-fetch is here, but we aren't validating MAC */
read_lseek_blockwise(devfd, device_block_size(cd, device), device_alignment(device), fve_validated_block, fve_size_real,
params->metadata_offset[i]) != fve_size_real ||
(crypt_crc32(~0, fve_validated_block, fve_size_real) ^ ~0) != le32_to_cpu(validation.fve_crc32)) {
/* found an invalid FVE metadata copy, log and skip */
log_dbg(cd, _("Failed to read or validate BITLK FVE metadata copy #%d from %s."), i, device_path(device));
} else {
/* found a valid FVE metadata copy, use it */
valid_fve_metadata_idx = i;
break;
}
}
if (valid_fve_metadata_idx < 0) {
/* all FVE metadata copies are invalid, fail */
log_err(cd, _("Failed to read and validate BITLK FVE metadata from %s."), device_path(device));
r = -EINVAL;
goto out;
}
/* check that a valid FVE metadata block is in its expected location */
if (params->metadata_offset[valid_fve_metadata_idx] != le64_to_cpu(fve.fve_offset[valid_fve_metadata_idx])) {
log_err(cd, _("Failed to validate the location of BITLK FVE metadata from %s."), device_path(device));
r = -EINVAL;
goto out;
}
/* update offsets from a valid FVE metadata copy */
for (i = 0; i < 3; i++)
params->metadata_offset[i] = le64_to_cpu(fve.fve_offset[i]);
/* check that the FVE metadata hasn't changed between reads, because we are preparing for the MAC check */
if (memcmp(&fve, fve_validated_block, sizeof(fve)) != 0) {
log_err(cd, _("BITLK FVE metadata changed between reads from %s."), device_path(device));
r = -EINVAL;
goto out;
}
crypt_backend_memzero(&params->sha256_fve, 32);
if (crypt_hash_init(&hash, "sha256")) {
log_err(cd, _("Failed to hash BITLK FVE metadata read from %s."), device_path(device));
r = -EINVAL;
goto out;
}
crypt_hash_write(hash, (const char *)fve_validated_block, fve_size_real);
crypt_hash_final(hash, (char *)&params->sha256_fve, 32);
crypt_hash_destroy(hash);
/* do some extended checks against FVE metadata, but not including MAC verification */
params->validation = malloc(sizeof(struct bitlk_validation));
if (!params->validation) {
r = -ENOMEM;
goto out;
}
if (!parse_fve_metadata_validation(params, &validation)) {
log_err(cd, _("Failed to parse BITLK FVE validation metadata from %s."), device_path(device));
r = -EINVAL;
goto out;
}
@@ -593,17 +726,18 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
}
memset(fve_entries, 0, fve_entries_size);
log_dbg(cd, "Reading BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
fve_entries_size, device_path(device), params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN);
log_dbg(cd, "Getting BITLK FVE metadata entries of size %zu on device %s, offset %" PRIu64 ".",
fve_entries_size, device_path(device), params->metadata_offset[valid_fve_metadata_idx] + BITLK_FVE_METADATA_HEADERS_LEN);
if (read_lseek_blockwise(devfd, device_block_size(cd, device),
device_alignment(device), fve_entries, fve_entries_size,
params->metadata_offset[0] + BITLK_FVE_METADATA_HEADERS_LEN) != (ssize_t)fve_entries_size) {
log_err(cd, _("Failed to read BITLK metadata entries from %s."), device_path(device));
if (BITLK_FVE_METADATA_HEADERS_LEN + fve_entries_size > fve_size_real) {
log_err(cd, _("Failed to check BITLK metadata entries previously read from %s."), device_path(device));
r = -EINVAL;
goto out;
}
/* fetch these entries from validated buffer to avoid double-fetch */
memcpy(fve_entries, fve_validated_block + BITLK_FVE_METADATA_HEADERS_LEN, fve_entries_size);
while ((fve_entries_size - start) >= (sizeof(entry_size) + sizeof(entry_type))) {
/* size of this entry */
@@ -724,10 +858,10 @@ int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params)
start += entry_size;
}
out:
if (fve_entries)
free(fve_entries);
free(fve_entries);
free(fve_validated_block);
return r;
}
@@ -749,7 +883,7 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
log_std(cd, "Description: \t%s\n", params->description);
log_std(cd, "Cipher name: \t%s\n", params->cipher);
log_std(cd, "Cipher mode: \t%s\n", params->cipher_mode);
log_std(cd, "Cipher key: \t%u bits\n", params->key_size);
log_std(cd, "Cipher key: \t%u [bits]\n", params->key_size);
log_std(cd, "\n");
@@ -768,15 +902,15 @@ int BITLK_dump(struct crypt_device *cd, struct device *device, struct bitlk_meta
vk_p = vmk_p->vk;
while (vk_p) {
log_std(cd, "\tKey data size:\t%zu [bytes]\n", vk_p->keylength);
vk_p = vk_p->next;
log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(vk_p));
vk_p = crypt_volume_key_next(vk_p);
}
vmk_p = vmk_p->next;
next_id++;
}
log_std(cd, " %d: FVEK\n", next_id);
log_std(cd, "\tKey data size:\t%zu [bytes]\n", params->fvek->vk->keylength);
log_std(cd, "\tKey data size:\t%zu [bytes]\n", crypt_volume_key_length(params->fvek->vk));
log_std(cd, "\n");
@@ -994,9 +1128,13 @@ static int bitlk_kdf(const char *password,
struct crypt_hash *hd = NULL;
int len = 0;
char16_t *utf16Password = NULL;
size_t utf16Len = 0;
int i = 0;
int r = 0;
if (!password)
return -EINVAL;
memcpy(kdf.salt, salt, 16);
r = crypt_hash_init(&hd, BITLK_KDF_HASH);
@@ -1019,7 +1157,8 @@ static int bitlk_kdf(const char *password,
if (r < 0)
goto out;
crypt_hash_write(hd, (char*)utf16Password, passwordLen * 2);
utf16Len = crypt_char16_strlen(utf16Password);
crypt_hash_write(hd, (char*)utf16Password, utf16Len * 2);
r = crypt_hash_final(hd, kdf.initial_sha256, len);
if (r < 0)
goto out;
@@ -1065,11 +1204,14 @@ static int decrypt_key(struct crypt_device *cd,
int r;
uint16_t key_size = 0;
outbuf = crypt_safe_alloc(enc_key->keylength);
outbuf = crypt_safe_alloc(crypt_volume_key_length(enc_key));
if (!outbuf)
return -ENOMEM;
r = crypt_bitlk_decrypt_key(key->key, key->keylength, enc_key->key, outbuf, enc_key->keylength,
r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(key),
crypt_volume_key_length(key),
crypt_volume_key_get_key(enc_key), outbuf,
crypt_volume_key_length(enc_key),
(const char*)iv, iv_size, (const char*)tag, tag_size);
if (r < 0) {
if (r == -ENOTSUP)
@@ -1080,9 +1222,10 @@ static int decrypt_key(struct crypt_device *cd,
/* key_data has it's size as part of the metadata */
memcpy(&key_size, outbuf, 2);
key_size = le16_to_cpu(key_size);
if (enc_key->keylength != key_size) {
if (crypt_volume_key_length(enc_key) != key_size) {
log_err(cd, _("Unexpected key data size."));
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "", enc_key->keylength, key_size);
log_dbg(cd, "Expected key data size: %zu, got %" PRIu16 "",
crypt_volume_key_length(enc_key), key_size);
r = -EINVAL;
goto out;
@@ -1092,7 +1235,7 @@ static int decrypt_key(struct crypt_device *cd,
crypt_get_volume_key_size(cd) == 32) {
/* 128bit AES-CBC with Elephant -- key size is 256 bit (2 keys) but key data is 512 bits,
data: 16B CBC key, 16B empty, 16B elephant key, 16B empty */
memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
crypt_safe_memcpy(outbuf + 16 + BITLK_OPEN_KEY_METADATA_LEN,
outbuf + 2 * 16 + BITLK_OPEN_KEY_METADATA_LEN, 16);
key_size = 32 + BITLK_OPEN_KEY_METADATA_LEN;
}
@@ -1106,6 +1249,41 @@ out:
return r;
}
static int get_clear_key(struct crypt_device *cd, const struct bitlk_vmk *vmk, struct volume_key **vmk_dec_key)
{
struct volume_key *nested_key = vmk->vk;
if (!nested_key) {
log_dbg(cd, "Clearkey VMK structure incomplete - missing nested key");
return -ENOTSUP;
}
struct volume_key *encrypted_vmk = crypt_volume_key_next(nested_key);
if (!encrypted_vmk) {
log_dbg(cd, "Clearkey VMK structure incomplete - missing encrypted VMK");
return -ENOTSUP;
}
/**
* For clearkey protection, we need to decrypt the encrypted VMK using the nested key
* and return the decrypted VMK as vmk_dec_key
*/
struct volume_key *decrypted_vmk = NULL;
int r = decrypt_key(cd, &decrypted_vmk, encrypted_vmk, nested_key,
vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
vmk->nonce, BITLK_NONCE_SIZE, false);
if (r == 0 && decrypted_vmk) {
log_dbg(cd, "Successfully decrypted VMK using nested key");
*vmk_dec_key = decrypted_vmk;
return 0;
} else {
log_dbg(cd, "Failed to decrypt VMK using nested key (error: %d)", r);
return r;
}
}
int BITLK_get_volume_key(struct crypt_device *cd,
const char *password,
size_t passwordLen,
@@ -1116,10 +1294,12 @@ int BITLK_get_volume_key(struct crypt_device *cd,
struct volume_key *open_vmk_key = NULL;
struct volume_key *vmk_dec_key = NULL;
struct volume_key *recovery_key = NULL;
struct bitlk_validation_hash dec_hash = {};
const struct bitlk_vmk *next_vmk = NULL;
next_vmk = params->vmks;
while (next_vmk) {
bool is_decrypted = false;
if (next_vmk->protection == BITLK_PROTECTION_PASSPHRASE) {
r = bitlk_kdf(password, passwordLen, false, next_vmk->salt, &vmk_dec_key);
if (r) {
@@ -1141,7 +1321,8 @@ int BITLK_get_volume_key(struct crypt_device *cd,
continue;
}
log_dbg(cd, "Trying to use given password as a recovery key.");
r = bitlk_kdf(recovery_key->key, recovery_key->keylength,
r = bitlk_kdf(crypt_volume_key_get_key(recovery_key),
crypt_volume_key_length(recovery_key),
true, next_vmk->salt, &vmk_dec_key);
crypt_free_volume_key(recovery_key);
if (r)
@@ -1153,8 +1334,18 @@ int BITLK_get_volume_key(struct crypt_device *cd,
continue;
}
log_dbg(cd, "Trying to use external key found in provided password.");
} else if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
r = get_clear_key(cd, next_vmk, &vmk_dec_key);
if (r) {
/* something wrong happened, but we still want to check other key slots */
next_vmk = next_vmk->next;
continue;
}
is_decrypted = true;
open_vmk_key = vmk_dec_key;
log_dbg(cd, "Extracted VMK using clearkey.");
} else {
/* only passphrase, recovery passphrase and startup key VMKs supported right now */
/* only passphrase, recovery passphrase, startup key and clearkey VMKs supported right now */
log_dbg(cd, "Skipping %s", get_vmk_protection_string(next_vmk->protection));
next_vmk = next_vmk->next;
if (r == 0)
@@ -1163,19 +1354,51 @@ int BITLK_get_volume_key(struct crypt_device *cd,
continue;
}
log_dbg(cd, "Trying to decrypt %s.", get_vmk_protection_string(next_vmk->protection));
r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
next_vmk->nonce, BITLK_NONCE_SIZE, false);
if (!is_decrypted) {
r = decrypt_key(cd, &open_vmk_key, next_vmk->vk, vmk_dec_key,
next_vmk->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
next_vmk->nonce, BITLK_NONCE_SIZE, false);
crypt_free_volume_key(vmk_dec_key);
}
if (r < 0) {
log_dbg(cd, "Failed to decrypt VMK using provided passphrase.");
crypt_free_volume_key(vmk_dec_key);
if (r == -ENOTSUP)
return r;
next_vmk = next_vmk->next;
continue;
}
crypt_free_volume_key(vmk_dec_key);
log_dbg(cd, "Trying to decrypt validation metadata using VMK.");
r = crypt_bitlk_decrypt_key(crypt_volume_key_get_key(open_vmk_key),
crypt_volume_key_length(open_vmk_key),
(const char*)params->validation->enc_datum,
(char *)&dec_hash,
BITLK_VALIDATION_VMK_DATA_SIZE - BITLK_NONCE_SIZE - BITLK_VMK_MAC_TAG_SIZE,
(const char*)params->validation->nonce, BITLK_NONCE_SIZE,
(const char*)params->validation->mac_tag, BITLK_VMK_MAC_TAG_SIZE);
if (r < 0) {
log_dbg(cd, "Failed to decrypt validation metadata using VMK.");
crypt_free_volume_key(open_vmk_key);
if (r == -ENOTSUP)
return r;
break;
}
/* now, do the MAC validation */
if (le16_to_cpu(dec_hash.role) != 0 ||le16_to_cpu(dec_hash.type) != 1 ||
(le16_to_cpu(dec_hash.hash_type) != 0x2005)) {
log_dbg(cd, "Failed to parse decrypted validation metadata.");
crypt_free_volume_key(open_vmk_key);
return -ENOTSUP;
}
if (memcmp(dec_hash.hash, params->sha256_fve, sizeof(dec_hash.hash)) != 0) {
log_dbg(cd, "Failed MAC validation of BITLK FVE metadata.");
crypt_free_volume_key(open_vmk_key);
return -EINVAL;
}
r = decrypt_key(cd, open_fvek_key, params->fvek->vk, open_vmk_key,
params->fvek->mac_tag, BITLK_VMK_MAC_TAG_SIZE,
@@ -1204,8 +1427,6 @@ int BITLK_get_volume_key(struct crypt_device *cd,
static int _activate_check(struct crypt_device *cd,
const struct bitlk_metadata *params)
{
const struct bitlk_vmk *next_vmk = NULL;
if (!params->state) {
log_err(cd, _("This BITLK device is in an unsupported state and cannot be activated."));
return -ENOTSUP;
@@ -1216,15 +1437,6 @@ static int _activate_check(struct crypt_device *cd,
return -ENOTSUP;
}
next_vmk = params->vmks;
while (next_vmk) {
if (next_vmk->protection == BITLK_PROTECTION_CLEAR_KEY) {
log_err(cd, _("Activation of partially decrypted BITLK device is not supported."));
return -ENOTSUP;
}
next_vmk = next_vmk->next;
}
return 0;
}
@@ -1248,7 +1460,7 @@ static int _activate(struct crypt_device *cd,
uint64_t next_start = 0;
uint64_t next_end = 0;
uint64_t last_segment = 0;
uint32_t dmt_flags = 0;
uint64_t dmt_flags = 0;
r = _activate_check(cd, params);
if (r)
@@ -1372,7 +1584,7 @@ static int _activate(struct crypt_device *cd,
crypt_get_cipher_spec(cd),
segments[i].iv_offset,
segments[i].iv_offset,
NULL, 0,
NULL, 0, 0,
params->sector_size);
if (r)
goto out;
@@ -1408,54 +1620,17 @@ out:
return r;
}
int BITLK_activate_by_passphrase(struct crypt_device *cd,
const char *name,
const char *password,
size_t passwordLen,
const struct bitlk_metadata *params,
uint32_t flags)
{
int r = 0;
struct volume_key *open_fvek_key = NULL;
r = _activate_check(cd, params);
if (r)
return r;
r = BITLK_get_volume_key(cd, password, passwordLen, params, &open_fvek_key);
if (r < 0)
goto out;
/* Password verify only */
if (!name)
goto out;
r = _activate(cd, name, open_fvek_key, params, flags);
out:
crypt_free_volume_key(open_fvek_key);
return r;
}
int BITLK_activate_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size,
struct volume_key *vk,
const struct bitlk_metadata *params,
uint32_t flags)
{
int r = 0;
struct volume_key *open_fvek_key = NULL;
int r;
r = _activate_check(cd, params);
if (r)
return r;
open_fvek_key = crypt_alloc_volume_key(volume_key_size, volume_key);
if (!open_fvek_key)
return -ENOMEM;
r = _activate(cd, name, open_fvek_key, params, flags);
crypt_free_volume_key(open_fvek_key);
return r;
return _activate(cd, name, vk, params, flags);
}

View File

@@ -1,23 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* BITLK (BitLocker-compatible) header definition
*
* Copyright (C) 2019-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2023 Milan Broz
* Copyright (C) 2019-2023 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.
* Copyright (C) 2019-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2019-2025 Milan Broz
* Copyright (C) 2019-2025 Vojtech Trefny
*/
#ifndef _CRYPTSETUP_BITLK_H
@@ -34,6 +21,8 @@ struct volume_key;
#define BITLK_NONCE_SIZE 12
#define BITLK_SALT_SIZE 16
#define BITLK_VMK_MAC_TAG_SIZE 16
#define BITLK_VALIDATION_VMK_HEADER_SIZE 8
#define BITLK_VALIDATION_VMK_DATA_SIZE 72
#define BITLK_STATE_NORMAL 0x0004
@@ -78,6 +67,7 @@ typedef enum {
BITLK_ENTRY_VALUE_OFFSET_SIZE = 0x000f,
BITLK_ENTRY_VALUE_RECOVERY_TIME = 0x015,
BITLK_ENTRY_VALUE_GUID = 0x0017,
BITLK_ENTRY_VALUE_HINT = 0x0018,
} BITLKFVEEntryValue;
struct bitlk_vmk {
@@ -97,6 +87,13 @@ struct bitlk_fvek {
struct volume_key *vk;
};
struct bitlk_validation {
uint8_t mac_tag[BITLK_VMK_MAC_TAG_SIZE];
uint8_t nonce[BITLK_NONCE_SIZE];
/* technically, this is not "VMK", but some sources call it this way */
uint8_t enc_datum[BITLK_VALIDATION_VMK_DATA_SIZE];
};
struct bitlk_metadata {
uint16_t sector_size;
uint64_t volume_size;
@@ -113,8 +110,10 @@ struct bitlk_metadata {
uint32_t metadata_version;
uint64_t volume_header_offset;
uint64_t volume_header_size;
const char *sha256_fve[32];
struct bitlk_vmk *vmks;
struct bitlk_fvek *fvek;
struct bitlk_validation *validation;
};
int BITLK_read_sb(struct crypt_device *cd, struct bitlk_metadata *params);
@@ -127,17 +126,9 @@ int BITLK_get_volume_key(struct crypt_device *cd,
const struct bitlk_metadata *params,
struct volume_key **open_fvek_key);
int BITLK_activate_by_passphrase(struct crypt_device *cd,
const char *name,
const char *password,
size_t passwordLen,
const struct bitlk_metadata *params,
uint32_t flags);
int BITLK_activate_by_volume_key(struct crypt_device *cd,
const char *name,
const char *volume_key,
size_t volume_key_size,
struct volume_key *vk,
const struct bitlk_metadata *params,
uint32_t flags);

View File

@@ -10,13 +10,13 @@
#include <stdint.h>
#include <sys/param.h>
#if defined(HAVE_BYTESWAP_H)
#if HAVE_BYTESWAP_H
# include <byteswap.h>
#endif
#if defined(HAVE_ENDIAN_H)
#if HAVE_ENDIAN_H
# include <endian.h>
#elif defined(HAVE_SYS_ENDIAN_H) /* BSDs have them here */
#elif HAVE_SYS_ENDIAN_H /* BSDs have them here */
# include <sys/endian.h>
#endif

View File

@@ -1,23 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* cryptsetup plain device helper functions
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#include <string.h>
@@ -105,7 +92,7 @@ int crypt_plain_hash(struct crypt_device *cd,
log_dbg(cd, "Too short plain passphrase.");
return -EINVAL;
}
memcpy(key, passphrase, hash_size);
crypt_safe_memcpy(key, passphrase, hash_size);
r = 0;
} else
r = hash(hash_name_buf, hash_size, key, passphrase_size, passphrase);

View File

@@ -13,7 +13,8 @@ libcrypto_backend_la_SOURCES = \
lib/crypto_backend/utf8.c \
lib/crypto_backend/argon2_generic.c \
lib/crypto_backend/cipher_generic.c \
lib/crypto_backend/cipher_check.c
lib/crypto_backend/cipher_check.c \
lib/crypto_backend/memutils.c
if CRYPTO_BACKEND_GCRYPT
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_gcrypt.c
@@ -30,6 +31,9 @@ endif
if CRYPTO_BACKEND_NETTLE
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_nettle.c
endif
if CRYPTO_BACKEND_MBEDTLS
libcrypto_backend_la_SOURCES += lib/crypto_backend/crypto_mbedtls.c
endif
if CRYPTO_INTERNAL_PBKDF2
libcrypto_backend_la_SOURCES += lib/crypto_backend/pbkdf2_generic.c

View File

@@ -360,7 +360,7 @@ int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
TRY(blake2b_final(&blake_state, out, outlen));
} else {
uint32_t toproduce;
uint8_t out_buffer[BLAKE2B_OUTBYTES];
uint8_t out_buffer[BLAKE2B_OUTBYTES] = {0};
uint8_t in_buffer[BLAKE2B_OUTBYTES];
TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));

View File

@@ -128,7 +128,7 @@ void secure_wipe_memory(void *v, size_t n) {
void secure_wipe_memory(void *v, size_t n) {
memset_s(v, n, 0, n);
}
#elif defined(HAVE_EXPLICIT_BZERO)
#elif HAVE_EXPLICIT_BZERO
void secure_wipe_memory(void *v, size_t n) {
explicit_bzero(v, n);
}
@@ -356,12 +356,9 @@ static int fill_memory_blocks_mt(argon2_instance_t *instance) {
}
fail:
if (thread != NULL) {
free(thread);
}
if (thr_data != NULL) {
free(thr_data);
}
free(thread);
free(thr_data);
return rc;
}

View File

@@ -83,7 +83,7 @@
static int b64_byte_to_char(unsigned x) {
return (LT(x, 26) & (x + 'A')) |
(GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
(GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
(GE(x, 52) & LT(x, 62) & (x - (52 - '0'))) | (EQ(x, 62) & '+') |
(EQ(x, 63) & '/');
}

View File

@@ -1,35 +1,25 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Argon2 PBKDF2 library wrapper
*
* Copyright (C) 2016-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2023 Milan Broz
*
* 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.
* Copyright (C) 2016-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2016-2025 Milan Broz
*/
#include <errno.h>
#include "crypto_backend_internal.h"
/* Check for HAVE_ARGON2_H is run only if libargon2 code is used */
#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H
#define CONST_CAST(x) (x)(uintptr_t)
#if HAVE_ARGON2_H
#include <argon2.h>
#else
#include "argon2/argon2.h"
#endif
#define CONST_CAST(x) (x)(uintptr_t)
#if USE_INTERNAL_ARGON2 || HAVE_ARGON2_H
int argon2(const char *type, const char *password, size_t password_length,
const char *salt, size_t salt_length,
char *key, size_t key_length,
@@ -52,6 +42,9 @@ int argon2(const char *type, const char *password, size_t password_length,
};
int r;
/* This code must not be run if crypt backend library natively supports Argon2 */
assert(!(crypt_backend_flags() & CRYPT_BACKEND_ARGON2));
if (!strcmp(type, "argon2i"))
atype = Argon2_i;
else if(!strcmp(type, "argon2id"))
@@ -87,3 +80,19 @@ int argon2(const char *type, const char *password, size_t password_length,
}
#endif
/* Additional string for crypt backend version */
const char *crypt_argon2_version(void)
{
const char *version = "";
if (crypt_backend_flags() & CRYPT_BACKEND_ARGON2)
return version;
#if HAVE_ARGON2_H /* this has priority over internal argon2 */
version = " [external libargon2]";
#elif USE_INTERNAL_ARGON2
version = " [cryptsetup libargon2]";
#endif
return version;
}

View File

@@ -1,24 +1,11 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Base64 "Not encryption" helpers, copied and adapted from systemd project.
*
* Copyright (C) 2010 Lennart Poettering
*
* cryptsetup related changes
* Copyright (C) 2021-2023 Milan Broz
*
* 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.
* Copyright (C) 2021-2025 Milan Broz
*/
#include <errno.h>
@@ -32,7 +19,7 @@
/* https://tools.ietf.org/html/rfc4648#section-4 */
static char base64char(int x)
{
static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
static const char table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
return table[x & 63];

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Cipher performance check
*
* Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2023 Milan Broz
*
* 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.
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2025 Milan Broz
*/
#include <errno.h>
@@ -55,43 +42,36 @@ static int time_ms(struct timespec *start, struct timespec *end, double *ms)
return 0;
}
static int cipher_perf_one(const char *name, const char *mode, char *buffer, size_t buffer_size,
const char *key, size_t key_size, const char *iv, size_t iv_size, int enc)
static int cipher_perf_one(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
const char *iv, size_t iv_size, int enc)
{
struct crypt_cipher_kernel cipher;
size_t done = 0, block = CIPHER_BLOCK_BYTES;
int r;
if (buffer_size < block)
block = buffer_size;
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
if (r < 0)
return r;
while (done < buffer_size) {
if ((done + block) > buffer_size)
block = buffer_size - done;
if (enc)
r = crypt_cipher_encrypt_kernel(&cipher, &buffer[done], &buffer[done],
r = crypt_cipher_encrypt_kernel(cipher, &buffer[done], &buffer[done],
block, iv, iv_size);
else
r = crypt_cipher_decrypt_kernel(&cipher, &buffer[done], &buffer[done],
r = crypt_cipher_decrypt_kernel(cipher, &buffer[done], &buffer[done],
block, iv, iv_size);
if (r < 0)
break;
return r;
done += block;
}
crypt_cipher_destroy_kernel(&cipher);
return r;
return 0;
}
static int cipher_measure(const char *name, const char *mode, char *buffer, size_t buffer_size,
const char *key, size_t key_size, const char *iv, size_t iv_size,
int encrypt, double *ms)
static int cipher_measure(struct crypt_cipher_kernel *cipher, char *buffer, size_t buffer_size,
const char *iv, size_t iv_size, int encrypt, double *ms)
{
struct timespec start, end;
int r;
@@ -103,7 +83,7 @@ static int cipher_measure(const char *name, const char *mode, char *buffer, size
if (clock_gettime(CLOCK_MONOTONIC_RAW, &start) < 0)
return -EINVAL;
r = cipher_perf_one(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, encrypt);
r = cipher_perf_one(cipher, buffer, buffer_size, iv, iv_size, encrypt);
if (r < 0)
return r;
@@ -131,15 +111,20 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
const char *key, size_t key_size, const char *iv, size_t iv_size,
double *encryption_mbs, double *decryption_mbs)
{
struct crypt_cipher_kernel cipher;
double ms_enc, ms_dec, ms;
int r, repeat_enc, repeat_dec;
r = crypt_cipher_init_kernel(&cipher, name, mode, key, key_size);
if (r < 0)
return r;
ms_enc = 0.0;
repeat_enc = 1;
while (ms_enc < 1000.0) {
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 1, &ms);
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 1, &ms);
if (r < 0)
return r;
goto out;
ms_enc += ms;
repeat_enc++;
}
@@ -147,9 +132,9 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
ms_dec = 0.0;
repeat_dec = 1;
while (ms_dec < 1000.0) {
r = cipher_measure(name, mode, buffer, buffer_size, key, key_size, iv, iv_size, 0, &ms);
r = cipher_measure(&cipher, buffer, buffer_size, iv, iv_size, 0, &ms);
if (r < 0)
return r;
goto out;
ms_dec += ms;
repeat_dec++;
}
@@ -157,5 +142,8 @@ int crypt_cipher_perf_kernel(const char *name, const char *mode, char *buffer, s
*encryption_mbs = speed_mbs(buffer_size * repeat_enc, ms_enc);
*decryption_mbs = speed_mbs(buffer_size * repeat_dec, ms_dec);
return 0;
r = 0;
out:
crypt_cipher_destroy_kernel(&cipher);
return r;
}

View File

@@ -1,27 +1,15 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel cipher generic utilities
*
* Copyright (C) 2018-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2023 Milan Broz
*
* 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.
* Copyright (C) 2018-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2018-2025 Milan Broz
*/
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include "crypto_backend.h"
struct cipher_alg {
@@ -76,6 +64,9 @@ int crypt_cipher_ivsize(const char *name, const char *mode)
if (!ca)
return -EINVAL;
if (mode && !strcasecmp(mode, "hctr2"))
return 32;
if (mode && !strcasecmp(mode, "ecb"))
return 0;
@@ -88,3 +79,21 @@ int crypt_cipher_wrapped_key(const char *name, const char *mode)
return ca ? (int)ca->wrapped_key : 0;
}
bool crypt_fips_mode_kernel(void)
{
int fd;
char buf = 0;
fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY);
if (fd < 0)
return false;
if (read(fd, &buf, 1) != 1)
buf = '0';
close(fd);
return (buf == '1');
}

View File

@@ -38,8 +38,6 @@
*
*/
#include <stdio.h>
#include "crypto_backend.h"
static const uint32_t crc32_tab[] = {

View File

@@ -1,23 +1,11 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#ifndef _CRYPTO_BACKEND_H
#define _CRYPTO_BACKEND_H
@@ -26,26 +14,32 @@
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#ifdef HAVE_UCHAR_H
#if HAVE_UCHAR_H
#include <uchar.h>
#else
#define char32_t uint32_t
#define char16_t uint16_t
#endif
# ifdef __cplusplus
extern "C" {
# endif
struct crypt_hash;
struct crypt_hmac;
struct crypt_cipher;
struct crypt_storage;
int crypt_backend_init(bool fips);
int crypt_backend_init(void);
void crypt_backend_destroy(void);
#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */
#define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */
#define CRYPT_BACKEND_ARGON2 (1 << 2) /* Backend provides native Argon2 implementation */
uint32_t crypt_backend_flags(void);
const char *crypt_backend_version(void);
const char *crypt_argon2_version(void);
/* HASH */
int crypt_hash_size(const char *name);
@@ -99,6 +93,7 @@ int crypt_base64_decode(char **out, size_t *out_length, const char *in, size_t i
/* UTF8/16 */
int crypt_utf16_to_utf8(char **out, const char16_t *s, size_t length /* bytes! */);
int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length);
size_t crypt_char16_strlen(const char16_t *s);
/* Block ciphers */
int crypt_cipher_ivsize(const char *name, const char *mode);
@@ -142,15 +137,10 @@ int crypt_bitlk_decrypt_key(const void *key, size_t key_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)
{
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(s, n);
#else
volatile uint8_t *p = (volatile uint8_t *)s;
while(n--) *p++ = 0;
#endif
}
void crypt_backend_memzero(void *s, size_t n);
/* Memcpy helper to avoid spilling sensitive data through additional registers */
void *crypt_backend_memcpy(void *dst, const void *src, size_t n);
/* Memcmp helper (memcmp in constant time) */
int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
@@ -158,4 +148,11 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n);
/* crypto backend running in FIPS mode */
bool crypt_fips_mode(void);
/* kernel running in FIPS mode */
bool crypt_fips_mode_kernel(void);
# ifdef __cplusplus
}
# endif
#endif /* _CRYPTO_BACKEND_H */

View File

@@ -1,29 +1,17 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#ifndef _CRYPTO_BACKEND_INTERNAL_H
#define _CRYPTO_BACKEND_INTERNAL_H
#include "crypto_backend.h"
/* internal PBKDF2 implementation */
/* Internal PBKDF2 implementation */
int pkcs5_pbkdf2(const char *hash,
const char *P, size_t Plen,
const char *S, size_t Slen,
@@ -59,17 +47,6 @@ int crypt_bitlk_decrypt_key_kernel(const void *key, size_t key_length,
const char *tag, size_t tag_length);
/* Internal implementation for constant time memory comparison */
static inline int crypt_internal_memeq(const void *m1, const void *m2, size_t n)
{
const unsigned char *_m1 = (const unsigned char *) m1;
const unsigned char *_m2 = (const unsigned char *) m2;
unsigned char result = 0;
size_t i;
for (i = 0; i < n; i++)
result |= _m1[i] ^ _m2[i];
return result;
}
int crypt_internal_memeq(const void *m1, const void *m2, size_t n);
#endif /* _CRYPTO_BACKEND_INTERNAL_H */

View File

@@ -1,35 +1,20 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel userspace API crypto backend implementation (skcipher)
*
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2023 Milan Broz
*
* 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.
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2025 Milan Broz
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include "crypto_backend_internal.h"
#ifdef ENABLE_AF_ALG
#if ENABLE_AF_ALG
#include <linux/if_alg.h>
@@ -55,6 +40,8 @@ static int _crypt_cipher_init(struct crypt_cipher_kernel *ctx,
const void *key, size_t key_length,
size_t tag_length, struct sockaddr_alg *sa)
{
void *optval = NULL;
if (!ctx)
return -EINVAL;
@@ -75,7 +62,7 @@ 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) {
if (tag_length && setsockopt(ctx->tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, &optval, tag_length) < 0) {
crypt_cipher_destroy_kernel(ctx);
return -EINVAL;
}
@@ -101,13 +88,31 @@ int crypt_cipher_init_kernel(struct crypt_cipher_kernel *ctx, const char *name,
if (!strcmp(name, "cipher_null"))
key_length = 0;
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;
if (!strncmp(name, "capi:", 5))
strncpy((char *)sa.salg_name, &name[5], sizeof(sa.salg_name) - 1);
else {
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, 0, &sa);
}
/* musl has broken CMSG_NXTHDR macro in system headers */
static inline struct cmsghdr *_CMSG_NXTHDR(struct msghdr* mhdr, struct cmsghdr* cmsg)
{
#if !defined(__GLIBC__) && defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcast-align"
#pragma clang diagnostic ignored "-Wsign-compare"
return CMSG_NXTHDR(mhdr, cmsg);
#pragma clang diagnostic pop
#else
return CMSG_NXTHDR(mhdr, cmsg);
#endif
}
/* The in/out should be aligned to page boundary */
/* coverity[ -taint_source : arg-3 ] */
static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
@@ -155,7 +160,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
/* Set IV */
if (iv) {
header = CMSG_NXTHDR(&msg, header);
header = _CMSG_NXTHDR(&msg, header);
if (!header)
return -EINVAL;
@@ -164,7 +169,7 @@ static int _crypt_cipher_crypt(struct crypt_cipher_kernel *ctx,
header->cmsg_len = iv_msg_size;
alg_iv = (void*)CMSG_DATA(header);
alg_iv->ivlen = iv_length;
memcpy(alg_iv->iv, iv, iv_length);
crypt_backend_memcpy(alg_iv->iv, iv, iv_length);
}
len = sendmsg(ctx->opfd, &msg, 0);
@@ -211,8 +216,8 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
const char *integrity, size_t key_length)
{
struct crypt_cipher_kernel c;
char mode_name[64], tmp_salg_name[180], *real_mode = NULL, *cipher_iv = NULL, *key;
const char *salg_type;
char mode_name[64], tmp_salg_name[180], *cipher_iv = NULL, *key;
const char *salg_type, *real_mode;
bool aead;
int r;
struct sockaddr_alg sa = {
@@ -220,6 +225,7 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
};
aead = integrity && strcmp(integrity, "none");
real_mode = NULL;
/* Remove IV if present */
if (mode) {
@@ -240,14 +246,22 @@ int crypt_cipher_check_kernel(const char *name, const char *mode,
memset(tmp_salg_name, 0, sizeof(tmp_salg_name));
/* FIXME: this is duplicating a part of devmapper backend */
if (aead && !strcmp(integrity, "poly1305"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
else if (!real_mode)
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
else if (aead && !strcmp(real_mode, "ccm"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
else
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
if (aead) {
/* In AEAD, mode parameter can be just IV like "random" */
if (!strcmp(integrity, "poly1305"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc7539(%s,%s)", name, integrity);
else if (!real_mode)
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
else if (!strcmp(real_mode, "ccm"))
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "rfc4309(%s(%s))", real_mode, name);
else
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode, name);
} else {
if (!mode)
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s", name);
else
r = snprintf(tmp_salg_name, sizeof(tmp_salg_name), "%s(%s)", real_mode ?: mode_name, name);
}
if (r < 0 || (size_t)r >= sizeof(tmp_salg_name))
return -EINVAL;

View File

@@ -1,27 +1,14 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* GCRYPT crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <strings.h>
#include <gcrypt.h>
#include <pthread.h>
#include "crypto_backend_internal.h"
@@ -64,7 +51,6 @@ static void crypt_hash_test_whirlpool_bug(void)
{
struct crypt_hash *h;
char buf[2] = "\0\0", hash_out1[64], hash_out2[64];
int r;
if (crypto_backend_whirlpool_bug >= 0)
return;
@@ -74,16 +60,16 @@ static void crypt_hash_test_whirlpool_bug(void)
return;
/* One shot */
if ((r = crypt_hash_write(h, &buf[0], 2)) ||
(r = crypt_hash_final(h, hash_out1, 64))) {
if (crypt_hash_write(h, &buf[0], 2) ||
crypt_hash_final(h, hash_out1, 64)) {
crypt_hash_destroy(h);
return;
}
/* Split buf (crypt_hash_final resets hash state) */
if ((r = crypt_hash_write(h, &buf[0], 1)) ||
(r = crypt_hash_write(h, &buf[1], 1)) ||
(r = crypt_hash_final(h, hash_out2, 64))) {
if (crypt_hash_write(h, &buf[0], 1) ||
crypt_hash_write(h, &buf[1], 1) ||
crypt_hash_final(h, hash_out2, 64)) {
crypt_hash_destroy(h);
return;
}
@@ -94,7 +80,7 @@ static void crypt_hash_test_whirlpool_bug(void)
crypto_backend_whirlpool_bug = 1;
}
int crypt_backend_init(bool fips __attribute__((unused)))
int crypt_backend_init(void)
{
int r;
@@ -127,10 +113,11 @@ int crypt_backend_init(bool fips __attribute__((unused)))
crypto_backend_initialised = 1;
crypt_hash_test_whirlpool_bug();
r = snprintf(version, sizeof(version), "gcrypt %s%s%s",
r = snprintf(version, sizeof(version), "gcrypt %s%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" : "",
crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? ", argon2" : "");
if (r < 0 || (size_t)r >= sizeof(version))
return -EINVAL;
@@ -152,7 +139,11 @@ const char *crypt_backend_version(void)
uint32_t crypt_backend_flags(void)
{
return 0;
uint32_t flags = 0;
#if HAVE_DECL_GCRY_KDF_ARGON2 && !USE_INTERNAL_ARGON2
flags |= CRYPT_BACKEND_ARGON2;
#endif
return flags;
}
static const char *crypt_hash_compat_name(const char *name, unsigned int *flags)
@@ -258,7 +249,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (!hash)
return -EINVAL;
memcpy(buffer, hash, length);
crypt_backend_memcpy(buffer, hash, length);
crypt_hash_restart(ctx);
return 0;
@@ -332,7 +323,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
if (!hash)
return -EINVAL;
memcpy(buffer, hash, length);
crypt_backend_memcpy(buffer, hash, length);
crypt_hmac_restart(ctx);
return 0;
@@ -460,6 +451,7 @@ static int gcrypt_argon2(const char *type,
.dispatch_job = gcrypt_dispatch_job,
.wait_all_jobs = gcrypt_wait_all_jobs
};
gpg_error_t err;
if (!strcmp(type, "argon2i"))
atype = GCRY_KDF_ARGON2I;
@@ -473,12 +465,11 @@ static int gcrypt_argon2(const char *type,
param[2] = memory;
param[3] = parallel;
if (gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4,
err = gcry_kdf_open(&hd, GCRY_KDF_ARGON2, atype, param, 4,
password, password_length, salt, salt_length,
NULL, 0, NULL, 0)) {
free(threads.jobs_ctx);
return -EINVAL;
}
NULL, 0, NULL, 0);
if (err)
return ((err & GPG_ERR_CODE_MASK) == GPG_ERR_ENOMEM) ? -ENOMEM : -EINVAL;
if (parallel == 1) {
/* Do not use threads here */
@@ -693,7 +684,7 @@ bool crypt_fips_mode(void)
if (fips_checked)
return fips_mode;
if (crypt_backend_init(false /* ignored */))
if (crypt_backend_init())
return false;
fips_mode = gcry_fips_mode_active();

View File

@@ -1,25 +1,11 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Linux kernel userspace API crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
@@ -117,7 +103,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
return 0;
}
int crypt_backend_init(bool fips __attribute__((unused)))
int crypt_backend_init(void)
{
struct utsname uts;
struct sockaddr_alg sa = {
@@ -422,5 +408,5 @@ int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
bool crypt_fips_mode(void)
{
return false;
return crypt_fips_mode_kernel();
}

View File

@@ -0,0 +1,532 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Mbed TLS crypto backend implementation
*
* Copyright (C) 2024-2025 Yiyuan Zhong
*/
#include "crypto_backend.h"
#include <errno.h>
#include <stdlib.h>
#include <mbedtls/ccm.h>
#include <mbedtls/constant_time.h>
#include <mbedtls/cipher.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/entropy.h>
#include <mbedtls/md.h>
#include <mbedtls/pkcs5.h>
#include <mbedtls/version.h>
#include "crypto_backend_internal.h"
struct crypt_hash {
const mbedtls_md_info_t *info;
mbedtls_md_context_t md;
};
struct crypt_hmac {
const mbedtls_md_info_t *info;
mbedtls_md_context_t md;
};
struct crypt_cipher {
const mbedtls_cipher_info_t *info;
mbedtls_cipher_context_t enc;
mbedtls_cipher_context_t dec;
int ecb;
};
static bool g_initialized = false;
static char g_backend_version[32];
static mbedtls_entropy_context g_entropy;
static mbedtls_ctr_drbg_context g_ctr_drbg;
static const mbedtls_md_info_t *crypt_get_hash(const char *name)
{
static const struct hash_alg {
const char *name;
mbedtls_md_type_t type;
} kHash[] = {
{"sha1", MBEDTLS_MD_SHA1 },
{"sha224", MBEDTLS_MD_SHA224 },
{"sha256", MBEDTLS_MD_SHA256 },
{"sha384", MBEDTLS_MD_SHA384 },
{"sha512", MBEDTLS_MD_SHA512 },
{"ripemd160", MBEDTLS_MD_RIPEMD160},
{NULL, 0, }
};
size_t i = 0;
while (name && kHash[i].name) {
if (strcmp(kHash[i].name, name) == 0)
return mbedtls_md_info_from_type(kHash[i].type);
i++;
}
return NULL;
}
int crypt_backend_init(void)
{
int ret;
if (g_initialized)
return 0;
mbedtls_version_get_string_full(g_backend_version);
mbedtls_entropy_init(&g_entropy);
mbedtls_ctr_drbg_init(&g_ctr_drbg);
ret = mbedtls_ctr_drbg_seed(
&g_ctr_drbg, mbedtls_entropy_func,
&g_entropy, NULL, MBEDTLS_CTR_DRBG_ENTROPY_LEN);
if (ret)
return -EINVAL;
g_initialized = true;
return 0;
}
void crypt_backend_destroy(void)
{
if (!g_initialized)
return;
mbedtls_ctr_drbg_free(&g_ctr_drbg);
mbedtls_entropy_free(&g_entropy);
g_initialized = false;
}
uint32_t crypt_backend_flags(void)
{
return 0;
}
const char *crypt_backend_version(void)
{
return g_backend_version;
}
bool crypt_fips_mode(void)
{
return false;
}
int crypt_backend_memeq(const void *m1, const void *m2, size_t n)
{
return mbedtls_ct_memcmp(m1, m2, n);
}
/* HASH */
int crypt_hash_size(const char *name)
{
const mbedtls_md_info_t *info;
info = crypt_get_hash(name);
return info ? mbedtls_md_get_size(info) : -ENOENT;
}
int crypt_hash_init(struct crypt_hash **ctx, const char *name)
{
struct crypt_hash *h;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
h->info = crypt_get_hash(name);
if (!h->info) {
free(h);
return -ENOENT;
}
mbedtls_md_init(&h->md);
if (mbedtls_md_setup(&h->md, h->info, 0)) {
mbedtls_md_free(&h->md);
free(h);
return -EINVAL;
}
if (mbedtls_md_starts(&h->md)) {
mbedtls_md_free(&h->md);
free(h);
return -EINVAL;
}
*ctx = h;
return 0;
}
int crypt_hash_write(struct crypt_hash *ctx, const char *buffer, size_t length)
{
if (mbedtls_md_update(&ctx->md, (const unsigned char *)buffer, length))
return -EINVAL;
return 0;
}
int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
{
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
if (length > mbedtls_md_get_size(ctx->info))
return -EINVAL;
if (mbedtls_md_finish(&ctx->md, tmp))
return -EINVAL;
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (mbedtls_md_starts(&ctx->md))
return -EINVAL;
return 0;
}
void crypt_hash_destroy(struct crypt_hash *ctx)
{
mbedtls_md_free(&ctx->md);
crypt_backend_memzero(ctx, sizeof(*ctx));
free(ctx);
}
/* HMAC */
int crypt_hmac_size(const char *name)
{
return crypt_hash_size(name);
}
int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
const void *key, size_t key_length)
{
struct crypt_hmac *h;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
h->info = crypt_get_hash(name);
if (!h->info) {
free(h);
return -ENOENT;
}
mbedtls_md_init(&h->md);
if (mbedtls_md_setup(&h->md, h->info, 1)) {
mbedtls_md_free(&h->md);
free(h);
return -EINVAL;
}
if (mbedtls_md_hmac_starts(&h->md, key, key_length)) {
mbedtls_md_free(&h->md);
free(h);
return -EINVAL;
}
*ctx = h;
return 0;
}
int crypt_hmac_write(struct crypt_hmac *ctx, const char *buffer, size_t length)
{
if (mbedtls_md_hmac_update(&ctx->md, (const unsigned char *)buffer, length))
return -EINVAL;
return 0;
}
int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
{
unsigned char tmp[MBEDTLS_MD_MAX_SIZE];
if (length > mbedtls_md_get_size(ctx->info))
return -EINVAL;
if (mbedtls_md_hmac_finish(&ctx->md, tmp))
return -EINVAL;
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (mbedtls_md_hmac_reset(&ctx->md))
return -EINVAL;
return 0;
}
void crypt_hmac_destroy(struct crypt_hmac *ctx)
{
mbedtls_md_free(&ctx->md);
crypt_backend_memzero(ctx, sizeof(*ctx));
free(ctx);
}
/* RNG */
int crypt_backend_rng(char *buffer, size_t length, int quality, int fips)
{
if (fips)
return -ENOTSUP;
/* Allow skipping reseeding for non-cryptographic strong random numbers */
if (quality == CRYPT_RND_NORMAL || quality == CRYPT_RND_SALT)
mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF);
else
mbedtls_ctr_drbg_set_prediction_resistance(&g_ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON);
if (mbedtls_ctr_drbg_random(&g_ctr_drbg, (unsigned char *)buffer, length))
return -EINVAL;
return 0;
}
/* CIPHER */
int crypt_cipher_init(struct crypt_cipher **ctx, const char *name,
const char *mode, const void *key, size_t key_length)
{
static const struct {
const char *name;
mbedtls_cipher_id_t id;
} kCipher[] = {
{ "aes", MBEDTLS_CIPHER_ID_AES },
{ "aria", MBEDTLS_CIPHER_ID_ARIA },
{ "camellia", MBEDTLS_CIPHER_ID_CAMELLIA },
{ NULL, 0 }
};
static const struct {
const char *name;
mbedtls_cipher_mode_t mode;
} kMode[] = {
{ "ecb", MBEDTLS_MODE_ECB },
{ "cbc", MBEDTLS_MODE_CBC },
{ "cfb", MBEDTLS_MODE_CFB },
{ "ofb", MBEDTLS_MODE_OFB },
{ "ctr", MBEDTLS_MODE_CTR },
{ "xts", MBEDTLS_MODE_XTS },
{ NULL, 0 }
};
mbedtls_cipher_id_t cid = MBEDTLS_CIPHER_ID_NONE;
mbedtls_cipher_mode_t cmode = MBEDTLS_MODE_NONE;
struct crypt_cipher *h;
size_t i;
int bits;
for (i = 0; kCipher[i].name; i++) {
if (strcmp(kCipher[i].name, name) == 0) {
cid = kCipher[i].id;
break;
}
}
for (i = 0; kMode[i].name; i++) {
if (strcmp(kMode[i].name, mode) == 0) {
cmode = kMode[i].mode;
break;
}
}
if (cid == MBEDTLS_CIPHER_ID_NONE || cmode == MBEDTLS_MODE_NONE)
return -ENOENT;
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
bits = key_length * 8;
h->info = mbedtls_cipher_info_from_values(cid, bits, cmode);
if (!h->info) {
free(h);
return -ENOENT;
}
mbedtls_cipher_init(&h->enc);
mbedtls_cipher_init(&h->dec);
if (mbedtls_cipher_setup(&h->enc, h->info) ||
mbedtls_cipher_setup(&h->dec, h->info) ||
mbedtls_cipher_setkey(&h->enc, key, bits, MBEDTLS_ENCRYPT) ||
mbedtls_cipher_setkey(&h->dec, key, bits, MBEDTLS_DECRYPT)) {
mbedtls_cipher_free(&h->dec);
mbedtls_cipher_free(&h->enc);
free(h);
return -EINVAL;
}
if (cmode == MBEDTLS_MODE_CBC) {
if (mbedtls_cipher_set_padding_mode(&h->enc, MBEDTLS_PADDING_NONE) ||
mbedtls_cipher_set_padding_mode(&h->dec, MBEDTLS_PADDING_NONE)) {
mbedtls_cipher_free(&h->dec);
mbedtls_cipher_free(&h->enc);
free(h);
return -EINVAL;
}
}
h->ecb = cmode == MBEDTLS_MODE_ECB;
*ctx = h;
return 0;
}
void crypt_cipher_destroy(struct crypt_cipher *ctx)
{
mbedtls_cipher_free(&ctx->dec);
mbedtls_cipher_free(&ctx->enc);
free(ctx);
}
static int crypt_cipher_crypt(
mbedtls_cipher_context_t *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length,
int ecb)
{
const unsigned char *input;
unsigned char *output;
size_t outlen;
size_t block;
size_t len;
if (ecb) /* ECB requires exactly block length input */
block = mbedtls_cipher_get_block_size(ctx);
else
block = length;
input = (const unsigned char *)in;
output = (unsigned char *)out;
if (mbedtls_cipher_set_iv(ctx, (const unsigned char *)iv, iv_length))
return -EINVAL;
if (mbedtls_cipher_reset(ctx))
return -EINVAL;
while (length) {
len = length < block ? length : block;
if (mbedtls_cipher_update(ctx, input, len, output, &outlen))
return -EINVAL;
output += outlen;
length -= len;
input += len;
}
if (mbedtls_cipher_finish(ctx, output, &outlen))
return -EINVAL;
return 0;
}
int crypt_cipher_encrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return crypt_cipher_crypt(&ctx->enc, in, out, length, iv, iv_length, ctx->ecb);
}
int crypt_cipher_decrypt(struct crypt_cipher *ctx,
const char *in, char *out, size_t length,
const char *iv, size_t iv_length)
{
return crypt_cipher_crypt(&ctx->dec, in, out, length, iv, iv_length, ctx->ecb);
}
bool crypt_cipher_kernel_only(struct crypt_cipher *ctx __attribute__((unused)))
{
return false;
}
int crypt_pbkdf(const char *kdf, const char *hash,
const char *password, size_t password_length,
const char *salt, size_t salt_length,
char *key, size_t key_length,
uint32_t iterations, uint32_t memory, uint32_t parallel)
{
const mbedtls_md_info_t *info;
#if !HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT
mbedtls_md_context_t md;
#endif
if (!kdf)
return -EINVAL;
if (strcmp(kdf, "pbkdf2") == 0) {
info = crypt_get_hash(hash);
if (!info)
return -EINVAL;
#if HAVE_MBEDTLS_PKCS5_PBKDF2_HMAC_EXT
if (mbedtls_pkcs5_pbkdf2_hmac_ext(mbedtls_md_get_type(info),
(const unsigned char *)password, password_length,
(const unsigned char *)salt, salt_length,
iterations, key_length, (unsigned char *)key)) {
return -EINVAL;
}
#else
mbedtls_md_init(&md);
if (mbedtls_md_setup(&md, info, 1))
return -EINVAL;
if (mbedtls_pkcs5_pbkdf2_hmac(&md,
(const unsigned char *)password, password_length,
(const unsigned char *)salt, salt_length,
iterations, key_length, (unsigned char *)key)) {
mbedtls_md_free(&md);
return -EINVAL;
}
mbedtls_md_free(&md);
#endif
return 0;
} else if (strncmp(kdf, "argon2", 6) == 0) {
return argon2(kdf, password, password_length, salt, salt_length,
key, key_length, iterations, memory, parallel);
}
return -EINVAL;
}
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)
{
const unsigned char *tagptr;
const unsigned char *input;
const unsigned char *ivptr;
mbedtls_ccm_context ctx;
unsigned char *output;
tagptr = (const unsigned char *)tag;
ivptr = (const unsigned char *)iv;
input = (const unsigned char *)in;
output = (unsigned char *)out;
mbedtls_ccm_init(&ctx);
if (mbedtls_ccm_setkey(&ctx, MBEDTLS_CIPHER_ID_AES, key, key_length * 8)) {
mbedtls_ccm_free(&ctx);
return -EINVAL;
}
if (mbedtls_ccm_auth_decrypt(&ctx, length, ivptr, iv_length, NULL, 0,
input, output, tagptr, tag_length)) {
mbedtls_ccm_free(&ctx);
return -EINVAL;
}
mbedtls_ccm_free(&ctx);
return 0;
}

View File

@@ -1,26 +1,12 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Nettle crypto backend implementation
*
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2023 Milan Broz
*
* 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.
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2025 Milan Broz
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <nettle/sha.h>
#include <nettle/sha3.h>
@@ -214,7 +200,7 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(bool fips __attribute__((unused)))
int crypt_backend_init(void)
{
return 0;
}
@@ -298,8 +284,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
memset(ctx, 0, sizeof(*ctx));
memset(h, 0, sizeof(*h));
h->hash = _get_alg(name);
if (!h->hash) {
@@ -313,7 +298,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
return -ENOMEM;
}
memcpy(h->key, key, key_length);
crypt_backend_memcpy(h->key, key, key_length);
h->key_length = key_length;
h->hash->init(&h->nettle_ctx);

View File

@@ -1,25 +1,12 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* NSS crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <nss.h>
#include <pk11pub.h>
@@ -75,7 +62,7 @@ static struct hash_alg *_get_alg(const char *name)
return NULL;
}
int crypt_backend_init(bool fips __attribute__((unused)))
int crypt_backend_init(void)
{
int r;
@@ -177,7 +164,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
return -EINVAL;
memcpy(buffer, tmp, length);
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (tmp_len < length)
@@ -220,8 +207,7 @@ int crypt_hmac_init(struct crypt_hmac **ctx, const char *name,
h = malloc(sizeof(*h));
if (!h)
return -ENOMEM;
memset(ctx, 0, sizeof(*ctx));
memset(h, 0, sizeof(*h));
h->hash = _get_alg(name);
if (!h->hash)
@@ -278,7 +264,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
if (PK11_DigestFinal(ctx->md, tmp, &tmp_len, length) != SECSuccess)
return -EINVAL;
memcpy(buffer, tmp, length);
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (tmp_len < length)

View File

@@ -1,36 +1,15 @@
// SPDX-License-Identifier: LGPL-2.1-or-later WITH cryptsetup-OpenSSL-exception
/*
* OPENSSL crypto backend implementation
*
* Copyright (C) 2010-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2023 Milan Broz
*
* 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.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
*
* You must obey the GNU Lesser General Public License in all respects
* for all of the code used other than OpenSSL.
* Copyright (C) 2010-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2025 Milan Broz
*/
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <strings.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
@@ -40,6 +19,7 @@
#include <openssl/provider.h>
#include <openssl/kdf.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
static OSSL_PROVIDER *ossl_legacy = NULL;
static OSSL_PROVIDER *ossl_default = NULL;
static OSSL_LIB_CTX *ossl_ctx = NULL;
@@ -197,12 +177,13 @@ static int openssl_backend_init(bool fips)
OSSL_get_max_threads(ossl_ctx) == MAX_THREADS)
ossl_threads = true;
r = snprintf(backend_version, sizeof(backend_version), "%s%s%s%s%s",
r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s%s%s",
OpenSSL_version(OPENSSL_VERSION),
ossl_default ? "[default]" : "",
ossl_legacy ? "[legacy]" : "",
fips ? "[fips]" : "",
ossl_threads ? "[threads]" : "");
ossl_threads ? "[threads]" : "",
crypt_backend_flags() & CRYPT_BACKEND_ARGON2 ? "[argon2]" : "");
if (r < 0 || (size_t)r >= sizeof(backend_version)) {
openssl_backend_exit();
@@ -224,12 +205,12 @@ static const char *openssl_backend_version(void)
}
#endif
int crypt_backend_init(bool fips)
int crypt_backend_init(void)
{
if (crypto_backend_initialised)
return 0;
if (openssl_backend_init(fips))
if (openssl_backend_init(crypt_fips_mode()))
return -EINVAL;
crypto_backend_initialised = 1;
@@ -251,11 +232,14 @@ void crypt_backend_destroy(void)
uint32_t crypt_backend_flags(void)
{
#if OPENSSL_VERSION_MAJOR >= 3
return 0;
#else
return CRYPT_BACKEND_PBKDF2_INT;
uint32_t flags = 0;
#if OPENSSL_VERSION_MAJOR < 3
flags |= CRYPT_BACKEND_PBKDF2_INT;
#endif
#if HAVE_DECL_OSSL_KDF_PARAM_ARGON2_VERSION
flags |= CRYPT_BACKEND_ARGON2;
#endif
return flags;
}
const char *crypt_backend_version(void)
@@ -398,7 +382,7 @@ int crypt_hash_final(struct crypt_hash *ctx, char *buffer, size_t length)
if (EVP_DigestFinal_ex(ctx->md, tmp, &tmp_len) != 1)
return -EINVAL;
memcpy(buffer, tmp, length);
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (tmp_len < length)
@@ -527,7 +511,7 @@ int crypt_hmac_final(struct crypt_hmac *ctx, char *buffer, size_t length)
HMAC_Final(ctx->md, tmp, &tmp_len);
#endif
memcpy(buffer, tmp, length);
crypt_backend_memcpy(buffer, tmp, length);
crypt_backend_memzero(tmp, sizeof(tmp));
if (tmp_len < length)
@@ -641,7 +625,7 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor
ctx = EVP_KDF_CTX_new(argon2);
if (!ctx) {
EVP_KDF_free(argon2);
return -EINVAL;;
return -EINVAL;
}
if (EVP_KDF_CTX_set_params(ctx, params) != 1) {
@@ -655,6 +639,10 @@ static int openssl_argon2(const char *type, const char *password, size_t passwor
EVP_KDF_CTX_free(ctx);
EVP_KDF_free(argon2);
/* Memory allocation is common issue with memory-hard Argon2 */
if (r == 0 && ERR_GET_REASON(ERR_get_error()) == ERR_R_MALLOC_FAILURE)
return -ENOMEM;
/* _derive() returns 0 or negative value on error, 1 on success */
return r == 1 ? 0 : -EINVAL;
#else

View File

@@ -1,31 +1,21 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Generic wrapper for storage encryption modes and Initial Vectors
* (reimplementation of some functions from Linux dm-crypt kernel)
*
* Copyright (C) 2014-2023 Milan Broz
*
* 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.
* Copyright (C) 2014-2025 Milan Broz
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include "bitops.h"
#include "crypto_backend.h"
#define SECTOR_SHIFT 9
#define SECTOR_SHIFT 9
#define MAX_CAPI_LEN 64
#define MAX_CAPI_LEN_STR "63"
/*
* Internal IV helper
@@ -225,43 +215,56 @@ int crypt_storage_init(struct crypt_storage **ctx,
bool large_iv)
{
struct crypt_storage *s;
char mode_name[64];
char cipher_name[MAX_CAPI_LEN], mode_name[MAX_CAPI_LEN], mode_tmp[MAX_CAPI_LEN];
char *cipher_iv = NULL;
int r = -EIO;
int r;
if (sector_size < (1 << SECTOR_SHIFT) ||
sector_size > (1 << (SECTOR_SHIFT + 3)) ||
sector_size & (sector_size - 1))
return -EINVAL;
s = malloc(sizeof(*s));
if (!s)
return -ENOMEM;
memset(s, 0, sizeof(*s));
/* Convert from capi mode */
if (!strncmp(cipher, "capi:", 5)) {
r = sscanf(cipher, "capi:%" MAX_CAPI_LEN_STR "[^(](%" MAX_CAPI_LEN_STR "[^)])", mode_tmp, cipher_name);
if (r != 2)
return -EINVAL;
r = snprintf(mode_name, sizeof(mode_name), "%s-%s", mode_tmp, cipher_mode);
if (r < 0 || (size_t)r >= sizeof(mode_name))
return -EINVAL;
} else {
strncpy(cipher_name, cipher, sizeof(cipher_name));
cipher_name[sizeof(cipher_name) - 1] = 0;
strncpy(mode_name, cipher_mode, sizeof(mode_name));
mode_name[sizeof(mode_name) - 1] = 0;
}
/* Remove IV if present */
strncpy(mode_name, cipher_mode, sizeof(mode_name));
mode_name[sizeof(mode_name) - 1] = 0;
cipher_iv = strchr(mode_name, '-');
if (cipher_iv) {
*cipher_iv = '\0';
cipher_iv++;
}
r = crypt_cipher_init(&s->cipher, cipher, mode_name, key, key_length);
s = malloc(sizeof(*s));
if (!s)
return -ENOMEM;
memset(s, 0, sizeof(*s));
r = crypt_cipher_init(&s->cipher, cipher_name, mode_name, key, key_length);
if (r) {
crypt_storage_destroy(s);
return r;
}
r = crypt_sector_iv_init(&s->cipher_iv, cipher, mode_name, cipher_iv, key, key_length, sector_size);
r = crypt_sector_iv_init(&s->cipher_iv, cipher_name, mode_name, cipher_iv, key, key_length, sector_size);
if (r) {
crypt_storage_destroy(s);
return r;
}
s->sector_size = sector_size;
s->iv_shift = large_iv ? int_log2(sector_size) - SECTOR_SHIFT : 0;
s->iv_shift = large_iv ? (unsigned)int_log2(sector_size) - SECTOR_SHIFT : 0;
*ctx = s;
return 0;

View File

@@ -0,0 +1,61 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Safe memory utilities
*
* Copyright (C) 2024-2025 Milan Broz
*/
#include "crypto_backend_internal.h"
#define ATTR_NOINLINE __attribute__ ((noinline))
#define ATTR_ZERO_REGS
#if HAVE_ATTRIBUTE_ZEROCALLUSEDREGS
# undef ATTR_ZERO_REGS
# define ATTR_ZERO_REGS __attribute__ ((zero_call_used_regs("used")))
#endif
/* Workaround for https://github.com/google/sanitizers/issues/1507 */
#if defined __has_feature
# if __has_feature (memory_sanitizer)
# undef HAVE_EXPLICIT_BZERO
# endif
#endif
/* Memzero helper (memset on stack can be optimized out) */
ATTR_NOINLINE ATTR_ZERO_REGS
void crypt_backend_memzero(void *s, size_t n)
{
#if HAVE_EXPLICIT_BZERO
explicit_bzero(s, n);
#else
volatile uint8_t *p = (volatile uint8_t *)s;
while(n--) *p++ = 0;
#endif
}
/* Memcpy helper to avoid spilling sensitive data through additional registers */
ATTR_NOINLINE ATTR_ZERO_REGS
void *crypt_backend_memcpy(void *dst, const void *src, size_t n)
{
volatile uint8_t *d = (volatile uint8_t *)dst;
const volatile uint8_t *s = (const volatile uint8_t *)src;
while(n--) *d++ = *s++;
return dst;
}
/* Internal implementation for constant time memory comparison */
ATTR_NOINLINE ATTR_ZERO_REGS
int crypt_internal_memeq(const void *m1, const void *m2, size_t n)
{
const unsigned char *_m1 = (const unsigned char *) m1;
const unsigned char *_m2 = (const unsigned char *) m2;
unsigned char result = 0;
size_t i;
for (i = 0; i < n; i++)
result |= _m1[i] ^ _m2[i];
return result;
}

View File

@@ -11,6 +11,7 @@ libcrypto_backend_link_with = []
libcrypto_backend_sources = files(
'argon2_generic.c',
'base64.c',
'memutils.c',
'cipher_check.c',
'cipher_generic.c',
'crc32.c',

View File

@@ -1,26 +1,12 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Implementation of Password-Based Cryptography as per PKCS#5
* Copyright (C) 2002,2003 Simon Josefsson
* Copyright (C) 2004 Free Software Foundation
*
* cryptsetup related changes
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2023 Milan Broz
*
* 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.
*
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2025 Milan Broz
*/
#include <errno.h>

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* PBKDF performance check
* Copyright (C) 2012-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2023 Milan Broz
* Copyright (C) 2012-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2025 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
* 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.
*/
#include <stdlib.h>
@@ -313,6 +300,7 @@ static int crypt_argon2_check(const char *kdf, const char *password,
} while (ms < ms_atleast || ms > ms_atmost);
out:
if (key) {
/* Key can be derived from a real provided password */
crypt_backend_memzero(key, key_length);
free(key);
}
@@ -394,6 +382,7 @@ static int crypt_pbkdf_check(const char *kdf, const char *hash,
}
out:
if (key) {
/* Key can be derived from a real provided password */
crypt_backend_memzero(key, key_length);
free(key);
}
@@ -419,6 +408,9 @@ int crypt_pbkdf_perf(const char *kdf, const char *hash,
if (r < 0)
return r;
if (parallel_threads > pbkdf_limits.max_parallel)
return -EINVAL;
min_memory = pbkdf_limits.min_bench_memory;
if (min_memory > max_memory_kb)
min_memory = max_memory_kb;

View File

@@ -1,10 +1,11 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* UTF8/16 helpers, copied and adapted from systemd project.
*
* Copyright (C) 2010 Lennart Poettering
*
* cryptsetup related changes
* Copyright (C) 2021-2023 Vojtech Trefny
* Copyright (C) 2021-2025 Vojtech Trefny
* Parts of the original systemd implementation are based on the GLIB utf8
* validation functions.
@@ -12,20 +13,6 @@
*
* Copyright (C) 1999 Tom Tromey
* Copyright (C) 2000 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <errno.h>
@@ -230,6 +217,7 @@ static size_t utf16_encode_unichar(char16_t *out, char32_t c)
return 1;
case 0x10000U ... 0x10ffffU:
/* coverity[overflow_const:FALSE] */
c -= 0x10000U;
out[0] = htole16((c >> 10) + 0xd800U);
out[1] = htole16((c & 0x3ffU) + 0xdc00U);
@@ -286,3 +274,20 @@ int crypt_utf8_to_utf16(char16_t **out, const char *s, size_t length)
*p = 0;
return 0;
}
/**
* crypt_char16_strlen()
* @s: string to get length of
*
* Returns: number of 16-bit words in the string
*/
size_t crypt_char16_strlen(const char16_t *s) {
size_t n = 0;
assert(s);
while (*s != 0)
n++, s++;
return n;
}

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* FVAULT2 (FileVault2-compatible) volume handling
*
* Copyright (C) 2021-2022 Pavel Tobias
*
* 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.
*/
#include <errno.h>
@@ -526,6 +513,7 @@ static int _read_volume_header(
int r = 0;
struct device *dev = crypt_metadata_device(cd);
struct volume_header *vol_header = NULL;
void *enc_key = NULL;
assert(sizeof(*vol_header) == FVAULT2_VOL_HEADER_SIZE);
@@ -570,8 +558,8 @@ static int _read_volume_header(
goto out;
}
*enc_md_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
if (*enc_md_key == NULL) {
enc_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE);
if (!enc_key) {
r = -ENOMEM;
goto out;
}
@@ -579,9 +567,15 @@ static int _read_volume_header(
*block_size = le32_to_cpu(vol_header->block_size);
*disklbl_blkoff = le64_to_cpu(vol_header->disklbl_blkoff);
uuid_unparse(vol_header->ph_vol_uuid, ph_vol_uuid);
memcpy((*enc_md_key)->key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
memcpy((*enc_md_key)->key + FVAULT2_AES_KEY_SIZE,
crypt_safe_memcpy(enc_key, vol_header->key_data, FVAULT2_AES_KEY_SIZE);
crypt_safe_memcpy((char *)enc_key + FVAULT2_AES_KEY_SIZE,
vol_header->ph_vol_uuid, FVAULT2_AES_KEY_SIZE);
*enc_md_key = crypt_alloc_volume_key_by_safe_alloc(&enc_key);
if (*enc_md_key == NULL) {
crypt_safe_free(enc_key);
r = -ENOMEM;
}
out:
free(vol_header);
return r;
@@ -717,7 +711,7 @@ static int _read_encrypted_metadata(
goto out;
}
r = crypt_cipher_init(&cipher, "aes", "xts", key->key, FVAULT2_XTS_KEY_SIZE);
r = crypt_cipher_init(&cipher, "aes", "xts", crypt_volume_key_get_key(key), FVAULT2_XTS_KEY_SIZE);
if (r < 0)
goto out;
@@ -848,8 +842,7 @@ static int _activate(
r = dm_crypt_target_set(&dm_dev.segment, 0, dm_dev.size,
crypt_data_device(cd), vol_key, cipher,
crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
crypt_get_integrity(cd), crypt_get_integrity_tag_size(cd),
crypt_get_sector_size(cd));
NULL, 0, 0, crypt_get_sector_size(cd));
if (!r)
r = dm_create_device(cd, name, CRYPT_FVAULT2, &dm_dev);
@@ -906,15 +899,14 @@ int FVAULT2_get_volume_key(
const char *passphrase,
size_t passphrase_len,
const struct fvault2_params *params,
struct volume_key **vol_key)
struct volume_key **r_vol_key)
{
int r = 0;
uint8_t family_uuid_bin[FVAULT2_UUID_BIN_SIZE];
struct volume_key *passphrase_key = NULL;
struct volume_key *kek = NULL;
struct crypt_hash *hash = NULL;
void *passphrase_key = NULL, *kek = NULL, *vol_key= NULL;
*vol_key = NULL;
*r_vol_key = NULL;
if (uuid_parse(params->family_uuid, family_uuid_bin) < 0) {
log_dbg(cd, "Could not parse logical volume family UUID: %s.",
@@ -923,61 +915,62 @@ int FVAULT2_get_volume_key(
goto out;
}
passphrase_key = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
passphrase_key = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE);
if (passphrase_key == NULL) {
r = -ENOMEM;
goto out;
}
r = crypt_pbkdf("pbkdf2", "sha256", passphrase, passphrase_len,
params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key->key,
params->pbkdf2_salt, FVAULT2_PBKDF2_SALT_SIZE, passphrase_key,
FVAULT2_AES_KEY_SIZE, params->pbkdf2_iters, 0, 0);
if (r < 0)
goto out;
kek = crypt_alloc_volume_key(FVAULT2_AES_KEY_SIZE, NULL);
kek = crypt_safe_alloc(FVAULT2_AES_KEY_SIZE);
if (kek == NULL) {
r = -ENOMEM;
goto out;
}
r = _unwrap_key(passphrase_key->key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
FVAULT2_WRAPPED_KEY_SIZE, kek->key, FVAULT2_AES_KEY_SIZE);
r = _unwrap_key(passphrase_key, FVAULT2_AES_KEY_SIZE, params->wrapped_kek,
FVAULT2_WRAPPED_KEY_SIZE, kek, FVAULT2_AES_KEY_SIZE);
if (r < 0)
goto out;
*vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, NULL);
if (*vol_key == NULL) {
vol_key = crypt_safe_alloc(FVAULT2_XTS_KEY_SIZE);
if (vol_key == NULL) {
r = -ENOMEM;
goto out;
}
r = _unwrap_key(kek->key, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
FVAULT2_WRAPPED_KEY_SIZE, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
r = _unwrap_key(kek, FVAULT2_AES_KEY_SIZE, params->wrapped_vk,
FVAULT2_WRAPPED_KEY_SIZE, vol_key, FVAULT2_AES_KEY_SIZE);
if (r < 0)
goto out;
r = crypt_hash_init(&hash, "sha256");
if (r < 0)
goto out;
r = crypt_hash_write(hash, (*vol_key)->key, FVAULT2_AES_KEY_SIZE);
r = crypt_hash_write(hash, vol_key, FVAULT2_AES_KEY_SIZE);
if (r < 0)
goto out;
r = crypt_hash_write(hash, (char *)family_uuid_bin,
FVAULT2_UUID_BIN_SIZE);
if (r < 0)
goto out;
r = crypt_hash_final(hash, (*vol_key)->key + FVAULT2_AES_KEY_SIZE,
r = crypt_hash_final(hash, (char *)vol_key + FVAULT2_AES_KEY_SIZE,
FVAULT2_AES_KEY_SIZE);
if (r < 0)
goto out;
*r_vol_key = crypt_alloc_volume_key_by_safe_alloc(&vol_key);
if (!*r_vol_key)
r = -ENOMEM;
out:
crypt_free_volume_key(passphrase_key);
crypt_free_volume_key(kek);
if (r < 0) {
crypt_free_volume_key(*vol_key);
*vol_key = NULL;
}
crypt_safe_free(passphrase_key);
crypt_safe_free(kek);
crypt_safe_free(vol_key);
if (hash != NULL)
crypt_hash_destroy(hash);
return r;
@@ -1010,48 +1003,19 @@ int FVAULT2_dump(
return 0;
}
int FVAULT2_activate_by_passphrase(
struct crypt_device *cd,
const char *name,
const char *passphrase,
size_t passphrase_len,
const struct fvault2_params *params,
uint32_t flags)
{
int r;
struct volume_key *vol_key = NULL;
r = FVAULT2_get_volume_key(cd, passphrase, passphrase_len, params, &vol_key);
if (r < 0)
return r;
if (name)
r = _activate(cd, name, vol_key, params, flags);
crypt_free_volume_key(vol_key);
return r;
}
int FVAULT2_activate_by_volume_key(
struct crypt_device *cd,
const char *name,
const char *key,
size_t key_size,
struct volume_key *vk,
const struct fvault2_params *params,
uint32_t flags)
{
int r = 0;
struct volume_key *vol_key = NULL;
assert(crypt_volume_key_length(vk) == FVAULT2_XTS_KEY_SIZE);
if (key_size != FVAULT2_XTS_KEY_SIZE)
return -EINVAL;
vol_key = crypt_alloc_volume_key(FVAULT2_XTS_KEY_SIZE, key);
if (vol_key == NULL)
return -ENOMEM;
r = _activate(cd, name, vol_key, params, flags);
crypt_free_volume_key(vol_key);
return r;
return _activate(cd, name, vk, params, flags);
}
size_t FVAULT2_volume_key_size(void)
{
return FVAULT2_XTS_KEY_SIZE;
}

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* FVAULT2 (FileVault2-compatible) volume handling
*
* Copyright (C) 2021-2022 Pavel Tobias
*
* 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_FVAULT2_H
@@ -54,27 +41,20 @@ int FVAULT2_get_volume_key(
const char *passphrase,
size_t passphrase_len,
const struct fvault2_params *params,
struct volume_key **vol_key);
struct volume_key **r_vol_key);
int FVAULT2_dump(
struct crypt_device *cd,
struct device *device,
const struct fvault2_params *params);
int FVAULT2_activate_by_passphrase(
struct crypt_device *cd,
const char *name,
const char *passphrase,
size_t passphrase_len,
const struct fvault2_params *params,
uint32_t flags);
int FVAULT2_activate_by_volume_key(
struct crypt_device *cd,
const char *name,
const char *key,
size_t key_size,
struct volume_key *vk,
const struct fvault2_params *params,
uint32_t flags);
size_t FVAULT2_volume_key_size(void);
#endif

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Integrity volume handling
*
* Copyright (C) 2016-2023 Milan Broz
*
* 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.
* Copyright (C) 2016-2025 Milan Broz
*/
#include <errno.h>
@@ -44,16 +31,22 @@ static int INTEGRITY_read_superblock(struct crypt_device *cd,
{
int devfd, r;
log_dbg(cd, "Reading kernel dm-integrity metadata on %s.", device_path(device));
devfd = device_open(cd, device, O_RDONLY);
if(devfd < 0)
return -EINVAL;
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))) {
device_alignment(device), sb, sizeof(*sb), offset) != sizeof(*sb)) {
log_dbg(cd, "Cannot read kernel dm-integrity metadata on %s.", device_path(device));
return -EINVAL;
}
if (memcmp(sb->magic, SB_MAGIC, sizeof(sb->magic))) {
log_dbg(cd, "No kernel dm-integrity metadata detected on %s.", device_path(device));
r = -EINVAL;
} else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_5) {
} else if (sb->version < SB_VERSION_1 || sb->version > SB_VERSION_6) {
log_err(cd, _("Incompatible kernel dm-integrity metadata (version %u) detected on %s."),
sb->version, device_path(device));
r = -EINVAL;
@@ -80,8 +73,10 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
if (r)
return r;
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
params->tag_size = sb.integrity_tag_size;
if (params) {
params->sector_size = SECTOR_SIZE << sb.log2_sectors_per_block;
params->tag_size = sb.integrity_tag_size;
}
if (flags)
*flags = sb.flags;
@@ -92,28 +87,32 @@ int INTEGRITY_read_sb(struct crypt_device *cd,
int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offset)
{
struct superblock sb;
uint64_t sector_size;
int r;
r = INTEGRITY_read_superblock(cd, device, offset, &sb);
if (r)
return r;
log_std(cd, "Info for integrity device %s.\n", device_path(device));
log_std(cd, "superblock_version %d\n", (unsigned)sb.version);
log_std(cd, "log2_interleave_sectors %d\n", sb.log2_interleave_sectors);
log_std(cd, "integrity_tag_size %u\n", sb.integrity_tag_size);
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);
sector_size = (uint64_t)SECTOR_SIZE << sb.log2_sectors_per_block;
log_std(cd, "INTEGRITY header information for %s.\n", device_path(device));
log_std(cd, "version: %d\n", (unsigned)sb.version);
log_std(cd, "tag size: %u [bytes]\n", sb.integrity_tag_size);
log_std(cd, "sector size: %" PRIu64 " [bytes]\n", sector_size);
log_std(cd, "data size: %" PRIu64 " [512-byte units] (%" PRIu64 " [bytes])\n",
sb.provided_data_sectors, sb.provided_data_sectors * SECTOR_SIZE);
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%s%s\n",
log_std(cd, "recalculate sector: %" PRIu64 "\n", sb.recalc_sector);
log_std(cd, "journal sections: %u\n", sb.journal_sections);
log_std(cd, "log2 interleave sectors: %d\n", sb.log2_interleave_sectors);
log_std(cd, "log2 blocks per bitmap: %u\n", sb.log2_blocks_per_bitmap_bit);
log_std(cd, "flags: %s%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_FIXED_PADDING ? "fix_padding " : "",
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "");
sb.flags & SB_FLAG_FIXED_HMAC ? "fix_hmac " : "",
sb.flags & SB_FLAG_INLINE ? "inline " : "");
return 0;
}
@@ -133,26 +132,42 @@ int INTEGRITY_data_sectors(struct crypt_device *cd,
return 0;
}
int INTEGRITY_key_size(const char *integrity)
int INTEGRITY_key_size(const char *integrity, int required_key_size)
{
int ks = 0;
if (!integrity && required_key_size)
return -EINVAL;
if (!integrity)
return 0;
//FIXME: use crypto backend hash size
if (!strcmp(integrity, "aead"))
return 0;
ks = 0;
else if (!strcmp(integrity, "hmac(sha1)"))
return 20;
ks = required_key_size ?: 20;
else if (!strcmp(integrity, "hmac(sha256)"))
return 32;
ks = required_key_size ?: 32;
else if (!strcmp(integrity, "hmac(sha512)"))
return 64;
ks = required_key_size ?: 64;
else if (!strcmp(integrity, "phmac(sha1)"))
ks = required_key_size ?: -EINVAL;
else if (!strcmp(integrity, "phmac(sha256)"))
ks = required_key_size ?: -EINVAL;
else if (!strcmp(integrity, "phmac(sha512)"))
ks = required_key_size ?: -EINVAL;
else if (!strcmp(integrity, "poly1305"))
return 0;
ks = 0;
else if (!strcmp(integrity, "none"))
return 0;
ks = 0;
else
return -EINVAL;
return -EINVAL;
if (required_key_size && ks != required_key_size)
return -EINVAL;
return ks;
}
/* Return hash or hmac(hash) size, if known */
@@ -171,6 +186,8 @@ int INTEGRITY_hash_tag_size(const char *integrity)
return 8;
r = sscanf(integrity, "hmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
if (r != 1)
r = sscanf(integrity, "phmac(%" MAX_CIPHER_LEN_STR "[^)]s", hash);
if (r == 1)
r = crypt_hash_size(hash);
else
@@ -213,6 +230,12 @@ int INTEGRITY_tag_size(const char *integrity,
auth_tag_size = 32;
else if (!strcmp(integrity, "hmac(sha512)"))
auth_tag_size = 64;
else if (!strcmp(integrity, "phmac(sha1)"))
auth_tag_size = 20;
else if (!strcmp(integrity, "phmac(sha256)"))
auth_tag_size = 32;
else if (!strcmp(integrity, "phmac(sha512)"))
auth_tag_size = 64;
else if (!strcmp(integrity, "poly1305")) {
if (iv_tag_size)
iv_tag_size = 12;
@@ -243,6 +266,9 @@ int INTEGRITY_create_dmd_device(struct crypt_device *cd,
if (sb_flags & SB_FLAG_RECALCULATING)
dmd->flags |= CRYPT_ACTIVATE_RECALCULATE;
if (sb_flags & SB_FLAG_INLINE)
dmd->flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
r = INTEGRITY_data_sectors(cd, INTEGRITY_metadata_device(cd),
crypt_get_data_offset(cd) * SECTOR_SIZE, &dmd->size);
if (r < 0)
@@ -262,14 +288,15 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
uint32_t sb_flags)
{
int r;
uint32_t dmi_flags;
uint64_t dmi_flags;
struct dm_target *tgt = &dmd->segment;
if (!single_segment(dmd) || tgt->type != DM_INTEGRITY)
return -EINVAL;
log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d, provided sectors %" PRIu64".",
device_path(tgt->data_device), name, tgt->u.integrity.tag_size, dmd->size);
log_dbg(cd, "Trying to activate INTEGRITY device on top of %s, using name %s, tag size %d%s, provided sectors %" PRIu64".",
device_path(tgt->data_device), name, tgt->u.integrity.tag_size,
(sb_flags & SB_FLAG_INLINE) ? " (inline)" :"", dmd->size);
r = create_or_reload_device(cd, name, type, dmd);
@@ -293,6 +320,12 @@ int INTEGRITY_activate_dmd_device(struct crypt_device *cd,
return -ENOTSUP;
}
if (r < 0 && (sb_flags & SB_FLAG_INLINE) && !dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
!(dmi_flags & DM_INTEGRITY_INLINE_MODE_SUPPORTED)) {
log_err(cd, _("Kernel does not support dm-integrity inline mode."));
return -ENOTSUP;
}
return r;
}
@@ -385,11 +418,14 @@ static int _create_reduced_device(struct crypt_device *cd,
int INTEGRITY_format(struct crypt_device *cd,
const struct crypt_params_integrity *params,
struct volume_key *integrity_key,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
uint64_t backing_device_sectors)
uint64_t backing_device_sectors,
uint32_t *sb_flags,
bool integrity_inline)
{
uint32_t dmi_flags;
uint64_t dmi_flags;
char reduced_device_name[70], tmp_name[64], tmp_uuid[40];
struct crypt_dm_active_device dmdi = {
.size = 8,
@@ -400,7 +436,6 @@ int INTEGRITY_format(struct crypt_device *cd,
uuid_t tmp_uuid_bin;
uint64_t data_offset_sectors;
struct device *p_metadata_device, *p_data_device, *reduced_device = NULL;
struct volume_key *vk = NULL;
uuid_generate(tmp_uuid_bin);
uuid_unparse(tmp_uuid_bin, tmp_uuid);
@@ -435,19 +470,18 @@ int INTEGRITY_format(struct crypt_device *cd,
p_data_device = crypt_data_device(cd);
}
/* 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);
if (integrity_inline)
dmdi.flags |= (CRYPT_ACTIVATE_NO_JOURNAL | CRYPT_ACTIVATE_INLINE_MODE);
r = dm_integrity_target_set(cd, tgt, 0, dmdi.size, p_metadata_device,
p_data_device, crypt_get_integrity_tag_size(cd),
data_offset_sectors, crypt_get_sector_size(cd), vk,
data_offset_sectors, crypt_get_sector_size(cd), integrity_key,
journal_crypt_key, journal_mac_key, params);
if (r < 0)
goto err;
log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d.",
device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size);
log_dbg(cd, "Trying to format INTEGRITY device on top of %s, tmp name %s, tag size %d%s.",
device_path(tgt->data_device), tmp_name, tgt->u.integrity.tag_size, integrity_inline ? " (inline)" : "");
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))) {
@@ -468,9 +502,14 @@ int INTEGRITY_format(struct crypt_device *cd,
goto err;
r = dm_remove_device(cd, tmp_name, CRYPT_DEACTIVATE_FORCE);
if (r)
goto err;
/* reload sb_flags from superblock (important for SB_FLAG_INLINE) */
if (sb_flags)
r = INTEGRITY_read_sb(cd, NULL, sb_flags);
err:
dm_targets_free(cd, &dmdi);
crypt_free_volume_key(vk);
if (reduced_device) {
dm_remove_device(cd, reduced_device_name, CRYPT_DEACTIVATE_FORCE);
device_free(cd, reduced_device);

View File

@@ -1,27 +1,15 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* Integrity header definition
*
* Copyright (C) 2016-2023 Milan Broz
*
* 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.
* Copyright (C) 2016-2025 Milan Broz
*/
#ifndef _CRYPTSETUP_INTEGRITY_H
#define _CRYPTSETUP_INTEGRITY_H
#include <stdint.h>
#include <stdbool.h>
struct crypt_device;
struct device;
@@ -36,12 +24,14 @@ struct crypt_dm_active_device;
#define SB_VERSION_3 3
#define SB_VERSION_4 4
#define SB_VERSION_5 5
#define SB_VERSION_6 6
#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 */
#define SB_FLAG_INLINE (1 << 5) /* V6 only */
struct superblock {
uint8_t magic[8];
@@ -53,8 +43,10 @@ struct superblock {
uint32_t flags;
uint8_t log2_sectors_per_block;
uint8_t log2_blocks_per_bitmap_bit; /* V3 only */
uint8_t pad[2];
uint8_t pad[2]; /* (padding) */
uint64_t recalc_sector; /* V2 only */
uint8_t pad2[8]; /* (padding) */
uint8_t salt[16]; /* for fixed hmac, V5 only */
} __attribute__ ((packed));
int INTEGRITY_read_sb(struct crypt_device *cd,
@@ -66,7 +58,7 @@ int INTEGRITY_dump(struct crypt_device *cd, struct device *device, uint64_t offs
int INTEGRITY_data_sectors(struct crypt_device *cd,
struct device *device, uint64_t offset,
uint64_t *data_sectors);
int INTEGRITY_key_size(const char *integrity);
int INTEGRITY_key_size(const char *integrity, int required_key_size);
int INTEGRITY_tag_size(const char *integrity,
const char *cipher,
const char *cipher_mode);
@@ -74,9 +66,12 @@ int INTEGRITY_hash_tag_size(const char *integrity);
int INTEGRITY_format(struct crypt_device *cd,
const struct crypt_params_integrity *params,
struct volume_key *integrity_key,
struct volume_key *journal_crypt_key,
struct volume_key *journal_mac_key,
uint64_t backing_device_sectors);
uint64_t backing_device_sectors,
uint32_t *sb_flags,
bool integrity_inline);
int INTEGRITY_activate(struct crypt_device *cd,
const char *name,

View File

@@ -1,24 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* libcryptsetup - cryptsetup library internal
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2025 Milan Broz
*/
#ifndef INTERNAL_H
@@ -61,24 +48,36 @@
struct crypt_device;
struct luks2_reencrypt;
struct volume_key;
struct volume_key {
int id;
size_t keylength;
const char *key_description;
struct volume_key *next;
char key[];
};
typedef enum {
KEY_QUALITY_KEY = 0,
KEY_QUALITY_NORMAL,
KEY_QUALITY_EMPTY
} key_quality_info;
struct volume_key *crypt_alloc_volume_key(size_t keylength, const char *key);
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength);
struct volume_key *crypt_alloc_volume_key_by_safe_alloc(void **safe_alloc);
struct volume_key *crypt_generate_volume_key(struct crypt_device *cd, size_t keylength,
key_quality_info quality);
void crypt_free_volume_key(struct volume_key *vk);
int crypt_volume_key_set_description(struct volume_key *key, const char *key_description);
const char *crypt_volume_key_get_key(const struct volume_key *vk);
size_t crypt_volume_key_length(const struct volume_key *vk);
int crypt_volume_key_set_description(struct volume_key *key,
const char *key_description, key_type_t keyring_key_type);
int crypt_volume_key_set_description_by_name(struct volume_key *vk, const char *key_name);
key_type_t crypt_volume_key_kernel_key_type(const struct volume_key *vk);
const char *crypt_volume_key_description(const struct volume_key *vk);
void crypt_volume_key_set_id(struct volume_key *vk, int id);
int crypt_volume_key_get_id(const struct volume_key *vk);
void crypt_volume_key_add_next(struct volume_key **vks, struct volume_key *vk);
struct volume_key *crypt_volume_key_next(struct volume_key *vk);
struct volume_key *crypt_volume_key_by_id(struct volume_key *vk, int id);
void crypt_volume_key_pass_safe_alloc(struct volume_key *vk, void **safe_alloc);
bool crypt_volume_key_is_set(const struct volume_key *vk);
bool crypt_volume_key_upload_kernel_key(struct volume_key *vk);
void crypt_volume_key_drop_uploaded_kernel_key(struct crypt_device *cd, struct volume_key *vk);
void crypt_volume_key_drop_kernel_key(struct crypt_device *cd, struct volume_key *vk);
struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd);
int init_pbkdf_type(struct crypt_device *cd,
@@ -99,7 +98,6 @@ int device_alloc_no_check(struct device **device, const char *path);
void device_close(struct crypt_device *cd, struct device *device);
void device_free(struct crypt_device *cd, struct device *device);
const char *device_path(const struct device *device);
const char *device_dm_name(const struct device *device);
const char *device_block_path(const struct device *device);
void device_topology_alignment(struct crypt_device *cd,
struct device *device,
@@ -116,6 +114,8 @@ void device_disable_direct_io(struct device *device);
int device_is_identical(struct device *device1, struct device *device2);
int device_is_rotational(struct device *device);
int device_is_dax(struct device *device);
int device_is_zoned(struct device *device);
int device_is_nop_dif(struct device *device, uint32_t *tag_size);
size_t device_alignment(struct device *device);
int device_direct_io(const struct device *device);
int device_fallocate(struct device *device, uint64_t size);
@@ -166,6 +166,8 @@ int crypt_confirm(struct crypt_device *cd, const char *msg);
char *crypt_lookup_dev(const char *dev_id);
int crypt_dev_is_rotational(int major, int minor);
int crypt_dev_is_dax(int major, int minor);
int crypt_dev_is_zoned(int major, int minor);
int crypt_dev_is_nop_dif(int major, int minor, uint32_t *tag_size);
int crypt_dev_is_partition(const char *dev_path);
char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t size);
int crypt_dev_get_partition_number(const char *dev_path);
@@ -173,8 +175,6 @@ char *crypt_get_base_device(const char *dev_path);
uint64_t crypt_dev_partition_offset(const char *dev_path);
int lookup_by_disk_id(const char *dm_uuid);
int lookup_by_sysfs_uuid_field(const char *dm_uuid);
int crypt_uuid_cmp(const char *dm_uuid, const char *hdr_uuid);
int crypt_uuid_type_cmp(const char *dm_uuid, const char *type);
size_t crypt_getpagesize(void);
unsigned crypt_cpusonline(void);
@@ -228,7 +228,7 @@ int crypt_wipe_device(struct crypt_device *cd,
/* Internal integrity helpers */
const char *crypt_get_integrity(struct crypt_device *cd);
int crypt_get_integrity_key_size(struct crypt_device *cd);
int crypt_get_integrity_key_size(struct crypt_device *cd, bool dm_compat);
int crypt_get_integrity_tag_size(struct crypt_device *cd);
int crypt_key_in_keyring(struct crypt_device *cd);
@@ -242,9 +242,18 @@ int crypt_keyring_get_key_by_name(struct crypt_device *cd,
const char *key_description,
char **key,
size_t *key_size);
int crypt_keyring_get_keysize_by_name(struct crypt_device *cd,
const char *key_description,
size_t *r_key_size);
int crypt_use_keyring_for_vk(struct crypt_device *cd);
void crypt_drop_keyring_key_by_description(struct crypt_device *cd, const char *key_description, key_type_t ktype);
void crypt_drop_keyring_key(struct crypt_device *cd, struct volume_key *vks);
void crypt_unlink_key_from_thread_keyring(struct crypt_device *cd,
key_serial_t key_id);
void crypt_unlink_key_by_description_from_thread_keyring(struct crypt_device *cd,
const char *key_description,
key_type_t ktype);
void crypt_drop_uploaded_keyring_key(struct crypt_device *cd, struct volume_key *vks);
static inline uint64_t compact_version(uint16_t major, uint16_t minor, uint16_t patch, uint16_t release)
{
@@ -266,6 +275,8 @@ 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 (size == 0)
return true;
if ((uint64_t)(*u / size) != b)
return true;
return false;
@@ -275,4 +286,6 @@ static inline bool uint64_mult_overflow(uint64_t *u, uint64_t b, size_t size)
#define KEY_EXTERNAL_VERIFICATION -1
#define KEY_VERIFIED 0
size_t crypt_safe_alloc_size(const void *data);
#endif /* INTERNAL_H */

View File

@@ -1,26 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
*
* Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2022-2023 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2022-2025 Ondrej Kozina
*/
#include <errno.h>
#include "bitlk/bitlk.h"
#include "fvault2/fvault2.h"
#include "luks1/luks.h"
#include "luks2/luks2.h"
#include "keyslot_context.h"
@@ -71,6 +60,44 @@ static int get_luks2_volume_key_by_passphrase(struct crypt_device *cd,
return get_luks2_key_by_passphrase(cd, kc, keyslot, CRYPT_DEFAULT_SEGMENT, r_vk);
}
static int get_bitlk_volume_key_by_passphrase(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct bitlk_metadata *params,
struct volume_key **r_vk)
{
int r;
assert(cd);
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
assert(params);
assert(r_vk);
r = BITLK_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk);
if (r < 0)
kc->error = r;
return r;
}
static int get_fvault2_volume_key_by_passphrase(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct fvault2_params *params,
struct volume_key **r_vk)
{
int r;
assert(cd);
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
assert(params);
assert(r_vk);
r = FVAULT2_get_volume_key(cd, kc->u.p.passphrase, kc->u.p.passphrase_size, params, r_vk);
if (r < 0)
kc->error = r;
return r;
}
static int get_passphrase_by_passphrase(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const char **r_passphrase,
@@ -173,6 +200,56 @@ static int get_luks1_volume_key_by_keyfile(struct crypt_device *cd,
return r;
}
static int get_bitlk_volume_key_by_keyfile(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct bitlk_metadata *params,
struct volume_key **r_vk)
{
int r;
const char *passphrase;
size_t passphrase_size;
assert(cd);
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
assert(params);
assert(r_vk);
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
if (r < 0)
return r;
r = BITLK_get_volume_key(cd, passphrase, passphrase_size, params, r_vk);
if (r < 0)
kc->error = r;
return r;
}
static int get_fvault2_volume_key_by_keyfile(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct fvault2_params *params,
struct volume_key **r_vk)
{
int r;
const char *passphrase;
size_t passphrase_size;
assert(cd);
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
assert(params);
assert(r_vk);
r = get_passphrase_by_keyfile(cd, kc, &passphrase, &passphrase_size);
if (r < 0)
return r;
r = FVAULT2_get_volume_key(cd, passphrase, passphrase_size, params, r_vk);
if (r < 0)
kc->error = r;
return r;
}
static int get_key_by_key(struct crypt_device *cd __attribute__((unused)),
struct crypt_keyslot_context *kc,
int keyslot __attribute__((unused)),
@@ -211,6 +288,22 @@ static int get_generic_volume_key_by_key(struct crypt_device *cd,
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
}
static int get_bitlk_volume_key_by_key(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct bitlk_metadata *params __attribute__((unused)),
struct volume_key **r_vk)
{
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
}
static int get_fvault2_volume_key_by_key(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct fvault2_params *params __attribute__((unused)),
struct volume_key **r_vk)
{
return get_key_by_key(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
}
static int get_generic_signed_key_by_key(struct crypt_device *cd,
struct crypt_keyslot_context *kc,
struct volume_key **r_vk,
@@ -367,7 +460,7 @@ static int get_luks2_key_by_keyring(struct crypt_device *cd,
if (r < 0)
kc->error = r;
return 0;
return r;
}
static int get_luks2_volume_key_by_keyring(struct crypt_device *cd,
@@ -386,7 +479,7 @@ static int get_luks1_volume_key_by_keyring(struct crypt_device *cd,
int r;
assert(cd);
assert(kc && kc->type == CRYPT_KC_TYPE_PASSPHRASE);
assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING);
assert(r_vk);
r = get_passphrase_by_keyring(cd, kc, CONST_CAST(const char **) &kc->i_passphrase,
@@ -427,9 +520,9 @@ static int get_key_by_vk_in_keyring(struct crypt_device *cd,
return -EINVAL;
}
*r_vk = crypt_alloc_volume_key(key_size, key);
crypt_safe_free(key);
*r_vk = crypt_alloc_volume_key_by_safe_alloc((void **)&key);
if (!*r_vk) {
crypt_safe_free(key);
kc->error = -ENOMEM;
return kc->error;
}
@@ -445,16 +538,41 @@ static int get_volume_key_by_vk_in_keyring(struct crypt_device *cd,
return get_key_by_vk_in_keyring(cd, kc, -2 /* unused */, -2 /* unused */, r_vk);
}
static void unlock_method_init_internal(struct crypt_keyslot_context *kc)
static void crypt_keyslot_context_init_common(struct crypt_keyslot_context *kc)
{
assert(kc);
kc->version = KC_VERSION_BASIC;
kc->error = 0;
kc->i_passphrase = NULL;
kc->i_passphrase_size = 0;
}
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
static void keyring_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_KEYRING);
free(kc->u.kr.i_key_description);
}
static int keyring_get_key_size(struct crypt_device *cd, struct crypt_keyslot_context *kc, size_t *r_key_size)
{
int r;
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
assert(r_key_size);
if (!kc->u.vk_kr.i_key_size) {
r = crypt_keyring_get_keysize_by_name(cd, kc->u.vk_kr.key_description, &kc->u.vk_kr.i_key_size);
if (r < 0)
return r;
}
*r_key_size = kc->u.vk_kr.i_key_size;
return 0;
}
void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc,
const char *key_description)
{
assert(kc);
@@ -463,18 +581,32 @@ void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
kc->u.kr.key_description = key_description;
kc->get_luks2_key = get_luks2_key_by_keyring;
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring;
kc->get_luks1_volume_key = get_luks1_volume_key_by_keyring;
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyring;
kc->get_passphrase = get_passphrase_by_keyring;
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = NULL;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
kc->context_free = keyring_context_free;
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
static void key_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
crypt_free_volume_key(kc->u.k.i_vk);
}
static int key_get_key_size(struct crypt_device *cd __attribute__((unused)),
struct crypt_keyslot_context *kc,
size_t *r_key_size)
{
assert(kc && kc->type == CRYPT_KC_TYPE_KEY);
assert(r_key_size);
*r_key_size = kc->u.k.volume_key_size;
return 0;
}
void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc,
const char *volume_key,
size_t volume_key_size)
{
@@ -483,19 +615,29 @@ void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
kc->type = CRYPT_KC_TYPE_KEY;
kc->u.k.volume_key = volume_key;
kc->u.k.volume_key_size = volume_key_size;
kc->get_luks2_key = get_key_by_key;
kc->get_luks2_volume_key = get_volume_key_by_key;
kc->get_luks1_volume_key = get_volume_key_by_key;
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
kc->get_luks2_volume_key = get_volume_key_by_key;
kc->get_plain_volume_key = get_generic_volume_key_by_key;
kc->get_bitlk_volume_key = get_generic_volume_key_by_key;
kc->get_fvault2_volume_key = get_generic_volume_key_by_key;
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_key;
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_key;
kc->get_verity_volume_key = get_generic_signed_key_by_key;
kc->get_integrity_volume_key = get_generic_volume_key_by_key;
unlock_method_init_internal(kc);
kc->get_key_size = key_get_key_size;
kc->context_free = key_context_free;
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc,
static void signed_key_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_SIGNED_KEY);
crypt_free_volume_key(kc->u.ks.i_vk);
crypt_free_volume_key(kc->u.ks.i_vk_sig);
}
void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc,
const char *volume_key,
size_t volume_key_size,
const char *signature,
@@ -508,19 +650,13 @@ void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_conte
kc->u.ks.volume_key_size = volume_key_size;
kc->u.ks.signature = signature;
kc->u.ks.signature_size = signature_size;
kc->get_luks2_key = NULL;
kc->get_luks2_volume_key = NULL;
kc->get_luks1_volume_key = NULL;
kc->get_passphrase = NULL;
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = get_generic_signed_key_by_key;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
kc->context_free = signed_key_context_free;
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc,
const char *passphrase,
size_t passphrase_size)
{
@@ -529,19 +665,24 @@ void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_conte
kc->type = CRYPT_KC_TYPE_PASSPHRASE;
kc->u.p.passphrase = passphrase;
kc->u.p.passphrase_size = passphrase_size;
kc->get_luks2_key = get_luks2_key_by_passphrase;
kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
kc->get_luks1_volume_key = get_luks1_volume_key_by_passphrase;
kc->get_luks2_volume_key = get_luks2_volume_key_by_passphrase;
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_passphrase;
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_passphrase;
kc->get_passphrase = get_passphrase_by_passphrase;
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = NULL;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
static void keyfile_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_KEYFILE);
free(kc->u.kf.i_keyfile);
}
void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc,
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset)
@@ -550,21 +691,28 @@ void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context
kc->type = CRYPT_KC_TYPE_KEYFILE;
kc->u.kf.keyfile = keyfile;
kc->u.kf.keyfile_size = keyfile_size;
kc->u.kf.keyfile_offset = keyfile_offset;
kc->u.kf.keyfile_size = keyfile_size;
kc->get_luks2_key = get_luks2_key_by_keyfile;
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
kc->get_luks1_volume_key = get_luks1_volume_key_by_keyfile;
kc->get_luks2_volume_key = get_luks2_volume_key_by_keyfile;
kc->get_bitlk_volume_key = get_bitlk_volume_key_by_keyfile;
kc->get_fvault2_volume_key = get_fvault2_volume_key_by_keyfile;
kc->get_passphrase = get_passphrase_by_keyfile;
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = NULL;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
kc->context_free = keyfile_context_free;
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
static void token_context_free(struct crypt_keyslot_context *kc)
{
assert(kc && kc->type == CRYPT_KC_TYPE_TOKEN);
free(kc->u.t.i_type);
crypt_safe_free(kc->u.t.i_pin);
}
void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc,
int token,
const char *type,
const char *pin,
@@ -579,47 +727,30 @@ void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *k
kc->u.t.pin = pin;
kc->u.t.pin_size = pin_size;
kc->u.t.usrptr = usrptr;
kc->get_luks2_key = get_luks2_key_by_token;
kc->get_luks2_volume_key = get_luks2_volume_key_by_token;
kc->get_luks1_volume_key = NULL; /* LUKS1 is not supported */
kc->get_passphrase = get_passphrase_by_token;
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = NULL;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
kc->context_free = token_context_free;
crypt_keyslot_context_init_common(kc);
}
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
const char *key_description)
static void vk_in_keyring_context_free(struct crypt_keyslot_context *kc)
{
assert(kc);
assert(kc && kc->type == CRYPT_KC_TYPE_VK_KEYRING);
kc->type = CRYPT_KC_TYPE_VK_KEYRING;
kc->u.vk_kr.key_description = key_description;
kc->get_luks2_key = get_key_by_vk_in_keyring;
kc->get_luks2_volume_key = get_volume_key_by_vk_in_keyring;
kc->get_luks1_volume_key = NULL;
kc->get_passphrase = NULL; /* keyslot key context does not provide passphrase */
kc->get_plain_volume_key = NULL;
kc->get_bitlk_volume_key = NULL;
kc->get_fvault2_volume_key = NULL;
kc->get_verity_volume_key = NULL;
kc->get_integrity_volume_key = NULL;
unlock_method_init_internal(kc);
free(kc->u.vk_kr.i_key_description);
}
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *kc)
{
if (!kc)
return;
if (kc->context_free)
kc->context_free(kc);
crypt_safe_free(kc->i_passphrase);
kc->i_passphrase = NULL;
kc->i_passphrase_size = 0;
}
void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
@@ -628,155 +759,441 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc)
free(kc);
}
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd __attribute__((unused)),
const char *passphrase,
static int _crypt_keyslot_context_init_by_passphrase(const char *passphrase,
size_t passphrase_size,
struct crypt_keyslot_context **kc)
struct crypt_keyslot_context **kc,
bool self_contained)
{
struct crypt_keyslot_context *tmp;
char *i_passphrase = NULL;
if (!kc || !passphrase)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_passphrase_init_internal(tmp, passphrase, passphrase_size);
if (self_contained) {
if (passphrase_size) {
i_passphrase = crypt_safe_alloc(passphrase_size);
if (!i_passphrase) {
free(tmp);
return -ENOMEM;
}
crypt_safe_memcpy(i_passphrase, passphrase, passphrase_size);
passphrase = i_passphrase;
} else
/*
* some crypto backend libraries expect a pointer even though
* passed passphrase size is set to zero.
*/
passphrase = "";
}
crypt_keyslot_context_init_by_passphrase_internal(tmp, passphrase, passphrase_size);
if (self_contained) {
tmp->i_passphrase = i_passphrase;
tmp->i_passphrase_size = passphrase_size;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
}
int crypt_keyslot_context_init_by_keyfile(struct crypt_device *cd __attribute__((unused)),
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_passphrase, 2, 8,
/* crypt_keyslot_context_init_by_passphrase parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *passphrase,
size_t passphrase_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, true);
}
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_passphrase, 2, 6,
/* crypt_keyslot_context_init_by_passphrase parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *passphrase,
size_t passphrase_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_passphrase(passphrase, passphrase_size, kc, false);
}
static int _crypt_keyslot_context_init_by_keyfile(const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
struct crypt_keyslot_context **kc,
bool self_contained)
{
char *i_keyfile;
struct crypt_keyslot_context *tmp;
if (!kc || !keyfile)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_keyfile_init_internal(tmp, keyfile, keyfile_size, keyfile_offset);
if (self_contained) {
i_keyfile = strdup(keyfile);
if (!i_keyfile) {
free(tmp);
return -ENOMEM;
}
keyfile = i_keyfile;
}
crypt_keyslot_context_init_by_keyfile_internal(tmp, keyfile, keyfile_size, keyfile_offset);
if (self_contained) {
tmp->u.kf.i_keyfile = i_keyfile;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
}
int crypt_keyslot_context_init_by_token(struct crypt_device *cd __attribute__((unused)),
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyfile, 2, 8,
/* crypt_keyslot_context_init_by_keyfile parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, true);
}
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyfile, 2, 6,
/* crypt_keyslot_context_init_by_keyfile parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_keyfile(keyfile, keyfile_size, keyfile_offset, kc, false);
}
static int _crypt_keyslot_context_init_by_token(int token,
const char *type,
const char *pin, size_t pin_size,
void *usrptr,
struct crypt_keyslot_context **kc,
bool self_contained)
{
char *i_type = NULL, *i_pin = NULL;
struct crypt_keyslot_context *tmp;
if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN) ||
(pin && !pin_size))
return -EINVAL;
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
if (self_contained && type) {
if (!(i_type = strdup(type)))
goto err;
type = i_type;
}
if (self_contained && pin) {
if (!(i_pin = crypt_safe_alloc(pin_size)))
goto err;
crypt_safe_memcpy(i_pin, pin, pin_size);
pin = i_pin;
}
crypt_keyslot_context_init_by_token_internal(tmp, token, type, pin, pin_size, usrptr);
if (self_contained) {
tmp->u.t.i_pin = i_pin;
tmp->u.t.i_type = i_type;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
err:
crypt_safe_free(i_pin);
free(i_type);
free(tmp);
return -ENOMEM;
}
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_token, 2, 8,
/* crypt_keyslot_context_init_by_token parameters follows */
struct crypt_device *cd __attribute__((unused)),
int token,
const char *type,
const char *pin, size_t pin_size,
void *usrptr,
struct crypt_keyslot_context **kc)
{
struct crypt_keyslot_context *tmp;
if (!kc || (token < 0 && token != CRYPT_ANY_TOKEN))
return -EINVAL;
tmp = malloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_token_init_internal(tmp, token, type, pin, pin_size, usrptr);
*kc = tmp;
return 0;
return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, true);
}
int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd __attribute__((unused)),
const char *volume_key,
size_t volume_key_size,
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_token, 2, 6,
/* crypt_keyslot_context_init_by_token parameters follows */
struct crypt_device *cd __attribute__((unused)),
int token,
const char *type,
const char *pin, size_t pin_size,
void *usrptr,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_token(token, type, pin, pin_size, usrptr, kc, false);
}
static int _crypt_keyslot_context_init_by_volume_key(const char *volume_key,
size_t volume_key_size,
struct crypt_keyslot_context **kc,
bool self_contained)
{
struct volume_key *i_vk = NULL;
struct crypt_keyslot_context *tmp;
if (!kc)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_key_init_internal(tmp, volume_key, volume_key_size);
if (self_contained && volume_key) {
if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key))) {
free(tmp);
return -ENOMEM;
}
volume_key = crypt_volume_key_get_key(i_vk);
}
crypt_keyslot_context_init_by_key_internal(tmp, volume_key, volume_key_size);
if (self_contained) {
tmp->u.k.i_vk = i_vk;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
}
int crypt_keyslot_context_init_by_signed_key(struct crypt_device *cd __attribute__((unused)),
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_volume_key, 2, 8,
/* crypt_keyslot_context_init_by_volume_key parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *volume_key,
size_t volume_key_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, true);
}
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_volume_key, 2, 6,
/* crypt_keyslot_context_init_by_volume_key parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *volume_key,
size_t volume_key_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_volume_key(volume_key, volume_key_size, kc, false);
}
static int _crypt_keyslot_context_init_by_signed_key(const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
struct crypt_keyslot_context **kc,
bool self_contained)
{
struct volume_key *i_vk = NULL, *i_vk_sig = NULL;
struct crypt_keyslot_context *tmp;
if (!kc)
return -EINVAL;
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
if (self_contained && volume_key) {
if (!(i_vk = crypt_alloc_volume_key(volume_key_size, volume_key)))
goto err;
volume_key = crypt_volume_key_get_key(i_vk);
}
if (self_contained && signature) {
if (!(i_vk_sig = crypt_alloc_volume_key(signature_size, signature)))
goto err;
signature = crypt_volume_key_get_key(i_vk_sig);
}
crypt_keyslot_context_init_by_signed_key_internal(tmp, volume_key, volume_key_size,
signature, signature_size);
if (self_contained) {
tmp->u.ks.i_vk = i_vk;
tmp->u.ks.i_vk_sig = i_vk_sig;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
err:
crypt_free_volume_key(i_vk);
crypt_free_volume_key(i_vk_sig);
free(tmp);
return -ENOMEM;
}
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_signed_key, 2, 8,
/* crypt_keyslot_context_init_by_signed_key parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, true);
}
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_signed_key, 2, 7,
/* crypt_keyslot_context_init_by_signed_key parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_signed_key(volume_key, volume_key_size, signature, signature_size, kc, false);
}
static int _crypt_keyslot_context_init_by_keyring(const char *key_description,
struct crypt_keyslot_context **kc,
bool self_contained)
{
char *i_key_description;
struct crypt_keyslot_context *tmp;
if (!kc)
if (!kc || !key_description)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_signed_key_init_internal(tmp, volume_key, volume_key_size,
signature, signature_size);
if (self_contained) {
if (!(i_key_description = strdup(key_description))) {
free(tmp);
return -ENOMEM;
}
key_description = i_key_description;
}
crypt_keyslot_context_init_by_keyring_internal(tmp, key_description);
if (self_contained) {
tmp->u.kr.i_key_description = i_key_description;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
}
int crypt_keyslot_context_init_by_keyring(struct crypt_device *cd __attribute__((unused)),
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_keyring, 2, 8,
/* crypt_keyslot_context_init_by_keyring parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *key_description,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_keyring(key_description, kc, true);
}
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_keyring, 2, 7,
/* crypt_keyslot_context_init_by_keyring parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *key_description,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_keyring(key_description, kc, false);
}
static int _crypt_keyslot_context_init_by_vk_in_keyring(const char *key_description,
struct crypt_keyslot_context **kc,
bool self_contained)
{
char *i_key_description;
struct crypt_keyslot_context *tmp;
if (!kc)
if (!kc || !key_description)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
tmp = crypt_zalloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_keyring_internal(tmp, key_description);
if (self_contained) {
if (!(i_key_description = strdup(key_description))) {
free(tmp);
return -ENOMEM;
}
key_description = i_key_description;
}
tmp->type = CRYPT_KC_TYPE_VK_KEYRING;
tmp->u.vk_kr.key_description = key_description;
tmp->get_luks2_key = get_key_by_vk_in_keyring;
tmp->get_luks2_volume_key = get_volume_key_by_vk_in_keyring;
tmp->get_key_size = keyring_get_key_size;
tmp->context_free = vk_in_keyring_context_free;
crypt_keyslot_context_init_common(tmp);
if (self_contained) {
tmp->u.vk_kr.i_key_description = i_key_description;
tmp->version = KC_VERSION_SELF_CONTAINED;
}
*kc = tmp;
return 0;
}
int crypt_keyslot_context_init_by_vk_in_keyring(struct crypt_device *cd __attribute__((unused)),
CRYPT_SYMBOL_EXPORT_NEW(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 8,
/* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *key_description,
struct crypt_keyslot_context **kc)
{
struct crypt_keyslot_context *tmp;
return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, true);
}
if (!kc)
return -EINVAL;
tmp = malloc(sizeof(*tmp));
if (!tmp)
return -ENOMEM;
crypt_keyslot_unlock_by_vk_in_keyring_internal(tmp, key_description);
*kc = tmp;
return 0;
CRYPT_SYMBOL_EXPORT_OLD(int, crypt_keyslot_context_init_by_vk_in_keyring, 2, 7,
/* crypt_keyslot_context_init_by_vk_in_keyring parameters follows */
struct crypt_device *cd __attribute__((unused)),
const char *key_description,
struct crypt_keyslot_context **kc)
{
return _crypt_keyslot_context_init_by_vk_in_keyring(key_description, kc, false);
}
int crypt_keyslot_context_get_error(struct crypt_keyslot_context *kc)
@@ -788,10 +1205,21 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd __attribute__((unused)
const char *pin, size_t pin_size,
struct crypt_keyslot_context *kc)
{
char *i_pin = NULL;
if (!kc || kc->type != CRYPT_KC_TYPE_TOKEN)
return -EINVAL;
kc->u.t.pin = pin;
if (kc->version >= KC_VERSION_SELF_CONTAINED && pin) {
if (!(i_pin = crypt_safe_alloc(pin_size)))
return -ENOMEM;
crypt_safe_memcpy(i_pin, pin, pin_size);
}
crypt_safe_free(kc->u.t.i_pin);
kc->u.t.i_pin = i_pin;
kc->u.t.pin = i_pin ?: pin;
kc->u.t.pin_size = pin_size;
kc->error = 0;

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup, keyslot unlock helpers
*
* Copyright (C) 2022-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2022-2023 Ondrej Kozina
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2022-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2022-2025 Ondrej Kozina
*/
#ifndef KEYSLOT_CONTEXT_H
@@ -27,6 +14,9 @@
#include "internal.h"
struct bitlk_metadata;
struct fvault2_params;
typedef int (*keyslot_context_get_key) (
struct crypt_device *cd,
struct crypt_keyslot_context *kc,
@@ -45,6 +35,19 @@ typedef int (*keyslot_context_get_generic_volume_key) (
struct crypt_keyslot_context *kc,
struct volume_key **r_vk);
typedef int (*keyslot_context_get_bitlk_volume_key) (
struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct bitlk_metadata *params,
struct volume_key **r_vk);
typedef int (*keyslot_context_get_fvault2_volume_key) (
struct crypt_device *cd,
struct crypt_keyslot_context *kc,
const struct fvault2_params *params,
struct volume_key **r_vk);
typedef int (*keyslot_context_get_generic_signed_key) (
struct crypt_device *cd,
struct crypt_keyslot_context *kc,
@@ -57,10 +60,28 @@ typedef int (*keyslot_context_get_passphrase) (
const char **r_passphrase,
size_t *r_passphrase_size);
typedef void (*keyslot_context_free) (
struct crypt_keyslot_context *kc);
typedef int (*keyslot_context_get_key_size) (
struct crypt_device *cd,
struct crypt_keyslot_context *kc,
size_t *r_key_size);
#define KC_VERSION_BASIC UINT8_C(1)
#define KC_VERSION_SELF_CONTAINED UINT8_C(2)
/* crypt_keyslot_context */
struct crypt_keyslot_context {
int type;
/* versions:
* v1: All passed pointers (e.g.: type, passphrase, keyfile,...) must
* be valid after ctx initialization.
* v2: Fully self-contained
*/
uint8_t version;
union {
struct {
const char *passphrase;
@@ -68,31 +89,40 @@ struct crypt_keyslot_context {
} p;
struct {
const char *keyfile;
char *i_keyfile;
uint64_t keyfile_offset;
size_t keyfile_size;
} kf;
struct {
int id;
const char *type;
char *i_type;
const char *pin;
char *i_pin;
size_t pin_size;
void *usrptr;
} t;
struct {
const char *volume_key;
size_t volume_key_size;
struct volume_key *i_vk;
} k;
struct {
const char *volume_key;
size_t volume_key_size;
struct volume_key *i_vk;
const char *signature;
size_t signature_size;
struct volume_key *i_vk_sig;
} ks;
struct {
const char *key_description;
char *i_key_description;
} kr;
struct {
const char *key_description;
char *i_key_description;
size_t i_key_size;
} vk_kr;
} u;
@@ -105,45 +135,44 @@ struct crypt_keyslot_context {
keyslot_context_get_volume_key get_luks1_volume_key;
keyslot_context_get_volume_key get_luks2_volume_key;
keyslot_context_get_generic_volume_key get_plain_volume_key;
keyslot_context_get_generic_volume_key get_bitlk_volume_key;
keyslot_context_get_generic_volume_key get_fvault2_volume_key;
keyslot_context_get_bitlk_volume_key get_bitlk_volume_key;
keyslot_context_get_fvault2_volume_key get_fvault2_volume_key;
keyslot_context_get_generic_signed_key get_verity_volume_key;
keyslot_context_get_generic_volume_key get_integrity_volume_key;
keyslot_context_get_passphrase get_passphrase;
keyslot_context_get_key_size get_key_size;
keyslot_context_free context_free;
};
void crypt_keyslot_context_destroy_internal(struct crypt_keyslot_context *method);
void crypt_keyslot_unlock_by_key_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_key_internal(struct crypt_keyslot_context *kc,
const char *volume_key,
size_t volume_key_size);
void crypt_keyslot_unlock_by_signed_key_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_signed_key_internal(struct crypt_keyslot_context *kc,
const char *volume_key,
size_t volume_key_size,
const char *signature,
size_t signature_size);
void crypt_keyslot_unlock_by_passphrase_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_passphrase_internal(struct crypt_keyslot_context *kc,
const char *passphrase,
size_t passphrase_size);
void crypt_keyslot_unlock_by_keyfile_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_keyfile_internal(struct crypt_keyslot_context *kc,
const char *keyfile,
size_t keyfile_size,
uint64_t keyfile_offset);
void crypt_keyslot_unlock_by_token_init_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_token_internal(struct crypt_keyslot_context *kc,
int token,
const char *type,
const char *pin,
size_t pin_size,
void *usrptr);
void crypt_keyslot_unlock_by_keyring_internal(struct crypt_keyslot_context *kc,
const char *key_description);
void crypt_keyslot_unlock_by_vk_in_keyring_internal(struct crypt_keyslot_context *kc,
void crypt_keyslot_context_init_by_keyring_internal(struct crypt_keyslot_context *kc,
const char *key_description);
const char *keyslot_context_type_string(const struct crypt_keyslot_context *kc);

View File

@@ -1,24 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* libcryptsetup - cryptsetup library
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2025 Milan Broz
*/
/**
@@ -607,7 +594,7 @@ struct crypt_params_integrity {
uint32_t sector_size; /**< sector size in bytes */
uint32_t buffer_sectors; /**< number of sectors in one buffer */
const char *integrity; /**< integrity algorithm, NULL for LUKS2 */
uint32_t integrity_key_size; /**< integrity key size in bytes, info only, 0 for LUKS2 */
uint32_t integrity_key_size; /**< integrity key size in bytes, info only */
const char *journal_integrity; /**< journal integrity algorithm */
const char *journal_integrity_key; /**< journal integrity key, only for crypt_load */
@@ -697,8 +684,8 @@ int crypt_format(struct crypt_device *cd,
* @param cipher for SW encryption (e.g. "aes") or NULL for HW encryption only
* @param cipher_mode including IV specification (e.g. "xts-plain") or NULL for HW encryption only
* @param uuid requested UUID or @e NULL if it should be generated
* @param volume_key pre-generated volume key or @e NULL if it should be generated (only for LUKS2 SW encryption)
* @param volume_key_size size of volume key in bytes (only for SW encryption).
* @param volume_keys pre-generated volume keys or @e NULL if it should be generated (only for LUKS2 SW encryption)
* @param volume_keys_size size of volume keys in bytes (only for SW encryption).
* @param params LUKS2 crypt type specific parameters (see @link crypt-type @endlink)
* @param opal_params OPAL specific parameters
*
@@ -716,6 +703,35 @@ int crypt_format_luks2_opal(struct crypt_device *cd,
struct crypt_params_luks2 *params,
struct crypt_params_hw_opal *opal_params);
/**
* Create (format) new integrity-protected device using integrity inline mode (HW sector tags).
* This can be used for @e INTEGRITY and @e LUKS2 with integrity protection
*
* @pre @e cd contains initialized and not formatted device context (device type must @b not be set)
*
* @param cd crypt device handle
* @param type type of device (optional params struct must be of this type)
* @param cipher (e.g. "aes") or @e NULL for @e INTEGRITY
* @param cipher_mode including IV specification (e.g. "xts-plain") or @e NULL for @e INTEGRITY
* @param uuid requested UUID or @e NULL if it should be generated
* @param volume_key pre-generated integrity/volume key (if needed) or @e NULL
* @param volume_key_size size of volume/integrity key in bytes.
* @param params crypt type specific parameters (see @link crypt-type @endlink)
*
* @returns @e 0 on success or negative errno value otherwise.
*
* @note Journal parameters must be set to zero in integrity part of @e params.
* Only tag_size, sector_size, buffer_sectors, integrity options should be set.
*/
int crypt_format_inline(struct crypt_device *cd,
const char *type,
const char *cipher,
const char *cipher_mode,
const char *uuid,
const char *volume_key,
size_t volume_key_size,
void *params);
/**
* Set format compatibility flags.
*
@@ -964,7 +980,7 @@ int crypt_resume_by_keyfile(struct crypt_device *cd,
* @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
* @param volume_key_size size of volume_key in bytes
*
* @return @e 0 on success or negative errno value otherwise.
*/
@@ -1136,7 +1152,7 @@ int crypt_keyslot_add_by_keyfile(struct crypt_device *cd,
* @param cd crypt device handle
* @param keyslot requested keyslot or CRYPT_ANY_SLOT
* @param volume_key provided volume key or @e NULL if used after crypt_format
* @param volume_key_size size of volume_key
* @param volume_key_size size of volume_key in bytes
* @param passphrase passphrase for new keyslot
* @param passphrase_size size of passphrase
*
@@ -1166,7 +1182,7 @@ int crypt_keyslot_add_by_volume_key(struct crypt_device *cd,
* @param cd crypt device handle
* @param keyslot requested keyslot or CRYPT_ANY_SLOT
* @param volume_key provided volume key or @e NULL (see note below)
* @param volume_key_size size of volume_key
* @param volume_key_size size of volume_key in bytes
* @param passphrase passphrase for new keyslot
* @param passphrase_size size of passphrase
* @param flags key flags to set
@@ -1217,6 +1233,10 @@ void crypt_keyslot_context_free(struct crypt_keyslot_context *kc);
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_PASSPHRASE
*
* @return zero on success or negative errno otherwise.
*
* @note The original buffer containing passphrase passed in parameters does
* not have to be valid after context initialization. The context
* contains copy of the original before freed with @link crypt_keyslot_context_free @endlink.
*/
int crypt_keyslot_context_init_by_passphrase(struct crypt_device *cd,
const char *passphrase,
@@ -1269,7 +1289,7 @@ int crypt_keyslot_context_init_by_token(struct crypt_device *cd,
*
* @param volume_key provided volume key or @e NULL if used after crypt_format
* or with CRYPT_VOLUME_KEY_NO_SEGMENT flag
* @param volume_key_size size of volume_key
* @param volume_key_size size of volume_key in bytes
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_KEY
*
* @return zero on success or negative errno otherwise.
@@ -1285,9 +1305,9 @@ int crypt_keyslot_context_init_by_volume_key(struct crypt_device *cd,
* @param cd crypt device handle initialized to device context
*
* @param volume_key provided volume key
* @param volume_key_size size of volume_key
* @param volume_key_size size of volume_key in bytes
* @param signature buffer with signature for the key
* @param signature_size bsize of signature buffer
* @param signature_size size of signature buffer
* @param kc returns crypt keyslot context handle type CRYPT_KC_TYPE_SIGNED_KEY
*
* @return zero on success or negative errno otherwise.
@@ -1363,7 +1383,7 @@ int crypt_keyslot_context_set_pin(struct crypt_device *cd,
struct crypt_keyslot_context *kc);
/**
* @defgroup crypt-keyslot-context-types Crypt keyslot context
* @defgroup crypt-keyslot-context-types Crypt keyslot context types
* @addtogroup crypt-keyslot-context-types
* @{
*/
@@ -1517,6 +1537,12 @@ int crypt_keyslot_destroy(struct crypt_device *cd, int keyslot);
#define CRYPT_ACTIVATE_RECALCULATE_RESET (UINT32_C(1) << 26)
/** dm-verity: try to use tasklets */
#define CRYPT_ACTIVATE_TASKLETS (UINT32_C(1) << 27)
/** dm-crypt: use high-priority workqueues */
#define CRYPT_ACTIVATE_HIGH_PRIORITY (UINT32_C(1) << 28)
/** dm-verity: also restart/panic on error, use with RESTART_ON_CORRUPTION or PANIC_ON_CORRUPTION */
#define CRYPT_ACTIVATE_ERROR_AS_CORRUPTION (UINT32_C(1) << 29)
/** dm-integrity: inline mode for compatible hardware profile */
#define CRYPT_ACTIVATE_INLINE_MODE (UINT32_C(1) << 30)
/**
* Active device runtime attributes
@@ -1570,6 +1596,8 @@ uint64_t crypt_get_active_integrity_failures(struct crypt_device *cd,
#define CRYPT_REQUIREMENT_ONLINE_REENCRYPT (UINT32_C(1) << 1)
/** Device configured with OPAL support */
#define CRYPT_REQUIREMENT_OPAL (UINT32_C(1) << 2)
/** Device configured with inline HW tags */
#define CRYPT_REQUIREMENT_INLINE_HW_TAGS (UINT32_C(1) << 3)
/** unknown requirement in header (output only) */
#define CRYPT_REQUIREMENT_UNKNOWN (UINT32_C(1) << 31)
@@ -1592,9 +1620,11 @@ typedef enum {
*
* @note Valid only for LUKS2.
*
* @note Not all activation flags can be stored. Only ALLOW_DISCARD,
* SAME_CPU_CRYPT, SUBMIT_FROM_CRYPT_CPU and NO_JOURNAL can be
* stored persistently.
* @note Not all activation flags can be stored. Only CRYPT_ACTIVATE_ALLOW_DISCARDS,
* CRYPT_ACTIVATE_SAME_CPU_CRYPT, CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS,
* CRYPT_ACTIVATE_NO_JOURNAL, CRYPT_ACTIVATE_NO_READ_WORKQUEUE,
* CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE and CRYPT_ACTIVATE_HIGH_PRIORITY
* can be stored persistently.
*
* @note Only requirements flags recognised by current library may be set.
* CRYPT_REQUIREMENT_UNKNOWN is illegal (output only) in set operation.
@@ -1624,13 +1654,25 @@ int crypt_persistent_flags_get(struct crypt_device *cd,
*/
/**
* Activate device or check using keyslot context.
* Activate device or check using keyslot context. In some cases (device under
* reencryption), more than one keyslot context is required (e.g. one for the old
* volume key and one for the new volume key). The order of the keyslot
* contexts does not matter. When less keyslot contexts are supplied than
* required to unlock the device an -ESRCH error code is returned and you
* should call the function again with an additional keyslot context specified.
*
* NOTE: the API at the moment fully works for single keyslot context only,
* the additional keyslot context currently works only with
* @e CRYPT_KC_TYPE_VK_KEYRING or @e CRYPT_KC_TYPE_KEY contexts.
*
* @param cd crypt device handle
* @param name name of device to create, if @e NULL only check passphrase
* @param keyslot requested keyslot to check or @e CRYPT_ANY_SLOT, keyslot is
* ignored for unlock methods not based on passphrase
* @param kc keyslot context providing volume key or passphrase.
* @param additional_keyslot requested additional keyslot to check or @e CRYPT_ANY_SLOT
* @param additional_kc keyslot context providing additional volume key or
* passphrase (e.g. old volume key for device under reencryption).
* @param flags activation flags
*
* @return unlocked key slot number for passphrase-based unlock, zero for other
@@ -1640,6 +1682,8 @@ int crypt_activate_by_keyslot_context(struct crypt_device *cd,
const char *name,
int keyslot,
struct crypt_keyslot_context *kc,
int additional_keyslot,
struct crypt_keyslot_context *additional_kc,
uint32_t flags);
/**
@@ -1709,7 +1753,7 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
* @param cd crypt device handle
* @param name name of device to create, if @e NULL only check volume key
* @param volume_key provided volume key (or @e NULL to use internal)
* @param volume_key_size size of volume_key
* @param volume_key_size size of volume_key in bytes
* @param flags activation flags
*
* @return @e 0 on success or negative errno value otherwise.
@@ -1722,9 +1766,9 @@ int crypt_activate_by_keyfile(struct crypt_device *cd,
* CRYPT_ACTIVATE_READONLY flag always.
* @note For TCRYPT the volume key should be always NULL
* the key from decrypted header is used instead.
* @note For BITLK @name cannot be @e NULL checking volume key is not
* supported for BITLK, the device will be activated even if the
* provided key is not correct.
* @note For BITLK the name cannot be @e NULL checking volume key is not
* supported for BITLK, the device will be activated even if the
* provided key is not correct.
*/
int crypt_activate_by_volume_key(struct crypt_device *cd,
const char *name,
@@ -1738,9 +1782,9 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
* @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 volume_key_size size of volume_key in bytes
* @param signature buffer with signature for the key
* @param signature_size bsize of signature buffer
* @param signature_size size of signature buffer
* @param flags activation flags
*
* @return @e 0 on success or negative errno value otherwise.
@@ -1821,7 +1865,7 @@ int crypt_deactivate(struct crypt_device *cd, const char *name);
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
* @param volume_key buffer for volume key
* @param volume_key_size on input, size of buffer @e volume_key,
* on output size of @e volume_key
* on output size of @e volume_key in bytes
* @param passphrase passphrase used to unlock volume key
* @param passphrase_size size of @e passphrase
*
@@ -1848,7 +1892,7 @@ int crypt_volume_key_get(struct crypt_device *cd,
* @param keyslot use this keyslot or @e CRYPT_ANY_SLOT
* @param volume_key buffer for volume key
* @param volume_key_size on input, size of buffer @e volume_key,
* on output size of @e volume_key
* on output size of @e volume_key in bytes
* @param kc keyslot context used to unlock volume key
*
* @return unlocked key slot number or negative errno otherwise.
@@ -1881,7 +1925,7 @@ int crypt_volume_key_get_by_keyslot_context(struct crypt_device *cd,
*
* @param cd crypt device handle
* @param volume_key provided volume key
* @param volume_key_size size of @e volume_key
* @param volume_key_size size of @e volume_key in bytes
*
* @return @e 0 on success or negative errno value otherwise.
*
@@ -2023,6 +2067,19 @@ uint64_t crypt_get_iv_offset(struct crypt_device *cd);
*/
int crypt_get_volume_key_size(struct crypt_device *cd);
/**
* Get size (in bytes) of old volume key for LUKS2 device in reencryption.
*
* @param cd crypt LUKS2 device handle
*
* @return old volume key size when device is in reencryption state
*
* @note For LUKS2, this function can be used only if there is at least
* one keyslot assigned to old data segment. Also with reencryption
* mode 'encrypt' there's no old volume key.
*/
int crypt_get_old_volume_key_size(struct crypt_device *cd);
/**
* Get size (in bytes) of encryption sector for crypt device.
*
@@ -2060,6 +2117,18 @@ int crypt_header_is_detached(struct crypt_device *cd);
int crypt_get_verity_info(struct crypt_device *cd,
struct crypt_params_verity *vp);
/**
* Get FEC repaired block count for VERITY device.
*
* @param cd crypt device handle
* @param name verity device name
* @param repaired FEC repaired blocks
*
* @return @e 0 on success or negative errno value otherwise.
*/
int crypt_get_verity_repaired(struct crypt_device *cd, const char *name,
uint64_t *repaired);
/**
* Get device parameters for INTEGRITY device.
*
@@ -2115,7 +2184,7 @@ int crypt_benchmark(struct crypt_device *cd,
* @param password_size size of password
* @param salt salt for benchmark
* @param salt_size size of salt
* @param volume_key_size output volume key size
* @param volume_key_size output volume key size in bytes
* @param progress callback function
* @param usrptr provided identification in callback
*
@@ -2352,8 +2421,8 @@ void crypt_set_debug_level(int level);
* @param cd crypt device handle
* @param keyfile keyfile to read
* @param key buffer for key
* @param key_size_read size of read key
* @param keyfile_offset key offset in keyfile
* @param key_size_read size of read key in bytes
* @param keyfile_offset key offset in bytes in keyfile
* @param key_size exact key length to read from file or 0
* @param flags keyfile read flags
*
@@ -2431,7 +2500,6 @@ int crypt_wipe(struct crypt_device *cd,
/** Use direct-io */
#define CRYPT_WIPE_NO_DIRECT_IO (UINT32_C(1) << 0)
/** @} */
enum {
CRYPT_LUKS2_SEGMENT = -2,
@@ -2462,6 +2530,8 @@ int crypt_wipe_hw_opal(struct crypt_device *cd,
uint32_t flags /* currently unused */
);
/** @} */
/**
* @defgroup crypt-tokens LUKS2 token wrapper access
*
@@ -2593,11 +2663,11 @@ int crypt_token_luks2_keyring_get(struct crypt_device *cd,
* (There can be more keyslots assigned to one token id.)
*
* @param cd crypt device handle
* @param token token id
* @param token specific token id
* @param keyslot keyslot to be assigned to token (CRYPT_ANY SLOT
* assigns all active keyslots to token)
*
* @return allocated token id or negative errno otherwise.
* @return requested token id to be assigned or negative errno otherwise.
*/
int crypt_token_assign_keyslot(struct crypt_device *cd,
int token,
@@ -2608,11 +2678,11 @@ int crypt_token_assign_keyslot(struct crypt_device *cd,
* (There can be more keyslots assigned to one token id.)
*
* @param cd crypt device handle
* @param token token id
* @param token specific token id
* @param keyslot keyslot to be unassigned from token (CRYPT_ANY SLOT
* unassigns all active keyslots from token)
*
* @return allocated token id or negative errno otherwise.
* @return requested token id to be unassigned or negative errno otherwise.
*/
int crypt_token_unassign_keyslot(struct crypt_device *cd,
int token,
@@ -2897,6 +2967,12 @@ int crypt_activate_by_token_pin(struct crypt_device *cd,
#define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3)
/** Reencryption requires metadata protection. (in/out) */
#define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4)
/**
* Calculate new (future) volume key digest directly during
* reencryption initialization. The keyslot context for new
* volume key must be CRYPT_KC_TYPE_KEY or
* CRYPT_KC_TYPE_VK_KEYRING. (in) */
#define CRYPT_REENCRYPT_CREATE_NEW_DIGEST (UINT32_C(1) << 5)
/**
* Reencryption direction
@@ -2993,6 +3069,71 @@ int crypt_reencrypt_init_by_keyring(struct crypt_device *cd,
const char *cipher_mode,
const struct crypt_params_reencrypt *params);
/**
*
* Initialize or reload LUKS2 reencryption operation using keyslot contexts.
*
* The function can initialize reencryption on-disk metadata or reload reencryption
* context from on-disk LUSK2 metadata to resume interrupted operation.
*
* If the device is not in reencryption state (@link crypt_reencrypt_status @endlink
* returns @link CRYPT_REENCRYPT_NONE @endlink) the function initializes on-disk
* metadata to include all necessary reencryption segments and new encryption
* parameters (cipher, cipher mode, encryption sector size) according to the
* provided parameters.
*
* If on-disk metadata already describes reencryption operation
* (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CLEAN @endlink),
* it loads these parameters and internally initializes reencryption context. It also verifies
* if the device is eligible to resume reencryption operation. Some reencryption parameters
* (@link crypt_params_reencrypt @endlink) may be modified depending on the original values in
* the initialization call. When resuming the operation, all parameters may be omitted except
* @e cd, @e name (offline/online),@e kc_old and @e kc_new.
*
* If on-disk metadata describes reencryption operation requiring recovery
* (@link crypt_reencrypt_status @endlink returns @link CRYPT_REENCRYPT_CRASH @endlink),
* it can be recovered by adding @link CRYPT_REENCRYPT_RECOVERY @endlink flag in @link
* crypt_params_reencrypt @endlink parameter.
*
* @param cd crypt device handle
* @param name name of the active device or @e NULL for offline reencryption
* @param kc_old keyslot context providing access to volume key in keyslot id @e keyslot_old.
* @param kc_new keyslot context providing access to volume key in keyslot id @e keyslot_new.
* @param keyslot_old keyslot id containing current volume key for the device or CRYPT_ANY_SLOT
* @param keyslot_new keyslot id containing (unbound) future volume key in encryption or reencryption
* operation. It must be set in the initialization call except when initializing the decrypt
* operation. In reencryption operation it may contain also the current volume key in case the
* volume key change is not requested.
* @param cipher new cipher specification (e.g. "aes") or @e NULL in decryption. Relevant only
* during metadata initialization.
* @param cipher_mode cipher mode and IV (e.g. "xts-plain64") or @e NULL in decryption.
* Relevant only during metadata initialization.
* @param params reencryption parameters @link crypt_params_reencrypt @endlink.
*
* @return reencryption key slot number or negative errno otherwise.
*
* @note Only after successful reencryption initialization you may run the operation with
* @link crypt_reencrypt_run @endlink.
*
* @note During @link CRYPT_REENCRYPT_REENCRYPT @endlink operation it is highly recommended
* to use same keyslot context (same passphrase, token, keyfile, etc) in both @e kc_old
* and @e kc_new parameters for at least one keyslot containing future volume key and one
* keyslot containing current volume key. If the same keyslot context can not be used
* to unlock any current or any future volume key it would be impossible to perform reencryption
* crash recovery during device activation for example after system reboot. Any keyslot
* passphrase may be changed in-before initializing reencryption operation via @link
* crypt_keyslot_change_by_passphrase @endlink.
*/
int crypt_reencrypt_init_by_keyslot_context(struct crypt_device *cd,
const char *name,
struct crypt_keyslot_context *kc_old,
struct crypt_keyslot_context *kc_new,
int keyslot_old,
int keyslot_new,
const char *cipher,
const char *cipher_mode,
const struct crypt_params_reencrypt *params);
/**
* Legacy data reencryption function.
*
@@ -3017,6 +3158,8 @@ __attribute__((deprecated));
* @param usrptr progress specific data
*
* @return @e 0 on success or negative errno value otherwise.
*
* @note A @e progress callback can interrupt reencryption process by returning non-zero code.
*/
int crypt_reencrypt_run(struct crypt_device *cd,
int (*progress)(uint64_t size, uint64_t offset, void *usrptr),
@@ -3085,19 +3228,51 @@ void *crypt_safe_realloc(void *data, size_t size);
*/
void crypt_safe_memzero(void *data, size_t size);
/**
* Memcpy helper to avoid spilling sensitive data through additional registers
*
* @param dst pointer to memory to be written
* @param src pointer to memory to be copied
* @param size size of memory in bytes
*/
void *crypt_safe_memcpy(void *dst, const void *src, size_t size);
/** @} */
/**
* @defgroup crypt-keyring Kernel keyring manipulation
* @addtogroup crypt-keyring
* @{
*/
/**
* Link the volume key to the specified kernel keyring.
*
* The volume can have one or two keys. Normally, the device has one key.
* However if reencryption was started and not finished yet, the volume will
* have two volume keys (the new VK for the already reencrypted segment and old
* VK for the not yet reencrypted segment).
*
* The @e old_key_description argument is required only for
* devices that are in re-encryption and have two volume keys at the same time
* (old and new). You can set the @e old_key_description to NULL,
* but if you supply number of keys less than required, the function will
* return -ESRCH. In that case you need to call the function again and set
* the missing key description. When supplying just one key description, make
* sure to supply it in the @e key_description.
*
* @param cd crypt device handle
* @param key_description the key description of volume key linked in desired keyring.
* @param key_type the key type used for the volume key. Currently only "user" and "logon" types are
* @param key_description the key description of the volume key linked in desired keyring.
* @param old_key_description the key description of the old volume key linked in desired keyring
* (for devices in re-encryption).
* @param key_type_desc the key type used for the volume key. Currently only "user" and "logon" types are
* supported. if @e NULL is specified the default "user" type is applied.
* @param keyring_to_link_vk the keyring description of the keyring in which volume key should
* be linked, if @e NULL is specified, linking will be disabled.
*
* @note keyring_to_link_vk may be passed in various string formats:
* It can be kernel key numeric id of existing keyring written as a string,
* keyring name prefixed optionally be either "%:" or "%keyring:" substrings or keyctl
* keyring name prefixed by either "%:" or "%keyring:" substrings or keyctl
* special values for keyrings "@t", "@p", "@s" and so on. See keyctl(1) man page,
* section KEY IDENTIFIERS for more information. All other prefixes starting "%<type>:"
* are ignored.
@@ -3105,8 +3280,11 @@ void crypt_safe_memzero(void *data, size_t size);
* @note key_description "%<type>:" prefixes are ignored. Type is applied based on key_type parameter
* value.
*/
int crypt_set_keyring_to_link(struct crypt_device *cd, const char *key_description,
const char *key_type_desc, const char *keyring_to_link_vk);
int crypt_set_keyring_to_link(struct crypt_device* cd,
const char* key_description,
const char* old_key_description,
const char* key_type_desc,
const char* keyring_to_link_vk);
/** @} */

View File

@@ -180,3 +180,23 @@ CRYPTSETUP_2.7 {
crypt_set_keyring_to_link;
crypt_wipe_hw_opal;
} CRYPTSETUP_2.6;
CRYPTSETUP_2.8 {
global:
crypt_safe_memcpy;
crypt_keyslot_context_init_by_passphrase;
crypt_keyslot_context_init_by_keyfile;
crypt_keyslot_context_init_by_token;
crypt_keyslot_context_init_by_volume_key;
crypt_keyslot_context_init_by_signed_key;
crypt_keyslot_context_init_by_keyring;
crypt_keyslot_context_init_by_vk_in_keyring;
crypt_reencrypt_init_by_keyslot_context;
crypt_get_old_volume_key_size;
crypt_format_inline;
} CRYPTSETUP_2.7;
CRYPTSETUP_2.9 {
global:
crypt_get_verity_repaired;
} CRYPTSETUP_2.8;

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Definitions of common constant and generic macros of libcryptsetup
*
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2025 Milan Broz
*/
#ifndef _LIBCRYPTSETUP_MACROS_H
@@ -62,9 +49,17 @@
#define DEFAULT_MEM_ALIGNMENT 4096
#define DM_UUID_LEN 129
#define DM_NAME_LEN 128
#define DM_BY_ID_PREFIX "dm-uuid-"
#define DM_BY_ID_PREFIX_LEN 8
#define DM_UUID_PREFIX "CRYPT-"
#define DM_UUID_PREFIX_LEN 6
#define OPAL_PSID_LEN 32
/* LUKS AF stripes, never set to any other value than 4000 */
#ifndef LUKS_STRIPES
# define LUKS_STRIPES 4000
#endif
#endif /* _LIBCRYPTSETUP_MACROS_H */

View File

@@ -1,21 +1,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Helpers for defining versioned symbols
*
* Copyright (C) 2021-2023 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2021-2025 Red Hat, Inc. All rights reserved.
*/
#ifndef _LIBCRYPTSETUP_SYMVER_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2023 Milan Broz
*
* 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.
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2025 Milan Broz
*/
#include <errno.h>
@@ -82,6 +69,7 @@ static int hash_keys(struct crypt_device *cd,
char tweak, *key_ptr;
unsigned int i;
int r = 0;
void *key = NULL;
hash_name = hash_override ?: get_hash(key_len_output);
tweak = get_tweak(keys_count);
@@ -92,24 +80,30 @@ static int hash_keys(struct crypt_device *cd,
return -EINVAL;
}
*vk = crypt_alloc_volume_key((size_t)key_len_output * keys_count, NULL);
if (!*vk)
key = crypt_safe_alloc((size_t)key_len_output * keys_count);
if (!key)
return -ENOMEM;
for (i = 0; i < keys_count; i++) {
key_ptr = &(*vk)->key[i * key_len_output];
key_ptr = &((char *)key)[i * key_len_output];
r = hash_key(input_keys[i], key_len_input, key_ptr,
key_len_output, hash_name);
if (r < 0)
break;
goto err;
key_ptr[0] ^= tweak;
}
if (r < 0 && *vk) {
crypt_free_volume_key(*vk);
*vk = NULL;
*vk = crypt_alloc_volume_key_by_safe_alloc(&key);
if (!*vk) {
r = -ENOMEM;
goto err;
}
return 0;
err:
crypt_safe_free(key);
*vk = NULL;
return r;
}
@@ -158,7 +152,7 @@ int LOOPAES_parse_keyfile(struct crypt_device *cd,
key_lengths[0] = 0;
while (offset < buffer_len && key_index < LOOPAES_KEYS_MAX) {
keys[key_index] = &buffer[offset];
key_lengths[key_index] = 0;;
key_lengths[key_index] = 0;
while (offset < buffer_len && buffer[offset]) {
offset++;
key_lengths[key_index]++;
@@ -204,7 +198,7 @@ int LOOPAES_activate(struct crypt_device *cd,
uint32_t flags)
{
int r;
uint32_t req_flags, dmc_flags;
uint64_t req_flags, dmc_flags;
char *cipher = NULL;
struct crypt_dm_active_device dmd = {
.flags = flags,
@@ -226,9 +220,8 @@ int LOOPAES_activate(struct crypt_device *cd,
return -ENOMEM;
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
vk, cipher, crypt_get_iv_offset(cd),
crypt_get_data_offset(cd), crypt_get_integrity(cd),
crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd));
vk, cipher, crypt_get_iv_offset(cd), crypt_get_data_offset(cd),
NULL, 0, 0, crypt_get_sector_size(cd));
if (r) {
free(cipher);

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* loop-AES compatible volume handling
*
* Copyright (C) 2011-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2023 Milan Broz
*
* 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.
* Copyright (C) 2011-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2025 Milan Broz
*/
#ifndef _LOOPAES_H

View File

@@ -1,25 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* AFsplitter - Anti forensic information splitter
*
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
*
* AFsplitter diffuses information over a large stripe of data,
* therefore supporting secure data destruction.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stddef.h>

View File

@@ -1,26 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* AFsplitter - Anti forensic information splitter
*
* Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
*
* AFsplitter diffuses information over a large stripe of data,
* therefore supporting secure data destruction.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
*/
#ifndef INCLUDED_CRYPTSETUP_LUKS_AF_H
#define INCLUDED_CRYPTSETUP_LUKS_AF_H

View File

@@ -1,23 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2012-2025 Milan Broz
*/
#include <stdio.h>
@@ -101,7 +88,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size,
crypt_metadata_device(ctx), vk, cipher_spec, 0, sector,
NULL, 0, SECTOR_SIZE);
NULL, 0, 0, SECTOR_SIZE);
if (r)
goto out;
@@ -109,7 +96,7 @@ static int LUKS_endec_template(char *src, size_t srcLength,
if (r < 0) {
if (r != -EACCES && r != -ENOTSUP)
_error_hint(ctx, device_path(crypt_metadata_device(ctx)),
cipher, cipher_mode, vk->keylength * 8);
cipher, cipher_mode, crypt_volume_key_length(vk) * 8);
r = -EIO;
goto out;
}
@@ -153,7 +140,8 @@ 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, false);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk),
crypt_volume_key_length(vk), false);
if (r)
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
@@ -166,7 +154,7 @@ int LUKS_encrypt_to_storage(char *src, size_t srcLength,
if (r) {
_error_hint(ctx, device_path(device), cipher, cipher_mode,
vk->keylength * 8);
crypt_volume_key_length(vk) * 8);
return r;
}
@@ -218,7 +206,8 @@ 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, false);
r = crypt_storage_init(&s, SECTOR_SIZE, cipher, cipher_mode, crypt_volume_key_get_key(vk),
crypt_volume_key_length(vk), false);
if (r)
log_dbg(ctx, "Userspace crypto wrapper cannot use %s-%s (%d).",
@@ -231,7 +220,7 @@ int LUKS_decrypt_from_storage(char *dst, size_t dstLength,
if (r) {
_error_hint(ctx, device_path(device), cipher, cipher_mode,
vk->keylength * 8);
crypt_volume_key_length(vk) * 8);
return r;
}

View File

@@ -1,23 +1,10 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2013-2025 Milan Broz
*/
#include <sys/types.h>
@@ -391,7 +378,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
{
struct luks_phdr temp_phdr;
const unsigned char *sector = (const unsigned char*)phdr;
struct volume_key *vk;
struct volume_key *fake_vk;
int i, bad, r, need_write = 0;
if (phdr->keyBytes != 16 && phdr->keyBytes != 32 && phdr->keyBytes != 64) {
@@ -437,8 +424,8 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
if (r < 0)
return -EINVAL;
vk = crypt_alloc_volume_key(phdr->keyBytes, NULL);
if (!vk)
fake_vk = crypt_generate_volume_key(ctx, phdr->keyBytes, KEY_QUALITY_EMPTY);
if (!fake_vk)
return -ENOMEM;
log_verbose(ctx, _("Repairing keyslots."));
@@ -446,7 +433,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
log_dbg(ctx, "Generating second header with the same parameters for check.");
/* cipherName, cipherMode, hashSpec, uuid are already null terminated */
/* payloadOffset - cannot check */
r = LUKS_generate_phdr(&temp_phdr, vk, phdr->cipherName, phdr->cipherMode,
r = LUKS_generate_phdr(&temp_phdr, fake_vk, phdr->cipherName, phdr->cipherMode,
phdr->hashSpec, phdr->uuid,
phdr->payloadOffset * SECTOR_SIZE, 0, 0, ctx);
if (r < 0)
@@ -505,7 +492,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx)
out:
if (r)
log_err(ctx, _("Repair failed."));
crypt_free_volume_key(vk);
crypt_free_volume_key(fake_vk);
crypt_safe_memzero(&temp_phdr, sizeof(temp_phdr));
return r;
}
@@ -723,14 +710,12 @@ int LUKS_check_cipher(struct crypt_device *ctx, size_t keylength, const char *ci
log_dbg(ctx, "Checking if cipher %s-%s is usable.", cipher, cipher_mode);
empty_key = crypt_alloc_volume_key(keylength, NULL);
/* No need to get KEY quality random but it must avoid known weak keys. */
empty_key = crypt_generate_volume_key(ctx, keylength, KEY_QUALITY_NORMAL);
if (!empty_key)
return -ENOMEM;
/* No need to get KEY quality random but it must avoid known weak keys. */
r = crypt_random_get(ctx, empty_key->key, empty_key->keylength, CRYPT_RND_NORMAL);
if (!r)
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
r = LUKS_decrypt_from_storage(buf, sizeof(buf), cipher, cipher_mode, empty_key, 0, ctx);
crypt_free_volume_key(empty_key);
crypt_safe_memzero(buf, sizeof(buf));
@@ -761,7 +746,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
memset(header, 0, sizeof(struct luks_phdr));
keyslot_sectors = AF_split_sectors(vk->keylength, LUKS_STRIPES);
keyslot_sectors = AF_split_sectors(crypt_volume_key_length(vk), LUKS_STRIPES);
header_sectors = LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE;
for (i = 0; i < LUKS_NUMKEYS; i++) {
@@ -808,7 +793,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
strncpy(header->hashSpec,hashSpec,LUKS_HASHSPEC_L-1);
_to_lower(header->hashSpec, LUKS_HASHSPEC_L);
header->keyBytes=vk->keylength;
header->keyBytes = crypt_volume_key_length(vk);
log_dbg(ctx, "Generating LUKS header version %d using hash %s, %s, %s, MK %d bytes",
header->version, header->hashSpec ,header->cipherName, header->cipherMode,
@@ -822,7 +807,7 @@ int LUKS_generate_phdr(struct luks_phdr *header,
/* Compute volume key digest */
pbkdf = crypt_get_pbkdf(ctx);
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength);
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk));
if (r < 0)
return r;
assert(pbkdf->iterations);
@@ -837,7 +822,9 @@ int LUKS_generate_phdr(struct luks_phdr *header,
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,
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, header->hashSpec,
crypt_volume_key_get_key(vk),
crypt_volume_key_length(vk),
header->mkDigestSalt, LUKS_SALTSIZE,
header->mkDigest,LUKS_DIGESTSIZE,
header->mkDigestIterations, 0, 0);
@@ -879,8 +866,9 @@ int LUKS_set_key(unsigned int keyIndex,
struct luks_phdr *hdr, struct volume_key *vk,
struct crypt_device *ctx)
{
struct volume_key *derived_key;
struct volume_key *derived_vk = NULL;
char *AfKey = NULL;
void *derived_key = NULL;
size_t AFEKSize;
struct crypt_pbkdf_type *pbkdf;
int r;
@@ -899,7 +887,7 @@ int LUKS_set_key(unsigned int keyIndex,
log_dbg(ctx, "Calculating data for key slot %d", keyIndex);
pbkdf = crypt_get_pbkdf(ctx);
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, vk->keylength);
r = crypt_benchmark_pbkdf_internal(ctx, pbkdf, crypt_volume_key_length(vk));
if (r < 0)
return r;
assert(pbkdf->iterations);
@@ -912,9 +900,11 @@ int LUKS_set_key(unsigned int keyIndex,
log_dbg(ctx, "Key slot %d use %" PRIu32 " password iterations.", keyIndex,
hdr->keyblock[keyIndex].passwordIterations);
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!derived_key)
return -ENOMEM;
derived_key = crypt_safe_alloc(hdr->keyBytes);
if (!derived_key) {
r = -ENOMEM;
goto out;
}
r = crypt_random_get(ctx, hdr->keyblock[keyIndex].passwordSalt,
LUKS_SALTSIZE, CRYPT_RND_SALT);
@@ -923,7 +913,7 @@ int LUKS_set_key(unsigned int keyIndex,
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen,
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
derived_key->key, hdr->keyBytes,
derived_key, hdr->keyBytes,
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
if (r < 0) {
if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) &&
@@ -932,11 +922,17 @@ int LUKS_set_key(unsigned int keyIndex,
goto out;
}
derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
if (!derived_vk) {
r = -ENOMEM;
goto out;
}
/*
* AF splitting, the volume key stored in vk->key is split to AfKey
*/
assert(vk->keylength == hdr->keyBytes);
AFEKSize = AF_split_sectors(vk->keylength, hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
assert(crypt_volume_key_length(vk) == hdr->keyBytes);
AFEKSize = AF_split_sectors(crypt_volume_key_length(vk), hdr->keyblock[keyIndex].stripes) * SECTOR_SIZE;
AfKey = crypt_safe_alloc(AFEKSize);
if (!AfKey) {
r = -ENOMEM;
@@ -945,7 +941,8 @@ int LUKS_set_key(unsigned int keyIndex,
log_dbg(ctx, "Using hash %s for AF in key slot %d, %d stripes",
hdr->hashSpec, keyIndex, hdr->keyblock[keyIndex].stripes);
r = AF_split(ctx, vk->key, AfKey, vk->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
r = AF_split(ctx, crypt_volume_key_get_key(vk), AfKey, crypt_volume_key_length(vk),
hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
if (r < 0)
goto out;
@@ -955,7 +952,7 @@ int LUKS_set_key(unsigned int keyIndex,
r = LUKS_encrypt_to_storage(AfKey,
AFEKSize,
hdr->cipherName, hdr->cipherMode,
derived_key,
derived_vk,
hdr->keyblock[keyIndex].keyMaterialOffset,
ctx);
if (r < 0)
@@ -973,7 +970,8 @@ int LUKS_set_key(unsigned int keyIndex,
r = 0;
out:
crypt_safe_free(AfKey);
crypt_free_volume_key(derived_key);
crypt_safe_free(derived_key);
crypt_free_volume_key(derived_vk);
return r;
}
@@ -983,7 +981,8 @@ int LUKS_verify_volume_key(const struct luks_phdr *hdr,
{
char checkHashBuf[LUKS_DIGESTSIZE];
if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, vk->key, vk->keylength,
if (crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, crypt_volume_key_get_key(vk),
crypt_volume_key_length(vk),
hdr->mkDigestSalt, LUKS_SALTSIZE,
checkHashBuf, LUKS_DIGESTSIZE,
hdr->mkDigestIterations, 0, 0) < 0)
@@ -1000,12 +999,13 @@ 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 **r_vk,
struct crypt_device *ctx)
{
crypt_keyslot_info ki = LUKS_keyslot_info(hdr, keyIndex);
struct volume_key *derived_key;
struct volume_key *derived_vk = NULL, *vk = NULL;
char *AfKey = NULL;
void *key = NULL, *derived_key = NULL;
size_t AFEKSize;
int r;
@@ -1015,12 +1015,12 @@ static int LUKS_open_key(unsigned int keyIndex,
if (ki < CRYPT_SLOT_ACTIVE)
return -ENOENT;
derived_key = crypt_alloc_volume_key(hdr->keyBytes, NULL);
derived_key = crypt_safe_alloc(hdr->keyBytes);
if (!derived_key)
return -ENOMEM;
*vk = crypt_alloc_volume_key(hdr->keyBytes, NULL);
if (!*vk) {
key = crypt_safe_alloc(hdr->keyBytes);
if (!key) {
r = -ENOMEM;
goto out;
}
@@ -1034,39 +1034,57 @@ static int LUKS_open_key(unsigned int keyIndex,
r = crypt_pbkdf(CRYPT_KDF_PBKDF2, hdr->hashSpec, password, passwordLen,
hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE,
derived_key->key, hdr->keyBytes,
derived_key, hdr->keyBytes,
hdr->keyblock[keyIndex].passwordIterations, 0, 0);
if (r < 0) {
log_err(ctx, _("Cannot open keyslot (using hash %s)."), hdr->hashSpec);
goto out;
}
derived_vk = crypt_alloc_volume_key_by_safe_alloc(&derived_key);
if (!derived_vk) {
r = -ENOMEM;
goto out;
}
log_dbg(ctx, "Reading key slot %d area.", keyIndex);
r = LUKS_decrypt_from_storage(AfKey,
AFEKSize,
hdr->cipherName, hdr->cipherMode,
derived_key,
derived_vk,
hdr->keyblock[keyIndex].keyMaterialOffset,
ctx);
if (r < 0)
goto out;
r = AF_merge(AfKey, (*vk)->key, (*vk)->keylength, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
r = AF_merge(AfKey, key, hdr->keyBytes, hdr->keyblock[keyIndex].stripes, hdr->hashSpec);
if (r < 0)
goto out;
r = LUKS_verify_volume_key(hdr, *vk);
vk = crypt_alloc_volume_key_by_safe_alloc(&key);
if (!vk) {
r = -ENOMEM;
goto out;
}
r = LUKS_verify_volume_key(hdr, vk);
if (r < 0)
goto out;
/* Allow only empty passphrase with null cipher */
if (!r && crypt_is_cipher_null(hdr->cipherName) && passwordLen)
if (crypt_is_cipher_null(hdr->cipherName) && passwordLen)
r = -EPERM;
else
*r_vk = vk;
out:
if (r < 0) {
crypt_free_volume_key(*vk);
*vk = NULL;
crypt_free_volume_key(vk);
*r_vk = NULL;
}
crypt_safe_free(AfKey);
crypt_free_volume_key(derived_key);
crypt_safe_free(key);
crypt_safe_free(derived_key);
crypt_free_volume_key(derived_vk);
return r;
}
@@ -1217,8 +1235,7 @@ int LUKS1_activate(struct crypt_device *cd,
r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd),
vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd),
crypt_get_data_offset(cd), crypt_get_integrity(cd),
crypt_get_integrity_tag_size(cd), crypt_get_sector_size(cd));
crypt_get_data_offset(cd), NULL, 0, 0, crypt_get_sector_size(cd));
if (!r)
r = create_or_reload_device(cd, name, CRYPT_LUKS1, &dmd);

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup
*
* Copyright (C) 2004-2006 Clemens Fruhwirth <clemens@endorphin.org>
* Copyright (C) 2009-2023 Red Hat, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2009-2025 Red Hat, Inc. All rights reserved.
*/
#ifndef INCLUDED_CRYPTSETUP_LUKS_LUKS_H

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* OPAL utilities
*
* Copyright (C) 2022-2023 Luca Boccassi <bluca@debian.org>
* 2023 Ondrej Kozina <okozina@redhat.com>
*
* 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.
* Copyright (C) 2023-2025 Ondrej Kozina <okozina@redhat.com>
* Copyright (C) 2024-2025 Milan Broz
*/
#ifndef _UTILS_OPAL
@@ -24,11 +12,14 @@
#include "internal.h"
struct crypt_lock_handle;
int opal_setup_ranges(struct crypt_device *cd,
struct device *dev,
const struct volume_key *vk,
uint64_t range_start,
uint64_t range_length,
uint64_t range_start_blocks,
uint64_t range_length_blocks,
uint32_t opal_block_bytes,
uint32_t segment_number,
const void *admin_key,
size_t admin_key_len);
@@ -38,7 +29,6 @@ int opal_unlock(struct crypt_device *cd,
uint32_t segment_number,
const struct volume_key *vk);
int opal_supported(struct crypt_device *cd, struct device *dev);
int opal_enabled(struct crypt_device *cd, struct device *dev);
int opal_factory_reset(struct crypt_device *cd,
struct device *dev,
const char *password,
@@ -54,13 +44,17 @@ int opal_geometry(struct crypt_device *cd,
uint32_t *ret_block_size,
uint64_t *ret_alignment_granularity_blocks,
uint64_t *ret_lowest_lba_blocks);
int opal_range_check_attributes(struct crypt_device *cd,
int opal_range_check_attributes_and_get_lock_state(struct crypt_device *cd,
struct device *dev,
uint32_t segment_number,
const struct volume_key *vk,
const uint64_t *check_offset_sectors,
const uint64_t *check_length_sectors,
bool *check_read_locked,
bool *check_write_locked);
bool *ret_read_locked,
bool *ret_write_locked);
int opal_exclusive_lock(struct crypt_device *cd,
struct device *opal_device,
struct crypt_lock_handle **opal_lock);
void opal_exclusive_unlock(struct crypt_device *cd, struct crypt_lock_handle *opal_lock);
#endif

View File

@@ -1,22 +1,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* LUKS - Linux Unified Key Setup v2
*
* Copyright (C) 2015-2023 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2023 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* Copyright (C) 2015-2025 Red Hat, Inc. All rights reserved.
* Copyright (C) 2015-2025 Milan Broz
*/
#ifndef _CRYPTSETUP_LUKS2_ONDISK_H
@@ -50,6 +37,8 @@
#define LUKS2_DIGEST_MAX 8
#define LUKS2_MIN_INTEGRITY_KEY_BYTES 16
#define CRYPT_ANY_SEGMENT -1
#define CRYPT_DEFAULT_SEGMENT -2
#define CRYPT_ONE_SEGMENT -3
@@ -122,6 +111,7 @@ struct luks2_hdr {
char uuid[LUKS2_UUID_L];
void *jobj;
void *jobj_rollback;
size_t on_disk_json_end_offset;
};
struct luks2_keyslot_params {
@@ -158,6 +148,8 @@ struct luks2_keyslot_params {
#define LUKS2_HDR_OFFSET_MAX 0x400000 /* 4 MiB */
#define LUKS2_HDR_MAX_MDA_SIZE 2 * LUKS2_HDR_OFFSET_MAX + LUKS2_MAX_KEYSLOTS_SIZE
/* Offsets for secondary header (for scan if primary header is corrupted). */
#define LUKS2_HDR2_OFFSETS { 0x04000, 0x008000, 0x010000, 0x020000, \
0x40000, 0x080000, 0x100000, 0x200000, LUKS2_HDR_OFFSET_MAX }
@@ -207,11 +199,11 @@ int LUKS2_keyslot_open(struct crypt_device *cd,
size_t password_len,
struct volume_key **vk);
int LUKS2_keyslot_open_all_segments(struct crypt_device *cd,
int LUKS2_keyslot_context_open_all_segments(struct crypt_device *cd,
int keyslot_old,
int keyslot_new,
const char *password,
size_t password_len,
struct crypt_keyslot_context *kc_old,
struct crypt_keyslot_context *kc_new,
struct volume_key **vks);
int LUKS2_keyslot_store(struct crypt_device *cd,
@@ -239,6 +231,24 @@ int LUKS2_keyslot_swap(struct crypt_device *cd,
int keyslot,
int keyslot2);
/*
* Segments
*/
bool LUKS2_segment_set_size(struct luks2_hdr *hdr,
int segment,
const uint64_t *segment_size_bytes);
bool LUKS2_segment_is_hw_opal(struct luks2_hdr *hdr, int segment);
bool LUKS2_segment_is_hw_opal_crypt(struct luks2_hdr *hdr, int segment);
bool LUKS2_segment_is_hw_opal_only(struct luks2_hdr *hdr, int segment);
int LUKS2_get_opal_segment_number(struct luks2_hdr *hdr, int segment,
uint32_t *ret_opal_segment_number);
int LUKS2_get_opal_key_size(struct luks2_hdr *hdr, int segment);
bool LUKS2_segments_dynamic_size(struct luks2_hdr *hdr);
/*
* Generic LUKS2 token
*/
@@ -274,17 +284,6 @@ crypt_token_info LUKS2_token_status(struct crypt_device *cd,
int token,
const char **type);
int LUKS2_token_open_and_activate(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
int token,
const char *name,
const char *type,
const char *pin,
size_t pin_size,
uint32_t flags,
void *usrptr);
int LUKS2_token_unlock_key(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -318,8 +317,7 @@ void crypt_token_unload_external_all(struct crypt_device *cd);
/*
* Generic LUKS2 digest
*/
int LUKS2_digest_any_matching(struct crypt_device *cd,
struct luks2_hdr *hdr,
int LUKS2_digest_verify_by_any_matching(struct crypt_device *cd,
const struct volume_key *vk);
int LUKS2_digest_verify_by_segment(struct crypt_device *cd,
@@ -382,6 +380,7 @@ int LUKS2_generate_hdr(
const struct volume_key *vk,
const char *cipher_spec,
const char *integrity,
uint32_t integrity_key_size, /* in bytes, only if separate (HMAC) */
const char *uuid,
unsigned int sector_size,
uint64_t data_offset,
@@ -402,15 +401,17 @@ 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, bool detached_header);
struct luks2_hdr *hdr);
uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
int LUKS2_get_data_size(struct luks2_hdr *hdr, uint64_t *size, bool *dynamic);
uint32_t LUKS2_get_sector_size(struct luks2_hdr *hdr);
const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
const char *LUKS2_get_integrity(struct luks2_hdr *hdr, int segment);
int LUKS2_get_integrity_key_size(struct luks2_hdr *hdr, int segment);
int LUKS2_keyslot_params_default(struct crypt_device *cd, struct luks2_hdr *hdr,
struct luks2_keyslot_params *params);
int LUKS2_get_old_volume_key_size(struct luks2_hdr *hdr);
int LUKS2_get_volume_key_size(struct luks2_hdr *hdr, int segment);
int LUKS2_get_keyslot_stored_key_size(struct luks2_hdr *hdr, int keyslot);
const char *LUKS2_get_keyslot_cipher(struct luks2_hdr *hdr, int keyslot, size_t *key_size);
@@ -438,7 +439,7 @@ int LUKS2_config_set_flags(struct crypt_device *cd, struct luks2_hdr *hdr, uint3
/*
* Requirements for device activation or header modification
*/
int LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs);
void LUKS2_config_get_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t *reqs);
int LUKS2_config_set_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs, bool commit);
int LUKS2_config_set_requirement_version(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t req_id, uint8_t req_version, bool commit);
@@ -446,12 +447,10 @@ int LUKS2_config_get_reencrypt_version(struct luks2_hdr *hdr, uint8_t *version);
bool LUKS2_reencrypt_requirement_candidate(struct luks2_hdr *hdr);
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint32_t reqs_mask, int quiet);
int LUKS2_unmet_requirements(struct crypt_device *cd, struct luks2_hdr *hdr, uint64_t reqs_mask, int quiet);
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,
struct luks2_hdr *hdr, struct volume_key *vk, int keyslot);
int LUKS2_volume_key_load_in_keyring_by_digest(struct crypt_device *cd,
struct volume_key *vk, int digest);
@@ -465,12 +464,8 @@ int LUKS2_luks2_to_luks1(struct crypt_device *cd,
/*
* LUKS2 reencryption
*/
int LUKS2_reencrypt_locked_recovery_by_passphrase(struct crypt_device *cd,
int keyslot_old,
int keyslot_new,
const char *passphrase,
size_t passphrase_size,
struct volume_key **vks);
int LUKS2_reencrypt_locked_recovery_by_vks(struct crypt_device *cd,
struct volume_key *vks);
void LUKS2_reencrypt_free(struct crypt_device *cd,
struct luks2_reencrypt *rh);
@@ -494,19 +489,13 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
uint64_t check_size,
uint64_t *dev_size,
bool activation,
bool device_exclusive_check,
bool dynamic);
int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
struct luks2_hdr *hdr,
struct volume_key *vks);
int LUKS2_reencrypt_max_hotzone_size(struct crypt_device *cd,
struct luks2_hdr *hdr,
const struct reenc_protection *rp,
int reencrypt_keyslot,
uint64_t *r_length);
void LUKS2_reencrypt_protection_erase(struct reenc_protection *rp);
unsigned LUKS2_reencrypt_vks_count(struct luks2_hdr *hdr);
#endif

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