github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/cbnt/cbntbootpolicy/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 github.com/linuxboot/fiano/pkg/intel/metadata/cbnt/cbntbootpolicy
    10  
    11  package cbntbootpolicy
    12  
    13  import (
    14  	"encoding/binary"
    15  	"fmt"
    16  	"io"
    17  	"strings"
    18  
    19  	"github.com/linuxboot/fiano/pkg/intel/metadata/cbnt"
    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  	_ = cbnt.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 StructureIDTXT:
    77  		return 2
    78  	case StructureIDReserved:
    79  		return 3
    80  	case StructureIDPCD:
    81  		return 4
    82  	case StructureIDPM:
    83  		return 5
    84  	case StructureIDSignature:
    85  		return 6
    86  	}
    87  
    88  	return -1
    89  }
    90  
    91  // fieldNameByIndex returns the name of the field by its position number
    92  // within structure Manifest.
    93  func (_ Manifest) fieldNameByIndex(fieldIndex int) string {
    94  	switch fieldIndex {
    95  	case 0:
    96  		return "BPMH"
    97  	case 1:
    98  		return "SE"
    99  	case 2:
   100  		return "TXTE"
   101  	case 3:
   102  		return "Res"
   103  	case 4:
   104  		return "PCDE"
   105  	case 5:
   106  		return "PME"
   107  	case 6:
   108  		return "PMSE"
   109  	}
   110  
   111  	return fmt.Sprintf("invalidFieldIndex_%d", fieldIndex)
   112  }
   113  
   114  // ReadFrom reads the Manifest from 'r' in format defined in the document #575623.
   115  func (s *Manifest) ReadFrom(r io.Reader) (returnN int64, returnErr error) {
   116  	var missingFieldsByIndices = [7]bool{
   117  		0: true,
   118  		6: true,
   119  	}
   120  	defer func() {
   121  		if returnErr != nil {
   122  			return
   123  		}
   124  		for fieldIndex, v := range missingFieldsByIndices {
   125  			if v {
   126  				returnErr = fmt.Errorf("field '%s' is missing", s.fieldNameByIndex(fieldIndex))
   127  				break
   128  			}
   129  		}
   130  	}()
   131  	var totalN int64
   132  	previousFieldIndex := int(-1)
   133  	for {
   134  		var structInfo cbnt.StructInfo
   135  		err := binary.Read(r, binary.LittleEndian, &structInfo)
   136  		if err == io.EOF || err == io.ErrUnexpectedEOF {
   137  			return totalN, nil
   138  		}
   139  		if err != nil {
   140  			return totalN, fmt.Errorf("unable to read structure info at %d: %w", totalN, err)
   141  		}
   142  		totalN += int64(binary.Size(structInfo))
   143  
   144  		structID := structInfo.ID.String()
   145  		fieldIndex := s.fieldIndexByStructID(structID)
   146  		if fieldIndex < 0 {
   147  			// TODO: report error "unknown structure ID: '"+structID+"'"
   148  			continue
   149  		}
   150  		if cbnt.StrictOrderCheck && fieldIndex < previousFieldIndex {
   151  			return totalN, fmt.Errorf("invalid order of fields (%d < %d): structure '%s' is out of order", fieldIndex, previousFieldIndex, structID)
   152  		}
   153  		missingFieldsByIndices[fieldIndex] = false
   154  
   155  		var n int64
   156  		switch structID {
   157  		case StructureIDBPMH:
   158  			if fieldIndex == previousFieldIndex {
   159  				return totalN, fmt.Errorf("field 'BPMH' is not a slice, but multiple elements found")
   160  			}
   161  			s.BPMH.SetStructInfo(structInfo)
   162  			n, err = s.BPMH.ReadDataFrom(r)
   163  			if err != nil {
   164  				return totalN, fmt.Errorf("unable to read field BPMH at %d: %w", totalN, err)
   165  			}
   166  		case StructureIDSE:
   167  			var el SE
   168  			el.SetStructInfo(structInfo)
   169  			n, err = el.ReadDataFrom(r)
   170  			s.SE = append(s.SE, el)
   171  			if err != nil {
   172  				return totalN, fmt.Errorf("unable to read field SE at %d: %w", totalN, err)
   173  			}
   174  		case StructureIDTXT:
   175  			if fieldIndex == previousFieldIndex {
   176  				return totalN, fmt.Errorf("field 'TXTE' is not a slice, but multiple elements found")
   177  			}
   178  			s.TXTE = &TXT{}
   179  			s.TXTE.SetStructInfo(structInfo)
   180  			n, err = s.TXTE.ReadDataFrom(r)
   181  			if err != nil {
   182  				return totalN, fmt.Errorf("unable to read field TXTE at %d: %w", totalN, err)
   183  			}
   184  		case StructureIDReserved:
   185  			if fieldIndex == previousFieldIndex {
   186  				return totalN, fmt.Errorf("field 'Res' is not a slice, but multiple elements found")
   187  			}
   188  			s.Res = &Reserved{}
   189  			s.Res.SetStructInfo(structInfo)
   190  			n, err = s.Res.ReadDataFrom(r)
   191  			if err != nil {
   192  				return totalN, fmt.Errorf("unable to read field Res at %d: %w", totalN, err)
   193  			}
   194  		case StructureIDPCD:
   195  			if fieldIndex == previousFieldIndex {
   196  				return totalN, fmt.Errorf("field 'PCDE' is not a slice, but multiple elements found")
   197  			}
   198  			s.PCDE = &PCD{}
   199  			s.PCDE.SetStructInfo(structInfo)
   200  			n, err = s.PCDE.ReadDataFrom(r)
   201  			if err != nil {
   202  				return totalN, fmt.Errorf("unable to read field PCDE at %d: %w", totalN, err)
   203  			}
   204  		case StructureIDPM:
   205  			if fieldIndex == previousFieldIndex {
   206  				return totalN, fmt.Errorf("field 'PME' is not a slice, but multiple elements found")
   207  			}
   208  			s.PME = &PM{}
   209  			s.PME.SetStructInfo(structInfo)
   210  			n, err = s.PME.ReadDataFrom(r)
   211  			if err != nil {
   212  				return totalN, fmt.Errorf("unable to read field PME at %d: %w", totalN, err)
   213  			}
   214  		case StructureIDSignature:
   215  			if fieldIndex == previousFieldIndex {
   216  				return totalN, fmt.Errorf("field 'PMSE' is not a slice, but multiple elements found")
   217  			}
   218  			s.PMSE.SetStructInfo(structInfo)
   219  			n, err = s.PMSE.ReadDataFrom(r)
   220  			if err != nil {
   221  				return totalN, fmt.Errorf("unable to read field PMSE at %d: %w", totalN, err)
   222  			}
   223  		default:
   224  			return totalN, fmt.Errorf("there is no field with structure ID '%s' in Manifest", structInfo.ID)
   225  		}
   226  		totalN += n
   227  		previousFieldIndex = fieldIndex
   228  	}
   229  }
   230  
   231  // RehashRecursive calls Rehash (see below) recursively.
   232  func (s *Manifest) RehashRecursive() {
   233  	s.BPMH.Rehash()
   234  	if s.TXTE != nil {
   235  		s.TXTE.Rehash()
   236  	}
   237  	if s.Res != nil {
   238  		s.Res.Rehash()
   239  	}
   240  	if s.PCDE != nil {
   241  		s.PCDE.Rehash()
   242  	}
   243  	if s.PME != nil {
   244  		s.PME.Rehash()
   245  	}
   246  	s.PMSE.Rehash()
   247  	s.Rehash()
   248  }
   249  
   250  // Rehash sets values which are calculated automatically depending on the rest
   251  // data. It is usually about the total size field of an element.
   252  func (s *Manifest) Rehash() {
   253  	s.BPMH = BPMH(s.rehashedBPMH())
   254  }
   255  
   256  // WriteTo writes the Manifest into 'w' in format defined in
   257  // the document #575623.
   258  func (s *Manifest) WriteTo(w io.Writer) (int64, error) {
   259  	totalN := int64(0)
   260  	s.Rehash()
   261  
   262  	// BPMH (ManifestFieldType: element)
   263  	{
   264  		n, err := s.BPMH.WriteTo(w)
   265  		if err != nil {
   266  			return totalN, fmt.Errorf("unable to write field 'BPMH': %w", err)
   267  		}
   268  		totalN += int64(n)
   269  	}
   270  
   271  	// SE (ManifestFieldType: elementList)
   272  	{
   273  		for idx := range s.SE {
   274  			n, err := s.SE[idx].WriteTo(w)
   275  			if err != nil {
   276  				return totalN, fmt.Errorf("unable to write field 'SE[%d]': %w", idx, err)
   277  			}
   278  			totalN += int64(n)
   279  		}
   280  	}
   281  
   282  	// TXTE (ManifestFieldType: element)
   283  	if s.TXTE != nil {
   284  		n, err := s.TXTE.WriteTo(w)
   285  		if err != nil {
   286  			return totalN, fmt.Errorf("unable to write field 'TXTE': %w", err)
   287  		}
   288  		totalN += int64(n)
   289  	}
   290  
   291  	// Res (ManifestFieldType: element)
   292  	if s.Res != nil {
   293  		n, err := s.Res.WriteTo(w)
   294  		if err != nil {
   295  			return totalN, fmt.Errorf("unable to write field 'Res': %w", err)
   296  		}
   297  		totalN += int64(n)
   298  	}
   299  
   300  	// PCDE (ManifestFieldType: element)
   301  	if s.PCDE != nil {
   302  		n, err := s.PCDE.WriteTo(w)
   303  		if err != nil {
   304  			return totalN, fmt.Errorf("unable to write field 'PCDE': %w", err)
   305  		}
   306  		totalN += int64(n)
   307  	}
   308  
   309  	// PME (ManifestFieldType: element)
   310  	if s.PME != nil {
   311  		n, err := s.PME.WriteTo(w)
   312  		if err != nil {
   313  			return totalN, fmt.Errorf("unable to write field 'PME': %w", err)
   314  		}
   315  		totalN += int64(n)
   316  	}
   317  
   318  	// PMSE (ManifestFieldType: element)
   319  	{
   320  		n, err := s.PMSE.WriteTo(w)
   321  		if err != nil {
   322  			return totalN, fmt.Errorf("unable to write field 'PMSE': %w", err)
   323  		}
   324  		totalN += int64(n)
   325  	}
   326  
   327  	return totalN, nil
   328  }
   329  
   330  // BPMHSize returns the size in bytes of the value of field BPMH
   331  func (s *Manifest) BPMHTotalSize() uint64 {
   332  	return s.BPMH.TotalSize()
   333  }
   334  
   335  // SESize returns the size in bytes of the value of field SE
   336  func (s *Manifest) SETotalSize() uint64 {
   337  	var size uint64
   338  	for idx := range s.SE {
   339  		size += s.SE[idx].TotalSize()
   340  	}
   341  	return size
   342  }
   343  
   344  // TXTESize returns the size in bytes of the value of field TXTE
   345  func (s *Manifest) TXTETotalSize() uint64 {
   346  	return s.TXTE.TotalSize()
   347  }
   348  
   349  // ResSize returns the size in bytes of the value of field Res
   350  func (s *Manifest) ResTotalSize() uint64 {
   351  	return s.Res.TotalSize()
   352  }
   353  
   354  // PCDESize returns the size in bytes of the value of field PCDE
   355  func (s *Manifest) PCDETotalSize() uint64 {
   356  	return s.PCDE.TotalSize()
   357  }
   358  
   359  // PMESize returns the size in bytes of the value of field PME
   360  func (s *Manifest) PMETotalSize() uint64 {
   361  	return s.PME.TotalSize()
   362  }
   363  
   364  // PMSESize returns the size in bytes of the value of field PMSE
   365  func (s *Manifest) PMSETotalSize() uint64 {
   366  	return s.PMSE.TotalSize()
   367  }
   368  
   369  // BPMHOffset returns the offset in bytes of field BPMH
   370  func (s *Manifest) BPMHOffset() uint64 {
   371  	return 0
   372  }
   373  
   374  // SEOffset returns the offset in bytes of field SE
   375  func (s *Manifest) SEOffset() uint64 {
   376  	return s.BPMHOffset() + s.BPMHTotalSize()
   377  }
   378  
   379  // TXTEOffset returns the offset in bytes of field TXTE
   380  func (s *Manifest) TXTEOffset() uint64 {
   381  	return s.SEOffset() + s.SETotalSize()
   382  }
   383  
   384  // ResOffset returns the offset in bytes of field Res
   385  func (s *Manifest) ResOffset() uint64 {
   386  	return s.TXTEOffset() + s.TXTETotalSize()
   387  }
   388  
   389  // PCDEOffset returns the offset in bytes of field PCDE
   390  func (s *Manifest) PCDEOffset() uint64 {
   391  	return s.ResOffset() + s.ResTotalSize()
   392  }
   393  
   394  // PMEOffset returns the offset in bytes of field PME
   395  func (s *Manifest) PMEOffset() uint64 {
   396  	return s.PCDEOffset() + s.PCDETotalSize()
   397  }
   398  
   399  // PMSEOffset returns the offset in bytes of field PMSE
   400  func (s *Manifest) PMSEOffset() uint64 {
   401  	return s.PMEOffset() + s.PMETotalSize()
   402  }
   403  
   404  // Size returns the total size of the Manifest.
   405  func (s *Manifest) TotalSize() uint64 {
   406  	if s == nil {
   407  		return 0
   408  	}
   409  
   410  	var size uint64
   411  	size += s.BPMHTotalSize()
   412  	size += s.SETotalSize()
   413  	size += s.TXTETotalSize()
   414  	size += s.ResTotalSize()
   415  	size += s.PCDETotalSize()
   416  	size += s.PMETotalSize()
   417  	size += s.PMSETotalSize()
   418  	return size
   419  }
   420  
   421  // PrettyString returns the content of the structure in an easy-to-read format.
   422  func (s *Manifest) PrettyString(depth uint, withHeader bool, opts ...pretty.Option) string {
   423  	var lines []string
   424  	if withHeader {
   425  		lines = append(lines, pretty.Header(depth, "Boot Policy Manifest", s))
   426  	}
   427  	if s == nil {
   428  		return strings.Join(lines, "\n")
   429  	}
   430  	// ManifestFieldType is element
   431  	lines = append(lines, pretty.SubValue(depth+1, "BPMH: Header", "", &s.BPMH, opts...)...)
   432  	// ManifestFieldType is elementList
   433  	lines = append(lines, pretty.Header(depth+1, fmt.Sprintf("SE: Array of \"Boot Policy Manifest\" of length %d", len(s.SE)), s.SE))
   434  	for i := 0; i < len(s.SE); i++ {
   435  		lines = append(lines, fmt.Sprintf("%sitem #%d: ", strings.Repeat("  ", int(depth+2)), i)+strings.TrimSpace(s.SE[i].PrettyString(depth+2, true)))
   436  	}
   437  	if depth < 1 {
   438  		lines = append(lines, "")
   439  	}
   440  	// ManifestFieldType is element
   441  	lines = append(lines, pretty.SubValue(depth+1, "TXTE", "", s.TXTE, opts...)...)
   442  	// ManifestFieldType is element
   443  	lines = append(lines, pretty.SubValue(depth+1, "Res", "", s.Res, opts...)...)
   444  	// ManifestFieldType is element
   445  	lines = append(lines, pretty.SubValue(depth+1, "PCDE: Platform Config Data", "", s.PCDE, opts...)...)
   446  	// ManifestFieldType is element
   447  	lines = append(lines, pretty.SubValue(depth+1, "PME: Platform Manufacturer", "", s.PME, opts...)...)
   448  	// ManifestFieldType is element
   449  	lines = append(lines, pretty.SubValue(depth+1, "PMSE: Signature", "", &s.PMSE, opts...)...)
   450  	if depth < 2 {
   451  		lines = append(lines, "")
   452  	}
   453  	return strings.Join(lines, "\n")
   454  }