github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/securelaunch/eventlog/eventlog.go (about) 1 // Copyright 2019 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package eventlog parses kernel event logs and saves the parsed data on a file on disk. 6 package eventlog 7 8 import ( 9 "fmt" 10 "io" 11 "log" 12 "os" 13 "strings" 14 15 slaunch "github.com/u-root/u-root/pkg/securelaunch" 16 tss "github.com/u-root/u-root/pkg/tss" 17 txtlog "github.com/u-root/u-root/pkg/txtlog" 18 ) 19 20 // EventLog stores location for dumping event logs on disk. 21 type EventLog struct { 22 Type string `json:"type"` 23 Location string `json:"location"` 24 } 25 26 const ( 27 eventLogFile = "/sys/kernel/security/slaunch/eventlog" 28 defaultEventLogFile = "eventlog.txt" //only used if user doesn't provide any 29 ) 30 31 // Add writes event logs to sysfs file. 32 func Add(b []byte) error { 33 fd, err := os.OpenFile(eventLogFile, os.O_WRONLY, 0644) 34 if err != nil { 35 return err 36 } 37 38 defer fd.Close() 39 _, err = fd.Write(b) 40 if err != nil && err != io.EOF { 41 return err 42 } 43 slaunch.Debug("err = %v", err) 44 return nil 45 } 46 47 /* 48 * parseEvtlog uses tpmtool package to parse the event logs generated by a 49 * kernel with CONFIG_SECURE_LAUNCH enabled and returns the parsed data in a byte slice. 50 * 51 * these event logs are originally in binary format and need to be parsed into human readable 52 * format. error is returned if parsing code fails in tpmtool. 53 */ 54 func parseEvtLog(evtLogFile string) ([]byte, error) { 55 txtlog.DefaultTCPABinaryLog = evtLogFile 56 firmware := txtlog.Txt 57 TPMSpecVersion := tss.TPMVersion20 58 tcpaLog, err := txtlog.ParseLog(firmware, TPMSpecVersion) 59 if err != nil { 60 return nil, err 61 } 62 63 var w strings.Builder 64 for _, pcr := range tcpaLog.PcrList { 65 fmt.Fprintf(&w, "%s\n", pcr) 66 fmt.Fprintf(&w, "\n") 67 } 68 return []byte(w.String()), nil 69 } 70 71 // Parse uses tpmtool to parse event logs generated by the kernel into 72 // human readable format, and queues the data to persist queue . 73 // 74 // The location of the file on disk is specified in policy file by Location tag. 75 // returns 76 // - error if parsing eventlog fails or user enters incorrect format for input. 77 func (e *EventLog) Parse() error { 78 if e.Type != "file" { 79 return fmt.Errorf("unsupported eventlog type exiting") 80 } 81 82 slaunch.Debug("Identified EventLog Type = file") 83 84 // e.Location is of the form sda:path/to/file.txt 85 eventlogPath := e.Location 86 if eventlogPath == "" { 87 return fmt.Errorf("empty eventlog path provided exiting") 88 } 89 90 // parse eventlog 91 data, err := parseEvtLog(eventLogFile) 92 if err != nil { 93 log.Printf("tpmtool could NOT parse Eventlogfile=%s, err=%s", eventLogFile, err) 94 return fmt.Errorf("parseEvtLog err=%v", err) 95 } 96 97 return slaunch.AddToPersistQueue("EventLog:", data, eventlogPath, defaultEventLogFile) 98 }