1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
package tpm2
// pcrSelectionFormatter is a Platform TPM Profile-specific interface for
// formatting TPM PCR selections.
// This interface isn't (yet) part of the go-tpm public interface. After we
// add a second implementation, we should consider making it public.
type pcrSelectionFormatter interface {
// PCRs returns the TPM PCR selection bitmask associated with the given PCR indices.
PCRs(pcrs ...uint) []byte
}
// PCClientCompatible is a pcrSelectionFormatter that formats PCR selections
// suitable for use in PC Client PTP-compatible TPMs (the vast majority):
// https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
// PC Client mandates at least 24 PCRs but does not provide an upper limit.
var PCClientCompatible pcrSelectionFormatter = pcClient{}
type pcClient struct{}
// The TPM requires all PCR selections to be at least big enough to select all
// the PCRs in the minimum PCR allocation.
const pcClientMinimumPCRCount = 24
func (pcClient) PCRs(pcrs ...uint) []byte {
// Find the biggest PCR we selected.
maxPCR := uint(0)
for _, pcr := range pcrs {
if pcr > maxPCR {
maxPCR = pcr
}
}
selectionSize := maxPCR/8 + 1
// Enforce the minimum PCR selection size.
if selectionSize < (pcClientMinimumPCRCount / 8) {
selectionSize = (pcClientMinimumPCRCount / 8)
}
// Allocate a byte array to store the bitfield, that has at least
// enough bits to store our selections.
selection := make([]byte, selectionSize)
for _, pcr := range pcrs {
// The PCR selection mask is byte-wise little-endian:
// select[0] contains bits representing the selection of PCRs 0 through 7
// select[1] contains PCRs 8 through 15, and so on.
byteIdx := pcr / 8
// Within the byte, the PCR selection is bit-wise big-endian:
// bit 0 of select[0] contains the selection of PCR 0
// bit 1 of select[0] contains the selection of PCR 1, and so on.
bitIdx := pcr % 8
selection[byteIdx] |= (1 << bitIdx)
}
return selection
}
|