github.com/xyproto/u-root@v6.0.1-0.20200302025726-5528e0c77a3c+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 "log" 11 "strings" 12 13 "github.com/9elements/tpmtool/pkg/tpm" 14 "github.com/u-root/u-root/pkg/mount" 15 slaunch "github.com/u-root/u-root/pkg/securelaunch" 16 ) 17 18 /* describes the "eventlog" section of policy file */ 19 type EventLog struct { 20 Type string `json:"type"` 21 Location string `json:"location"` 22 } 23 24 const ( 25 eventLogFile = "/sys/kernel/security/slaunch/eventlog" 26 defaultEventLogFile = "eventlog.txt" //only used if user doesn't provide any 27 ) 28 29 /* 30 * parseEvtlog uses tpmtool package to parse the event logs generated by a 31 * kernel with CONFIG_SECURE_LAUNCH enabled and returns the parsed data in a byte slice. 32 * 33 * these event logs are originally in binary format and need to be parsed into human readable 34 * format. error is returned if parsing code fails in tpmtool. 35 */ 36 func parseEvtLog(evtLogFile string) ([]byte, error) { 37 38 tpm.DefaultTCPABinaryLog = evtLogFile 39 firmware := tpm.Txt 40 TPMSpecVersion := tpm.TPM20 41 tcpaLog, err := tpm.ParseLog(firmware, TPMSpecVersion) 42 if err != nil { 43 return nil, err 44 } 45 46 var w strings.Builder 47 for _, pcr := range tcpaLog.PcrList { 48 fmt.Fprintf(&w, "%s\n", pcr) 49 fmt.Fprintf(&w, "\n") 50 } 51 return []byte(w.String()), nil 52 } 53 54 /* 55 * Persist uses tpmtool to parse event logs generated by the kernel into 56 * human readable format, mounts the target disk and store the result in the file on 57 * target disk. 58 * 59 * The location of the file on disk is specified in policy file by Location tag. 60 * returns 61 * - error if mounting the disk fails __OR_ writing to location on disk fails. 62 */ 63 func (e *EventLog) Persist() error { 64 65 if e.Type != "file" { 66 return fmt.Errorf("unsupported eventlog type exiting") 67 } 68 69 slaunch.Debug("Identified EventLog Type = file") 70 71 // e.Location is of the form sda:path/to/file.txt 72 eventlogPath := e.Location 73 if eventlogPath == "" { 74 return fmt.Errorf("empty eventlog path provided exiting") 75 } 76 77 filePath, mountPath, r := slaunch.GetMountedFilePath(eventlogPath, 0) // 0 is flag value for rw mount option 78 if r != nil { 79 return fmt.Errorf("failed to mount target disk for target=%s, err=%v", eventlogPath, r) 80 } 81 82 dst := filePath // /tmp/boot-733276578/evtlog 83 84 // parse eventlog 85 data, err := parseEvtLog(eventLogFile) 86 if err != nil { 87 log.Printf("tpmtool could NOT parse Eventlogfile=%s, err=%s", eventLogFile, err) 88 if ret := mount.Unmount(mountPath, true, false); ret != nil { 89 log.Printf("Unmount failed. PANIC") 90 panic(ret) 91 } 92 return fmt.Errorf("parseEvtLog err=%v", err) 93 } 94 95 // write parsed data onto disk 96 target, err := slaunch.WriteToFile(data, dst, defaultEventLogFile) 97 if ret := mount.Unmount(mountPath, true, false); ret != nil { 98 log.Printf("Unmount failed. PANIC") 99 panic(ret) 100 } 101 102 if err != nil { 103 log.Printf("EventLog: Write err=%v, dst=%s, exiting", err, dst) 104 return fmt.Errorf("failed to write parsed eventLog to disk, err=%v, dst=%s, exiting", err, dst) 105 } 106 107 slaunch.Debug("EventLog: success, data written to %s", target) 108 return nil 109 }