On So, 10.05.26 13:31, Akshay Hendre ([email protected]) wrote:

Some comments. Sorry not for responding when you originally posted
this.

Generally: systemd has a lot of functionality in the TPM area, people
might not be aware of. It's not a central daemon though (and I think
it shouldn't be), and it relies on on tpm2-tss heavily (but mostly
esapi, not fapi) and on the linux kernel, obviously.

Note that much of systemd's logic will enable itself only if you boot
a UKI with systemd-stub, because only then the first part of systemd's
measurement chain is enabled, and if you don't do this, we do not
assume you want systemd to manage your PCRs and stuff.

> * System Administrators: Currently, because there is no centralized daemon
> to automatically provision the TPM and establish a shared Storage Root Key
> (SRK), applications often attempt to create their own primary keys directly
> under the Owner hierarchy. If an administrator follows security best
> practices and password-protects the Owner hierarchy, core OS utilities like
> systemd-cryptenroll immediately fail to bind LUKS2 volumes, throwing an
> 0x000009a2 authorization error. Administrators are caught in a paradox:
> leave the TPM Owner hierarchy entirely unprotected, or break system
> functionality.

systemd does have "systemd-tpm2-setup" that sets up an SRK these
days. It also nowadays configures some additional "fake" PCRs that are
backed by nvindexes.

> * Managed Enterprise Fleets: In large deployments, the lack of a
> centralized policy broker means that standard software and kernel updates
> alter Platform Configuration Registers (PCRs). This arbitrarily breaks
> fragile local trust chains, locks users out of encrypted disks, and causes
> disruptive false positives in continuous remote attestation
> frameworks.

systemd will measure a lot of things these days automatically – as
long as you run systemd-stub, which is the initial hook that tells us
you are OK with this.

https://github.com/systemd/systemd/blob/main/docs/TPM2_PCR_MEASUREMENTS.md

> 2. Proposed Solution: systemd-tpmd Architecture
> ========================
> systemd-tpmd is proposed as a persistent, stateful userspace management
> layer acting as the absolute foundation for TPM integration on Linux. It
> operates as a highly privileged system daemon sitting directly between the
> in-kernel resource manager and the unprivileged application layer,
> providing unified abstraction and state escrow.

I must say, I kinda like the current approach in systemd of separate
services that deal with separate aspects of it all.

>
> 2.1 Boot-Time Provisioning and State Escrow
> ------------------------
> Upon initialization, systemd-tpmd evaluates the hardware provisioning
> state. If unprovisioned, it acts based on a configuration parameter (e.g.,
> ProvisioningMode=):
> * Auto (Default): It automatically takes ownership, generating high-entropy
> cryptographic secrets for the Owner, Endorsement, and Lockout hierarchies.
> It invokes TPM2_CreatePrimary to establish the Storage Root Key (SRK) and
> utilizes TPM2_EvictControl to lock the SRK into the TPM's persistent NVRAM
> at the TCG-standardized handle 0x81000001. The SRK is instantiated with an
> empty authorization value, allowing the daemon to utilize it as a universal
> parent for encrypting and decrypting application-specific child keys
> without needing to unlock the protected Owner hierarchy.

We do the SRK stuff in systemd-tpm2-setup. We do not set
authorizations on the hierarchies. We kinda wanted to stay away from
that so far to not collide with a parallel Windows install.

However, we can certainly look into supporting this, if there's a
clear approach for avoiding breaking things with parallel OS
installs. Happy to take patches. Should probably sit in tpm2-setup as well.

> 2.3 Standard Interaction Sequence
> ------------------------
> Step 1. Request Formulation: An unprivileged application (e.g., a web
> server) needs to sign a TLS handshake. It reads its encrypted privateBlob
> and publicBlob from the standard filesystem.
> Step 2. Transmission: The application issues a signing request either
> through the OpenSSL 3.0 provider or natively via a JSON Varlink socket.
> Step 3. Broker Execution: systemd-tpmd receives the request, utilizes the
> public, empty-password SRK to load the encrypted private blob into the
> TPM's volatile memory, and instructs the hardware to sign the digest.
> Step 4. Response Delivery: The TPM outputs the signature. systemd-tpmd
> clears the transient context and returns the signature to the application
> via the chosen interface. The application successfully utilized the
> hardware without ever possessing permissions to the TPM device node.

So I very much sympathize with a goal of having some generic
Varlink-based API for acquiring/operating with key material. With the
systemd-sbsign and systemd-measure stuff (i.e. UKI signing for SB and
for TPM) it just became clear how painful this currently is. However,
I'd draw a wider circle here, and any such varlink API should be
generic enough to support other, non TPM backends too, so that one can
reasonably connect other stuff too, for example that the same api can
be used to sign artifacts with a key on a yubikey or so. Moreover,
remote access matters a lot, but that creates so many headaches
because of workload identification and attestation issues and so
on.

> 3.1 Path A: The OpenSSL 3.0 Provider
> ------------------------
> To guarantee immediate, seamless integration for the vast majority of the
> Linux ecosystem (including web servers, VPN daemons, and SSH agents),
> systemd-tpmd ships with a dedicated OpenSSL 3.0 provider module.
> * Transparent Execution: When configured in openssl.cnf, applications
> utilizing standard OpenSSL EVP APIs will have their cryptographic
> operations transparently intercepted by the provider.
> * Stateless Routing: The OpenSSL provider acts as a lightweight client,
> packaging the OpenSSL memory buffers into Varlink payloads and routing them
> to the systemd-tpmd daemon.
> * Zero-Code Changes: Existing C/C++, Rust, and Python applications relying
> on OpenSSL can leverage TPM hardware-backed keys with minimal changes to
> application code.

The problem with OpenSSL is always that it's a C level thing, and
while that is relevant to many, it's irrelevant in many other
languages.

Hence, providing a generic Varlink IPC API is the key to everything
here I think: you can implement a provider or anything else on top of it.

>
> 4.2 Command Line Integration and Access Control
> ------------------------
> Administration integrates directly into systemctl via a new top-level tpm
> verb:
> * systemctl tpm status: Reports hardware capabilities and the presence of
> the SRK.

We have "systemd-analyze has-tpm2", "… identify-tpm2", "… pcrs", "…
nvpcrs", "… srk" already. We can certainly add to that.

> * systemctl tpm clear: Securely wipes the TPM and rotates the locally
> escrowed hierarchy passwords.

We have something like that in systemd-tpm2-clear already. If you boot
with systemd.tpm2_allow_clear=1 on the kernel cmdline we'll ask
firmware to reset the TPM via PPI.

> * systemctl tpm reset-lockout: Submits the escrowed Owner password to clear
> the DA lockout counter.

adding something like this to systemd-tpm2-setup certainly would make
sense. THis has been requested before, but would require us to take
ownership of the TPM2, which – as mentioned – we certainly can do.


>
> 6.1 Seamless Firmware Updates (Solving the LUKS / fwupd Lockout)
> ------------------------
> Currently, binding LUKS disk encryption to Platform Configuration Registers
> creates severe system fragility. When an administrator updates the system
> firmware using fwupd, the PCR 7 measurement changes, which permanently
> breaks the LUKS unlocking policy and locks the user out. systemd-tpmd will
> resolve this by leveraging TPM2_PolicyAuthorize. Instead of binding disk
> encryption to static PCR values, the disk is bound to a cryptographic
> ticket signed by systemd-tpmd. When fwupd schedules an update, it can
> communicate its intent via Varlink. systemd-tpmd can automatically generate
> a new authorized policy for the incoming firmware state, ensuring the disk
> unseals smoothly after the reboot.

We have a good chunk of this in systemd-pcrlock. THis is not hooked up
with fwupd however, but there's a github issue discussing this somewhere.

> 6.2 Standardizing TPM-Backed Passkeys for the Linux Desktop
> ------------------------
> The Linux desktop currently lacks a unified, hardware-backed API for modern
> WebAuthn/FIDO2 passkeys. systemd-tpmd could serve as the foundational
> backend for projects like credentialsd. By deriving keys from the TPM's
> primary seed and encrypting the credential blobs, systemd-tpmd would allow
> browsers to store highly secure, phishing-resistant passkeys that never
> leave the hardware in plaintext.

passkey support backed by tpm would be lovely.
>
> 6.3 Stabilizing Continuous Remote Attestation for Fleet Management
> ------------------------
> In enterprise deployments, continuous remote attestation agents (such as
> Keylime) are used to cryptographically prove to a central server that a
> machine's Linux Integrity Measurement Architecture (IMA) log has not been
> compromised. However, these agents frequently suffer from false alerts and
> access conflicts when querying the TPM simultaneously with other system
> updates. By acting as the sole orchestrator, systemd-tpmd could safely
> broker attestation quotes and IMA measurements, ensuring that fleet
> management tools operate reliably without resource contention on the
> /dev/tpmrm0 node.

we do have plans to adding signing (as in pcr quote) of system "reports" to
"systemd-report", which is a tool that collects metrics of the system.

My summary: I think the features all make sense to me. I am pretty
sure though they shouldn't all be implemented in a singleton daemon,
but be split up in smaller bits, how it makes sense, and how we are
already doing it for the stuff we already have. for example the
ownership thing seems resonably bounded so that one could implement
that in tpm2-setup pretty quickly too. Once that's done (or at the same
time) the DA lock stuff could be done too.

A varlink iface for doing key operations would be a lot more
involvement. i.e. figuring out the basic subset to start with, that is
reasonably easy to implement but leaves enough avenues open to hook
other stuff behind it.

I hope that all makes sense?

Would love to review patches in this area!

Lennart

--
Lennart Poettering, Berlin

Reply via email to