github.com/linuxboot/fiano@v1.2.0/pkg/intel/metadata/cbnt/cbntkey/manifest.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:generate manifestcodegen 6 7 package cbntkey 8 9 import ( 10 "bytes" 11 "crypto" 12 "fmt" 13 14 "github.com/linuxboot/fiano/pkg/intel/metadata/cbnt" 15 ) 16 17 // PrettyString: CBnT Key Manifest 18 type Manifest struct { 19 cbnt.StructInfo `id:"__KEYM__" version:"0x21" var0:"0" var1:"0"` 20 21 // KeyManifestSignatureOffset is Key Manifest KeySignature offset. 22 // 23 // The original name is "KeySignatureOffset" (in #575623). 24 KeyManifestSignatureOffset uint16 `rehashValue:"KeyAndSignatureOffset()" json:"kmSigOffset,omitempty"` 25 26 // Reserved2 is an alignment. 27 Reserved2 [3]byte `json:"kmReserved2,omitempty"` 28 29 // Revision is the revision of the Key Manifest defined by the Platform 30 // Manufacturer. 31 Revision uint8 `json:"kmRevision"` 32 33 // KMSVN is the Key Manifest Security Version Number. 34 KMSVN cbnt.SVN `json:"kmSVN"` 35 36 // KMID is the Key Manifest Identifier. 37 KMID uint8 `json:"kmID"` 38 39 // PubKeyHashAlg is the hash algorithm of OEM public key digest programmed 40 // into the FPF. 41 PubKeyHashAlg cbnt.Algorithm `json:"kmPubKeyHashAlg"` 42 43 // Hash is the slice of KMHASH_STRUCT (KHS) structures (see table 5-3 44 // of the document #575623). Describes BPM pubkey digest (among other). 45 Hash []Hash `json:"kmHash"` 46 47 // KeyAndSignature is the Key Manifest signature. 48 KeyAndSignature cbnt.KeySignature `json:"kmKeySignature"` 49 } 50 51 func (m *Manifest) SetSignature( 52 algo cbnt.Algorithm, 53 hashAlgo cbnt.Algorithm, 54 privKey crypto.Signer, 55 signedData []byte, 56 ) error { 57 err := m.KeyAndSignature.SetSignature(algo, hashAlgo, privKey, signedData) 58 if err != nil { 59 return fmt.Errorf("unable to set the signature: %w", err) 60 } 61 m.PubKeyHashAlg = m.KeyAndSignature.Signature.HashAlg 62 63 return nil 64 } 65 66 func (m *Manifest) ValidateBPMKey(bpmKS cbnt.KeySignature) error { 67 hashCount := 0 68 for _, hashEntry := range m.Hash { 69 if !hashEntry.Usage.IsSet(UsageBPMSigningPKD) { 70 continue 71 } 72 73 h, err := hashEntry.Digest.HashAlg.Hash() 74 if err != nil { 75 return fmt.Errorf("invalid hash algo %v: %w", hashEntry.Digest.HashAlg, err) 76 } 77 78 if len(hashEntry.Digest.HashBuffer) != h.Size() { 79 return fmt.Errorf("invalid hash lenght: actual:%d expected:%d", len(hashEntry.Digest.HashBuffer), h.Size()) 80 } 81 82 switch bpmKS.Key.KeyAlg { 83 case cbnt.AlgRSA: 84 if _, err := h.Write(bpmKS.Key.Data[4:]); err != nil { 85 return fmt.Errorf("unable to hash: %w", err) 86 } 87 default: 88 return fmt.Errorf("unsupported key algorithm: %v", bpmKS.Key.KeyAlg) 89 } 90 digest := h.Sum(nil) 91 92 if !bytes.Equal(hashEntry.Digest.HashBuffer, digest) { 93 return fmt.Errorf("BPM key hash does not match the one in KM: actual:%X != in-KM:%X (hash algo: %v)", digest, hashEntry.Digest.HashBuffer, hashEntry.Digest.HashAlg) 94 } 95 hashCount++ 96 } 97 98 if hashCount == 0 { 99 return fmt.Errorf("no hash of BPM's key was found in KM") 100 } 101 102 return nil 103 }