diff --git a/tpm2/test/hierarchy_change_auth_test.go b/tpm2/test/hierarchy_change_auth_test.go new file mode 100644 index 00000000..73f45f25 --- /dev/null +++ b/tpm2/test/hierarchy_change_auth_test.go @@ -0,0 +1,75 @@ +package tpm2test + +import ( + "testing" + + . "github.com/google/go-tpm/tpm2" + "github.com/google/go-tpm/tpm2/transport/simulator" +) + +func TestHierarchyChangeAuth(t *testing.T) { + thetpm, err := simulator.OpenSimulator() + if err != nil { + t.Fatalf("could not connect to TPM simulator: %v", err) + } + defer thetpm.Close() + + authKey := []byte("authkey") + newAuthKey := []byte("newAuthKey") + + t.Run("HierarchyChangeAuthOwner", func(t *testing.T) { + hca := HierarchyChangeAuth{ + AuthHandle: TPMRHOwner, + NewAuth: TPM2BAuth{ + Buffer: authKey, + }, + } + + _, err := hca.Execute(thetpm) + if err != nil { + t.Fatalf("failed HierarchyChangeAuth: %v", err) + } + }) + + t.Run("HierarchyChangeAuthOwnerUnauth", func(t *testing.T) { + hca := HierarchyChangeAuth{ + AuthHandle: TPMRHOwner, + NewAuth: TPM2BAuth{ + Buffer: newAuthKey, + }, + } + + _, err := hca.Execute(thetpm) + if err == nil { + t.Fatal("failed HierarchyChangeAuthWithoutAuth: Expected HierarchyChangeAuth to fail") + } + }) + + t.Run("HierarchyChangeAuthOwnerAuth", func(t *testing.T) { + hca := HierarchyChangeAuth{ + AuthHandle: AuthHandle{ + Handle: TPMRHOwner, + Auth: PasswordAuth(authKey), + }, + NewAuth: TPM2BAuth{ + Buffer: newAuthKey, + }, + } + + _, err := hca.Execute(thetpm) + if err != nil { + t.Fatalf("failed HierarchyChangeAuthWithAuth: %v", err) + } + }) + + t.Run("Clear", func(t *testing.T) { + clear := Clear{ + AuthHandle: TPMRHLockout, + } + + _, err := clear.Execute(thetpm) + if err != nil { + t.Fatalf("failed Clear: %v", err) + } + }) +} diff --git a/tpm2/tpm2.go b/tpm2/tpm2.go index 45a4bdfe..513dbb7f 100644 --- a/tpm2/tpm2.go +++ b/tpm2/tpm2.go @@ -1427,6 +1427,30 @@ func (cmd Clear) Execute(t transport.TPM, s ...Session) (*ClearResponse, error) // ClearResponse is the response from TPM2_Clear. type ClearResponse struct{} +// HierarchyChangeAuth is the input to TPM2_HierarchyChangeAuth. +// See definition in Part 3, Commands, section 24.8 +type HierarchyChangeAuth struct { + // TPM_RH_ENDORSEMENT, TPM_RH_LOCKOUT, TPM_RH_OWNER or TPM_RH_PLATFORM+{PP} + AuthHandle handle `gotpm:"handle,auth"` + // new authorization value + NewAuth TPM2BAuth +} + +// Command implements the Command interface. +func (HierarchyChangeAuth) Command() TPMCC { return TPMCCHierarchyChanegAuth } + +// Execute executes the command and returns the response. +func (cmd HierarchyChangeAuth) Execute(t transport.TPM, s ...Session) (*HierarchyChangeAuthResponse, error) { + var rsp HierarchyChangeAuthResponse + if err := execute[HierarchyChangeAuthResponse](t, cmd, &rsp, s...); err != nil { + return nil, err + } + return &rsp, nil +} + +// HierarchyChangeAuthResponse is the response from TPM2_HierarchyChangeAuth. +type HierarchyChangeAuthResponse struct {} + // ContextSave is the input to TPM2_ContextSave. // See definition in Part 3, Commands, section 28.2 type ContextSave struct {