Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Resource Manager (/dev/tpmrrm0) rather then /dev/tpm0 #222

Open
bugraaydogar opened this issue Jan 9, 2023 · 3 comments
Open

Use Resource Manager (/dev/tpmrrm0) rather then /dev/tpm0 #222

bugraaydogar opened this issue Jan 9, 2023 · 3 comments

Comments

@bugraaydogar
Copy link

bugraaydogar commented Jan 9, 2023

Hi,

The snapd reports the following error message when an application snap tries to open up the /dev/tpm0.
stateengine.go:149: state ensure error: devicemgr: cannot connect to TPM: no TPM2 device is available

Any application snap could block the use of /dev/tpm0 and therefore, we might consider using the resource manager (/dev/tpmrmx) rather than using the /dev/tpm0 as described here => https://github.com/snapcore/secboot/blob/master/internal/tcti/tcti.go#L29

In addition to that, potentially, we might want to change the snapd's tpm interface to block access to /dev/tpmx directly. => https://github.com/snapcore/snapd/blob/master/interfaces/builtin/tpm.go#L36

What do you think?

Thanks,
Bugra

@bugraaydogar bugraaydogar changed the title Use Resource Manager rather then /dev/tpm0 Use Resource Manager (/dev/tpmrrm0) rather then /dev/tpm0 Jan 9, 2023
@chrisccoulson
Copy link
Collaborator

Yes, ultimately we should use the resource manager backed device, although I'd rather not during early boot because it's not really necessary there.

There are some additional challenges / risks here:

  • I'm not sure how much real world testing the kernel resource manager has had.
  • Using the resource manager introduces the possibility that the TPM state may change during a transaction (composed of multiple commands) that's initiated by snapd. We'll need to make sure that secboot is ready to handle these scenarios.

So whilst we should move towards using it, it's not quite as simple as changing the device path to /dev/tpmrm0.

(On a related note, go-tpm2 has a proper API for iterating / accessing TPM devices now that doesn't rely on specifying the device path - https://pkg.go.dev/github.com/canonical/[email protected]/linux#DefaultTPM2Device. And there's an accessor for the resource manager backed device as well - https://pkg.go.dev/github.com/canonical/[email protected]/linux#TPMDeviceRaw.ResourceManagedDevice)

@chrisccoulson
Copy link
Collaborator

chrisccoulson commented Jan 9, 2025

This may finally get worked on since #357 has landed, which provides a nice internal API for doing what we want. I suspect what we'll want is to hide the internals of this a bit such that:

  • TPM connections from the initrd use the direct device (ie, the existing /dev/tpm0), to reduce the amount of kernel code involved in unlocking and minimise the likelihood of failure (and there should only be a single user in the initrd anyway).
  • TPM connections at runtime will try to use the resource managed device (/dev/tpmrm0), although the code landed in tpm2: Use tpm2.TPMDevice abstraction #357 has an automatic fallback to the direct device if the resource managed device doesn't exist (which should only be an issue on really old kernels). The go-tpm2/linux sub-package is very careful with device enumeration, so it doesn't make an assumption that /dev/tpmrm0 is the resource managed version of /dev/tpm0 (even though it probably is) - it makes extensive use of sysfs to build tpm2.TPMDevice instances accurately.

@pedronis does this seem like a reasonable approach?

When doing the switch to the resource managed device, we'll need to audit the code in the tpm2 sub-package to make sure there are no places where we assume we have exclusive access to the device whilst we have a connection and are performing multiple commands. Once we are using the resource managed device, the kernel will context switch between every command, potentially giving other processes the opportunity to perform operations in-between. I don't imagine there will be any issues though tbh.

@pedronis
Copy link
Collaborator

pedronis commented Jan 9, 2025

@pedronis does this seem like a reasonable approach?

yes, it seems reasonable. One question

TPM connections from the initrd use the direct device (ie, the existing /dev/tpm0), to reduce the amount of kernel code involved in unlocking and minimise the likelihood of failure (and there should only be a single user in the initrd anyway).

what's the idea to achieve this? just that the unlocking code is separate enough to know where to use Direct? or something else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants