Page MenuHomeFreeBSD

bhyve: Reinitialise swtpm's TPM at startup
AcceptedPublic

Authored by quentin.thebault_defenso.fr on Sep 2 2026, 1:47 PM.
Tags
None
Referenced Files
Unknown Object (File)
Wed, Oct 14, 6:59 AM
Unknown Object (File)
Tue, Oct 13, 5:41 AM
Unknown Object (File)
Mon, Oct 12, 8:16 AM
Unknown Object (File)
Mon, Oct 12, 1:32 AM
Unknown Object (File)
Sun, Oct 11, 3:22 PM
Unknown Object (File)
Sat, Oct 10, 4:02 PM
Unknown Object (File)
Sat, Oct 10, 10:07 AM
Unknown Object (File)
Fri, Oct 9, 12:44 PM

Details

Reviewers
corvink
novel
bnovkov
markj
kevans
Group Reviewers
bhyve
Summary

bhyve does not currently reinitialise swtpm on startup, which results in
PCRs being carried over across reboots. This means that any guest VM
implementing measured boot controls, such as Windows with BitLocker and
Secure Boot enabled, will consider the system compromised and refuse to
start or ask for a recovery key.

swtpm has a control channel that allows us to send commands for that
purpose: CMD_INIT shuts the TPM down and starts it again clearing the
PCRs in the process, like a cold boot on real hardware.

Connect a second socket when the new ctrl_path option is set and send
CMD_INIT there. Without the option nothing changes.

MFC after: 2 weeks
Sponsored by: Defenso

Signed-off-by: Quentin Thébault <quentin.thebault@defenso.fr>

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 77788
Build 74671: arc lint + arc unit

Event Timeline

kevans added inline comments.
usr.sbin/bhyve/bhyve.8
860

New sentence must begin on a new line

usr.sbin/bhyve/tpm_emul_swtpm.c
39

This doesn't seem to need __packed, 2x uint32_t lines up nicely to avoid padding.

57

It's maybee worth checking for truncation here so that you can provide a better error than 'unable to conect'

67

I guess this will get optimized away anyways, but here and below: 0 is the same in every byte order, no?

73

Not so sure about EFAULT here? That seems like it might be misleading- maybe better to just preserve errno befofre warnx and return that?

quentin.thebault_defenso.fr added inline comments.
usr.sbin/bhyve/tpm_emul_swtpm.c
73

That is how those errors are processed in the existing
tpm_swtpm_execute_cmd function a bit below. Should I correct both?

Remove unnecessary bits and improve error management for strlcpy and send/recv functions (incl. on existing code for harmonization).

This doesn't seem like it particularly violates any bhyve principles, so I may proceed with commtting this within the next week or so with no objection otherwise from bhyve folks

usr.sbin/bhyve/bhyve.8
868

perhaps, to drive the point home.

Explicit that the option is needed for measured boot in manpage.

This revision is now accepted and ready to land.Tue, Sep 22, 12:49 PM
usr.sbin/bhyve/bhyve.8
854

Is there a reason why we shouldn't reinitialize the swtpm on every reboot?

usr.sbin/bhyve/tpm_emul_swtpm.c
180

This is a new configuration variable so it should be documented in bhyve_conf(5).

usr.sbin/bhyve/bhyve.8
845

ctrl_path also needs to be documented in bhyve_config.5.

usr.sbin/bhyve/tpm_emul_swtpm.c
86

Do we risk hanging here if the process does not respond?

182–190

Would it be cleaner to add a label for error handling to close tpm->fd, deallocate tpm, etc?

quentin.thebault_defenso.fr added inline comments.
usr.sbin/bhyve/bhyve.8
854

I don't think so. Hardware always does. But if we do not have the path to swtpm's control socket, we can't do it. I will reword in that sense.

868

I worded it a bit differently to be more accurate. If you shut down the guest and try to cold boot it again without restarting swtpm manually, it will break. Not only during a direct guest reboot.

quentin.thebault_defenso.fr marked an inline comment as done.

Added bhyve_config.5 update, control socket timeout and an error label.
Clarified wording in bhyve.8

This revision now requires review to proceed.Tue, Oct 6, 9:56 AM
quentin.thebault_defenso.fr retitled this revision from bhyve: reinitialise swtpm's TPM at startup to bhyve: Reinitialise swtpm's TPM at startup.Tue, Oct 6, 10:00 AM
quentin.thebault_defenso.fr edited the summary of this revision. (Show Details)
quentin.thebault_defenso.fr added inline comments.
usr.sbin/bhyve/bhyve.8
845

Added an update to bhyve_config(5).

usr.sbin/bhyve/tpm_emul_swtpm.c
86

Done, added timeout.

180

Added bhyve_conf(5) update.

182–190

Added error label.

wanpengqian_gmail.com added inline comments.
usr.sbin/bhyve/bhyve.8
867

Is startup-clear actually required here? After CMD_INIT (TPM_Init), the PCRs are reset by TPM2_Startup(TPM_SU_CLEAR), and the UEFI firmware sends that itself (edk2's Tcg2Pei does). We run swtpm without startup-clear behind bhyve's UEFI firmware, and the PCRs start from zero on every boot; Windows 11 with BitLocker unseals fine across reboots. If both send it, the firmware just gets TPM_RC_INITIALIZE, which edk2 accepts. So maybe the flag is only needed when the guest firmware does not send TPM2_Startup itself?

usr.sbin/bhyve/tpm_emul_swtpm.c
71

Since this adds the control channel anyway, it might be worth also sending CMD_SET_BUFFERSIZE (with the CRB data buffer size, 0xf80) before CMD_INIT, as QEMU's tpm_emulator does. Otherwise swtpm advertises 4096-byte commands/responses through TPM2_GetCapability while the CRB buffer only holds 3968. I haven't seen a response that large in practice, so this is more about consistency than a known failure; it could also be a follow-up. (The reply to SET_BUFFERSIZE is 16 bytes, not 4. And swtpm only accepts it while the TPM is stopped, so when swtpm is still running from a previous boot, a CMD_STOP has to go first.)

quentin.thebault_defenso.fr added inline comments.
usr.sbin/bhyve/bhyve.8
867

You are right. This was a leftover from my initial test setup before the patch, when I relied on restarting swtpm to clear the PCRs. I tested again and it is not required. I will remove it from the manpage.

Remove the startup-clear flag mention for swtpm since it is not needed.

This revision is now accepted and ready to land.Wed, Oct 7, 8:47 AM
usr.sbin/bhyve/tpm_emul_swtpm.c
71

Yes, good point. I will address that in a follow-up DR. Thanks for bringing it up.