github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/txtlog/pcr_event.go (about)

     1  // Copyright 2020 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  package txtlog
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/binary"
     9  	"errors"
    10  	"fmt"
    11  	"io"
    12  	"strings"
    13  )
    14  
    15  func parseTcgBiosSpecIDEvent(handle io.Reader) (*TcgBiosSpecIDEvent, error) {
    16  	var endianess binary.ByteOrder = binary.LittleEndian
    17  	var biosSpecEvent TcgBiosSpecIDEvent
    18  
    19  	if err := binary.Read(handle, endianess, &biosSpecEvent.signature); err != nil {
    20  		return nil, err
    21  	}
    22  
    23  	identifier := string(bytes.Trim(biosSpecEvent.signature[:], "\x00"))
    24  	if string(identifier) != TCGOldEfiFormatID {
    25  		return nil, nil
    26  	}
    27  
    28  	if err := binary.Read(handle, endianess, &biosSpecEvent.platformClass); err != nil {
    29  		return nil, err
    30  	}
    31  
    32  	if err := binary.Read(handle, endianess, &biosSpecEvent.specVersionMinor); err != nil {
    33  		return nil, err
    34  	}
    35  
    36  	if err := binary.Read(handle, endianess, &biosSpecEvent.specVersionMajor); err != nil {
    37  		return nil, err
    38  	}
    39  
    40  	if err := binary.Read(handle, endianess, &biosSpecEvent.specErrata); err != nil {
    41  		return nil, err
    42  	}
    43  
    44  	if err := binary.Read(handle, endianess, &biosSpecEvent.uintnSize); err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	if err := binary.Read(handle, endianess, &biosSpecEvent.vendorInfoSize); err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	biosSpecEvent.vendorInfo = make([]byte, biosSpecEvent.vendorInfoSize)
    53  	if err := binary.Read(handle, endianess, &biosSpecEvent.vendorInfo); err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	return &biosSpecEvent, nil
    58  }
    59  
    60  func parseEfiSpecEvent(handle io.Reader) (*TcgEfiSpecIDEvent, error) {
    61  	var endianess binary.ByteOrder = binary.LittleEndian
    62  	var efiSpecEvent TcgEfiSpecIDEvent
    63  
    64  	if err := binary.Read(handle, endianess, &efiSpecEvent.signature); err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	identifier := string(bytes.Trim(efiSpecEvent.signature[:], "\x00"))
    69  	if string(identifier) != TCGAgileEventFormatID {
    70  		return nil, nil
    71  	}
    72  
    73  	if err := binary.Read(handle, endianess, &efiSpecEvent.platformClass); err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	if err := binary.Read(handle, endianess, &efiSpecEvent.specVersionMinor); err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	if err := binary.Read(handle, endianess, &efiSpecEvent.specVersionMajor); err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	if err := binary.Read(handle, endianess, &efiSpecEvent.specErrata); err != nil {
    86  		return nil, err
    87  	}
    88  
    89  	if err := binary.Read(handle, endianess, &efiSpecEvent.uintnSize); err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	if err := binary.Read(handle, endianess, &efiSpecEvent.numberOfAlgorithms); err != nil {
    94  		return nil, err
    95  	}
    96  
    97  	efiSpecEvent.digestSizes = make([]TcgEfiSpecIDEventAlgorithmSize, efiSpecEvent.numberOfAlgorithms)
    98  	for i := uint32(0); i < efiSpecEvent.numberOfAlgorithms; i++ {
    99  		if err := binary.Read(handle, endianess, &efiSpecEvent.digestSizes[i].algorithID); err != nil {
   100  			return nil, err
   101  		}
   102  		if err := binary.Read(handle, endianess, &efiSpecEvent.digestSizes[i].digestSize); err != nil {
   103  			return nil, err
   104  		}
   105  	}
   106  
   107  	if err := binary.Read(handle, endianess, &efiSpecEvent.vendorInfoSize); err != nil {
   108  		return nil, err
   109  	}
   110  
   111  	efiSpecEvent.vendorInfo = make([]byte, efiSpecEvent.vendorInfoSize)
   112  	if err := binary.Read(handle, endianess, &efiSpecEvent.vendorInfo); err != nil {
   113  		return nil, err
   114  	}
   115  
   116  	return &efiSpecEvent, nil
   117  }
   118  
   119  // TcgPcrEvent parser and PCREvent interface implementation
   120  func parseTcgPcrEvent(handle io.Reader) (*TcgPcrEvent, error) {
   121  	var endianess binary.ByteOrder = binary.LittleEndian
   122  	var pcrEvent TcgPcrEvent
   123  
   124  	if err := binary.Read(handle, endianess, &pcrEvent.pcrIndex); err != nil {
   125  		return nil, err
   126  	}
   127  	if err := binary.Read(handle, endianess, &pcrEvent.eventType); err != nil {
   128  		return nil, err
   129  	}
   130  	if err := binary.Read(handle, endianess, &pcrEvent.digest); err != nil {
   131  		return nil, err
   132  	}
   133  	if err := binary.Read(handle, endianess, &pcrEvent.eventSize); err != nil {
   134  		return nil, err
   135  	}
   136  
   137  	pcrEvent.event = make([]byte, pcrEvent.eventSize)
   138  	if err := binary.Read(handle, endianess, &pcrEvent.event); err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	return &pcrEvent, nil
   143  }
   144  
   145  func (e *TcgPcrEvent) PcrIndex() int {
   146  	return int(e.pcrIndex)
   147  }
   148  
   149  func (e *TcgPcrEvent) PcrEventType() uint32 {
   150  	return e.eventType
   151  }
   152  
   153  func (e *TcgPcrEvent) PcrEventName() string {
   154  	if BIOSLogTypes[BIOSLogID(e.eventType)] != "" {
   155  		return BIOSLogTypes[BIOSLogID(e.eventType)]
   156  	}
   157  	if EFILogTypes[EFILogID(e.eventType)] != "" {
   158  		return EFILogTypes[EFILogID(e.eventType)]
   159  	}
   160  	if TxtLogTypes[TxtLogID(e.eventType)] != "" {
   161  		return TxtLogTypes[TxtLogID(e.eventType)]
   162  	}
   163  
   164  	return ""
   165  }
   166  
   167  func (e *TcgPcrEvent) PcrEventData() string {
   168  	if BIOSLogID(e.eventType) == EvNoAction {
   169  		return string(e.event)
   170  	}
   171  
   172  	eventDataString, _ := getEventDataString(e.eventType, e.event)
   173  	if eventDataString != nil {
   174  		return *eventDataString
   175  	}
   176  
   177  	return ""
   178  }
   179  
   180  func (e *TcgPcrEvent) Digests() *[]PCRDigestValue {
   181  	d := make([]PCRDigestValue, 1)
   182  	d[0].DigestAlg = TPMAlgSha
   183  	d[0].Digest = make([]byte, TPMAlgShaSize)
   184  	copy(d[0].Digest, e.digest[:])
   185  
   186  	return &d
   187  }
   188  
   189  func (e *TcgPcrEvent) String() string {
   190  	var b strings.Builder
   191  
   192  	fmt.Fprintf(&b, "PCR: %d\n", e.PcrIndex())
   193  	fmt.Fprintf(&b, "Event Name: %s\n", e.PcrEventName())
   194  	fmt.Fprintf(&b, "Event Data: %s\n", stripControlSequences(e.PcrEventData()))
   195  	fmt.Fprintf(&b, "SHA1 Digest: %x", e.digest)
   196  
   197  	return b.String()
   198  }
   199  
   200  // TcgPcrEvent2 parser and PCREvent interface implementation
   201  func parseTcgPcrEvent2(handle io.Reader) (*TcgPcrEvent2, error) {
   202  	var endianess binary.ByteOrder = binary.LittleEndian
   203  	var pcrEvent TcgPcrEvent2
   204  
   205  	if err := binary.Read(handle, endianess, &pcrEvent.pcrIndex); err != nil {
   206  		return nil, err
   207  	}
   208  	if err := binary.Read(handle, endianess, &pcrEvent.eventType); err != nil {
   209  		return nil, err
   210  	}
   211  	if err := binary.Read(handle, endianess, &pcrEvent.digests.count); err != nil {
   212  		return nil, err
   213  	}
   214  
   215  	pcrEvent.digests.digests = make([]THA, pcrEvent.digests.count)
   216  	for i := uint32(0); i < pcrEvent.digests.count; i++ {
   217  		if err := binary.Read(handle, endianess, &pcrEvent.digests.digests[i].hashAlg); err != nil {
   218  			return nil, err
   219  		}
   220  
   221  		pcrEvent.digests.digests[i].digest.hash = make([]byte, HashAlgoToSize[pcrEvent.digests.digests[i].hashAlg])
   222  		if err := binary.Read(handle, endianess, &pcrEvent.digests.digests[i].digest.hash); err != nil {
   223  			return nil, err
   224  		}
   225  	}
   226  
   227  	if err := binary.Read(handle, endianess, &pcrEvent.eventSize); err != nil {
   228  		return nil, err
   229  	}
   230  
   231  	pcrEvent.event = make([]byte, pcrEvent.eventSize)
   232  	if err := binary.Read(handle, endianess, &pcrEvent.event); err != nil {
   233  		return nil, err
   234  	}
   235  
   236  	return &pcrEvent, nil
   237  }
   238  
   239  func (e *TcgPcrEvent2) PcrIndex() int {
   240  	return int(e.pcrIndex)
   241  }
   242  
   243  func (e *TcgPcrEvent2) PcrEventType() uint32 {
   244  	return e.eventType
   245  }
   246  
   247  func (e *TcgPcrEvent2) PcrEventName() string {
   248  	if BIOSLogTypes[BIOSLogID(e.eventType)] != "" {
   249  		return BIOSLogTypes[BIOSLogID(e.eventType)]
   250  	}
   251  	if EFILogTypes[EFILogID(e.eventType)] != "" {
   252  		return EFILogTypes[EFILogID(e.eventType)]
   253  	}
   254  	if TxtLogTypes[TxtLogID(e.eventType)] != "" {
   255  		return TxtLogTypes[TxtLogID(e.eventType)]
   256  	}
   257  
   258  	return ""
   259  }
   260  
   261  func (e *TcgPcrEvent2) PcrEventData() string {
   262  	if BIOSLogID(e.eventType) == EvNoAction {
   263  		return string(e.event)
   264  	}
   265  	eventDataString, _ := getEventDataString(e.eventType, e.event)
   266  	if eventDataString != nil {
   267  		return *eventDataString
   268  	}
   269  
   270  	return ""
   271  }
   272  
   273  func (e *TcgPcrEvent2) Digests() *[]PCRDigestValue {
   274  	d := make([]PCRDigestValue, e.digests.count)
   275  	for i := uint32(0); i < e.digests.count; i++ {
   276  		d[i].DigestAlg = e.digests.digests[i].hashAlg
   277  		d[i].Digest = make([]byte, HashAlgoToSize[e.digests.digests[i].hashAlg])
   278  		copy(d[i].Digest, e.digests.digests[i].digest.hash)
   279  	}
   280  	return &d
   281  }
   282  
   283  func (e *TcgPcrEvent2) String() string {
   284  	var b strings.Builder
   285  
   286  	fmt.Fprintf(&b, "PCR: %d\n", e.PcrIndex())
   287  	fmt.Fprintf(&b, "Event Name: %s\n", e.PcrEventName())
   288  	fmt.Fprintf(&b, "Event Data: %s\n", stripControlSequences(e.PcrEventData()))
   289  	for i := uint32(0); i < e.digests.count; i++ {
   290  		d := &e.digests.digests[i]
   291  		switch d.hashAlg {
   292  		case TPMAlgSha:
   293  			b.WriteString("SHA1 Digest: ")
   294  		case TPMAlgSha256:
   295  			b.WriteString("SHA256 Digest: ")
   296  		case TPMAlgSha384:
   297  			b.WriteString("SHA384 Digest: ")
   298  		case TPMAlgSha512:
   299  			b.WriteString("SHA512 Digest: ")
   300  		case TPMAlgSm3s256:
   301  			b.WriteString("SM3 Digest: ")
   302  		}
   303  
   304  		fmt.Fprintf(&b, "%x\n", d.digest.hash)
   305  	}
   306  
   307  	return b.String()
   308  }
   309  
   310  func readTxtEventLogContainer(handle io.Reader) (*TxtEventLogContainer, error) {
   311  	var container TxtEventLogContainer
   312  
   313  	if err := binary.Read(handle, binary.LittleEndian, &container.Signature); err != nil {
   314  		return nil, err
   315  	}
   316  	if err := binary.Read(handle, binary.LittleEndian, &container.Reserved); err != nil {
   317  		return nil, err
   318  	}
   319  	if err := binary.Read(handle, binary.LittleEndian, &container.ContainerVerMajor); err != nil {
   320  		return nil, err
   321  	}
   322  	if err := binary.Read(handle, binary.LittleEndian, &container.ContainerVerMinor); err != nil {
   323  		return nil, err
   324  	}
   325  	if err := binary.Read(handle, binary.LittleEndian, &container.PcrEventVerMajor); err != nil {
   326  		return nil, err
   327  	}
   328  	if err := binary.Read(handle, binary.LittleEndian, &container.PcrEventVerMinor); err != nil {
   329  		return nil, err
   330  	}
   331  	if err := binary.Read(handle, binary.LittleEndian, &container.Size); err != nil {
   332  		return nil, err
   333  	}
   334  	if err := binary.Read(handle, binary.LittleEndian, &container.PcrEventsOffset); err != nil {
   335  		return nil, err
   336  	}
   337  	if err := binary.Read(handle, binary.LittleEndian, &container.NextEventOffset); err != nil {
   338  		return nil, err
   339  	}
   340  
   341  	return &container, nil
   342  }
   343  
   344  func getEventDataString(eventType uint32, eventData []byte) (*string, error) {
   345  	if eventType < uint32(EvEFIEventBase) {
   346  		switch BIOSLogID(eventType) {
   347  		case EvSeparator:
   348  			eventInfo := fmt.Sprintf("%x", eventData)
   349  			return &eventInfo, nil
   350  		case EvAction:
   351  			eventInfo := string(bytes.Trim(eventData, "\x00"))
   352  			return &eventInfo, nil
   353  		case EvOmitBootDeviceEvents:
   354  			eventInfo := string("BOOT ATTEMPTS OMITTED")
   355  			return &eventInfo, nil
   356  		case EvPostCode:
   357  			eventInfo := string(bytes.Trim(eventData, "\x00"))
   358  			return &eventInfo, nil
   359  		case EvEventTag:
   360  			eventInfo, err := getTaggedEvent(eventData)
   361  			if err != nil {
   362  				return nil, err
   363  			}
   364  			return eventInfo, nil
   365  		case EvSCRTMContents:
   366  			eventInfo := string(bytes.Trim(eventData, "\x00"))
   367  			return &eventInfo, nil
   368  		case EvIPL:
   369  			eventInfo := string(bytes.Trim(eventData, "\x00"))
   370  			return &eventInfo, nil
   371  		}
   372  	} else {
   373  		switch EFILogID(eventType) {
   374  		case EvEFIHCRTMEvent:
   375  			eventInfo := "HCRTM"
   376  			return &eventInfo, nil
   377  		case EvEFIAction:
   378  			eventInfo := string(bytes.Trim(eventData, "\x00"))
   379  			return &eventInfo, nil
   380  		case EvEFIVariableDriverConfig, EvEFIVariableBoot, EvEFIVariableAuthority:
   381  			eventInfo, err := getVariableDataString(eventData)
   382  			if err != nil {
   383  				return nil, err
   384  			}
   385  			return eventInfo, nil
   386  		case EvEFIRuntimeServicesDriver, EvEFIBootServicesDriver, EvEFIBootServicesApplication:
   387  			eventInfo, err := getImageLoadEventString(eventData)
   388  			if err != nil {
   389  				return nil, err
   390  			}
   391  			return eventInfo, nil
   392  		case EvEFIGPTEvent:
   393  			eventInfo, err := getGPTEventString(eventData)
   394  			if err != nil {
   395  				return nil, err
   396  			}
   397  			return eventInfo, nil
   398  		case EvEFIPlatformFirmwareBlob:
   399  			eventInfo, err := getPlatformFirmwareBlob(eventData)
   400  			if err != nil {
   401  				return nil, err
   402  			}
   403  			return eventInfo, nil
   404  		case EvEFIHandoffTables:
   405  			eventInfo, err := getHandoffTablePointers(eventData)
   406  			if err != nil {
   407  				return nil, err
   408  			}
   409  			return eventInfo, nil
   410  		}
   411  	}
   412  
   413  	eventInfo := string(bytes.Trim(eventData, "\x00"))
   414  	return &eventInfo, errors.New("Event type couldn't get parsed")
   415  }
   416  
   417  func stripControlSequences(str string) string {
   418  	b := make([]byte, len(str))
   419  	var bl int
   420  	for i := 0; i < len(str); i++ {
   421  		c := str[i]
   422  		if c >= 32 && c < 127 {
   423  			b[bl] = c
   424  			bl++
   425  		}
   426  	}
   427  	return string(b[:bl])
   428  }