github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/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/mvdan/u-root-coreutils/pkg/securelaunch"
    16  	tss "github.com/mvdan/u-root-coreutils/pkg/tss"
    17  	txtlog "github.com/mvdan/u-root-coreutils/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  var eventLogPath string
    32  
    33  // Add writes event logs to sysfs file.
    34  func Add(b []byte) error {
    35  	fd, err := os.OpenFile(eventLogFile, os.O_WRONLY, 0o644)
    36  	if err != nil {
    37  		return err
    38  	}
    39  
    40  	defer fd.Close()
    41  	_, err = fd.Write(b)
    42  	if err != nil && err != io.EOF {
    43  		return err
    44  	}
    45  	slaunch.Debug("err = %v", err)
    46  	return nil
    47  }
    48  
    49  // ParseEventlog uses the tpmtool package to parse the event logs generated by a
    50  // kernel with CONFIG_SECURE_LAUNCH enabled and and queues the data to persist queue.
    51  //
    52  // These event logs are originally in binary format and need to be parsed into human readable
    53  // format. An error is returned if parsing code fails in tpmtool.
    54  func ParseEventLog() error {
    55  	txtlog.DefaultTCPABinaryLog = eventLogFile
    56  	firmware := txtlog.Txt
    57  	tpmSpecVersion := tss.TPMVersion20
    58  
    59  	tcpaLog, err := txtlog.ParseLog(firmware, tpmSpecVersion)
    60  	if err != nil {
    61  		log.Printf("eventlog: ERR: could not parse eventlog file '%s': %v", eventLogFile, err)
    62  		return fmt.Errorf("could not parse eventlog file '%s': %v", eventLogFile, err)
    63  	}
    64  
    65  	var dataStr strings.Builder
    66  	for _, pcr := range tcpaLog.PcrList {
    67  		fmt.Fprintf(&dataStr, "%s\n", pcr)
    68  		fmt.Fprintf(&dataStr, "\n")
    69  	}
    70  
    71  	data := []byte(dataStr.String())
    72  
    73  	return slaunch.AddToPersistQueue("EventLog:", data, eventLogPath, defaultEventLogFile)
    74  }
    75  
    76  // Parse parses the eventlog section of the policy file.
    77  //
    78  // The location of the file on disk is specified in the policy file by the Location tag.
    79  // An error is returned if parsing fails or an incorrect value or format is used.
    80  func (e *EventLog) Parse() error {
    81  	if e.Type != "file" {
    82  		return fmt.Errorf("unsupported eventlog type")
    83  	}
    84  
    85  	slaunch.Debug("Identified EventLog Type = file")
    86  
    87  	// e.Location is of the form sda:path/to/file.txt
    88  	eventLogPath = e.Location
    89  	if eventLogPath == "" {
    90  		return fmt.Errorf("empty eventlog path provided")
    91  	}
    92  
    93  	return nil
    94  }