Skip to content

Commit

Permalink
policyutil: make it possible to authorize permanent resources with a …
Browse files Browse the repository at this point in the history
…policy
  • Loading branch information
chrisccoulson committed Apr 5, 2024
1 parent 8473da1 commit 3bb5509
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
14 changes: 14 additions & 0 deletions cmds_cap.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,20 @@ func (t *TPMContext) GetCapabilityAuthPolicies(first Handle, propertyCount uint3
return data.Data.AuthPolicies, nil
}

// GetCapabilityAuthPolicy is a convenience function for [TPMContext.GetCapability], and returns
// the auth policy digest associated with the supplied permanent handle, if there is one. This will
// return a null hash if there is no auth policy digest.
func (t *TPMContext) GetCapabilityAuthPolicy(handle Handle, sessions ...SessionContext) (TaggedHash, error) {
policies, err := t.GetCapabilityAuthPolicies(handle, 1, sessions...)
if err != nil {
return MakeTaggedHash(HashAlgorithmNull, nil), err
}
if len(policies) == 0 || policies[0].Handle != handle {
return MakeTaggedHash(HashAlgorithmNull, nil), fmt.Errorf("handle %v does no exist", handle)
}
return policies[0].PolicyHash, nil
}

// IsTPM2 determines whether this TPMContext is connected to a TPM2 device. It does this by
// attempting to execute a TPM2_GetCapability command, and verifying that the response packet has
// the expected tag.
Expand Down
7 changes: 7 additions & 0 deletions cmds_cap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"math"
"reflect"

"github.com/canonical/go-tpm2"
. "github.com/canonical/go-tpm2"
internal_testutil "github.com/canonical/go-tpm2/internal/testutil"
"github.com/canonical/go-tpm2/mu"
Expand Down Expand Up @@ -627,6 +628,12 @@ func (s *capabilitiesSuite) TestGetCapabilityPCRProperties3(c *C) {
{Tag: PropertyPCRSave, Select: []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}}})
}

func (s *capabilitiesSuite) TestGetCapabilityAuthPolicy(c *C) {
policy, err := s.TPM.GetCapabilityAuthPolicy(tpm2.HandleOwner)
c.Check(err, IsNil)
c.Check(policy.HashAlg, Equals, HashAlgorithmNull)
}

// We don't have a TPM1.2 simulator, so create a mock Transport that just returns
// a TPM_BAD_ORDINAL error
type mockTPM12Transport struct {
Expand Down
24 changes: 19 additions & 5 deletions policyutil/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -1138,8 +1138,6 @@ func (r *policyExecuteRunner) authorize(auth ResourceContext, askForPolicy bool,
}
}

alg := auth.Resource().Name().Algorithm()

// build available session types
availableSessionTypes := map[tpm2.SessionType]bool{
tpm2.SessionTypeHMAC: true,
Expand All @@ -1150,6 +1148,8 @@ func (r *policyExecuteRunner) authorize(auth ResourceContext, askForPolicy bool,
availableSessionTypes[tpm2.SessionTypePolicy] = false
}

var alg tpm2.HashAlgorithmId

switch auth.Resource().Handle().Type() {
case tpm2.HandleTypeNVIndex:
pub, err := r.tpm.NVReadPublic(auth.Resource())
Expand All @@ -1164,10 +1164,23 @@ func (r *policyExecuteRunner) authorize(auth ResourceContext, askForPolicy bool,
// index only supports policy read
availableSessionTypes[tpm2.SessionTypeHMAC] = false
}
alg = auth.Resource().Name().Algorithm()
case tpm2.HandleTypePermanent:
// auth value is always available, no support for policy yet
alg = r.sessionAlg
availableSessionTypes[tpm2.SessionTypePolicy] = false
// Auth value is always available for permanent resources. Auth policy
// is available if
policyDigest, err := r.tpm.GetPermanentHandleAuthPolicy(auth.Resource().Handle())
if err != nil {
return nil, fmt.Errorf("cannot obtain permanent handle auth policy: %w", err)
}
switch {
case policyDigest.HashAlg == tpm2.HashAlgorithmNull:
// policy is not enabled for this resource
alg = r.sessionAlg
availableSessionTypes[tpm2.SessionTypePolicy] = false
default:
// policy is enabled for this resource
alg = policyDigest.HashAlg
}
case tpm2.HandleTypeTransient, tpm2.HandleTypePersistent:
pub, err := r.tpm.ReadPublic(auth.Resource())
if err != nil {
Expand All @@ -1177,6 +1190,7 @@ func (r *policyExecuteRunner) authorize(auth ResourceContext, askForPolicy bool,
// object only supports policy for user role
availableSessionTypes[tpm2.SessionTypeHMAC] = false
}
alg = auth.Resource().Name().Algorithm()
default:
return nil, errors.New("unexpected handle type")
}
Expand Down
18 changes: 15 additions & 3 deletions policyutil/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ func (s *policySuite) TestPolicyNVDifferentAuth(c *C) {
operandB: internal_testutil.DecodeHexString(c, "00001000"),
offset: 4,
operation: tpm2.OpEq,
expectedCommands: 7,
expectedCommands: 8,
expectedAuthorize: true,
expectedSessionType: tpm2.HandleTypeHMACSession})
c.Check(err, IsNil)
Expand Down Expand Up @@ -1054,15 +1054,15 @@ func (s *policySuite) TestPolicySecret(c *C) {
err := s.testPolicySecret(c, &testExecutePolicySecretData{
authObject: s.TPM.OwnerHandleContext(),
policyRef: []byte("foo"),
expectedCommands: 7,
expectedCommands: 8,
expectedSessionType: tpm2.HandleTypeHMACSession})
c.Check(err, IsNil)
}

func (s *policySuite) TestPolicySecretNoPolicyRef(c *C) {
err := s.testPolicySecret(c, &testExecutePolicySecretData{
authObject: s.TPM.OwnerHandleContext(),
expectedCommands: 7,
expectedCommands: 8,
expectedSessionType: tpm2.HandleTypeHMACSession})
c.Check(err, IsNil)
}
Expand Down Expand Up @@ -2276,6 +2276,7 @@ func (s *policySuite) TestPolicyBranchesDifferentBranchIndex(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand All @@ -2295,6 +2296,7 @@ func (s *policySuite) TestPolicyBranchesNumericSelectorDifferentBranchIndex(c *C
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2339,6 +2341,7 @@ func (s *policySuite) TestPolicyBranchAutoSelectWithUsage2(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2551,6 +2554,7 @@ func (s *policySuite) TestPolicyBranchesMultipleNodes3(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2631,6 +2635,7 @@ func (s *policySuite) TestPolicyBranchesMultipleNodesAutoSelectWithUsage3(c *C)
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand All @@ -2653,6 +2658,7 @@ func (s *policySuite) TestPolicyBranchesMultipleNodesAutoSelectOneWithUsage(c *C
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2691,6 +2697,7 @@ func (s *policySuite) TestPolicyBranchesMultipleNodesAutoSelectWildcard2(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2864,6 +2871,7 @@ func (s *policySuite) TestPolicyBranchesEmbeddedNodes3(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand All @@ -2885,6 +2893,7 @@ func (s *policySuite) TestPolicyBranchesEmbeddedNodes4(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2936,6 +2945,7 @@ func (s *policySuite) TestPolicyBranchesEmbeddedNodesAutoSelectOneWithUsage(c *C
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -2987,6 +2997,7 @@ func (s *policySuite) TestPolicyBranchesEmbeddedNodesAutoSelectWithUsage3(c *C)
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down Expand Up @@ -3025,6 +3036,7 @@ func (s *policySuite) TestPolicyBranchesEmbeddedNodesAutoSelectWildcard2(c *C) {
tpm2.CommandPolicyNvWritten,
tpm2.CommandContextSave,
tpm2.CommandContextLoad,
tpm2.CommandGetCapability,
tpm2.CommandContextSave,
tpm2.CommandStartAuthSession,
tpm2.CommandContextLoad,
Expand Down
12 changes: 12 additions & 0 deletions policyutil/tpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ type TPMHelper interface {
// is required by any policy that includes TPM2_PolicyNV assertions or TPM2_PolicySecret
// assertions on NV indices.
NVReadPublic(handle tpm2.HandleContext) (*tpm2.NVPublic, error)

// GetPermanentHandleAuthPolicy returns the auth policy digest for the specified
// permanent handle, if there is one. If there isn't one, it returns a null hash.
GetPermanentHandleAuthPolicy(handle tpm2.Handle) (tpm2.TaggedHash, error)
}

type onlineTpmHelper struct {
Expand Down Expand Up @@ -132,6 +136,10 @@ func (h *onlineTpmHelper) NVReadPublic(handle tpm2.HandleContext) (*tpm2.NVPubli
return pub, err
}

func (h *onlineTpmHelper) GetPermanentHandleAuthPolicy(handle tpm2.Handle) (tpm2.TaggedHash, error) {
return h.tpm.GetCapabilityAuthPolicy(handle, h.sessions...)
}

type nullTpmHelper struct{}

func (*nullTpmHelper) StartAuthSession(sessionType tpm2.SessionType, alg tpm2.HashAlgorithmId) (SessionContext, PolicySession, error) {
Expand Down Expand Up @@ -165,3 +173,7 @@ func (*nullTpmHelper) NVRead(auth, index tpm2.ResourceContext, size, offset uint
func (*nullTpmHelper) NVReadPublic(handle tpm2.HandleContext) (*tpm2.NVPublic, error) {
return nil, errors.New("no TPMHelper")
}

func (*nullTpmHelper) GetPermanentHandleAuthPolicy(handle tpm2.Handle) (tpm2.TaggedHash, error) {
return tpm2.MakeTaggedHash(tpm2.HashAlgorithmNull, nil), errors.New("no TPMHelper")
}

0 comments on commit 3bb5509

Please sign in to comment.