From: Jarkko Sakkinen <jarkko@kernel.org>
To: Daniel Golle <daniel@makrotopia.org>
Cc: James Bottomley <James.Bottomley@hansenpartnership.com>,
Christoph Anton Mitterer <calestyo@scientia.org>,
linux-integrity@vger.kernel.org
Subject: Re: inherit null-key across hibernate (was: Re: regression: kernel log "flooded" with tpm tpm0: A TPM error (2306) occurred attempting to create NULL primary)
Date: Fri, 19 Jun 2026 03:38:53 +0300 [thread overview]
Message-ID: <ajSPndgTYFJgpTaE@kernel.org> (raw)
In-Reply-To: <ajDIDcW_EzgLB0qX@makrotopia.org>
On Tue, Jun 16, 2026 at 04:50:37AM +0100, Daniel Golle wrote:
> Hi Jarkko,
> Hi James,
>
> first of all, sorry for hijacking a thread from 2 years ago.
>
> On Thu, Nov 14, 2024 at 12:34:30AM +0200, Jarkko Sakkinen wrote:
> > On Wed Nov 13, 2024 at 8:12 PM EET, James Bottomley wrote:
> > > > I think we might have to expect the NULL name to change on actual
> > > > hibernation because unlike suspend to ram it does power off the TPM.
> > >
> > > I checked the code: we're coming in on the correct path to renew the
> > > null seed after hibernation, so it should all work. The problem seems
> > > to be that your TPM itself is doing something invalid because the name
> > > we calculate for the primary key doesn't match what your TPM says it
> > > should be. Absent some form of attack or bus integrity problem, that
> > > shouldn't ever happen, so I'm even more curious to know why it worked
> > > in 6.11.5 and before and whether current upstream works.
> > >
> > > I haven't found it yet, but I think the every 10s signature is because
> > > the hibernation path is trying to restart the TPM device and won't take
> > > no for an answer.
> >
> > My fix returned the behavior how it was before my earlier fix in this
> > corner case (i.e. disable TPM). The issue has gone unnoticed before
> > since it has emitted only a single klog entry.
> >
> > On suspend this has not happened to me so obvious deduction is that
> > hibernate resets the null seed.
> >
> > Hibernate needs an addition a fix to disable bus encryption from kernel
> > command-line completely, i.e. tpm.disable_integrity following the
> > convention from my earlier fix [1].
>
> I'd like to offer a way it might be resolvable with the null key after
> all, without provisioning a persistent NV key -- by changing the
> question from "re-derive the null primary and compare" to "inherit the
> trust the resume has already established".
>
> Resume-from-hibernation is a TPM Restart (Shutdown(STATE) ->
> Startup(CLEAR)), i.e. a firmware cold-init of the (f)TPM, after which
> the boot/initramfs kernel establishes a fresh, genuine null primary.
> In the common configuration (FDE with the resume/swap device inside
> a TPM-sealed LUKS2 container) that same TPM has, moments earlier and
> *before* the hibernation image is restored, cryptographically attested
> itself by unsealing the resume device. A substituted or interposed TPM
> cannot produce that unseal.
>
> So rather than letting the resumed kernel re-derive the null name,
> find a mismatch and disable the chip, the boot kernel's
> freshly-established and unseal-validated null primary could be
> inherited by the resumed image. The existing null-seed TOFU model is
> preserved; nothing new is provisioned.
>
> The gate is the unseal, and the adversary case shows why it is the
> right gate:
>
> Malice swaps (or interposes on) the TPM while the machine is
> hibernated, then leaves. Alice powers on. The initramfs attempts the
> TPM unseal of the resume device; with a foreign TPM it fails, so
> systemd-cryptsetup falls back to the passphrase, which Alice --
> seeing a prompt -- types. The disk opens and the system resumes.
>
> If trust were re-established here, Alice would have personally vouched
> for Malice's TPM. But the unseal *failed*, so under this scheme
> nothing is inherited and the chip stays fail-closed exactly as today.
> The passphrase proves a human is present; it never proves the TPM is
> the genuine one.
> Hence: unseal succeeded -> inherit the validated null primary;
> passphrase fallback -> trust is lost, stay disabled.
>
> This keeps the property the null-seed design wants -- an in-session
> reset is not on the hibernate-restore path and is still caught --
> while removing the false positive only where the platform has already
> re-attested the TPM.
>
> The hard parts, and where I'd value direction:
>
> - systemd-cryptsetup would need to signal "the resume device was
> unsealed by the TPM this boot" (vs. the passphrase fallback).
> This is per-resume runtime state; a static command-line parameter
> (and obviously build-time config as well) cannot represent it.
>
> - the validated null primary has to cross the boot -> resumed memory
> discontinuity (the initramfs kernel's state is overwritten by the
> restored image). Boot and image kernel are the same binary, so
> patching chip->null_key_name in the restored image is mechanically
> possible; a small reserved/nosave hand-off area may be cleaner.
> I don't know the hibernate path well enough to say which is right.
>
> It is admittedly cross-subsystem (tpm + pm/hibernate +
> systemd/cryptsetup), which is presumably why it hasn't been done.
> Compared with the persistent NV-key route
> (tpm.integrity_key=<handle>): that avoids the carry-across but needs
> the key provisioned and managed, and a persistent key's name no longer
> changes on a genuine reset, so the implicit reset detection has to be
> reconstructed. The null-key-inherit approach keeps the existing model
> and defers "is this the same TPM?" to the unseal that has already
> happened.
>
> Does this seem viable, or is there a reason the unseal-as-attestation
> gate does not hold that I'm missing?
>
> (For motivation: on a firmware TPM -- Intel PTT here -- there is no
> external bus to interpose, so the protection has no benefit on this
> class of hardware at all, yet the legitimate hibernation power-cycle
> still trips the disable. For fTPMs specifically, not enabling the
> feature is arguably the better answer; but for discrete TPMs that
> hibernate, a real solution seems a good idea if doable.)
I think this has at least changed since 2024: bootc container type
of deployment is where you can realistically configure hibernate,
and use it in a real application.
>
>
> Cheers
>
>
> Daniel
BR, Jarkko
next prev parent reply other threads:[~2026-06-19 0:38 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-11-13 14:44 regression: kernel log "flooded" with tpm tpm0: A TPM error (2306) occurred attempting to create NULL primary Christoph Anton Mitterer
2024-11-13 15:47 ` James Bottomley
2024-11-13 18:12 ` James Bottomley
2024-11-13 22:34 ` Jarkko Sakkinen
2024-11-13 22:43 ` Jarkko Sakkinen
2026-06-16 3:50 ` inherit null-key across hibernate (was: Re: regression: kernel log "flooded" with tpm tpm0: A TPM error (2306) occurred attempting to create NULL primary) Daniel Golle
2026-06-19 0:38 ` Jarkko Sakkinen [this message]
2024-11-13 23:56 ` regression: kernel log "flooded" with tpm tpm0: A TPM error (2306) occurred attempting to create NULL primary Christoph Anton Mitterer
2024-11-14 2:06 ` James Bottomley
2024-11-14 2:17 ` Christoph Anton Mitterer
2024-11-14 4:57 ` Jarkko Sakkinen
2024-11-25 13:49 ` Christoph Anton Mitterer
2024-11-30 2:37 ` Jarkko Sakkinen
2024-11-14 4:56 ` Jarkko Sakkinen
2024-11-13 18:49 ` Jarkko Sakkinen
2024-11-13 18:59 ` Jarkko Sakkinen
2024-11-14 0:04 ` Christoph Anton Mitterer
2024-11-14 4:52 ` Jarkko Sakkinen
2024-11-14 23:57 ` Christoph Anton Mitterer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ajSPndgTYFJgpTaE@kernel.org \
--to=jarkko@kernel.org \
--cc=James.Bottomley@hansenpartnership.com \
--cc=calestyo@scientia.org \
--cc=daniel@makrotopia.org \
--cc=linux-integrity@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox