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  }