Commit Graph
287 Commits
Author SHA1 Message Date
Daan De Meyer bcf716ca01 tree-wide: Remove dead code
This code seems to not be used anywhere at all, so let's drop it.

Follow up for ba8d00e859
Follow up for 85686b37b0
Follow up for aff853f8ea
Follow up for 36dad381a2
2025-04-24 10:15:19 +09:00
Daan De Meyer 5332be60d3 tree-wide: Use assert_se() instead of assert() in various places
assert() is compiled away if NDEBUG is set which causes an unused
variable warning in various places when the next commit is applied
so let's use assert_se() to avoid these warnings.
2025-04-23 13:48:16 +02:00
Lennart Poettering 0015502168 tpm2-util: return better errors if we try to unlock a tpm key on the wrong tpm
Let's improve error handling in case one tries to unlock a TPM2 locked
volume on a different machine via TPM than it was originally enrolled
on. Let's recognize this case and print a clearer error message.
2025-03-19 21:27:54 +01:00
Lennart Poettering 6a2097dd78 openssl-util: add helper for converting EVP_PKEY to PEM string
And also give the rverse a bit of love.
2025-03-07 18:13:16 +01:00
Mike Yuan 70923ed358 meson: enable -Wzero-as-null-pointer-constant
Support for C added in gcc 15:
https://github.com/gcc-mirror/gcc/commit/236c0829ee21a179c81b83f0d7f112ca23c47a4d
2025-01-16 02:26:56 +01:00
Lennart Poettering 3085782020 tpm2-util: refuse hash algorithm/value specification when we only parse a mask
tpm2_parse_pcr_argument_to_mask() is supposed to parse a PCR mask
string, and uses the full blown tpm2_parse_pcr_argument() call at its
core, which parses more than just a mask, i.e. values and algorithms
too. Which is very confusing at times, because commands such as
"systemd-cryptenroll --tpm2-device=auto
--tpm2-public-key-pcrs=1:sha1=09dbdbc7f6cdd8029cc90b57a915c19a0ac21bce"
are very confusing, since they suggest enrollment with a specific
algorithm and has value, but this is not in fact what happens: both are
entirely ignored.

That this was accepted this way was more an accident than intended,
which is already visible in the fact that extensive test case entirely
ignores the fact that strings like this are accepted.
2025-01-03 10:44:26 +01:00
Lennart Poettering 982e791f1c tpm2-util: optionally do wildcard hash check in tpm2_pcr_values_to_mask()
If TPM2_ALG_ERROR (aka "0") is specified as algorithm in
tpm2_pcr_values_to_mask() we'll simply match all algorithms. This allows
us to shorten tpm2_parse_pcr_argument_to_mask() a bit. The function
accepts but ignores a hash algorithm specification currently, hence this
should not really much effect.
2025-01-03 10:39:10 +01:00
Lennart Poettering 0db32a3bfb tpm2-util: drop ret_x prefix from two arguments that are not just return but also input params 2025-01-03 10:39:10 +01:00
Mike Yuan 1e4e557262 tree-wide: replace FLAGS_SET(..., 1 << v) with BIT_SET(..., v) 2024-12-28 15:08:00 +01:00
Fabian Vogt e61032bf47 tpm2-util: Also retry unsealing after policy_pcr returns PCR_CHANGED
It's not just Esys_Unseal that may fail due to PCR changes during the
session, but also Esys_PolicyPCR. Perform a retry in that case as well.

Fixes #35490
2024-12-18 13:34:55 +01:00
Yu Watanabe 66d2c693ac tpm2-util: allow to control if legend and/or footer shown by tpm2_list_devices() 2024-12-12 15:21:16 +09:00
Lennart Poettering bd4beaa2eb tree-wide: always do dlopen() with RTLD_NOW + RTLD_NODELETE
Let's systematically use RTL_NOW|RLTD_NODELETE as flags passed to
dlopen(), across our codebase.

Various distros build with "-z now" anyway, hence it's weird to specify
RTLD_LAZY trying to override that (which it doesn't). Hence, let's
follow suit, and just do what everybody else does.

Also set RTLD_NODELETE, which is apparently what distros will probably
end up implying sooner or later anyway. Given that for pretty much all
our dlopen() calls we never call dlclose() anyway, let's just set this
everywhere too, to make things systematic.

This way, the flags we use by default match what distros such as fedora
do, there are no surprises, and read-only relocations can be a thing.

Fixes: #34537
2024-10-02 07:13:21 +02:00
Yu Watanabe 82f2c33db5 tpm2-util: show loaded libraries in 'systemd-analyze has-tpm2'
After 3b16e9f419, even the libraries are
documented in the man page, it is useful to mention which libraries are
checked in the command output.

Of course, the dependencies are kind of implementation detail, and may
be changed in the future version, but that's especially why I think
showing the library deps in the output is useful.

systemd-analyze is a debugging tool, and already shows many internal
states. I think there is nothing to prevent from showing the deps.

Prompted by #34477.
2024-09-30 15:40:14 +02:00
Yu Watanabe d5a7f3b7d4 tpm2-util: colorize output of 'systemd-analyze has-tpm2' 2024-09-19 19:14:19 +09:00
Yu Watanabe 1ee6570843 tpm2-util: do not load tpm2 libraries when not interested in the existence of the libraries
For example, 'bootctl status' only interested in if the efi has TPM2
support and a TPM2 driver is loaded. Hence, not necessary to load
libtss2.
2024-09-19 19:06:46 +09:00
Lennart Poettering 58e359604f analyze: move "has-tpm2" from systemd-creds to systemd-analyze
The verb s not really specific to credential management, it was always a
bit misplaced. Hence move it to systemd-analyze, where we already have
some general TPM related verbs such as "srk" and "pcrs"
2024-09-12 12:56:03 +02:00
Lennart Poettering c355208d83 tpm2-util: fix whitespace 2024-09-11 10:28:36 +02:00
Lennart Poettering b52af7d243 tpm2-util: introduce tpm2b_sensitive_data_erase_and_esys_freep() destructor
Let's make sure we erase TPM2B_SENSITIVE_DATA structures reliably in all
code paths.
2024-09-06 15:55:28 +02:00
Lennart Poettering 8e6587679b cryptenroll/cryptsetup: allow combined signed TPM2 PCR policy + pcrlock policy
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.
2024-09-06 15:55:28 +02:00
Lennart Poettering be5bee2a13 tree-wide: port over to new builder apis 2024-06-19 22:50:02 +02:00
Zbigniew Jędrzejewski-Szmek ff3f29537c various: move ptr indicator to return value 2024-06-19 16:37:12 +02:00
Zbigniew Jędrzejewski-Szmek bfd5a0687f various: move const ptr indicator to return value 2024-06-19 16:28:28 +02:00
Lennart Poettering 4d6222b6a4 random-util: add crypto_random_bytes_allocate_iovec()
Just a simple helper that allocates some memory, initializes it
randomly, and places this in a struct iovec.
2024-06-15 12:43:37 +01:00
Mike Yuan 609bc3ae16 Merge pull request #33037 from keszybz/dlopen-open-code-definitions
Make dlopen macros more explicit and drop mac_selinux_free()
2024-06-15 12:49:59 +02:00
Lennart Poettering 13e6b823a9 tpm2-util: make one sd_json_dispatch_field[] table static const 2024-06-14 13:22:47 +02:00
Lennart Poettering 309a747fa6 libsystemd: turn json.[ch] into a public API
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.
2024-06-12 18:42:22 +02:00
Zbigniew Jędrzejewski-Szmek 5c672e90a6 basic/dlfcn-util: deobfuscate macro definitions
When looking at how dlopen for various libs is implemented, I found that the
macros hide too much. I find it much easier to see what is going on if 'extern'
and '= NULL' are written explicitly. After all, we don't hide those for other
definitions, e.g. our style guide says that static variables should be
initialized with '= NULL'. With that change, it's much more obvious what is
a variable declaration and what is a variable initialization.
2024-06-12 15:21:15 +02:00
Daan De Meyer d6518003f8 tpm2-setup: Don't fail if we can't access the TPM due to authorization failure
The TPM might be password/pin protected for various reasons even if
there is no SRK yet. Let's handle those cases gracefully instead of
failing the unit as it is enabled by default.
2024-06-12 18:31:21 +09:00
Lennart Poettering a5139b1415 tpm2-util: tighten rules on the nvindex handle range we allocate from
Let's follow the conventions set by "Registry of Reserved TPM 2.0 Handles
and Localities" and only allocate nvindex currently not assigned to any
vendor.

For details see:

https://trustedcomputinggroup.org/resource/registry/

Section 2.2
2024-06-11 22:40:23 +01:00
Lennart Poettering b3efb67ddc tpm2-util: improve compat with older unlocking tools
Let's only generate the pin and pcrlock booleans if they are enabled, in
order to not unnecessarily confuse older unlocking tools.
2024-05-23 15:38:37 +02:00
Lennart Poettering 360198efc3 tpm2-util: do not serialize tpm2 bank if none is specified
If both literal and signed PCR bindings are not used then we won't
determine a PCR bank to use, and hence we shouldnt attempt to serialize
it either.

Hence, if the bank is zero, skip serialization.

(And while we are at it, also skip serialization of the primary
algorithm if not set, purely to make things systematic).

[This effectively results in little change, as previously we'd then
seralize a json "null", while now we simply won't genreate the field]
2024-05-23 15:38:37 +02:00
Lennart PoetteringandLuca Boccassi cd7c207795 tree-wide: add dlopen ELF notes to all dlopen() deps of ours
Use 'recommended' priority for the default compression library, to
indicate that it should be prioritized over the other ones, as it
will be used to compress journals/core files.
Also use 'recommended' for kmod, as systems will likely fail to boot
if it's missing from the initrd.
Use 'suggested' for everything else.

There is one dlopen'ed TPM library that has the name generated
at runtime (depending on the driver), so that cannot be added, as it
needs to be known at build time.
Also when we support multiple ABI versions list them all, as for the
same reason we cannot know which one will be used at build time.

$ dlopen-notes.py build/libsystemd.so.0.39.0 build/src/shared/libsystemd-shared-256.so
libarchive.so.13 suggested
libbpf.so.0 suggested
libbpf.so.1 suggested
libcryptsetup.so.12 suggested
libdw.so.1 suggested
libelf.so.1 suggested
libfido2.so.1 suggested
libgcrypt.so.20 suggested
libidn2.so.0 suggested
libip4tc.so.2 suggested
libkmod.so.2 recommended
liblz4.so.1 suggested
liblzma.so.5 suggested
libp11-kit.so.0 suggested
libpcre2-8.so.0 suggested
libpwquality.so.1 suggested
libqrencode.so.3 suggested
libqrencode.so.4 suggested
libtss2-esys.so.0 suggested
libtss2-mu.so.0 suggested
libtss2-rc.so.0 suggested
libzstd.so.1 recommended

Co-authored-by: Luca Boccassi <bluca@debian.org>
2024-05-08 11:07:36 +01:00
Lennart Poettering 3f2402171b tpm2-util: tweak JSON condition check
As for the other fields let's check if the actual variable we serialize
is set before serializing it.

This shouldn't make any difference, since the pubkey and the PCR mask
should always be set together or neither, but I think it's easier to
grok this way, and makes the function nicely "dumb": it serializes what
is specified, without trying to be smart by suppressng specified fields.
2024-05-06 16:15:16 +02:00
Dmitry V. Levin c309b9e9c3 treewide: fix a few typos in NEWS, docs, comments, and log messages 2024-04-27 12:11:13 +02:00
Lennart Poettering 21a3bc6b9f tpm2-util: add generic wrapper tpm2_context_new_or_warn() that wrpas 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
2024-04-22 12:40:09 +02:00
Luca Boccassi 5dcd6b1d55 Merge pull request #31978 from nolange/fix_openssl_deprecations
Fix openssl deprecations
2024-04-19 11:20:44 +02:00
Lennart Poettering dd37963aff Merge pull request #31790 from poettering/pcrlock-policy-fix
Replace PolicyAuthValue by PolicySigned as access policy for pcrlock policy nvindex
2024-04-18 21:11:27 +02:00
Lennart Poettering d10d4a3701 tpm2-util: now that we don't use PolicyAuthValue anymore, let's not set an authValue anymore for the policy nvindex
We have now switched from PolicyAuthValue to PolicySigned to control
access to the policy nvindex to. This means there's no point in setting
an authValue on the nvindex anymore, hence drop this.
2024-04-18 18:12:23 +02:00
Lennart Poettering cb835a2ed1 pcrlock: switch access policy for nvindex to store policy in from PolicyAuthValue to PolicySigned (with an HMAC-SHA256 key)
So far the nvindex to store the pcrlock policy in was protected via a
PolicyAuthValue policy (i.e. with a simple PIN set on the nvindex).
That's a bad idea however, as it means an attacker can simply remove and
re-create the nvindex and the "name" of the nvindex does not change,
thus defeating the logic. (This is because the authValue is *not* part
of the "name" of an nvindex!).

Fix this by switching from PolicyAuthValue to PolicySigned with an
HMAC-SHA256 key. Behaviour is very similar: however, the PIN is now part
of of the access policy hash, which *is* part of the "name" of an
nvindex. Thus, if an attacker removes and recreates the nvindex it has
to provide the same PIN again or the "name" of the nvindex will change.
Mission accomplished.

I'd like to thank Chris Coulson for finding this issue (and helping me
address it). Thank you!
2024-04-18 18:12:23 +02:00
Lennart Poettering 19d82e1bee tpm2-util: add comment explaining what tpm2_define_policy_nv_index() actually does 2024-04-18 18:12:23 +02:00
Lennart Poettering 371b594414 tpm2-util: load external key into NULL hierarchy if private key is provided
If we load an external key into the TPM we must do so in the NULL
hierarchy. An external key after all is one that is not wrapped by any
hierarchy's seed.

See TPM2 spec, Part 3, Section 12.3.1
2024-04-18 18:12:23 +02:00
Lennart Poettering d0f8da9815 tpm2-util: rename tpm2_get_pin_auth() → tpm2_auth_value_from_pin()
Just some renaming. I found the old name a bit confusing since it sounds
as if this would get the pin from somewhere, but it really doesn't. It
just converts a PIN into an auth_value, and I think saying so explicitly
makes things easier to grok.
2024-04-18 18:12:23 +02:00
Lennart Poettering 98ef5f8419 tpm2: export tpm2_get_name()
We later want to use this from pcrlock.c, hence export it.
2024-04-18 18:12:23 +02:00
Lennart Poettering 9892b7238b tpm2-util: import two more symbols from tpm2-tss libraries
We want to make use of TPM_PolicySigned soon, hence import the necessary
symbols from tpm2-tss.
2024-04-18 18:12:23 +02:00
Matteo Croce 854711645b use FOREACH_ELEMENT
Use FOREACH_ELEMENT where possible. Generated with this command,
and checked manually:

    git grep -l 'FOREACH_ARRAY.*ELEMENTSOF' | \
    xargs sed -ri 's/FOREACH_ARRAY\((.*), (.*), (ELEMENTSOF.*)\)/FOREACH_ELEMENT(\1, \2)/'
2024-04-18 17:39:34 +02:00
Norbert Lange 81d61d6aa7 openssl-util: compatible with restricted openssl3
openssl can be built without support for engines or with deprecated
definitions disabled.
This also will not pull in most headers automatically,
so add the rsa.h and ec.h header explicitly.

Remove Engine stuff from the header - it is only needed in one
source file.

Make Engine support dependent on the macros.
2024-04-18 09:23:15 +02:00
Luca Boccassi dd6c0df65c dlopen: log debug message when a library is dlopened
Useful to track what is being used and when
2024-04-03 14:23:04 +01:00
Gabríel Arthúr Pétursson 1923e21316 shared: Fix TPM2 unsealing when PCR values change
Recreate the encryption session on each retry. It's invalidated along
with the policy session when freed, failing subsequent retries.

	Unsealing HMAC key.
	WARNING:esys:src/tss2-esys/api/Esys_Unseal.c:295:Esys_Unseal_Finish() Received TPM Error
	ERROR:esys:src/tss2-esys/api/Esys_Unseal.c:98:Esys_Unseal() Esys Finish ErrorCode (0x00000128)
	A PCR value changed during the TPM2 policy session, restarting HMAC key unsealing (30 tries left).
	Missing encryption session
	Failed to unseal secret using TPM2: Invalid argument

Fixes #31881
2024-03-24 12:49:22 +00:00
Zbigniew Jędrzejewski-Szmek ec596fe34e Merge pull request #30480 from keszybz/kernel-install-more-paths
Read kernel-install config from /run/kernel too
2024-03-08 08:25:07 +01:00
Lennart Poettering 9dbabd0a8b tree-wide: switch dlopen hooks over to DLSYM_PROTOTYPE()/DLSYM_FUNCTION()
We have these pretty macros, let's use them everywhere (so far we mostly
used them for newer additions only).

This PR is mostly an excercise in "perl -p -i -e", but there are some
special cases:

* idn-util.c exposes a function whose prototype in the official library
  headers is marked with the "const" attribute, and this apparently does
  not propagate along typeof() correctly and then
  __builtin_types_compatible_p() fails later because it detects that
  prototype and original function don't match in prototype.

* libbpf removed some symbols in newer versions, hence we need to define
  some prototypes manually to still be able to build.

* libcryptsetup marked a symbol as deprecated we want to use (knowing it
  is deprecated). By using the macros this is detected by the compiler.
  We work around it via the usual warning off macros.

Note by using these macros we assume that all symbols are known during
build time. Which might not be the case. We might need to revert this
commit for some symbols if this trips up builds on older distros.
2024-03-01 15:51:24 +00:00