github.com/linuxboot/fiano@v1.2.0/pkg/intel/me/me.go (about)

     1  // Copyright 2021 the LinuxBoot 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 me
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"io"
    11  )
    12  
    13  var (
    14  	Signature = [4]byte{0x24, 0x46, 0x50, 0x54}
    15  )
    16  
    17  func parseLegacyFlashPartitionTableHeader(r io.Reader) (*LegacyFlashPartitionTableHeader, error) {
    18  	var header LegacyFlashPartitionTableHeader
    19  	var scrap [12]byte
    20  	if err := binary.Read(r, binary.LittleEndian, &scrap); err != nil {
    21  		return nil, err
    22  	}
    23  	if err := binary.Read(r, binary.LittleEndian, &header.Marker); err != nil {
    24  		return nil, err
    25  	}
    26  	if err := binary.Read(r, binary.LittleEndian, &header.NumFptEntries); err != nil {
    27  		return nil, err
    28  	}
    29  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderVersion); err != nil {
    30  		return nil, err
    31  	}
    32  	if err := binary.Read(r, binary.LittleEndian, &header.EntryVersion); err != nil {
    33  		return nil, err
    34  	}
    35  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderLength); err != nil {
    36  		return nil, err
    37  	}
    38  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderChecksum); err != nil {
    39  		return nil, err
    40  	}
    41  	if err := binary.Read(r, binary.LittleEndian, &header.TicksToAdd); err != nil {
    42  		return nil, err
    43  	}
    44  	if err := binary.Read(r, binary.LittleEndian, &header.TokensToAdd); err != nil {
    45  		return nil, err
    46  	}
    47  	if err := binary.Read(r, binary.LittleEndian, &header.UMASize); err != nil {
    48  		return nil, err
    49  	}
    50  	if err := binary.Read(r, binary.LittleEndian, &header.Flags); err != nil {
    51  		return nil, err
    52  	}
    53  	return &header, nil
    54  
    55  }
    56  
    57  func parseFlashPartitionTableHeader(r io.Reader) (*FlashPartitionTableHeader, error) {
    58  	var header FlashPartitionTableHeader
    59  	// Set Signature
    60  	header.Marker = Signature
    61  
    62  	if err := binary.Read(r, binary.LittleEndian, &header.NumFptEntries); err != nil {
    63  		return nil, err
    64  	}
    65  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderVersion); err != nil {
    66  		return nil, err
    67  	}
    68  	if err := binary.Read(r, binary.LittleEndian, &header.EntryVersion); err != nil {
    69  		return nil, err
    70  	}
    71  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderLength); err != nil {
    72  		return nil, err
    73  	}
    74  	if err := binary.Read(r, binary.LittleEndian, &header.HeaderChecksum); err != nil {
    75  		return nil, err
    76  	}
    77  	if err := binary.Read(r, binary.LittleEndian, &header.TicksToAdd); err != nil {
    78  		return nil, err
    79  	}
    80  	if err := binary.Read(r, binary.LittleEndian, &header.TokensToAdd); err != nil {
    81  		return nil, err
    82  	}
    83  	if err := binary.Read(r, binary.LittleEndian, &header.UMASizeOrReserved); err != nil {
    84  		return nil, err
    85  	}
    86  	if err := binary.Read(r, binary.LittleEndian, &header.FlashLayoutOrFlags); err != nil {
    87  		return nil, err
    88  	}
    89  	if err := binary.Read(r, binary.LittleEndian, &header.FitcMajor); err != nil {
    90  		return nil, err
    91  	}
    92  	if err := binary.Read(r, binary.LittleEndian, &header.FitcMinor); err != nil {
    93  		return nil, err
    94  	}
    95  	if err := binary.Read(r, binary.LittleEndian, &header.FitcHotfix); err != nil {
    96  		return nil, err
    97  	}
    98  	if err := binary.Read(r, binary.LittleEndian, &header.FitcBuild); err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	return &header, nil
   103  }
   104  
   105  func parseEntry(r io.Reader) (*FlashPartitionTableEntry, error) {
   106  	var entry FlashPartitionTableEntry
   107  	if err := binary.Read(r, binary.LittleEndian, &entry); err != nil {
   108  		return nil, err
   109  	}
   110  	return &entry, nil
   111  }
   112  
   113  // ParseIntelFirmware parses the Intel firmware image by uefi.Firmware interface`
   114  func ParseIntelME(r io.Reader) (*IntelME, error) {
   115  	var me IntelME
   116  	me.legacy = false
   117  	var numEntries uint32
   118  
   119  	// Read first 4 byte, we catch the marker as prefix or suffix
   120  	var markerarea [4]byte
   121  	if err := binary.Read(r, binary.LittleEndian, &markerarea); err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	// Check on new header
   126  	if bytes.HasPrefix(markerarea[:], Signature[:]) {
   127  		hdr, err := parseFlashPartitionTableHeader(r)
   128  		if err != nil {
   129  			return nil, err
   130  		}
   131  		me.hdr = hdr
   132  		numEntries = hdr.NumFptEntries
   133  	} else {
   134  		me.legacy = true
   135  		hdr, err := parseLegacyFlashPartitionTableHeader(r)
   136  		if err != nil {
   137  			return nil, err
   138  		}
   139  		me.legacyhdr = hdr
   140  		numEntries = hdr.NumFptEntries
   141  	}
   142  
   143  	partitions := make([]FlashPartitionTableEntry, 0)
   144  	for i := uint32(0); i < numEntries; i++ {
   145  		entry, err := parseEntry(r)
   146  		if err != nil {
   147  			return nil, err
   148  		}
   149  		partitions = append(partitions, *entry)
   150  	}
   151  	me.partitions = partitions
   152  	return &me, nil
   153  }