Skip to content

Commit

Permalink
attestationreport, tpmdriver: added support for TPM_PCR_INIT_VALUE
Browse files Browse the repository at this point in the history
The TPM_PCR_INIT_VALUE contains the value that is used to initialize the specific PCR. It is prepended for each PCR specifically

Signed-off-by: Jeremias Giesecke <[email protected]>
  • Loading branch information
Jeremias Giesecke authored and smo4201 committed Jan 29, 2024
1 parent fd0036a commit fc3386f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 8 deletions.
3 changes: 2 additions & 1 deletion attestationreport/attestationreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ type HashChainElem struct {
Pcr int32 `json:"pcr" cbor:"1,keyasint"`
Sha256 []HexByte `json:"sha256" cbor:"2,keyasint"`
Summary bool `json:"summary" cbor:"3,keyasint"` // Indicates if element represents final PCR value or single artifact
EventData []EventData `json:"eventdata,omitempty" cbor:"4,keyasint,omitempty"`
EventName []string `json:"eventname,omitempty" cbor:"4,keyasint,omitempty"`
EventData []EventData `json:"eventdata,omitempty" cbor:"5,keyasint,omitempty"`
}

// TpmMeasurement represents the attestation report
Expand Down
34 changes: 30 additions & 4 deletions attestationreport/tpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,16 @@ func recalculatePcrs(tpmM *TpmMeasurement, referenceValues []ReferenceValue) (ma
// reference values
if _, ok := calculatedPcrs[*ref.Pcr]; !ok {
calculatedPcrs[*ref.Pcr] = make([]byte, 32)
//first event could be a TPM_PCR_INIT_VALUE ()
if ref.Name == "TPM_PCR_INIT_VALUE" {
calculatedPcrs[*ref.Pcr] = ref.Sha256 //the Sha256 should contain the init value
continue //break the loop iteration and continue with the next event
}
}

calculatedPcrs[*ref.Pcr] = extendHash(calculatedPcrs[*ref.Pcr], ref.Sha256)
refResult := DigestResult{
// Type: "Reference Value",
Pcr: ref.Pcr,
Name: ref.Name,
Digest: hex.EncodeToString(ref.Sha256),
Expand All @@ -179,7 +186,7 @@ func recalculatePcrs(tpmM *TpmMeasurement, referenceValues []ReferenceValue) (ma
if bytes.Equal(sha256, ref.Sha256) {
found = true
refResult.Success = true
if hce.EventData != nil {
if hce.EventData != nil && len(hce.EventData) > i {
refResult.EventData = &hce.EventData[i]
}
break
Expand Down Expand Up @@ -218,6 +225,13 @@ func recalculatePcrs(tpmM *TpmMeasurement, referenceValues []ReferenceValue) (ma
// the final PCR value for comparison
measurement = make([]byte, 32)
for i, sha256 := range hce.Sha256 {
if i == 0 {
//if the first event is a TPM_PCR_INIT_VALUE
if hce.EventName != nil && len(hce.EventName) > i && hce.EventName[i] == "TPM_PCR_INIT_VALUE" {
measurement = sha256 //because the first element in the sha256 chain is the locality, (as part of the locality event)
continue //continues with next element from the hash chain
}
}
measurement = extendHash(measurement, sha256)

// Check, if a reference value exists for the measured value
Expand All @@ -231,7 +245,11 @@ func recalculatePcrs(tpmM *TpmMeasurement, referenceValues []ReferenceValue) (ma
Type: "Measurement",
}

if hce.EventData != nil {
if hce.EventName != nil && len(hce.EventName) > i {
measResult.Name = hce.EventName[i]
}

if hce.EventData != nil && len(hce.EventData) > i {
measResult.EventData = &hce.EventData[i]
}

Expand Down Expand Up @@ -306,8 +324,16 @@ func recalculatePcrs(tpmM *TpmMeasurement, referenceValues []ReferenceValue) (ma
// Measurement contains individual values which must be extended to result in
// the final PCR value for comparison
measurement = make([]byte, 32)
for _, sha256 := range hce.Sha256 {
measurement = extendHash(measurement, sha256)
for i, sha256 := range hce.Sha256 {
//first element is the TPM_PCR_INIT_VALUE
if i == 0 {
if hce.EventName[i] != "TPM_PCR_INIT_VALUE" {
log.Errorln("First event is not a TPM_PCR_INIT_VALUE")
}
measurement = sha256
} else {
measurement = extendHash(measurement, sha256)
}
}
}

Expand Down
63 changes: 62 additions & 1 deletion tpmdriver/bioseventlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (

// Constants
var (
STARTUP_LOCALITY_SIGNATURE = [16]byte{0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x4C, 0x6F, 0x63, 0x61, 0x6C, 0x69, 0x74, 0x79, 0x0}
EV_PREBOOT_CERT = uint32(0)
EV_POST_CODE = uint32(1)
EV_UNUSED = uint32(2)
Expand Down Expand Up @@ -137,6 +138,7 @@ func GetBiosMeasurements(file string) ([]ar.ReferenceValue, error) {
func parseBiosMeasurements(data []byte) ([]ar.ReferenceValue, error) {

extends := make([]ar.ReferenceValue, 0)
initializedPCR := make([]bool, 24) //bool array track of what pcrs have been initialized
buf := bytes.NewBuffer(data)

// Read initial TCG Event to detect event log format
Expand Down Expand Up @@ -203,7 +205,29 @@ func parseBiosMeasurements(data []byte) ([]ar.ReferenceValue, error) {
//bytes of the event should be added to the array
eventData := make([]uint8, eventSize)
binary.Read(buf, binary.LittleEndian, &eventData)
extendedeventData = ar.ParseEventData(eventData, eventName)

parseEvent := true

//checks for locality
if pcrIndex > 24 {
log.Errorf("Invalid PCR: %v", pcrIndex)
}
//pcr value has not been initialized
if !initializedPCR[pcrIndex] {
//generate the locality entry
entry, skipEvent, err := generateLocalityEntry(int(pcrIndex), eventType, eventData)
if err != nil {
log.Trace(err)
} else {
extends = append(extends, entry)
}
parseEvent = !skipEvent
initializedPCR[pcrIndex] = true

}
if parseEvent {
extendedeventData = ar.ParseEventData(eventData, eventName)
}

//either Sha256 or Sha384 must be present
if !(len(sha384Digest) == SHA384_DIGEST_LEN || len(sha256Digest) == SHA256_DIGEST_LEN) {
Expand All @@ -225,6 +249,43 @@ func parseBiosMeasurements(data []byte) ([]ar.ReferenceValue, error) {
return extends, nil
}

func generateLocalityEntry(pcrIndex int, eventType uint32, eventData []uint8) (ar.ReferenceValue, bool, error) {
var found_hcrtm bool
var locality byte
skipEvent := false
eventD := bytes.NewBuffer(eventData)

if pcrIndex == 0 {
if eventType == EV_EFI_HCRTM_EVENT {
found_hcrtm = true
locality = 0x04 //startup locality shall be set to 0x04 if a H-CRTM event was found
}

/* Handle StartupLocality in replay for PCR0 */
if !found_hcrtm && eventType == EV_NO_ACTION && pcrIndex == 0 {
if eventD.Len() < 17 { // sizeof(EV_NO_ACTION_STRUCT))
return ar.ReferenceValue{}, false, errors.New("eventsize is too small")
}

signature := eventD.Next(16)

if bytes.Equal(signature, STARTUP_LOCALITY_SIGNATURE[:]) {

locality = eventD.Next(1)[0]
skipEvent = true
}
}
}

digest := make([]byte, 32)
digest[31] = locality

entry := ar.ReferenceValue{Type: "INITVAL", Sha256: digest, Sha384: nil, Name: "TPM_PCR_INIT_VALUE", Pcr: &pcrIndex, Snp: nil, Description: "", EventData: nil}

//generate the Locality
return entry, skipEvent, nil
}

// switch for the event types
func eventtypeToString(event_type uint32) string {
switch event_type {
Expand Down
9 changes: 7 additions & 2 deletions tpmdriver/tpmdriver.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,18 @@ func (t *Tpm) Measure(nonce []byte) (ar.Measurement, error) {
hashChain := make([]*ar.HashChainElem, len(t.Pcrs))
for i, num := range t.Pcrs {
sha256 := make([]ar.HexByte, 0)
eventDataArray := make([]ar.EventData, 0) //to capture additional EventData
eventNameArray := make([]string, 0)
eventDataArray := make([]ar.EventData, 0)

if t.MeasurementLog {
for _, digest := range biosMeasurements {
if num == *digest.Pcr {
sha256 = append(sha256, digest.Sha256)
eventNameArray = append(eventNameArray, digest.Name)

if t.MeasurementLog {
if digest.Name == "TPM_PCR_INIT_VALUE" {
eventDataArray = append(eventDataArray, ar.EventData{})
} else {
eventDataArray = append(eventDataArray, *digest.EventData)
}
}
Expand All @@ -239,6 +243,7 @@ func (t *Tpm) Measure(nonce []byte) (ar.Measurement, error) {
//appending EventData
if t.MeasurementLog {
hashChain[i].EventData = eventDataArray
hashChain[i].EventName = eventNameArray
}
}

Expand Down

0 comments on commit fc3386f

Please sign in to comment.