github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/bg/bgbootpolicy/manifest_manifestcodegen.go (about)

     1  // Copyright 2017-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  //go:build !manifestcodegen
     6  // +build !manifestcodegen
     7  
     8  // Code generated by "menifestcodegen". DO NOT EDIT.
     9  // To reproduce: go run github.com/linuxboot/fiano/pkg/intel/metadata/common/manifestcodegen/cmd/manifestcodegen -package bg github.com/linuxboot/fiano/pkg/intel/metadata/bg/bgbootpolicy
    10  
    11  package bgbootpolicy
    12  
    13  import (
    14  	"encoding/binary"
    15  	"fmt"
    16  	"io"
    17  	"strings"
    18  
    19  	"github.com/linuxboot/fiano/pkg/intel/metadata/bg"
    20  	"github.com/linuxboot/fiano/pkg/intel/metadata/common/pretty"
    21  )
    22  
    23  var (
    24  	// Just to avoid errors in "import" above in case if it wasn't used below
    25  	_ = binary.LittleEndian
    26  	_ = (fmt.Stringer)(nil)
    27  	_ = (io.Reader)(nil)
    28  	_ = pretty.Header
    29  	_ = strings.Join
    30  	_ = bg.StructInfo{}
    31  )
    32  
    33  // NewManifest returns a new instance of Manifest with
    34  // all default values set.
    35  func NewManifest() *Manifest {
    36  	s := &Manifest{}
    37  	// Recursively initializing a child structure:
    38  	s.BPMH = *NewBPMH()
    39  	// Recursively initializing a child structure:
    40  	s.PMSE = *NewSignature()
    41  	s.Rehash()
    42  	return s
    43  }
    44  
    45  // Validate (recursively) checks the structure if there are any unexpected
    46  // values. It returns an error if so.
    47  func (s *Manifest) Validate() error {
    48  	// Recursively validating a child structure:
    49  	if err := s.BPMH.Validate(); err != nil {
    50  		return fmt.Errorf("error on field 'BPMH': %w", err)
    51  	}
    52  	// See tag "rehashValue"
    53  	{
    54  		expectedValue := BPMH(s.rehashedBPMH())
    55  		if s.BPMH != expectedValue {
    56  			return fmt.Errorf("field 'BPMH' expects write-value '%v', but has %v", expectedValue, s.BPMH)
    57  		}
    58  	}
    59  	// Recursively validating a child structure:
    60  	if err := s.PMSE.Validate(); err != nil {
    61  		return fmt.Errorf("error on field 'PMSE': %w", err)
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  // fieldIndexByStructID returns the position index within
    68  // structure Manifest of the field by its StructureID
    69  // (see document #575623, an example of StructureID value is "__KEYM__").
    70  func (_ Manifest) fieldIndexByStructID(structID string) int {
    71  	switch structID {
    72  	case StructureIDBPMH:
    73  		return 0
    74  	case StructureIDSE:
    75  		return 1
    76  	case StructureIDPM:
    77  		return 2
    78  	case StructureIDSignature:
    79  		return 3
    80  	}
    81  
    82  	return -1
    83  }
    84  
    85  // fieldNameByIndex returns the name of the field by its position number
    86  // within structure Manifest.
    87  func (_ Manifest) fieldNameByIndex(fieldIndex int) string {
    88  	switch fieldIndex {
    89  	case 0:
    90  		return "BPMH"
    91  	case 1:
    92  		return "SE"
    93  	case 2:
    94  		return "PME"
    95  	case 3:
    96  		return "PMSE"
    97  	}
    98  
    99  	return fmt.Sprintf("invalidFieldIndex_%d", fieldIndex)
   100  }
   101  
   102  // ReadFrom reads the Manifest from 'r' in format defined in the document #575623.
   103  func (s *Manifest) ReadFrom(r io.Reader) (returnN int64, returnErr error) {
   104  	var missingFieldsByIndices = [4]bool{
   105  		0: true,
   106  		3: true,
   107  	}
   108  	defer func() {
   109  		if returnErr != nil {
   110  			return
   111  		}
   112  		for fieldIndex, v := range missingFieldsByIndices {
   113  			if v {
   114  				returnErr = fmt.Errorf("field '%s' is missing", s.fieldNameByIndex(fieldIndex))
   115  				break
   116  			}
   117  		}
   118  	}()
   119  	var totalN int64
   120  	previousFieldIndex := int(-1)
   121  	for {
   122  		var structInfo bg.StructInfo
   123  		err := binary.Read(r, binary.LittleEndian, &structInfo)
   124  		if err == io.EOF || err == io.ErrUnexpectedEOF {
   125  			return totalN, nil
   126  		}
   127  		if err != nil {
   128  			return totalN, fmt.Errorf("unable to read structure info at %d: %w", totalN, err)
   129  		}
   130  		totalN += int64(binary.Size(structInfo))
   131  
   132  		structID := structInfo.ID.String()
   133  		fieldIndex := s.fieldIndexByStructID(structID)
   134  		if fieldIndex < 0 {
   135  			// TODO: report error "unknown structure ID: '"+structID+"'"
   136  			continue
   137  		}
   138  		if bg.StrictOrderCheck && fieldIndex < previousFieldIndex {
   139  			return totalN, fmt.Errorf("invalid order of fields (%d < %d): structure '%s' is out of order", fieldIndex, previousFieldIndex, structID)
   140  		}
   141  		missingFieldsByIndices[fieldIndex] = false
   142  
   143  		var n int64
   144  		switch structID {
   145  		case StructureIDBPMH:
   146  			if fieldIndex == previousFieldIndex {
   147  				return totalN, fmt.Errorf("field 'BPMH' is not a slice, but multiple elements found")
   148  			}
   149  			s.BPMH.SetStructInfo(structInfo)
   150  			n, err = s.BPMH.ReadDataFrom(r)
   151  			if err != nil {
   152  				return totalN, fmt.Errorf("unable to read field BPMH at %d: %w", totalN, err)
   153  			}
   154  		case StructureIDSE:
   155  			var el SE
   156  			el.SetStructInfo(structInfo)
   157  			n, err = el.ReadDataFrom(r)
   158  			s.SE = append(s.SE, el)
   159  			if err != nil {
   160  				return totalN, fmt.Errorf("unable to read field SE at %d: %w", totalN, err)
   161  			}
   162  		case StructureIDPM:
   163  			if fieldIndex == previousFieldIndex {
   164  				return totalN, fmt.Errorf("field 'PME' is not a slice, but multiple elements found")
   165  			}
   166  			s.PME = &PM{}
   167  			s.PME.SetStructInfo(structInfo)
   168  			n, err = s.PME.ReadDataFrom(r)
   169  			if err != nil {
   170  				return totalN, fmt.Errorf("unable to read field PME at %d: %w", totalN, err)
   171  			}
   172  		case StructureIDSignature:
   173  			if fieldIndex == previousFieldIndex {
   174  				return totalN, fmt.Errorf("field 'PMSE' is not a slice, but multiple elements found")
   175  			}
   176  			s.PMSE.SetStructInfo(structInfo)
   177  			n, err = s.PMSE.ReadDataFrom(r)
   178  			if err != nil {
   179  				return totalN, fmt.Errorf("unable to read field PMSE at %d: %w", totalN, err)
   180  			}
   181  		default:
   182  			return totalN, fmt.Errorf("there is no field with structure ID '%s' in Manifest", structInfo.ID)
   183  		}
   184  		totalN += n
   185  		previousFieldIndex = fieldIndex
   186  	}
   187  }
   188  
   189  // RehashRecursive calls Rehash (see below) recursively.
   190  func (s *Manifest) RehashRecursive() {
   191  	s.BPMH.Rehash()
   192  	if s.PME != nil {
   193  		s.PME.Rehash()
   194  	}
   195  	s.PMSE.Rehash()
   196  	s.Rehash()
   197  }
   198  
   199  // Rehash sets values which are calculated automatically depending on the rest
   200  // data. It is usually about the total size field of an element.
   201  func (s *Manifest) Rehash() {
   202  	s.BPMH = BPMH(s.rehashedBPMH())
   203  }
   204  
   205  // WriteTo writes the Manifest into 'w' in format defined in
   206  // the document #575623.
   207  func (s *Manifest) WriteTo(w io.Writer) (int64, error) {
   208  	totalN := int64(0)
   209  	s.Rehash()
   210  
   211  	// BPMH (ManifestFieldType: element)
   212  	{
   213  		n, err := s.BPMH.WriteTo(w)
   214  		if err != nil {
   215  			return totalN, fmt.Errorf("unable to write field 'BPMH': %w", err)
   216  		}
   217  		totalN += int64(n)
   218  	}
   219  
   220  	// SE (ManifestFieldType: elementList)
   221  	{
   222  		for idx := range s.SE {
   223  			n, err := s.SE[idx].WriteTo(w)
   224  			if err != nil {
   225  				return totalN, fmt.Errorf("unable to write field 'SE[%d]': %w", idx, err)
   226  			}
   227  			totalN += int64(n)
   228  		}
   229  	}
   230  
   231  	// PME (ManifestFieldType: element)
   232  	if s.PME != nil {
   233  		n, err := s.PME.WriteTo(w)
   234  		if err != nil {
   235  			return totalN, fmt.Errorf("unable to write field 'PME': %w", err)
   236  		}
   237  		totalN += int64(n)
   238  	}
   239  
   240  	// PMSE (ManifestFieldType: element)
   241  	{
   242  		n, err := s.PMSE.WriteTo(w)
   243  		if err != nil {
   244  			return totalN, fmt.Errorf("unable to write field 'PMSE': %w", err)
   245  		}
   246  		totalN += int64(n)
   247  	}
   248  
   249  	return totalN, nil
   250  }
   251  
   252  // BPMHSize returns the size in bytes of the value of field BPMH
   253  func (s *Manifest) BPMHTotalSize() uint64 {
   254  	return s.BPMH.TotalSize()
   255  }
   256  
   257  // SESize returns the size in bytes of the value of field SE
   258  func (s *Manifest) SETotalSize() uint64 {
   259  	var size uint64
   260  	for idx := range s.SE {
   261  		size += s.SE[idx].TotalSize()
   262  	}
   263  	return size
   264  }
   265  
   266  // PMESize returns the size in bytes of the value of field PME
   267  func (s *Manifest) PMETotalSize() uint64 {
   268  	return s.PME.TotalSize()
   269  }
   270  
   271  // PMSESize returns the size in bytes of the value of field PMSE
   272  func (s *Manifest) PMSETotalSize() uint64 {
   273  	return s.PMSE.TotalSize()
   274  }
   275  
   276  // BPMHOffset returns the offset in bytes of field BPMH
   277  func (s *Manifest) BPMHOffset() uint64 {
   278  	return 0
   279  }
   280  
   281  // SEOffset returns the offset in bytes of field SE
   282  func (s *Manifest) SEOffset() uint64 {
   283  	return s.BPMHOffset() + s.BPMHTotalSize()
   284  }
   285  
   286  // PMEOffset returns the offset in bytes of field PME
   287  func (s *Manifest) PMEOffset() uint64 {
   288  	return s.SEOffset() + s.SETotalSize()
   289  }
   290  
   291  // PMSEOffset returns the offset in bytes of field PMSE
   292  func (s *Manifest) PMSEOffset() uint64 {
   293  	return s.PMEOffset() + s.PMETotalSize()
   294  }
   295  
   296  // Size returns the total size of the Manifest.
   297  func (s *Manifest) TotalSize() uint64 {
   298  	if s == nil {
   299  		return 0
   300  	}
   301  
   302  	var size uint64
   303  	size += s.BPMHTotalSize()
   304  	size += s.SETotalSize()
   305  	size += s.PMETotalSize()
   306  	size += s.PMSETotalSize()
   307  	return size
   308  }
   309  
   310  // PrettyString returns the content of the structure in an easy-to-read format.
   311  func (s *Manifest) PrettyString(depth uint, withHeader bool, opts ...pretty.Option) string {
   312  	var lines []string
   313  	if withHeader {
   314  		lines = append(lines, pretty.Header(depth, "Boot Policy Manifest", s))
   315  	}
   316  	if s == nil {
   317  		return strings.Join(lines, "\n")
   318  	}
   319  	// ManifestFieldType is element
   320  	lines = append(lines, pretty.SubValue(depth+1, "BPMH: Header", "", &s.BPMH, opts...)...)
   321  	// ManifestFieldType is elementList
   322  	lines = append(lines, pretty.Header(depth+1, fmt.Sprintf("SE: Array of \"Boot Policy Manifest\" of length %d", len(s.SE)), s.SE))
   323  	for i := 0; i < len(s.SE); i++ {
   324  		lines = append(lines, fmt.Sprintf("%sitem #%d: ", strings.Repeat("  ", int(depth+2)), i)+strings.TrimSpace(s.SE[i].PrettyString(depth+2, true)))
   325  	}
   326  	if depth < 1 {
   327  		lines = append(lines, "")
   328  	}
   329  	// ManifestFieldType is element
   330  	lines = append(lines, pretty.SubValue(depth+1, "PME: Platform Manufacturer", "", s.PME, opts...)...)
   331  	// ManifestFieldType is element
   332  	lines = append(lines, pretty.SubValue(depth+1, "PMSE: Signature", "", &s.PMSE, opts...)...)
   333  	if depth < 2 {
   334  		lines = append(lines, "")
   335  	}
   336  	return strings.Join(lines, "\n")
   337  }