From 77d0de8718a8638d94d2e9b6ae2a8b6122b38d47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jiankun=20L=C3=BC?= Date: Tue, 25 Jan 2022 18:28:11 -0800 Subject: [PATCH] Add PCRReset command for tpm2 (#268) --- tpm2/constants.go | 1 + tpm2/test/tpm2_test.go | 33 +++++++++++++++++++++++++++++++++ tpm2/tpm2.go | 23 +++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/tpm2/constants.go b/tpm2/constants.go index e72cd096..2b0de544 100644 --- a/tpm2/constants.go +++ b/tpm2/constants.go @@ -454,6 +454,7 @@ const ( CmdDictionaryAttackLockReset tpmutil.Command = 0x00000139 CmdDictionaryAttackParameters tpmutil.Command = 0x0000013A CmdPCREvent tpmutil.Command = 0x0000013C + CmdPCRReset tpmutil.Command = 0x0000013D CmdSequenceComplete tpmutil.Command = 0x0000013E CmdStartup tpmutil.Command = 0x00000144 CmdShutdown tpmutil.Command = 0x00000145 diff --git a/tpm2/test/tpm2_test.go b/tpm2/test/tpm2_test.go index 4ac45864..d961f114 100644 --- a/tpm2/test/tpm2_test.go +++ b/tpm2/test/tpm2_test.go @@ -1102,6 +1102,39 @@ func TestReadPCR(t *testing.T) { } } +func TestPCRReset(t *testing.T) { + rw := openTPM(t) + defer rw.Close() + allZeroBytes := make([]byte, 32) + debugPCR := 16 + + var fakeHashSum [32]byte + err := PCRExtend(rw, tpmutil.Handle(debugPCR), AlgSHA256, fakeHashSum[:], "") + if err != nil { + t.Fatal(err) + } + + pcrVal, err := ReadPCR(rw, debugPCR, AlgSHA256) + if err != nil { + t.Fatal(err) + } + if bytes.Equal(allZeroBytes, pcrVal) { + t.Fatal("PCR shouldn't be all zeros after PCRExtend") + } + + err = PCRReset(rw, tpmutil.Handle(debugPCR)) + if err != nil { + t.Fatal(err) + } + pcrVal, err = ReadPCR(rw, debugPCR, AlgSHA256) + if err != nil { + t.Fatal(err) + } + if !bytes.Equal(allZeroBytes, pcrVal) { + t.Fatal("PCR should be all zeros after PCRReset") + } +} + func makeAttestationData() AttestationData { signer := tpmutil.Handle(100) return AttestationData{ diff --git a/tpm2/tpm2.go b/tpm2/tpm2.go index c09b810b..0f2d32c7 100644 --- a/tpm2/tpm2.go +++ b/tpm2/tpm2.go @@ -1930,6 +1930,29 @@ func ReadPCR(rw io.ReadWriter, pcr int, hashAlg Algorithm) ([]byte, error) { return pcrVal, nil } +func encodePCRReset(pcr tpmutil.Handle) ([]byte, error) { + ha, err := tpmutil.Pack(pcr) + if err != nil { + return nil, err + } + auth, err := encodeAuthArea(AuthCommand{Session: HandlePasswordSession, Attributes: AttrContinueSession, Auth: EmptyAuth}) + if err != nil { + return nil, err + } + return concat(ha, auth) +} + +// PCRReset resets the value of the given PCR. Usually, only PCR 16 (Debug) and +// PCR 23 (Application) are resettable on the default locality. +func PCRReset(rw io.ReadWriter, pcr tpmutil.Handle) error { + Cmd, err := encodePCRReset(pcr) + if err != nil { + return err + } + _, err = runCommand(rw, TagSessions, CmdPCRReset, tpmutil.RawBytes(Cmd)) + return err +} + // EncryptSymmetric encrypts data using a symmetric key. // // WARNING: This command performs low-level cryptographic operations.