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 }