diff --git a/policyutil/policy.go b/policyutil/policy.go index 5f1fd77..b0982ce 100644 --- a/policyutil/policy.go +++ b/policyutil/policy.go @@ -1440,6 +1440,46 @@ type PolicyExecuteResult struct { // Path indicates the executed path. Path string + + policyCommandCode *tpm2.CommandCode + policyCpHash tpm2.Digest + policyNameHash tpm2.Digest + policyNvWritten *bool +} + +// CommandCode returns the command code if a TPM2_PolicyCommandCode assertion +// was executed. +func (r *PolicyExecuteResult) CommandCode() (code tpm2.CommandCode, set bool) { + if r.policyCommandCode == nil { + return 0, false + } + return *r.policyCommandCode, true +} + +// CpHash returns the command parameter hash if a TPM2_PolicyCpHash assertion +// was executed. +func (r *PolicyExecuteResult) CpHash() (cpHashA tpm2.Digest, set bool) { + if len(r.policyCpHash) == 0 { + return nil, false + } + return r.policyCpHash, true +} + +// CpHash returns the name hash if a TPM2_PolicyNameHash assertion was executed. +func (r *PolicyExecuteResult) NameHash() (nameHash tpm2.Digest, set bool) { + if len(r.policyNameHash) == 0 { + return nil, false + } + return r.policyNameHash, true +} + +// NvWritten returns the nvWrittenSet value if a TPM2_PolicyNvWritten assertion +// was executed. +func (r *PolicyExecuteResult) NvWritten() (nvWrittenSet bool, set bool) { + if r.policyNvWritten == nil { + return false, false + } + return *r.policyNvWritten, true } // Execute runs this policy using the supplied TPM context and on the supplied policy session. @@ -1536,6 +1576,18 @@ func (p *Policy) Execute(session PolicySession, resources PolicyResources, tpm T AuthValueNeeded: details.AuthValueNeeded, Path: string(runner.currentPath), } + if commandCode, set := details.CommandCode(); set { + result.policyCommandCode = &commandCode + } + if cpHash, set := details.CpHash(); set { + result.policyCpHash = cpHash + } + if nameHash, set := details.NameHash(); set { + result.policyNameHash = nameHash + } + if nvWritten, set := details.NvWritten(); set { + result.policyNvWritten = &nvWritten + } for _, ticket := range tickets.newTickets { result.NewTickets = append(result.NewTickets, ticket) diff --git a/policyutil/policy_test.go b/policyutil/policy_test.go index 4592a03..162908a 100644 --- a/policyutil/policy_test.go +++ b/policyutil/policy_test.go @@ -1763,6 +1763,14 @@ func (s *policySuite) testPolicyNV(c *C, data *testExecutePolicyNVData) error { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) c.Check(authorized, Equals, data.expectedAuthorize) @@ -2108,6 +2116,14 @@ func (s *policySuite) testPolicySecret(c *C, data *testExecutePolicySecretData) c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) c.Check(authObjectHandle, Not(Equals), tpm2.Handle(0)) @@ -2521,6 +2537,14 @@ func (s *policySuite) testPolicySigned(c *C, data *testExecutePolicySignedData) c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -2691,6 +2715,14 @@ func (s *policySuite) TestPolicySignedWithTicket(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) c.Check(s.TPM.PolicyRestart(session), IsNil) @@ -2702,6 +2734,14 @@ func (s *policySuite) TestPolicySignedWithTicket(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set = result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -2715,6 +2755,9 @@ type testExecutePolicyAuthorizeData struct { path string expectedRequireAuthValue bool expectedPath string + expectedCommandCode tpm2.CommandCode + expectedNvWrittenSet bool + expectedNvWritten bool } func (s *policySuite) testPolicyAuthorize(c *C, data *testExecutePolicyAuthorizeData) error { @@ -2746,6 +2789,20 @@ func (s *policySuite) testPolicyAuthorize(c *C, data *testExecutePolicyAuthorize c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, Equals, data.expectedRequireAuthValue) c.Check(result.Path, Equals, data.expectedPath) + code, set := result.CommandCode() + if data.expectedCommandCode == tpm2.CommandCode(0) { + c.Check(set, internal_testutil.IsFalse) + } else { + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, data.expectedCommandCode) + } + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWritten, set := result.NvWritten() + c.Check(set, Equals, data.expectedNvWrittenSet) + c.Check(nvWritten, Equals, data.expectedNvWritten) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -2908,6 +2965,9 @@ func (s *policySuite) testPolicyAuthorizeWithSubPolicyBranches(c *C, path string path: path, expectedRequireAuthValue: expectedRequireAuthValue, expectedPath: strings.Join([]string{fmt.Sprintf("%x", approvedPolicy), expectedPath}, "/"), + expectedCommandCode: tpm2.CommandNVChangeAuth, + expectedNvWrittenSet: true, + expectedNvWritten: true, }) c.Check(err, IsNil) } @@ -2973,6 +3033,14 @@ func (s *policySuite) TestPolicyAuthValue(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsTrue) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) // TPM2_PolicyPassword and TPM2_PolicyAuthValue have the same digest, so make sure // we executed the correct command. @@ -2999,6 +3067,15 @@ func (s *policySuite) testPolicyCommandCode(c *C, code tpm2.CommandCode) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + codeResult, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(codeResult, Equals, code) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -3037,6 +3114,14 @@ func (s *policySuite) testPolicyCounterTimer(c *C, data *testExecutePolicyCounte c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -3118,6 +3203,17 @@ func (s *policySuite) testPolicyCpHash(c *C, data *testExecutePolicyCpHashData) c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + cpHash, set := result.CpHash() + c.Check(set, internal_testutil.IsTrue) + expectedCpHash, err := ComputeCpHash(tpm2.HashAlgorithmSHA256, data.code, data.handles, data.params...) + c.Assert(err, IsNil) + c.Check(cpHash, DeepEquals, expectedCpHash) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -3154,6 +3250,17 @@ func (s *policySuite) testPolicyNameHash(c *C, handles ...Named) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + nameHash, set := result.NameHash() + c.Check(set, internal_testutil.IsTrue) + expectedNameHash, err := ComputeNameHash(tpm2.HashAlgorithmSHA256, handles...) + c.Assert(err, IsNil) + c.Check(nameHash, DeepEquals, expectedNameHash) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -3236,6 +3343,16 @@ func (s *policySuite) testPolicyBranches(c *C, data *testExecutePolicyBranchesDa c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, Equals, data.expectedRequireAuthValue) c.Check(result.Path, Equals, data.expectedPath) + code, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, tpm2.CommandNVChangeAuth) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWrittenSet, set := result.NvWritten() + c.Check(set, internal_testutil.IsTrue) + c.Check(nvWrittenSet, internal_testutil.IsTrue) log := s.CommandLog() c.Assert(log, internal_testutil.LenEquals, len(data.expectedCommands)) @@ -3407,6 +3524,16 @@ func (s *policySuite) TestPolicyBranchesMultipleDigests(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsTrue) c.Check(result.Path, Equals, "branch1") + code, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, tpm2.CommandNVChangeAuth) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWrittenSet, set := result.NvWritten() + c.Check(set, internal_testutil.IsTrue) + c.Check(nvWrittenSet, internal_testutil.IsTrue) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -3467,6 +3594,16 @@ func (s *policySuite) testPolicyBranchesMultipleNodes(c *C, data *testExecutePol c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, Equals, data.expectedRequireAuthValue) c.Check(result.Path, Equals, data.expectedPath) + code, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, data.expectedCommandCode) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWritten, set := result.NvWritten() + c.Check(set, internal_testutil.IsTrue) + c.Check(nvWritten, internal_testutil.IsTrue) log := s.CommandLog() c.Assert(log, internal_testutil.LenEquals, len(data.expectedCommands)) @@ -3772,6 +3909,16 @@ func (s *policySuite) testPolicyBranchesEmbeddedNodes(c *C, data *testExecutePol c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, Equals, data.expectedRequireAuthValue) c.Check(result.Path, Equals, data.expectedPath) + code, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, data.expectedCommandCode) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWritten, set := result.NvWritten() + c.Check(set, internal_testutil.IsTrue) + c.Check(nvWritten, internal_testutil.IsTrue) log := s.CommandLog() c.Assert(log, internal_testutil.LenEquals, len(data.expectedCommands)) @@ -4171,6 +4318,14 @@ func (s *policySuite) testPolicyPCR(c *C, values tpm2.PCRValues) error { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -4232,6 +4387,18 @@ func (s *policySuite) testPolicyDuplicationSelect(c *C, data *testExecutePolicyD c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + code, set := result.CommandCode() + c.Check(set, internal_testutil.IsTrue) + c.Check(code, Equals, tpm2.CommandDuplicate) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + nameHash, set := result.NameHash() + c.Check(set, internal_testutil.IsTrue) + expectedNameHash, err := ComputeNameHash(tpm2.HashAlgorithmSHA256, data.object.Name(), data.newParent.Name()) + c.Assert(err, IsNil) + c.Check(nameHash, DeepEquals, expectedNameHash) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -4299,6 +4466,14 @@ func (s *policySuite) TestPolicyPassword(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsTrue) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) // TPM2_PolicyPassword and TPM2_PolicyAuthValue have the same digest, so make sure // we executed the correct command. @@ -4325,6 +4500,15 @@ func (s *policySuite) testPolicyNvWritten(c *C, writtenSet bool) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + nvWritten, set := result.NvWritten() + c.Check(set, internal_testutil.IsTrue) + c.Check(nvWritten, Equals, writtenSet) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) @@ -4665,6 +4849,14 @@ func (s *policySuitePCR) TestPolicyBranchesAutoSelected(c *C) { c.Check(result.InvalidTickets, internal_testutil.LenEquals, 0) c.Check(result.AuthValueNeeded, internal_testutil.IsFalse) c.Check(result.Path, Equals, "$[1]") + _, set := result.CommandCode() + c.Check(set, internal_testutil.IsFalse) + _, set = result.CpHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NameHash() + c.Check(set, internal_testutil.IsFalse) + _, set = result.NvWritten() + c.Check(set, internal_testutil.IsFalse) digest, err := s.TPM.PolicyGetDigest(session) c.Check(err, IsNil) diff --git a/policyutil/session.go b/policyutil/session.go index c64f96f..d1e98f8 100644 --- a/policyutil/session.go +++ b/policyutil/session.go @@ -729,7 +729,7 @@ func (s *recorderPolicySession) PolicyDuplicationSelect(objectName, newParentNam if err := s.PolicyNameHash(nameHash); err != nil { return err } - return s.PolicyCommandCode(tpm2.CommandPolicyDuplicationSelect) + return s.PolicyCommandCode(tpm2.CommandDuplicate) } func (s *recorderPolicySession) PolicyAuthorize(approvedPolicy tpm2.Digest, policyRef tpm2.Nonce, keySign tpm2.Name, verified *tpm2.TkVerified) error {