| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
Prompted by https://github.com/systemd/systemd/pull/35110#discussion_r1835885340
|
|
|
|
| |
For justification, see 3f9a0a522f2029e9295ea5e9984259022be88413.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
So far you had to pick:
1. Use a signed PCR TPM2 policy to lock your disk to (i.e. UKI vendor
blesses your setup via signature)
or
2. Use a pcrlock policy (i.e. local system blesses your setup via
dynamic local policy stored in NV index)
It was not possible combine these two, because TPM2 access policies do
not allow the combination of PolicyAuthorize (used to implement #1
above) and PolicyAuthorizeNV (used to implement #2) in a single policy,
unless one is "further upstream" (and can simply remove the other from
the policy freely).
This is quite limiting of course, since we actually do want to enforce
on each TPM object that both the OS vendor policy and the local policy
must be fulfilled, without the chance for the vendor or the local system
to disable the other.
This patch addresses this: instead of trying to find a way to come up
with some adventurous scheme to combine both policy into one TPM2
policy, we simply shard the symmetric LUKS decryption key: one half we
protect via the signed PCR policy, and the other we protect via the
pcrlock policy. Only if both halves can be acquired the disk can be
decrypted.
This means:
1. we simply double the unlock key in length in case both policies shall
be used.
2. We store two resulting TPM policy hashes in the LUKS token JSON, one
for each policy
3. We store two sealed TPM policy key blobs in the LUKS token JSON, for
both halves of the LUKS unlock key.
This patch keeps the "sharding" logic relatively generic (i.e. the low
level logic is actually fine with more than 2 shards), because I figure
sooner or later we might have to encode more shards, for example if we
add further TPM2-based access policies, for example when combining FIDO2
with TPM2, or implementing TOTP for this.
|
|
|
|
|
|
|
|
| |
Use these helpers whenever appropriate. Drop separate string checks,
since these helpers already do them anyway.
No actual code change, just a rework to make use of a nice helper we
have already.
|
|
|
|
|
|
|
|
|
| |
This commit makes systemd-cryptsetup exit with a successful status when
the volume gets unlocked outside of the current systemd-cryptsetup
process while it was executing. This can be easily reproduced by calling
systemd-cryptsetup, and while it waits for user to input a password/PIN,
unlock the volume in a second terminal. Then after entering the password
systemd-cryptsetup will exit with a non-zero status code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The new "password-cache" option allows customizing behavior of the
ask-password module in regards to caching credentials in the kernel
keyring. There are 3 possible values for this option:
* read-only - look for credentials in kernel keyring before asking
* on - same as read-only, but also save credentials input by user
* off - disable keyring credential cache
Currently the cache is forced upon the user and this can cause issues.
For example, if user wants to attach two volumes with two different
FIDO2 tokens in a quick succession, the attachment operation for the
second volume will use the PIN cached from the first FIDO2 token, which
of course will fail and since tokens are only attempted once, this will
cause fallback to a password prompt.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently, if user doesn't specify a key file, /etc/cryptsetup-keys.d/
and /run/cryptsetup-keys.d/ will be searched for a key file with name
matching the volume name. But current implementation has an important
flaw. When the auto-discovered key is a socket file - it will read the
key only once, while the socket might provide different keys for
different types of tokens. The issue is fixed by trying to discover the
key on each unlock attempt, this way we can populate the socket bind
name with something the key provider might use to differentiate between
different keys it has to provide.
|
|
|
|
| |
Just a tiny change to fix an eyesore in cryptsetup luksDump display :)
|
|
|
|
|
|
|
| |
Don't cram function calls and assignment into if condition checks. It's
not how we usually do things.
Also, define variables at innermost scope.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
systemd-cryptsetup supports a FIDO2 mode with manual parameters, where
the user provides all the information necessary for recreating the
secret, such as: credential ID, relaying party ID and the salt. This
feature works great for implementing 2FA schemes, where the salt file
is for example a secret unsealed from the TPM or some other source.
While the unlocking part is quite straightforward to set up, enrolling
such a keyslot - not so easy. There is no clearly documented
way on how to set this up and online resources are scarce on this topic
too. By implementing a straightforward way to enroll such a keyslot
directly from systemd-cryptenroll we streamline the enrollment process
and reduce chances for user error when doing such things manually.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
When in FIDO2 mode with manual parameters, i.e. when not reading the
parameters off the LUKS2 header, the current behavior in regards to PIN,
UP and UV features is to default to v248 logic, where we use PIN + UP
when needed, and do not configure UV at all. Let's allow users to
configure those features in manual mode too.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This is preparation for making our Varlink API a public API. Since our
Varlink API is built on top of our JSON API we need to make that public
first (it's a nice API, but JSON APIs there are already enough, this is
purely about the Varlink angle).
I made most of the json.h APIs public, and just placed them in
sd-json.h. Sometimes I wasn't so sure however, since the underlying data
structures would have to be made public too. If in doubt I didn#t risk
it, and moved the relevant API to src/libsystemd/sd-json/json-util.h
instead (without any sd_* symbol prefixes).
This is mostly a giant search/replace patch.
|
| |
|
| |
|
|
|
|
|
| |
Let's make the crypttab parser more robust and continue even if parsing
of a line failed.
|
|
|
|
|
|
| |
Move the processing of a crypttab entry to a separate function.
No functional changes, just refactoring.
|
|
|
|
|
| |
The first try will be on the TPM2, so in practice this was always skipped
as it happens only on the first try. Use a different bool to track this.
|
|
|
|
|
|
|
|
|
|
| |
If we couldn't unlock a device with the chosen unlock path, let's not
fall back to the lowest one right away, but only flush out one path, and
try the next.
Fixes: #30425
Follow-up-for: #30185
Alternative-to: #33183
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- drop unnecessary SYNTHETIC_ERRNO() when the logger does not propagate
error code,
- drop unnecessary '%m' in error message when the error code is
specified with SYNTHETIC_ERRNO(),
- add missing full stop at the end of log message,
- use RET_GATHER(),
- add missing ", ignoring.",
- upeercase the first letter, etc., etc...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If a user only presses ENTER when the PIN is requested (without actually typing
the PIN), an assertion is reached and no other unlock method is requested.
```
sh-5.2# systemctl status systemd-cryptsetup@cr_root
× systemd-cryptsetup@cr_root.service - Cryptography Setup for cr_root
Loaded: loaded (/etc/crypttab; generated)
Drop-In: /etc/systemd/system/systemd-cryptsetup@.service.d
└─pcr-signature.conf
Active: failed (Result: core-dump) since Thu 2024-04-25 08:44:30 UTC; 10min ago
Docs: man:crypttab(5)
man:systemd-cryptsetup-generator(8)
man:systemd-cryptsetup@.service(8)
Process: 559 ExecStartPre=/usr/bin/pcr-signature.sh (code=exited, status=0/SUCCESS)
Process: 604 ExecStart=/usr/bin/systemd-cryptsetup attach cr_root /dev/disk/by-uuid/a8cbd937-6975-4e61-9120-ce5c03138700 none x-initrd.attach,tpm2-device=auto (code=dumped, signal=ABRT)
Main PID: 604 (code=dumped, signal=ABRT)
CPU: 19ms
Apr 25 08:44:29 localhost systemd[1]: Starting Cryptography Setup for cr_root...
Apr 25 08:44:30 localhost systemd-cryptsetup[604]: Assertion '!pin || pin_size > 0' failed at src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c:60, function cryptsetup_token_open_pin(). Aborting.
Apr 25 08:44:30 localhost systemd[1]: systemd-cryptsetup@cr_root.service: Main process exited, code=dumped, status=6/ABRT
Apr 25 08:44:30 localhost systemd[1]: systemd-cryptsetup@cr_root.service: Failed with result 'core-dump'.
Apr 25 08:44:30 localhost systemd[1]: Failed to start Cryptography Setup for cr_root.
```
In this case, `cryptsetup_token_open_pin()` receives an empty (non-NULL) `pin`
with `pin_size` equals to 0.
```
🔐 Please enter LUKS2 token PIN:
Breakpoint 3, cryptsetup_token_open_pin (cd=0x5555555744c0, token=0, pin=0x5555555b3cc0 "", pin_size=0, ret_password=0x7fffffffd380,
ret_password_len=0x7fffffffd378, usrptr=0x0) at ../src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c:42
42 void *usrptr /* plugin defined parameter passed to crypt_activate_by_token*() API */) {
(gdb) continue
Assertion '!pin || pin_size > 0' failed at src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c:60, function cryptsetup_token_open_pin(). Aborting.
```
|
|
|
|
|
|
|
|
|
|
| |
tpm2_context_new and logs about errors
We so far just print a short log message that is not very useful, let's
add some recognizable error codes, and output better log messages if we
can't get TPM stuff to work.
Fixes: #31925
|
|
|
|
|
|
|
| |
The order of the arguments of the function `acquire_luks2_key()` in
`luks2-tpm2.h` is wrong, `pcrlock_path` and `pin` are swapped.
Fixes 404aea7815595c1324947ed7f2a7502b17d3cc01
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This bool controls whether we should interactively ask for a password,
which is pretty much what the ask_password-api.c APIs are about. Hence,
just make the bool a flag in AskPasswordFlags enum, and use it
everywhere.
This still catches the flag early in upper levels of the codebase,
exactly as before, but if the flag is still present in the lower layers
it's also handled there and results in ENOEXEC if seen.
This is mostly an excercise in simplifying our ridiculously long
function call parameter lists a bit.
|
| |
|
|
|
|
|
|
| |
Let's make sure that when cryptenroll asks for the TPM2 or FIDO2 token
PIN it uses cryptenroll.* credential namespace, and cryptsetup uses
cryptsetup.*.
|
|
|
|
|
|
|
|
|
|
|
| |
Rather than adding more and more parameters to ask_password_auto(), let's
pass a structure of the fields that often are constant anyway.
This way, callers can fill in what they need, and we take the filled
structure which we can pass around internally as one.
This is in particular preparation for adding one more field in one of
the next commits.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Let's make sure that versions generated by meson-vcs-tag.sh always
sort higher than official and stable releases. We achieve this by
immediately updating the meson version in meson.build after a new
release. To make sure this version always sorts lower than future
rcs, we suffix it with "~devel" which will sort lower than "~rcX".
The new release workflow is to update the version in meson.build
for each rc and the official release and to also update the version
number after a new release to the next development version.
The full version is exposed as PROJECT_VERSION_FULL and used where
it makes sense over PROJECT_VERSION.
We also switch to reading the version from a meson.version file in
the repo instead of hardcoding it in meson.build. This makes it
easier to access both inside and outside of the project.
The meson-vcs-tag.sh script is rewritten to query the version from
meson.version instead of passing it in via the command line. This
makes it easier to use outside of systemd since users don't have to
query the version themselves first.
|
|
|
|
| |
Follow-up for c5daf14c88ba44cefabe052de93a29d28b6b0175.
|
|
|
|
|
|
|
|
|
|
|
| |
cryptsetup 2.7.0 adds feature to link effective volume key in custom
kernel keyring during device activation. It can be used later to pass
linked volume key to other services.
For example: kdump enabled systems installed on LUKS2 device.
This feature allows it to store volume key linked in a kernel keyring
to the kdump reserved memory and reuse it to reactivate LUKS2 device
in case of kernel crash.
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
| |
Let's move more code to using struct iovec for passing around binary
chunks of data.
No real changes in behaviour, just refactoring.
|
|
|
|
|
|
|
|
|
|
|
| |
The header and keyfile are necessary only for opening the device, not
for closing, so it is not necessary to deactivate the generated
cryptsetup unit when the header or keyfile backing store are removed.
This is especially useful in the case of softreboot, when the new
mount root is setup under /run/nextroot/ but we don't want to close
the cryptsetup devices for encrypted /var/ or so, and we simply
mount it directly on /run/nextroot/var/ before the soft-reboot.
|
|
|
|
|
| |
(There's a bunch more in src/basic/linux/, but those files are copied from the
kernel and should not be modified.)
|
|
|
| |
Previously only the first entered passphrase would be used. Add the ability to check all the passwords entered by the user. The total number of passwords entered is still limited by passphrase entry limit.
|
|
|
|
|
|
|
|
|
|
|
| |
The pkcs11 uri is no set if the smart card is not inserted while using
`pkcs11-uri=auto` with libcryptsetup plugins.
```
> systemd-cryptsetup attach cr_data /dev/sda1 - pkcs11-uri=auto
Set cipher aes, mode xts-plain64, key size 512 bits for device /dev/sda1.
Security token (null) not present for unlocking volume Linux filesystem (cr_data), please plug it in.
```
|
|\
| |
| | |
new pcrlock tool for generating signed PCR policies for PCR 0, 1, 4, …
|
| |
| |
| |
| |
| |
| |
| | |
Make sure cryptenroll and repart can enroll TPM2 policies with pcrlock
logic.
Make sure cryptsetup can unlock TPM2 policies with pcrlock in effect.
|
| | |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The pkcs11 cryptsetup token module is a bit different from the tpm2 +
fido2 ones: it asks for the PIN itself, rather than bubbling up a
request to get a PIN. That's because it might need multiple, and because
we don't want to destroy a the pkcs11 session half-way and thus risk
increasing pin counters.
Hence, we sometimes ask for PINs from our code, rather than let the
libcryptsetup caller do that. So far we didn't pass the AskPasswordFlags
field down into the module though. Fix that.
Fixes: #28665
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
volume key
if we allow cryptsetup to activate a volume via token plugin we never
get access to the volume key, which we'd like to measure. Hence disable
token plugins in that case.
(I tempted to say we probably should disable them entirely, and only use
them if classic cryptsetup is used, but that's a discussion for another
day.)
Fixes: #29790
|