Skip to content

Commit

Permalink
Implemented and Tested pcrReset. (#295)
Browse files Browse the repository at this point in the history
* Implemented and Tested pcrReset.

* Fixed nits and rewrote TestPCRReset.

* Changed zero check in test to be more clear.

Co-authored-by: Matthew Tsai <matthewtsai@google.com>
  • Loading branch information
matt-tsai and Matthew Tsai authored Jul 30, 2022
1 parent eff70a6 commit 6f9794f
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
128 changes: 128 additions & 0 deletions direct/tpm2/pcr_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package tpm2

import (
"bytes"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"testing"

"github.com/google/go-tpm/direct/structures/tpm"
"github.com/google/go-tpm/direct/structures/tpml"
"github.com/google/go-tpm/direct/structures/tpms"
"github.com/google/go-tpm/direct/structures/tpmt"
"github.com/google/go-tpm/direct/transport/simulator"
)

var extendsDirect = map[tpm.AlgID][]struct {
digest []byte
}{
tpm.AlgSHA1: {
{bytes.Repeat([]byte{0x00}, sha1.Size)},
{bytes.Repeat([]byte{0x01}, sha1.Size)},
{bytes.Repeat([]byte{0x02}, sha1.Size)}},
tpm.AlgSHA256: {
{bytes.Repeat([]byte{0x00}, sha256.Size)},
{bytes.Repeat([]byte{0x01}, sha256.Size)},
{bytes.Repeat([]byte{0x02}, sha256.Size)}},
tpm.AlgSHA384: {
{bytes.Repeat([]byte{0x00}, sha512.Size384)},
{bytes.Repeat([]byte{0x01}, sha512.Size384)},
{bytes.Repeat([]byte{0x02}, sha512.Size384)}},
}

func allZero(s []byte) bool {
for _, v := range s {
if v != 0 {
return false
}
}
return true
}

func TestPCRReset(t *testing.T) {
thetpm, err := simulator.OpenSimulator()
if err != nil {
t.Fatalf("could not connect to TPM simulator: %v", err)
}
defer thetpm.Close()

DebugPCR := 16

cases := []struct {
name string
hashalg tpm.AlgID
}{
{"SHA1", tpm.AlgSHA1},
{"SHA256", tpm.AlgSHA256},
{"SHA384", tpm.AlgSHA384},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
PCRs, err := CreatePCRSelection([]int{DebugPCR})
if err != nil {
t.Fatalf("Failed to create PCRSelection")
}

authHandle := AuthHandle{
Handle: tpm.Handle(DebugPCR),
Auth: PasswordAuth(nil),
}

pcrRead := PCRRead{
PCRSelectionIn: tpml.PCRSelection{
PCRSelections: []tpms.PCRSelection{
{
Hash: c.hashalg,
PCRSelect: PCRs,
},
},
},
}

// Extending PCR 16
for _, d := range extendsDirect[c.hashalg] {
pcrExtend := PCRExtend{
PCRHandle: authHandle,
Digests: tpml.DigestValues{
Digests: []tpmt.HA{
{
HashAlg: c.hashalg,
Digest: d.digest,
},
},
},
}
if err := pcrExtend.Execute(thetpm); err != nil {
t.Fatalf("failed to extend pcr for test %v", err)
}
}

pcrReadRsp, err := pcrRead.Execute(thetpm)
if err != nil {
t.Fatalf("failed to read PCRs")
}
postExtendPCR16 := pcrReadRsp.PCRValues.Digests[0].Buffer
if allZero(postExtendPCR16) {
t.Errorf("postExtendPCR16 not expected to be all Zero: %v", postExtendPCR16)
}

// Resetting PCR 16
pcrReset := PCRReset{
PCRHandle: authHandle,
}
if _, err := pcrReset.Execute(thetpm); err != nil {
t.Fatalf("pcrReset failed: %v", err)
}
if pcrReadRsp, err = pcrRead.Execute(thetpm); err != nil {
t.Fatalf("failed to read PCRs")
}
postResetPCR16 := pcrReadRsp.PCRValues.Digests[0].Buffer

if !allZero(postResetPCR16) {
t.Errorf("postResetPCR16 expected to be all Zero: %v", postExtendPCR16)
}
})
}
}
25 changes: 25 additions & 0 deletions direct/tpm2/tpm2.go
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,31 @@ type PCRReadResponse struct {
// Response implements the Response interface.
func (*PCRReadResponse) Response() tpm.CC { return tpm.CCPCRRead }

// PCRReset is the input to TPM2_PCRReset.
// See definition in Part 3, Commands, section 22.8.
type PCRReset struct {
// the PCR to reset
PCRHandle handle `gotpm:"handle,auth"`
}

// Command implements the Command interface.
func (*PCRReset) Command() tpm.CC { return tpm.CCPCRReset }

// Execute executes the command and returns the response.
func (cmd *PCRReset) Execute(t transport.TPM, s ...Session) (*PCRResetResponse, error) {
var rsp PCRResetResponse
if err := execute(t, cmd, &rsp, s...); err != nil {
return nil, err
}
return &rsp, nil
}

// PCRResetResponse is the response from TPM2_PCRReset.
type PCRResetResponse struct{}

// Response implements the Response interface.
func (*PCRResetResponse) Response() tpm.CC { return tpm.CCPCRReset }

// PolicySigned is the input to TPM2_PolicySigned.
// See definition in Part 3, Commands, section 23.3.
type PolicySigned struct {
Expand Down

0 comments on commit 6f9794f

Please sign in to comment.