github.com/linuxboot/fiano@v1.2.0/pkg/amd/psb/errors.go (about) 1 // Copyright 2023 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 psb 6 7 import ( 8 "errors" 9 "fmt" 10 11 amd_manifest "github.com/linuxboot/fiano/pkg/amd/manifest" 12 ) 13 14 // SignatureCheckError is an error type which indicates that signature of an element cannot be validated against its signing key 15 type SignatureCheckError struct { 16 signingKey *Key 17 signedElement FirmwareItem 18 err error 19 } 20 21 // Error returns the string representation of SignatureCheckError 22 func (m *SignatureCheckError) Error() string { 23 if m.signedElement == nil { 24 return fmt.Sprintf("signature does not validate against signing key %s: %s", m.signingKey.data.KeyID.Hex(), m.err.Error()) 25 } 26 return fmt.Sprintf("signature of element %s does not validate against signing key %s: %s", m.signedElement, m.signingKey.data.KeyID.Hex(), m.err.Error()) 27 } 28 29 func (m *SignatureCheckError) Unwrap() error { 30 return m.err 31 } 32 33 // SigningKey returns the SigningKey associated to the error. Might return nil value 34 func (m *SignatureCheckError) SigningKey() *Key { 35 return m.signingKey 36 } 37 38 // SignedElement returns an optional item whose signature check failed 39 func (m *SignatureCheckError) SignedElement() FirmwareItem { 40 return m.signedElement 41 } 42 43 // UnknownSigningKeyError is an error type which indicates that the signing key is unknown 44 type UnknownSigningKeyError struct { 45 signedElement FirmwareItem 46 keyID KeyID 47 } 48 49 // SignedElement returns an optional item whose signature check failed 50 func (s *UnknownSigningKeyError) SignedElement() FirmwareItem { 51 return s.signedElement 52 } 53 54 // Error returns the string representation of the UnknownSigningKeyError 55 func (s *UnknownSigningKeyError) Error() string { 56 if s.signedElement == nil { 57 return fmt.Sprintf("key ID '%s' is unknown", s.keyID.Hex()) 58 } 59 return fmt.Sprintf("failed to check signature of element '%s' key ID '%s' is unknown", s.signedElement, s.keyID.Hex()) 60 } 61 62 // FirmwareItem is a special item that references a PSP firmware item and could be one of the following types: 63 // DirectoryType or BIOSDirectoryEntryItem or PSPDirectoryEntryItem 64 type FirmwareItem interface{} 65 66 func newDirectoryItem(directory DirectoryType) FirmwareItem { 67 return directory 68 } 69 70 // BIOSDirectoryEntryItem determines a BIOS directory entry 71 type BIOSDirectoryEntryItem struct { 72 Level uint8 73 Entry amd_manifest.BIOSDirectoryTableEntryType 74 Instance uint8 75 } 76 77 func (biosEntry BIOSDirectoryEntryItem) String() string { 78 return fmt.Sprintf("entry '0x%X' (%s) instance %d of bios directory level %d", biosEntry.Entry, BIOSEntryType(biosEntry.Entry), biosEntry.Instance, biosEntry.Level) 79 } 80 81 func newBIOSDirectoryEntryItem(level uint8, entry amd_manifest.BIOSDirectoryTableEntryType, instance uint8) FirmwareItem { 82 return BIOSDirectoryEntryItem{ 83 Level: level, 84 Entry: entry, 85 Instance: instance, 86 } 87 } 88 89 // PSPDirectoryEntryItem determines a PSP directory entry 90 type PSPDirectoryEntryItem struct { 91 Level uint8 92 Entry amd_manifest.PSPDirectoryTableEntryType 93 } 94 95 func (pspEntry PSPDirectoryEntryItem) String() string { 96 return fmt.Sprintf("entry '0x%X' (%s) of psp directory level %d", pspEntry.Entry, PSPEntryType(pspEntry.Entry), pspEntry.Level) 97 } 98 99 func newPSPDirectoryEntryItem(level uint8, entry amd_manifest.PSPDirectoryTableEntryType) PSPDirectoryEntryItem { 100 return PSPDirectoryEntryItem{ 101 Level: level, 102 Entry: entry, 103 } 104 } 105 106 // ErrNotFound describes a situation when firmware item is not found 107 type ErrNotFound struct { 108 item FirmwareItem 109 } 110 111 // GetItem returns a not found item 112 func (err ErrNotFound) GetItem() FirmwareItem { 113 return err.item 114 } 115 116 // Error returns the string representation of the UnknownSigningKeyError 117 func (err ErrNotFound) Error() string { 118 if err.item == nil { 119 return "not found" 120 } 121 return fmt.Sprintf("'%s' is not found", err.item) 122 } 123 124 func newErrNotFound(item FirmwareItem) ErrNotFound { 125 return ErrNotFound{ 126 item: item, 127 } 128 } 129 130 // ErrInvalidFormat describes a situation when parsing of firmware failed because of invalid format 131 type ErrInvalidFormat struct { 132 item FirmwareItem 133 err error 134 } 135 136 // GetItem returns the affected item (could be nil) 137 func (err ErrInvalidFormat) GetItem() FirmwareItem { 138 return err.item 139 } 140 141 func (err ErrInvalidFormat) Error() string { 142 return fmt.Sprintf("'%s' has invalid format format: '%s'", err.item, err.err.Error()) 143 } 144 145 func (err ErrInvalidFormat) Unwrap() error { 146 return err.err 147 } 148 149 func newErrInvalidFormatWithItem(item FirmwareItem, err error) ErrInvalidFormat { 150 return ErrInvalidFormat{item: item, err: err} 151 } 152 153 func newErrInvalidFormat(err error) ErrInvalidFormat { 154 return ErrInvalidFormat{err: err} 155 } 156 157 func addFirmwareItemToError(err error, item FirmwareItem) error { 158 if err == nil { 159 return nil 160 } 161 162 var sigCheckErr *SignatureCheckError 163 if errors.As(err, &sigCheckErr) { 164 if sigCheckErr.signedElement == nil { 165 return &SignatureCheckError{signingKey: sigCheckErr.signingKey, signedElement: item, err: sigCheckErr.err} 166 } 167 return err 168 } 169 170 var unknownKey *UnknownSigningKeyError 171 if errors.As(err, &unknownKey) { 172 if unknownKey.signedElement == nil { 173 return &UnknownSigningKeyError{keyID: unknownKey.keyID, signedElement: item} 174 } 175 return err 176 } 177 178 var notFoundErr ErrNotFound 179 if errors.As(err, ¬FoundErr) { 180 if notFoundErr.item == nil { 181 return ErrNotFound{item: item} 182 } 183 return err 184 } 185 186 var invalidFormatErr ErrInvalidFormat 187 if errors.As(err, &invalidFormatErr) { 188 if notFoundErr.item == nil { 189 return ErrNotFound{item: item} 190 } 191 return err 192 } 193 return err 194 }