constellation/image/measured-boot/measure/pcr.go

121 lines
2.7 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package measure
import (
"crypto/sha256"
"fmt"
)
// PCR256 is a 256-bit PCR value.
type PCR256 [32]byte
// MarshalJSON implements json.Marshaler.
func (p PCR256) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("{\"expected\": \"%x\"}", p[:])), nil
}
// Digest256 is a 256-bit digest value (sha256).
type Digest256 [32]byte
// MarshalJSON implements json.Marshaler.
func (d Digest256) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("\"%x\"", d[:])), nil
}
// PCR256Bank is a map of PCR index to PCR256 value.
type PCR256Bank map[uint32]PCR256
// Event is a pcr extend event.
type Event struct {
PCRIndex uint32
Digest Digest256
Data []byte `json:",omitempty"`
Description string
}
// EventLog is a list of events.
type EventLog struct {
Events []Event
}
// Simulator is a TPM PCR simulator.
type Simulator struct {
Bank PCR256Bank `json:"measurements"`
EventLog EventLog
}
// NewDefaultSimulator returns a new Simulator with default PCR values.
func NewDefaultSimulator() *Simulator {
return &Simulator{
Bank: PCR256Bank{
4: ZeroPCR256(),
8: ZeroPCR256(),
9: ZeroPCR256(),
11: ZeroPCR256(),
12: ZeroPCR256(),
13: ZeroPCR256(),
15: ZeroPCR256(),
},
}
}
// ExtendPCR extends the PCR at index with the digest and data.
func (s *Simulator) ExtendPCR(index uint32, digest [32]byte, data []byte, description string) error {
hashCtx := sha256.New()
old, ok := s.Bank[index]
if !ok {
return fmt.Errorf("PCR index %d not found", index)
}
hashCtx.Write(old[:])
hashCtx.Write(digest[:])
newHash := hashCtx.Sum(nil)
s.Bank[index] = PCR256(newHash)
var eventData []byte
if data != nil {
eventData = make([]byte, len(data))
copy(eventData, data)
}
s.EventLog.Events = append(s.EventLog.Events, Event{
PCRIndex: index,
Digest: digest,
Data: eventData,
Description: description,
})
return nil
}
// ZeroPCR256 returns a zeroed PCR256 value.
func ZeroPCR256() PCR256 {
return PCR256{}
}
// EVEFIActionPCR256 returns the expected PCR256 value for EV_EFI_ACTION.
func EVEFIActionPCR256() PCR256 {
return PCR256{
0x3d, 0x67, 0x72, 0xb4, 0xf8, 0x4e, 0xd4, 0x75,
0x95, 0xd7, 0x2a, 0x2c, 0x4c, 0x5f, 0xfd, 0x15,
0xf5, 0xbb, 0x72, 0xc7, 0x50, 0x7f, 0xe2, 0x6f,
0x2a, 0xae, 0xe2, 0xc6, 0x9d, 0x56, 0x33, 0xba,
}
}
// EVSeparatorPCR256 returns the expected PCR256 value for EV_SEPARATOR.
func EVSeparatorPCR256() PCR256 {
return PCR256{
0xdf, 0x3f, 0x61, 0x98, 0x04, 0xa9, 0x2f, 0xdb,
0x40, 0x57, 0x19, 0x2d, 0xc4, 0x3d, 0xd7, 0x48,
0xea, 0x77, 0x8a, 0xdc, 0x52, 0xbc, 0x49, 0x8c,
0xe8, 0x05, 0x24, 0xc0, 0x14, 0xb8, 0x11, 0x19,
}
}