Closed nicowilliams closed 2 years ago
It's possible that the -e
option won't work for policies with several more alternations than I tried.
The correct way to evaluate a policy with alternations would be to first evaluate all the alternatives not-taken in trial sessions, flushing loaded sessions as one goes, then start a policy session for all the taken alternatives and execute those, with any tpm2 policyor
s referring to not-taken alternatives by their already-computed policyDigest
s. This way there is no risk of running out of loaded session handle space on the TPM.
The correct way to evaluate a policy with alternations would be to first evaluate all the alternatives not-taken in trial sessions, flushing loaded sessions as one goes, then start a policy session for all the taken alternatives and execute those, with any tpm2 policyors referring to not-taken alternatives by their already-computed policyDigests. This way there is no risk of running out of loaded session handle space on the TPM.
Fixed. Now the policy is first executed in trial sessions (one per alternation + one for the top-level), the policy digests are saved, then the chosen alternatives are executed in a single policy session and the previously computed policy digests are used for the alternatives not-taken. This minimizes the number of saved session contexts used that must be available concurrently.
EDIT: Well... the current implementation uses N trial sessions concurrently, where N is the alternation depth. This could be reduced to 1 by calling first executing all the leaf alternations, then their parents, and so on.
I don't know how to fix this:
In /github/workspace/tests/test-enroll.sh line 16:
. "$TOP/functions.sh"
^-----------------^ SC1091: Not following: functions.sh was not specified as input (see shellcheck -x).
The make shellcheck
target wasn't even listing that file, but even now that I added it...
@osresearch has requested making the language pithier by not requiring that every sub-command be tpm2_policy*
or tpm2 policy*
. So one would write tpm2-policy secret ...
instead of tpm2-policy tpm2 policysecret ...
.
Also, clearly the language will need something like symbolic bindings for user-provided items, and/or maybe inlined literals like public keys.
For example, suppose a policy uses TPM2_PolicySigned()
, and needs to specify a public key for the signer... The key in that case might need to be inlined in the policy language as a literal (line-joined PEM?) or as a reference to a literal that follows the policy in the same file (like a here-doc), and since we might need several such literals, we might need to name them and be able to refer to them by $name
in the sub-commands. Items such as policyRef
s might need to be caller-provided, in which case we'd need a way to refer to them by $name
in the sub-commands, with a way for the user to provide them on the tpm2-policy
command-line.
We then might as well have the alternatives-taken argument for policy session evaluation be given as a tpm2-policy
command option.
So we might have:
$ cat > policy.def
or ( secret endorsement ) ( signed $signer $policyRef )
--
signer <<EOS
<PEM of signer pubkey here>
EOS
^D
$ tpm2-policy -s session.ctx -L policy.dat -a 1 -V policyRef=abcd ./policy.def
or
$ cat > policy.def
or ( secret $entity ) ( signed $signer $policyRef )
--
entity: load <<EOPRIV <<EOPUB
<base64-encoded private part>
EOPRIV
<base64-encoded public part>
EOPUB
signer <<EOS
<PEM of signer pubkey here>
EOS
^D
$ tpm2-policy -s session.ctx -L policy.dat -a 1 -V policyRef=abcd ./policy.def
Any prompting for passwords/authValues would have to be handled too.
@williamcroberts maybe tpm2-tools could use something like this, a policy language for EA policies. I'm just playing here, and currently it's really half-baked.
@kgoldman maybe we can even design an EA policy language that TCG might standardize?
@williamcroberts maybe tpm2-tools could use something like this, a policy language for EA policies. I'm just playing here, and currently it's really half-baked.
@kgoldman maybe we can even design an EA policy language that TCG might standardize?
It already exists inside of FAPI and the TSS WG is actually working on pulling that out of FAPI and standardizing the policy language and a library for handling it in a separate spec.
@williamcroberts maybe tpm2-tools could use something like this, a policy language for EA policies. I'm just playing here, and currently it's really half-baked. @kgoldman maybe we can even design an EA policy language that TCG might standardize?
It already exists inside of FAPI and the TSS WG is actually working on pulling that out of FAPI and standardizing the policy language and a library for handling it in a separate spec.
Oh! Ok, I'll take a look. Thanks for the tip.
@williamcroberts maybe tpm2-tools could use something like this, a policy language for EA policies. I'm just playing here, and currently it's really half-baked. @kgoldman maybe we can even design an EA policy language that TCG might standardize?
It already exists inside of FAPI and the TSS WG is actually working on pulling that out of FAPI and standardizing the policy language and a library for handling it in a separate spec.
Oh! Ok, I'll take a look. Thanks for the tip.
FYI theirs also a policy generator GUI: https://tpm2-software.github.io/fapipolicies/
@williamcroberts does the tpm2-tools stack support FAPI JSON policies?
@williamcroberts does the tpm2-tools stack support FAPI JSON policies?
IIUC, The tss2 prefixed tools do. However, we wanted to create a new tpm2 policy tool that takes the engine out of FAPI and supports it.
IIUC, The tss2 prefixed tools do. However, we wanted to create a new tpm2 policy tool that takes the engine out of FAPI and supports it.
Yes. In fact, I'm thinking of writing a bash + jq script to do just that using existing tpm2_*
commands.
I'm not keen on the tss2 tools' abstraction of "let's pretend there's a database of metadata-rich entities". I really like the very thin tpm2 tools' abstraction of just adding automatic context save/load to TPM2_*()
commands. The tss2 tool approach cannot and, really, MUST NOT know about everything a TPM is used for, so this idea of storing a DB of extra metadata in /etc/
just does not work. The tpm2 tooling's thin abstraction means the user is on the hook for flushing contexts out of the TPM (though that too could be automated), but otherwise by being such a thin abstraction I can focus on the TCG TPM 2.0 Library parts 1 and 3 and easily build complex applications out of simple tools.
IIUC, The tss2 prefixed tools do. However, we wanted to create a new tpm2 policy tool that takes the engine out of FAPI and supports it.
Yes. In fact, I'm thinking of writing a bash + jq script to do just that using existing
tpm2_*
commands.I'm not keen on the tss2 tools' abstraction of "let's pretend there's a database of metadata-rich entities". I really like the very thin tpm2 tools' abstraction of just adding automatic context save/load to
TPM2_*()
commands. The tss2 tool approach cannot and, really, MUST NOT know about everything a TPM is used for, so this idea of storing a DB of extra metadata in/etc/
just does not work. The tpm2 tooling's thin abstraction means the user is on the hook for flushing contexts out of the TPM (though that too could be automated), but otherwise by being such a thin abstraction I can focus on the TCG TPM 2.0 Library parts 1 and 3 and easily build complex applications out of simple tools.
The policy engine code in FAPI that we can rip out just calls callback functions that would be plumbed to TPM commands. So it would keep that thin abstraction while automatically reading the json policy file. It keeps one from having to write a bash + jq thing. I can take a look at ripping this library out today.
Ahh ifapi_policyutil_execute_prepare depends on a FAPI context, and we want to break that dependency. Let me bring this up with Andreas and see what we can come up with.
Ahh ifapi_policyutil_execute_prepare depends on a FAPI context, and we want to break that dependency. Let me bring this up with Andreas and see what we can come up with.
Sure. But I think I can go with jq + bash for now. Basically a bash script that calls a jq program to emit a set of tpm2 commands to eval
in order using the jq @sh
shell quoting feature.
Ahh ifapi_policyutil_execute_prepare depends on a FAPI context, and we want to break that dependency. Let me bring this up with Andreas and see what we can come up with.
Sure. But I think I can go with jq + bash for now. Basically a bash script that calls a jq program to emit a set of tpm2 commands to
eval
in order using the jq@sh
shell quoting feature.
I was hoping to spur development of a permanent tool so you don't have to maintain both things. You also pick up TPM-less policy calculations.
I was hoping to spur development of a permanent tool so you don't have to maintain both things. You also pick up TPM-less policy calculations.
I'm starting to think that software operations (make credential, trial policies, duplicate) should be implemented in a completely separate codebase. The reason for this is that it could be a very small and clean codebase that way.
As for executing policies from a description language, I do think too that scripting with jq is very tempting as a first prototype, and if the command-line tools are good enough, why not?
I was hoping to spur development of a permanent tool so you don't have to maintain both things. You also pick up TPM-less policy calculations.
I'm starting to think that software operations (make credential, trial policies, duplicate) should be implemented in a completely separate codebase. The reason for this is that it could be a very small and clean codebase that way.
I thought you guys had a script for this no?
As for executing policies from a description language, I do think too that scripting with jq is very tempting as a first prototype, and if the command-line tools are good enough, why not?
prototype yes, i'm trying to spur long term thoughts here and conformity so theirs not 10 ways to do something. Since their already is a format for policies, building something to do that generically for all users has a promising future and would reduce your overall maintenance burden.
Hi all... Jumping onto the train here. We already have a running implementation of a policy calculation and execution inside the tss (used internally by libtss2-fapi). That being said, we made sure that this module does not have any other internal dependencies (besides some helpers, but nothing state related), because we already planned for making this standalone at some point.
Long story short, here are the three function we defined (that are knowing-working code) that we could extract into a separate library: https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_instantiate.h#L73-L81 https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_calculate.h#L22-L28 https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_execute.h#L161-L170
Would you be willing to spend some effort on helping me extract the code into a separate library instead of coding a second implementation ?
Hi all... Jumping onto the train here. We already have a running implementation of a policy calculation and execution inside the tss (used internally by libtss2-fapi). That being said, we made sure that this module does not have any other internal dependencies (besides some helpers, but nothing state related), because we already planned for making this standalone at some point.
Long story short, here are the three function we defined (that are knowing-working code) that we could extract into a separate library: https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_instantiate.h#L73-L81 https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_calculate.h#L22-L28 https://github.com/tpm2-software/tpm2-tss/blob/ec58f0a43931b18de9c3c5e0cd884892c218041a/src/tss2-fapi/ifapi_policy_execute.h#L161-L170
Would you be willing to spend some effort on helping me extract the code into a separate library instead of coding a second implementation ?
in progress...
So I have something early started:
Theirs a lot of todos and its very raw and only partially working. But I'd like to get feedback early on direction.
I'm toying with a scheme like so:
rbin/*
-- helper scripts
loadexternal
, and another for verifysignature
sha256sum
, xxd
, and such utilsloadexternal
rbash
(restricted Bash) with just rbin
in PATH
sbin/tpm2-policy
will eval policies, in both trial and policy sessions as requested and necessary
(cd $policy && rbash ./policy)
, with temp files (e.g., loaded key contexts, tickets) in $TMPDIR
For EAs the alternatives to execute would be given to sbin/tpm2-policy
as an argument but communicated to the rbash
and rbin
scripts via env vars. $TMPDIR
would be where to put temp items, as one would expect. $TMPDIR/policy-session.ctx
would be the policy session. Etc.
Superseded by #144.
This allows one to express complex policies (ones with alternations) using a simple language.
The pattern is simply that conjunctions are
tpm2 policy*
command-lines joined with a';'
argument, and alternations aretpm2 policyor
commands with arguments that are themselves policies surrounded by'('
and')'
arguments.For example:
which allows an entity sporting such a policy to be used for signing or decryption only, and only when PCR#11 is cleared.
The same, verbosely:
One can also execute a policy in a policy session using
sbin/tpm2-policy
:Internally we have
exec_policy
in functions.sh that can execute a policy in either a trial session or in policy session, and if in a policy session then the caller must supply the indices of alternatives to take in the policy, otherwise the caller must not supply those.I.e.,
This is recursive, so it generalizes to policies of arbitrary complexity, limited to nesting alternations up to nine (9) times, or the shell's recursion limit if it be lower.