Add CBnT 2.1 and replace code generation in intel/metadata#450
Add CBnT 2.1 and replace code generation in intel/metadata#450micgor32 wants to merge 37 commits intolinuxboot:mainfrom
Conversation
bg and cbnt packages will be merged in the follow-up commits. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Add README describing new approach for metadata handling, and move old readme to separate place. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
cbntbootpolicy and bgbootpolicy will be merged in the follow-up commits, thus bit of housekeeping here. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
same reason as with cbntbootpolicy removal Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
types.go is basically for interfaces definition that do not belong to one type but is rather implemented by remaining types. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Move bgheader.go to cbnt package since it is no longer reused by two separate packages (bg and cbnt as before). Recognize Header version > 0x21 is as CBnT 2.1 (Version21) after Table 5-16 in #575623-1.2.9. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Add Common struct. Acts as an accessor for shared methods (ReadFrom, WriteTo, <type>TotalSize, <>Offset, TotalSize and PrettyString). Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Currently the calculation to find FIT pointer starts (as per spec) with substracting 0x40 from the image size. On some boards (Intel CRB's for e.g but I also experienced similar issues on production boards) this will end in null dereference, since the BIOS flash area is not span over the whole image (i.e. there is some padding at the end of the image). This can be solved by comparing BIOS flash area size exposed in IFD against the image size, and replacing image size with BIOS flash area size in the calculation if these two do not match. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Merge Key Manifest for BG and CBnT. Given the differences, there are still two separate implementations of KM, these can, however, be accessed by the common constructor. While this commit adds a lots of code (sorry :D) there are no changes in the logic (as there was no changes in the 2.1 spec affecting KM). Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Similarly as with KM, merge BG and CBnT BPM. Constructor returns version specific implementation of BPM. No logical changes apart from usage of Common for shared methods in the Manifest implementation. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Moved these out to the separate file for readabilty. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
No logic changes. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Will be replaced in the follow-up commit with the integration tests. Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #450 +/- ##
===========================================
+ Coverage 34.13% 44.76% +10.62%
===========================================
Files 209 170 -39
Lines 14120 12243 -1877
===========================================
+ Hits 4820 5480 +660
+ Misses 8411 5939 -2472
+ Partials 889 824 -65 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
ping @orangecms, @rminnich |
seen it! It's a bit of a change... :D I would also want to port the general logic and structs to |
|
I'll take a look as well, will take a bit of time though... |
rminnich
left a comment
There was a problem hiding this comment.
WOW, this is an impressive and overwhelming PR! I guess it can not be done in smaller chunks, it has to be one thing?
| return nil | ||
| } | ||
|
|
||
| func (s *ManifestCBnT) Layout() []cbnt.LayoutField { |
There was a problem hiding this comment.
Please put a function comment here, thanks.
| { | ||
| ID: 6, | ||
| Name: "PMSE: Signature", | ||
| Size: func() uint64 { return s.PMSE.TotalSize() }, |
There was a problem hiding this comment.
I much prefer this one-line structure to the multiline structures above, it makes it far easier to read.
Can you change the ones above to match this format?
There was a problem hiding this comment.
I could do something like
func() uint64 { if s.PME == nil { return 0 } return s.PME.TotalSize() }as oneliner.
But the check have to stay there for all substructs of BPM that are optional. Otherwise things might fail quite bad :D
| } | ||
|
|
||
| // ReadFrom reads the Manifest from 'r' in format defined in the document #575623. | ||
| // Same note as above: this is an exception from the rule of usijg common approach. |
|
|
||
| // ReadFrom reads the Manifest from 'r' in format defined in the document #575623. | ||
| // Same note as above: this is an exception from the rule of usijg common approach. | ||
| func (s *ManifestCBnT) ReadFrom(r io.Reader) (returnN int64, returnErr error) { |
There was a problem hiding this comment.
do you really need the named return parameters? In the code below in many places you use different return values.
There was a problem hiding this comment.
right, similar case as with size in pm.go, my bad. Though for the error it make sense to keep it as named parameter, since it is used in the closure few lines below.
| } | ||
| } | ||
|
|
||
| func (s *ManifestCBnT) RehashRecursive() { |
There was a problem hiding this comment.
I think on all these exported functions, you need a comment.
If RehashRecursive is part of an interface (I forgot to look) it can be as simple as
// xyz implements xyz
or some such.
| ID: 3, | ||
| Name: "Data", | ||
| Size: func() uint64 { | ||
| size := uint64(binary.Size(uint16(0))) |
There was a problem hiding this comment.
I wonder why it can't just
return int64(binary.Size(uint16(0))) + uint64(binary.Size(s.DataSize))
There was a problem hiding this comment.
Right, my bad. In here I just blindly moved PM.DataTotalSize logic into the closure (https://github.com/linuxboot/fiano/blob/main/pkg/intel/metadata/cbnt/cbntbootpolicy/pm_manifestcodegen.go#L199)
| s := &Signature{StructInfo: cbnt.NewStructInfo(bgv)} | ||
| copy(s.StructInfo.(*cbnt.StructInfoBG).ID[:], []byte(StructureIDSignature)) | ||
| s.StructInfo.(*cbnt.StructInfoBG).Version = 0x10 | ||
| // Recursively initializing a child structure: |
There was a problem hiding this comment.
Is this comment really necessary?
Is this from AI?
There was a problem hiding this comment.
It's leftover from the manifestcodegen https://github.com/linuxboot/fiano/blob/main/pkg/intel/metadata/cbnt/cbntbootpolicy/signature_manifestcodegen.go#L39 and https://github.com/linuxboot/fiano/blob/main/pkg/intel/metadata/common/manifestcodegen/cmd/manifestcodegen/template_methods.tpl.go#L62.
Not sure whether it makes sense to have it there, but I assumed there was a reason for it.
|
|
||
| // NewTXT returns a new instance of TXT with | ||
| // all default values set. | ||
| func NewTXT() *TXT { |
There was a problem hiding this comment.
For all these New functions that set non-zero values:
what if someone does this: s := &TXT{}
and does not call this function? Will the zero value work or cause panics?
Should there be a test for the zero value?
There was a problem hiding this comment.
Didn't thought about that, will check and add a test for that if needed.
There was a problem hiding this comment.
So I have checked two cases of such usage with bg-prov of CSS.
changing this part to:
func (g *generateBPMCmdv2) Run(ctx *context) error {
var b bootguard.BootGuard
b.Version = cbnt.Version20
if g.Config != "" {
err := b.ReadJSON(g.Config)
if err != nil {
return err
}
} else {
cbntbpm := &bootpolicy.ManifestCBnT{}
bp := &bootpolicy.BPMHCBnT{}
b.VData.CBNTbpm = cbntbpm
b.VData.CBNTbpm.BPMHCBnT = *bpworks fine (i.e. no panics), though the values that would have been set to non-zero by New<*> func's won't be spec compliant.
There was a problem hiding this comment.
the linked part should be different line... https://github.com/9elements/converged-security-suite/blob/cbnt21-refactor/cmd/core/bg-prov/cmd.go#L668 sorry :)
rminnich
left a comment
There was a problem hiding this comment.
my inclination is that we need to accept this, although I don't understand it all ... and hope nothing will break.
It could be split into smaller ones yes, the thing is, these would not be functional on their own i.e. after applying it would leave the |
CBnT 2.1 (MTL and newer) brings breaking changes:
PDRSandCNBSare now mandatory element ofPCD(see d75ae02).0x00050004, given that the R/W methods for all SACM versions are same, the logic is moved out to the generic implementation (see 1800718, lines 357-377).0x21, thus0x22to0x25is recognized asBootGuardVersion.Version21.Replace codegen for manifest/structure methods. This is done by moving out the logic to a dedicated struct (
Common), that is then embed into the remaining structs. These have to provide their layout descriptor on each call toCommon. This reduces the amount of the code in general in theintel/metadata. Additionally,bgandcbntare now merged by letting the per-type constructor to return the correct type implementation. Both concepts are documented inpkg/intel/metadata/README.mdin 5903d58.Since the amount of (+- lines) changes is huge, I've tried to split commits into one per type + the unit test for it. There are few types that are just moved from either
bgorcbnt, and contribute to the modified lines, but do not contain any meaningful logic change. I've noted such cases in the commit description.Renamed
common/unittesttocommon/integrationto avoid confusion with the purpose of it and*_test.goincbnt. The integration test is now extended a bit, and its full scope is document inpkg/intel/metadata/common/integration/README.mdin c96a8bd.