From 6e6199438513719dad29f5a0198f407663584dcc Mon Sep 17 00:00:00 2001 From: Daniel Maslowski Date: Fri, 6 Aug 2021 19:10:10 +0200 Subject: [PATCH] Add JSON support to eventlog dump Signed-off-by: Daniel Maslowski --- cmd/tpmtool/commands.go | 2 +- cmd/tpmtool/main.go | 1 + pkg/tpm/structures.go | 36 +++++++++++++++++++++++++++++++++--- pkg/tpm/tcpa_log.go | 9 ++++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/cmd/tpmtool/commands.go b/cmd/tpmtool/commands.go index 4016901..bdc4a19 100644 --- a/cmd/tpmtool/commands.go +++ b/cmd/tpmtool/commands.go @@ -355,5 +355,5 @@ func EventlogDump() error { return err } - return tpm.DumpLog(tcpaLog) + return tpm.DumpLog(tcpaLog, *eventlogJson) } diff --git a/cmd/tpmtool/main.go b/cmd/tpmtool/main.go index 7f68ecb..1fa5107 100644 --- a/cmd/tpmtool/main.go +++ b/cmd/tpmtool/main.go @@ -102,6 +102,7 @@ var ( eventlogDumpTPMSpec1 = eventlogDump.Flag("tpm12", "Set tpm12 specification").Bool() eventlogDumpTPMSpec2 = eventlogDump.Flag("tpm20", "Set tpm20 specification").Bool() eventlogDumpFile = eventlogDump.Arg("log", "Custom eventlog file path").String() + eventlogJson = eventlogDump.Flag("json", "Output in JSON format").Bool() ) func main() { diff --git a/pkg/tpm/structures.go b/pkg/tpm/structures.go index 3e5e16d..7c3df92 100644 --- a/pkg/tpm/structures.go +++ b/pkg/tpm/structures.go @@ -1,6 +1,9 @@ package tpm import ( + "encoding/json" + "fmt" + "github.com/rekby/gpt" ) @@ -123,22 +126,49 @@ type TcgBiosSpecIDEvent struct { // TcgPcrEvent2 is a TPM2 default log structure (EFI only) type TcgPcrEvent2 struct { - pcrIndex uint32 + pcrIndex uint32 `json:"index"` eventType uint32 digests LDigestValues eventSize uint32 event []byte } +func (e *TcgPcrEvent2) MarshalJSON() ([]byte, error) { + m := make(map[string]string) + m["type"] = e.PcrEventName() + d := e.PcrEventData() + if d != "" { + m["data"] = d + } + // TODO: This feels a bit hacky. Is it event correct? + ds, err := json.Marshal(e.digests) + if err != nil { + return nil, err + } + m["digests"] = string(ds) + return json.Marshal(m) +} + // TcgPcrEvent is the TPM1.2 default log structure (BIOS, EFI compatible) type TcgPcrEvent struct { - pcrIndex uint32 + pcrIndex uint32 `json:"index"` eventType uint32 digest [20]byte eventSize uint32 event []byte } +func (e *TcgPcrEvent) MarshalJSON() ([]byte, error) { + m := make(map[string]string) + m["type"] = e.PcrEventName() + d := e.PcrEventData() + if d != "" { + m["data"] = d + } + m["digest"] = fmt.Sprintf("%x", e.digest) + return json.Marshal(m) +} + // PCRDigestValue is the hash and algorithm type PCRDigestValue struct { DigestAlg IAlgHash @@ -159,8 +189,8 @@ type PCREvent interface { type PCRLog struct { Firmware FirmwareType PcrList []PCREvent - } + // [2] http://kib.kiev.ua/x86docs/SDMs/315168-011.pdf (Pre-TrEE MLE Guide) // [3] https://www.intel.com/content/dam/www/public/us/en/documents/guides/intel-txt-software-development-guide.pdf diff --git a/pkg/tpm/tcpa_log.go b/pkg/tpm/tcpa_log.go index 875cdd3..4f867d4 100644 --- a/pkg/tpm/tcpa_log.go +++ b/pkg/tpm/tcpa_log.go @@ -3,6 +3,7 @@ package tpm import ( "bytes" "encoding/binary" + "encoding/json" "errors" "fmt" "io" @@ -456,7 +457,13 @@ func ParseLog(firmware FirmwareType, tpmSpec string) (*PCRLog, error) { return pcrLog, nil } -func DumpLog(tcpaLog *PCRLog) error { +func DumpLog(tcpaLog *PCRLog, jsonDump bool) error { + if jsonDump { + log, err := json.MarshalIndent(tcpaLog, "", " ") + fmt.Println(string(log)) + return err + } + for _, pcr := range tcpaLog.PcrList { fmt.Printf("%s\n", pcr)