-
Notifications
You must be signed in to change notification settings - Fork 159
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce helper for formatting PCR selection bitmasks (#345)
* Introduce helper for formatting PCR selection bitmasks This change introduces PCClientCompatible.PCRs(), a function that converts a variadic list of PCR indices (as ints) into a PCR selection bitmask. Because of the vagaries of TPM: 1. That the minimum size of a PCR selection bitmask is not 0, but related to the minimum number of PCRs specified by the profile 2. That the PC Client Platform TPM Profile specification mandates a minimum but not a maximum number of implementation PCR, this change creates an interface that could be implemented for other TPM profiles that specify different amounts of PCRs. The vast majority of on-market TPMs will just work with PCClientCompatible.PCRs, even if they implement more than 24 PCRs. PCRs() can panic if given invalid values; this is to allow it to be inlined into the definition of a structure that needs a PCR selection. * Don't publish the interface for the PCR selection formatter just yet. * use uint instead
- Loading branch information
1 parent
f397c27
commit ee6cbcd
Showing
6 changed files
with
111 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters