Skip to content
36 changes: 20 additions & 16 deletions tpm2/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,22 +304,26 @@ var toGoCurve = map[EllipticCurve]elliptic.Curve{

// Supported TPM operations.
const (
cmdEvictControl tpmutil.Command = 0x00000120
cmdUndefineSpace tpmutil.Command = 0x00000122
cmdClockSet tpmutil.Command = 0x00000128
cmdDefineSpace tpmutil.Command = 0x0000012A
cmdPCRAllocate tpmutil.Command = 0x0000012B
cmdCreatePrimary tpmutil.Command = 0x00000131
cmdIncrementNVCounter tpmutil.Command = 0x00000134
cmdWriteNV tpmutil.Command = 0x00000137
cmdPCREvent tpmutil.Command = 0x0000013C
cmdStartup tpmutil.Command = 0x00000144
cmdShutdown tpmutil.Command = 0x00000145
cmdStirRandom tpmutil.Command = 0x00000146
cmdActivateCredential tpmutil.Command = 0x00000147
cmdCertify tpmutil.Command = 0x00000148
cmdCertifyCreation tpmutil.Command = 0x0000014A
cmdReadNV tpmutil.Command = 0x0000014E
cmdEvictControl tpmutil.Command = 0x00000120
cmdUndefineSpace tpmutil.Command = 0x00000122
cmdClear tpmutil.Command = 0x00000126
cmdClearControl tpmutil.Command = 0x00000127
cmdClockSet tpmutil.Command = 0x00000128
cmdHierarchyChangeAuth tpmutil.Command = 0x00000129
cmdDefineSpace tpmutil.Command = 0x0000012A
cmdPCRAllocate tpmutil.Command = 0x0000012B
cmdCreatePrimary tpmutil.Command = 0x00000131
cmdIncrementNVCounter tpmutil.Command = 0x00000134
cmdWriteNV tpmutil.Command = 0x00000137
cmdPCREvent tpmutil.Command = 0x0000013C
cmdDictionaryAttackParameters tpmutil.Command = 0x0000013A
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move it one line higher, to keep sorted order

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I've done that now.

cmdStartup tpmutil.Command = 0x00000144
cmdShutdown tpmutil.Command = 0x00000145
cmdStirRandom tpmutil.Command = 0x00000146
cmdActivateCredential tpmutil.Command = 0x00000147
cmdCertify tpmutil.Command = 0x00000148
cmdCertifyCreation tpmutil.Command = 0x0000014A
cmdReadNV tpmutil.Command = 0x0000014E
// CmdPolicySecret is a command code for TPM2_PolicySecret.
// It's exported for computing of default AuthPolicy value.
CmdPolicySecret tpmutil.Command = 0x00000151
Expand Down
96 changes: 96 additions & 0 deletions tpm2/tpm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,102 @@ func CreatePrimaryRawTemplate(rw io.ReadWriter, owner tpmutil.Handle, sel PCRSel
return hnd, pubKey, nil
}

func encodeClear(hierarchy tpmutil.Handle, password string) ([]byte, error) {
ha, err := tpmutil.Pack(hierarchy)
if err != nil {
return nil, err
}
auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: []byte(password)})
if err != nil {
return nil, err
}
return concat(ha, auth)
}

func Clear(rw io.ReadWriter, hierarchy tpmutil.Handle, password string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add doc comments to all exported funcs

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

cmd, err := encodeClear(hierarchy, password)
if err != nil {
return err
}
_, err = runCommand(rw, TagSessions, cmdClear, tpmutil.RawBytes(cmd))
return err
}

func encodeDisableOwnerClear(password string) ([]byte, error) {
lockout, err := tpmutil.Pack(HandleLockout)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass the handle as argument

if err != nil {
return nil, err
}
auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: []byte(password)})
if err != nil {
return nil, err
}
param, err := tpmutil.Pack(true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass this as argument

if err != nil {
return nil, err
}
return concat(lockout, auth, param)
}

func DisableOwnerClear(rw io.ReadWriter, password string) error {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change this to ClearControl and take hierarchy and enable/disable as arguments

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated this now.

cmd, err := encodeDisableOwnerClear(password)
if err != nil {
return err
}
_, err = runCommand(rw, TagSessions, cmdClearControl, tpmutil.RawBytes(cmd))
return err
}

func encodeSetDAParameters(maxTries, recoveryTime, lockoutRecovery uint32, password string) ([]byte, error) {
lockout, err := tpmutil.Pack(HandleLockout)
if err != nil {
return nil, err
}
auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: []byte(password)})
if err != nil {
return nil, err
}
params, err := tpmutil.Pack(maxTries, recoveryTime, lockoutRecovery)
if err != nil {
return nil, err
}
return concat(lockout, auth, params)
}

func SetDictionaryAttackParameters(rw io.ReadWriter, maxTries, recoveryTime, lockoutRecovery uint32, password string) error {
cmd, err := encodeSetDAParameters(maxTries, recoveryTime, lockoutRecovery, password)
if err != nil {
return err
}
_, err = runCommand(rw, TagSessions, cmdDictionaryAttackParameters, tpmutil.RawBytes(cmd))
return err
}

func encodeHierarchyChangeAuthParameters(hierarchy tpmutil.Handle, oldPassword, newPassword string) ([]byte, error) {
handle, err := tpmutil.Pack(hierarchy)
if err != nil {
return nil, err
}
auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: []byte(oldPassword)})
if err != nil {
return nil, err
}
params, err := tpmutil.Pack(tpmutil.U16Bytes(newPassword))
if err != nil {
return nil, err
}
return concat(handle, auth, params)
}

func HierarchyChangeAuth(rw io.ReadWriter, hierarchy tpmutil.Handle, oldPassword, newPassword string) error {
cmd, err := encodeHierarchyChangeAuthParameters(hierarchy, oldPassword, newPassword)
if err != nil {
return err
}
_, err = runCommand(rw, TagSessions, cmdHierarchyChangeAuth, tpmutil.RawBytes(cmd))
return err
}

func decodeReadPublic(in []byte) (Public, []byte, []byte, error) {
var resp struct {
Public tpmutil.U16Bytes
Expand Down
53 changes: 53 additions & 0 deletions tpm2/tpm2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1363,3 +1363,56 @@ func TestCreatePrimaryRawTemplate(t *testing.T) {
t.Errorf("got key exponent %v, want %v", pubRSA.E, defaultKeyParams.RSAParameters.Exponent)
}
}

func TestClear(t *testing.T) {
rw := openTPM(t)
defer rw.Close()

rootHandle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, emptyPassword, emptyPassword, defaultKeyParams)
if err != nil {
t.Fatalf("CreatePrimary failed: %v", err)
}
defer FlushContext(rw, rootHandle)

persistentHandle := tpmutil.Handle(0x817FFFFF)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment explaining where this value comes from

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied this value from other tests in tpm2_test.go.

// Evict persistent key, if there is one already (e.g. last test run failed).
if err := EvictControl(rw, emptyPassword, HandleOwner, persistentHandle, persistentHandle); err != nil {
t.Logf("(expected) EvictControl failed: %v", err)
}
// Make key persistent.
if err := EvictControl(rw, emptyPassword, HandleOwner, rootHandle, persistentHandle); err != nil {
t.Fatalf("EvictControl failed: %v", err)
}

if err := Clear(rw, HandleLockout, emptyPassword); err != nil {
if err := EvictControl(rw, emptyPassword, HandleOwner, persistentHandle, persistentHandle); err != nil {
t.Logf("EvictControl failed: %v", err)
}
t.Fatalf("Clear failed: %v", err)
}

vals, _, err := GetCapability(rw, CapabilityHandles, 1, uint32(persistentHandle))
if err != nil {
t.Fatalf("GetCapability failed: %v", err)
}

if len(vals) != 0 {
t.Errorf("Persistent handle wasn't cleared")
}
}

func TestHierarchyChangeAuth(t *testing.T) {
rw := openTPM(t)
defer rw.Close()

if err := HierarchyChangeAuth(rw, HandleOwner, emptyPassword, defaultPassword); err != nil {
t.Fatalf("HierarchyChangeAuth failed: %v", err)
}
defer HierarchyChangeAuth(rw, HandleOwner, defaultPassword, emptyPassword)

handle, _, err := CreatePrimary(rw, HandleOwner, pcrSelection7, defaultPassword, emptyPassword, defaultKeyParams)
if err != nil {
t.Errorf("CreatePrimary failed: %v", err)
}
FlushContext(rw, handle)
}