Skip to content

Commit

Permalink
Merge pull request #104 from chrisccoulson/provision-tpm-api-changes
Browse files Browse the repository at this point in the history
Remove ProvisionStatus and refactor provision API.

ProvisionStatus is a problematic API - AttrValidSRK and AttrValidEK
indicate that objects with the expected public areas exist at the expected
handles, but can't indicate whether those objects were created with the
correct templates and are actually valid objects. These attributes can't
be used to make a decision about whether ProvisionTPM should be called or
not, so just remove the ProvisionStatus API entirely.

Rename ProvisionTPM to EnsureProvisioned (and make it a method of
TPMConnection), and introduce a new error (ErrTPMProvisioningRequiresLockout)
which is returned from EnsureProvisioned if it is called with
ProvisionModeWithoutLockout but use of the lockout hierarchy is required
to fully provision the TPM. This new error is an indication that
EnsureProvisioned needs to be called again with a different mode in order
to fully provision it.
  • Loading branch information
chrisccoulson authored Sep 24, 2020
2 parents 7e933de + f55740a commit 111df58
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 364 deletions.
2 changes: 1 addition & 1 deletion crypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func unsealKeyFromTPM(tpm *TPMConnection, k *SealedKeyObject, pin string) ([]byt
// has a null authorization value, then this will allow us to unseal the key without requiring any type of manual recovery. If the
// storage hierarchy has a non-null authorization value, ProvionTPM will fail. If the TPM owner has changed, ProvisionTPM might
// succeed, but UnsealFromTPM will fail with InvalidKeyFileError when retried.
if pErr := ProvisionTPM(tpm, ProvisionModeWithoutLockout, nil); pErr == nil {
if pErr := tpm.EnsureProvisioned(ProvisionModeWithoutLockout, nil); pErr == nil || pErr == ErrTPMProvisioningRequiresLockout {
key, err = k.UnsealFromTPM(tpm, pin)
}
}
Expand Down
8 changes: 4 additions & 4 deletions crypt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ type cryptTPMTestBase struct {
func (ctb *cryptTPMTestBase) setUpTestBase(c *C, ttb *testutil.TPMTestBase) {
ctb.cryptTestBase.setUpTestBase(c, &ttb.BaseTest)

c.Assert(ProvisionTPM(ttb.TPM, ProvisionModeFull, nil), IsNil)
c.Assert(ttb.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)

dir := c.MkDir()
ctb.keyFile = dir + "/keydata"
Expand Down Expand Up @@ -558,7 +558,7 @@ func (s *cryptTPMSuite) TestActivateVolumeWithTPMSealedKeyErrorHandling4(c *C) {
// Test that recovery fallback works with the TPM in DA lockout mode.
c.Assert(s.TPM.DictionaryAttackParameters(s.TPM.LockoutHandleContext(), 0, 7200, 86400, nil), IsNil)
defer func() {
c.Check(ProvisionTPM(s.TPM, ProvisionModeFull, nil), IsNil)
c.Check(s.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)
}()

s.testActivateVolumeWithTPMSealedKeyErrorHandling(c, &testActivateVolumeWithTPMSealedKeyErrorHandlingData{
Expand Down Expand Up @@ -620,7 +620,7 @@ func (s *cryptTPMSuite) TestActivateVolumeWithTPMSealedKeyErrorHandling7(c *C) {
// Test that activation fails if RecoveryKeyTries is zero.
c.Assert(s.TPM.DictionaryAttackParameters(s.TPM.LockoutHandleContext(), 0, 7200, 86400, nil), IsNil)
defer func() {
c.Check(ProvisionTPM(s.TPM, ProvisionModeFull, nil), IsNil)
c.Check(s.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)
}()

s.testActivateVolumeWithTPMSealedKeyErrorHandling(c, &testActivateVolumeWithTPMSealedKeyErrorHandlingData{
Expand All @@ -635,7 +635,7 @@ func (s *cryptTPMSuite) TestActivateVolumeWithTPMSealedKeyErrorHandling8(c *C) {
// Test that activation fails if the wrong recovery key is provided.
c.Assert(s.TPM.DictionaryAttackParameters(s.TPM.LockoutHandleContext(), 0, 7200, 86400, nil), IsNil)
defer func() {
c.Check(ProvisionTPM(s.TPM, ProvisionModeFull, nil), IsNil)
c.Check(s.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)
}()

s.testActivateVolumeWithTPMSealedKeyErrorHandling(c, &testActivateVolumeWithTPMSealedKeyErrorHandlingData{
Expand Down
7 changes: 6 additions & 1 deletion errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@ import (
)

var (
// ErrTPMClearRequiresPPI is returned from ProvisionTPM and indicates that clearing the TPM must be performed via
// ErrTPMClearRequiresPPI is returned from TPMConnection.EnsureProvisioned and indicates that clearing the TPM must be performed via
// the Physical Presence Interface.
ErrTPMClearRequiresPPI = errors.New("clearing the TPM requires the use of the Physical Presence Interface")

// ErrTPMProvisioningRequiresLockout is returned from TPMConnection.EnsureProvisioned when fully provisioning the TPM requires
// the use of the lockout hierarchy. In this case, the provisioning steps that can be performed without the use of the lockout
// hierarchy are completed.
ErrTPMProvisioningRequiresLockout = errors.New("provisioning the TPM requires the use of the lockout hierarchy")

// ErrTPMProvisioning indicates that the TPM is not provisioned correctly for the requested operation. Please note that other errors
// that can be returned may also be caused by incomplete provisioning, as it is not always possible to detect incomplete or
// incorrect provisioning in all contexts.
Expand Down
2 changes: 1 addition & 1 deletion keydata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type keyDataSuite struct {
var _ = Suite(&keyDataSuite{})

func (s *keyDataSuite) TestValidateAfterLock(c *C) {
c.Assert(ProvisionTPM(s.TPM, ProvisionModeFull, nil), IsNil)
c.Assert(s.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)

key := make([]byte, 64)
rand.Read(key)
Expand Down
2 changes: 1 addition & 1 deletion pin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func (s *pinSuite) SetUpSuite(c *C) {

func (s *pinSuite) SetUpTest(c *C) {
s.TPMTestBase.SetUpTest(c)
c.Assert(ProvisionTPM(s.TPM, ProvisionModeFull, nil), IsNil)
c.Assert(s.TPM.EnsureProvisioned(ProvisionModeFull, nil), IsNil)

dir := c.MkDir()
s.keyFile = dir + "/keydata"
Expand Down
240 changes: 82 additions & 158 deletions provisioning.go

Large diffs are not rendered by default.

Loading

0 comments on commit 111df58

Please sign in to comment.