-
Notifications
You must be signed in to change notification settings - Fork 28
Complex policy expressions #134
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
Conversation
19ae7ad
to
5de2990
Compare
It's possible that the 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 |
ad575b8
to
4678119
Compare
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. |
3b4643d
to
318f048
Compare
I don't know how to fix this:
The |
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 are {tpm2 policyor} commands with arguments that are themselves policies surrounded by '(' and ')' arguments. For example: $ sbin/tpm2-policy \ tpm2 policyor \ '(' tpm2 policycommandcode TPM2_CC_Sign ')' \ '(' tpm2 policycommandcode TPM2_CC_RSA_Decrypt ')' ';' \ tpm2 policypcr -l "sha256:11" 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: $ sbin/tpm2-policy -v \ tpm2 policyor \ '(' tpm2 policycommandcode TPM2_CC_Sign ')' \ '(' tpm2 policycommandcode TPM2_CC_RSA_Decrypt ')' ';' \ tpm2 policypcr -l "sha256:11" Running: (AND) exec_policyOR_helper ( tpm2 policycommandcode TPM2_CC_Sign ) ( tpm2 policycommandcode TPM2_CC_RSA_Decrypt ) ; Running: (AND) tpm2 policycommandcode --session /tmp/tmp.jbXmSKOtzR/session-0-0 --policy /tmp/tmp.jbXmSKOtzR/policy-0-0 TPM2_CC_Sign cc6918b226273b08f5bd406d7f10cf160f0a7d13dfd83b7770ccbcd1aa80d811 cc6918b226273b08f5bd406d7f10cf160f0a7d13dfd83b7770ccbcd1aa80d811 Running: (AND) tpm2 policycommandcode --session /tmp/tmp.jbXmSKOtzR/session-0-1 --policy /tmp/tmp.jbXmSKOtzR/policy-0-1 TPM2_CC_RSA_Decrypt 3c29869a1312094782b86df5a430caae587f5dfb16dfa3f7204151054c1340d2 3c29869a1312094782b86df5a430caae587f5dfb16dfa3f7204151054c1340d2 ORing: cc6918b226273b08f5bd406d7f10cf160f0a7d13dfd83b7770ccbcd1aa80d811 3c29869a1312094782b86df5a430caae587f5dfb16dfa3f7204151054c1340d2 Running: tpm2 policyor --session /tmp/tmp.jbXmSKOtzR/session --policy /tmp/tmp.jbXmSKOtzR/policy sha256:/tmp/tmp.jbXmSKOtzR/policy-0-0,/tmp/tmp.jbXmSKOtzR/policy-0-1 39faada14fb6d5deba4315d8bce0247813262ebf15e1aee35477d26759f1b29e Running: (AND) tpm2 policypcr --session /tmp/tmp.jbXmSKOtzR/session --policy /tmp/tmp.jbXmSKOtzR/policy -l sha256:11 3b9ea8dca851fac5d077d7b6925b8cc38847619e4b9a0f026ca5cc6262ff8a1c 3b9ea8dca851fac5d077d7b6925b8cc38847619e4b9a0f026ca5cc6262ff8a1c $ 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., # Compute policyDigest of the policy above: tpm2_flushall tpm2 startauthsession --session session exec_policy session policy \ tpm2 policyor \ '(' tpm2 policycommandcode TPM2_CC_Sign ')' \ '(' tpm2 policycommandcode TPM2_CC_RSA_Decrypt ')' ';' \ tpm2 policypcr -l "sha256:11" # Execute the policy above with the second alternative: tpm2_flushall tpm2 startauthsession --session session exec_policy 1 session policy \ tpm2 policyor \ '(' tpm2 policycommandcode TPM2_CC_Sign ')' \ '(' tpm2 policycommandcode TPM2_CC_RSA_Decrypt ')' ';' \ tpm2 policypcr -l "sha256:11" 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.
Good suggestion by Erik Larsson.
2867e1d
to
db6adcb
Compare
@osresearch has requested making the language pithier by not requiring that every sub-command be |
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 We then might as well have the alternatives-taken argument for policy session evaluation be given as a |
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? |
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? |
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 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 |
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. |
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 |
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 thought you guys had a script for this no?
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. Long story short, here are the three function we defined (that are knowing-working code) that we could extract into a separate library: 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:
For EAs the alternatives to execute would be given to |
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-linesjoined 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 apolicy 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.