Add a lot of policy and NV commands to TPMDirect #272
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces a helper called
PolicyCalculator
for calculating TPM policies. Every Policy TPM command now implements an interface calledPolicyCommand
for updating aPolicyCalculator
. This allows TPM policies to be found without using trial sessions in a TPM.This PR updates existing TPM command
Execute
functions to simply returnerror
values when the response structure is empty. To support the reflection logic (and future likely auditing logic), all the empty response structure definitions still have to exist, but we just won't return them to callers, who will 100% of the time assign them to _.This PR fixes a couple of typos and missed error conditions. The most interesting of these fixes is that
Execute
will now remind the user when they forgot to add an authorization to anAuthHandle
, instead of panicking.This PR also adds the following 22 commands into TPMDirect, approximately doubling the number of supported commands in TPMDirect to 47 out of the 122 commands in the latest TPM specification:
LoadExternal was added because VerifySignature isn't very useful without it, and CreateLoaded was added because it (like LoadExternal) has an "optional" command parameter that needs to be handled correctly. "Optional" parameters are 2Bs that can contain nothing, even if what they normally contain does not have a legal empty serialization: LoadExternal accepts one "optional" and CreateLoaded returns one "optional" - together, their implementation validates the special logic required for these parameters.
This change modifies the templates in the
templates
package to have typetpmt.Public
instead oftpm2b.Public
. This is so that they can be used for the contents oftpm2b.Template
as needed by CreateLoaded.This change introduces 2 actual go
interface
s for some very special types where, to preserve backwards compatibility, the TPM spec introduced new alternative serializations of existing types for CreateLoaded:tpm2b.Template
can be either classictpmt.Public
or a slightly modified version, which I have generified astpmu.Template
tpms.SensitiveCreate
can be either classictpm2b.SensitiveData
or the label/context pairing intpm2b.Derive
, which I have generified astpmu.SensitiveCreate
.These special pseudo-unions need to be assignable from both the "classic" types as well as the special ones depending on the context of CreateLoaded. Making them into interfaces allows callers to write both of these:
and
This increases the boilerplate for the types, doesn't offer unmarshalling logic, and would be frustrating to scale over time if this weren't a highly special case for this one command. However in this one case, it greatly improves the ergonomics over the alternatives I can think of (for example, making
tpm2b.Template
contain two pointer members and documenting for users that they should only fill one in).Fun fact about this change: to add the first 20 commands (as well as some other helper functionality), we only needed 300 lines of new structure types, and 600 lines of new command types and methods, and all 900 of these lines were extremely rote, boilerplate implementations. Extrapolating this data (45 lines per command), it should take around 3500 more lines of boilerplate code to implement the rest of the spec. CreateLoaded and LoadExternal required a bit more changes to the marshalling logic, because they introduce "optional" parameters (no other commands have these).