github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/tss/pcr.go (about) 1 // Copyright 2020 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package tss 6 7 import ( 8 "fmt" 9 "io" 10 11 "github.com/google/go-tpm/tpm" 12 "github.com/google/go-tpm/tpm2" 13 "github.com/google/go-tpm/tpmutil" 14 ) 15 16 func extendPCR12(rwc io.ReadWriter, pcrIndex uint32, hash [20]byte) error { 17 if _, err := tpm.PcrExtend(rwc, pcrIndex, hash); err != nil { 18 return err 19 } 20 return nil 21 } 22 23 func extendPCR20(rwc io.ReadWriter, pcrIndex uint32, hash []byte) error { 24 if err := tpm2.PCRExtend(rwc, tpmutil.Handle(pcrIndex), tpm2.AlgSHA256, hash, ""); err != nil { 25 return err 26 } 27 return nil 28 } 29 30 func readAllPCRs20(tpm io.ReadWriter, alg tpm2.Algorithm) (map[uint32][]byte, error) { 31 numPCRs := 24 32 out := map[uint32][]byte{} 33 34 // The TPM 2.0 spec says that the TPM can partially fulfill the 35 // request. As such, we repeat the command up to 8 times to get all 36 // 24 PCRs. 37 for i := 0; i < numPCRs; i++ { 38 // Build a selection structure, specifying all PCRs we do 39 // not have the value for. 40 sel := tpm2.PCRSelection{Hash: alg} 41 for pcr := 0; pcr < numPCRs; pcr++ { 42 if _, present := out[uint32(pcr)]; !present { 43 sel.PCRs = append(sel.PCRs, pcr) 44 } 45 } 46 47 // Ask the TPM for those PCR values. 48 ret, err := tpm2.ReadPCRs(tpm, sel) 49 if err != nil { 50 return nil, fmt.Errorf("tpm2.ReadPCRs(%+v) failed with err: %v", sel, err) 51 } 52 // Keep track of the PCRs we were actually given. 53 for pcr, digest := range ret { 54 out[uint32(pcr)] = digest 55 } 56 if len(out) == numPCRs { 57 break 58 } 59 } 60 61 if len(out) != numPCRs { 62 return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out)) 63 } 64 65 return out, nil 66 } 67 68 func readAllPCRs12(rwc io.ReadWriter) (map[uint32][]byte, error) { 69 numPCRs := 24 70 out := map[uint32][]byte{} 71 72 for i := 0; i < numPCRs; i++ { 73 // Ask the TPM for those PCR values. 74 pcr, err := tpm.ReadPCR(rwc, uint32(i)) 75 if err != nil { 76 return nil, fmt.Errorf("tpm.ReadPCR(%d) failed with err: %v", i, err) 77 } 78 out[uint32(i)] = pcr 79 if len(out) == numPCRs { 80 break 81 } 82 } 83 84 if len(out) != numPCRs { 85 return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out)) 86 } 87 88 return out, nil 89 } 90 91 func readPCR12(rwc io.ReadWriter, pcrIndex uint32) ([]byte, error) { 92 return tpm.ReadPCR(rwc, pcrIndex) 93 } 94 95 func readPCR20(rwc io.ReadWriter, pcrIndex uint32) ([]byte, error) { 96 return tpm2.ReadPCR(rwc, int(pcrIndex), tpm2.AlgSHA256) 97 }