Skip to content

plugin/tpm: support persisted shared SRKs#32

Merged
Foxboron merged 1 commit intoFoxboron:masterfrom
Popax21:master
Aug 1, 2025
Merged

plugin/tpm: support persisted shared SRKs#32
Foxboron merged 1 commit intoFoxboron:masterfrom
Popax21:master

Conversation

@Popax21
Copy link
Copy Markdown
Contributor

@Popax21 Popax21 commented Jul 28, 2025

Currently, the plugin will attempt to create a new storage primary every time an operation involving the TPM is performed. This is not only inefficient (since deriving such a primary can be an expensive operation), it also breaks on systems where the TPM has a password set for the owner hierarchy, which causes CreatePrimary to fail with TPM_RC_BAD_AUTH.

However, by convention, the standard TCG shared SRK is usually persisted in NVRAM at index 0x81000001, which allows applications to just skip the expensive CreatePrimary call when the SRK is present at this location. This PR adds support for using this persisted shared SRK to age-plugin-tpm, addressing both issues outlined earlier.

@Popax21
Copy link
Copy Markdown
Contributor Author

Popax21 commented Jul 28, 2025

Note that I just realized that this might break existing TPM2 identities since the shared SRK is typically an RSA-based primary key, compared to the ECC-based primary key currently in use by this plugin. As such it might be required to introduce new information in the serialized output identities which contains information about which SRK was used to generate a given identity. This should be fairly easy to do, but until I do so I have marked this PR as a draft.

@Popax21 Popax21 marked this pull request as draft July 28, 2025 04:34
@Foxboron
Copy link
Copy Markdown
Owner

The "store a persistent SRK in an index" is a relic from TPM 1.2 when we didn't have ECC keys. With ECC keys we don't really need this as it doesn't take a lot of time to create a primary SRK, and we save memory on the TPM.

Instead you could implement this as a switch thing where you point at an index, or a flag to make it check for a persistent SRK. But I'm reluctant to make this into default behaviour.

@Popax21
Copy link
Copy Markdown
Contributor Author

Popax21 commented Jul 28, 2025

The "store a persistent SRK in an index" is a relic from TPM 1.2 when we didn't have ECC keys. With ECC keys we don't really need this as it doesn't take a lot of time to create a primary SRK, and we save memory on the TPM.

Instead you could implement this as a switch thing where you point at an index, or a flag to make it check for a persistent SRK. But I'm reluctant to make this into default behaviour.

I am well aware of the origins of SRKs, and that the switch over to the storage primary key model was intended to allow multiple applications to manage their own key hierarchies (among other things). However, as mentioned above creating such a primary key requires owner authorization, something which this plugin currently does not handle at all (and frankly should not need to operate). For these reasons the TCG TPM2 Provisioning Guidance contains the following section (emphasis mine; this is also the place the well-known 0x81000001 handle is specified):

Legacy TPMs (i.e. version 1.2 and earlier) accommodated only one SRK and thus only one key hierar-
chy. By convention, Owners often set the authorization for the SRK to a well-known Authorization
Value of all zeros so that multiple operating systems and applications could provision their own key
hierarchies underneath it. For version 2.0, operating systems and applications may now create and
manage their own SRK and the key hierarchy underneath it. The creation of a shared SRK facilitates
backwards compatibility with the behavior of legacy operating systems and applications, as well as
for operating systems and applications that want to use a shared SRK without the extra overhead of
managing their own key hierarchies
.
The creation of an SRK requires Owner Authorization through utilization of the Owner Authorization
Value or Owner Authorization Policy. Since this document provides the Owner wide latitude in form-
ing Owner Authorization, it cannot predict how the Owner will use policy to delegate SRK creation to
instantiate non-persistent shared SRKs. However, use of a persistent SRK requires the authorization
for that key and does not require Owner Authorization
.

This is especially relevant since the plugin is currently always deriving the standard shared SRK anyway; the only difference to using the persisted SRK (if present) is that the plugin currently always derives an ECC SRK, while the persistent SRK may either be RSA or ECC. As such I do not see a good reason to not use the persisted shared SRK if present.

Note that systemd eventually also adapted usage of said shared SRK for similar reasons (as part of some security improvements not relevant here); see said discussion in systemd/systemd#26185.

@Popax21 Popax21 marked this pull request as ready for review July 28, 2025 12:05
@Popax21
Copy link
Copy Markdown
Contributor Author

Popax21 commented Jul 28, 2025

I've now addressed the backwards compatibility issues I've mentioned above by introducing a new version of the identity struct which also stores the name of the SRK that was used to generate said identity, in addition to proper handling of both versions in the SRK acquisition logic; as such this PR is ready for review again.

@Foxboron
Copy link
Copy Markdown
Owner

LGTM.

If you can squash the intermediate commits so we just get the functional commits that would be cool. It can either be one commit or split up logically depending on what you prefer.

@Popax21 Popax21 temporarily deployed to Build, sign, release binaries July 30, 2025 20:03 — with GitHub Actions Inactive
@Popax21 Popax21 temporarily deployed to Build, sign, release binaries July 30, 2025 20:03 — with GitHub Actions Inactive
@Popax21 Popax21 temporarily deployed to Build, sign, release binaries July 30, 2025 20:03 — with GitHub Actions Inactive
This commit adds support for the standard persisted shared SRK, allowing for usage of the plugin without owner authorization.

Squash-merge of the following commits:

plugin/tpm: support persisted shared SRKs
plugin: store SRK name in output identities
plugin/crypto: fix wrong SRK usage
plugin: clean up SRK accessor functions
plugin/plugin: address PR reviews
plugin/plugin: fix test failure
@Popax21
Copy link
Copy Markdown
Contributor Author

Popax21 commented Jul 30, 2025

LGTM.

If you can squash the intermediate commits so we just get the functional commits that would be cool. It can either be one commit or split up logically depending on what you prefer.

Done; I've decided to just squash everything into one single commit as that's simpler (and all intermediate versions were sort-of broken in one way or another anyway). I've also fixed up the one failing Go test while doing so.

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

Successfully merging this pull request may close these issues.

2 participants