2 # Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with
5 # Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
16 class FmpCapsuleImageHeaderClass (object):
21 # /// Used to identify device firmware targeted by this update. This guid is matched by
22 # /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR
24 # EFI_GUID UpdateImageTypeId;
27 # /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage ()
29 # UINT8 UpdateImageIndex;
30 # UINT8 reserved_bytes[3];
33 # /// Size of the binary update image which immediately follows this structure
35 # UINT32 UpdateImageSize;
38 # /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule
40 # UINT32 UpdateVendorCodeSize;
43 # /// The HardwareInstance to target with this update. If value is zero it means match all
44 # /// HardwareInstances. This field allows update software to target only a single device in
45 # /// cases where there are more than one device with the same ImageTypeId GUID.
46 # /// This header is outside the signed data of the Authentication Info structure and
47 # /// therefore can be modified without changing the Auth data.
49 # UINT64 UpdateHardwareInstance;
50 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
52 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000002
54 _StructFormat
= '<I16sB3BIIQ'
55 _StructSize
= struct
.calcsize (_StructFormat
)
57 EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
= 0x00000002
61 self
.Version
= self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
62 self
.UpdateImageTypeId
= uuid
.UUID ('00000000-0000-0000-0000-000000000000')
63 self
.UpdateImageIndex
= 0
64 self
.UpdateImageSize
= 0
65 self
.UpdateVendorCodeSize
= 0
66 self
.UpdateHardwareInstance
= 0x0000000000000000
68 self
.VendorCodeBytes
= b
''
71 self
.UpdateImageSize
= len (self
.Payload
)
72 self
.UpdateVendorCodeSize
= len (self
.VendorCodeBytes
)
73 FmpCapsuleImageHeader
= struct
.pack (
76 self
.UpdateImageTypeId
.bytes_le
,
77 self
.UpdateImageIndex
,
80 self
.UpdateVendorCodeSize
,
81 self
.UpdateHardwareInstance
84 return FmpCapsuleImageHeader
+ self
.Payload
+ self
.VendorCodeBytes
86 def Decode (self
, Buffer
):
87 if len (Buffer
) < self
._StructSize
:
89 (Version
, UpdateImageTypeId
, UpdateImageIndex
, r0
, r1
, r2
, UpdateImageSize
, UpdateVendorCodeSize
, UpdateHardwareInstance
) = \
92 Buffer
[0:self
._StructSize
]
95 if Version
< self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
:
97 if UpdateImageIndex
< 1:
99 if UpdateImageSize
+ UpdateVendorCodeSize
!= len (Buffer
[self
._StructSize
:]):
102 self
.Version
= Version
103 self
.UpdateImageTypeId
= uuid
.UUID (bytes_le
= UpdateImageTypeId
)
104 self
.UpdateImageIndex
= UpdateImageIndex
105 self
.UpdateImageSize
= UpdateImageSize
106 self
.UpdateVendorCodeSize
= UpdateVendorCodeSize
107 self
.UpdateHardwareInstance
= UpdateHardwareInstance
108 self
.Payload
= Buffer
[self
._StructSize
:self
._StructSize
+ UpdateImageSize
]
109 self
.VendorCodeBytes
= Buffer
[self
._StructSize
+ UpdateImageSize
:]
111 return Buffer
[self
._StructSize
:]
116 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version
= self
.Version
))
117 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId
= str(self
.UpdateImageTypeId
).upper()))
118 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex
= self
.UpdateImageIndex
))
119 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize
= self
.UpdateImageSize
))
120 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize
= self
.UpdateVendorCodeSize
))
121 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance
= self
.UpdateHardwareInstance
))
122 print ('sizeof (Payload) = {Size:08X}'.format (Size
= len (self
.Payload
)))
123 print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size
= len (self
.VendorCodeBytes
)))
125 class FmpCapsuleHeaderClass (object):
130 # /// The number of drivers included in the capsule and the number of corresponding
131 # /// offsets stored in ItemOffsetList array.
133 # UINT16 EmbeddedDriverCount;
136 # /// The number of payload items included in the capsule and the number of
137 # /// corresponding offsets stored in the ItemOffsetList array.
139 # UINT16 PayloadItemCount;
142 # /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount]
143 # /// containing offsets of each of the drivers and payload items contained within the capsule
145 # // UINT64 ItemOffsetList[];
146 # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
148 # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001
149 _StructFormat
= '<IHH'
150 _StructSize
= struct
.calcsize (_StructFormat
)
152 _ItemOffsetFormat
= '<Q'
153 _ItemOffsetSize
= struct
.calcsize (_ItemOffsetFormat
)
155 EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
= 0x00000001
159 self
.Version
= self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
160 self
.EmbeddedDriverCount
= 0
161 self
.PayloadItemCount
= 0
162 self
._ItemOffsetList
= []
163 self
._EmbeddedDriverList
= []
164 self
._PayloadList
= []
165 self
._FmpCapsuleImageHeaderList
= []
167 def AddEmbeddedDriver (self
, EmbeddedDriver
):
168 self
._EmbeddedDriverList
.append (EmbeddedDriver
)
170 def GetEmbeddedDriver (self
, Index
):
171 if Index
> len (self
._EmbeddedDriverList
):
173 return self
._EmbeddedDriverList
[Index
]
175 def AddPayload (self
, UpdateImageTypeId
, Payload
= b
'', VendorCodeBytes
= b
'', HardwareInstance
= 0):
176 self
._PayloadList
.append ((UpdateImageTypeId
, Payload
, VendorCodeBytes
, HardwareInstance
))
178 def GetFmpCapsuleImageHeader (self
, Index
):
179 if Index
>= len (self
._FmpCapsuleImageHeaderList
):
181 return self
._FmpCapsuleImageHeaderList
[Index
]
184 self
.EmbeddedDriverCount
= len (self
._EmbeddedDriverList
)
185 self
.PayloadItemCount
= len (self
._PayloadList
)
187 FmpCapsuleHeader
= struct
.pack (
190 self
.EmbeddedDriverCount
,
191 self
.PayloadItemCount
195 Offset
= self
._StructSize
+ (self
.EmbeddedDriverCount
+ self
.PayloadItemCount
) * self
._ItemOffsetSize
196 for EmbeddedDriver
in self
._EmbeddedDriverList
:
197 FmpCapsuleData
= FmpCapsuleData
+ EmbeddedDriver
198 self
._ItemOffsetList
.append (Offset
)
199 Offset
= Offset
+ len (EmbeddedDriver
)
201 for (UpdateImageTypeId
, Payload
, VendorCodeBytes
, HardwareInstance
) in self
._PayloadList
:
202 FmpCapsuleImageHeader
= FmpCapsuleImageHeaderClass ()
203 FmpCapsuleImageHeader
.UpdateImageTypeId
= UpdateImageTypeId
204 FmpCapsuleImageHeader
.UpdateImageIndex
= Index
205 FmpCapsuleImageHeader
.Payload
= Payload
206 FmpCapsuleImageHeader
.VendorCodeBytes
= VendorCodeBytes
207 FmpCapsuleImageHeader
.UpdateHardwareInstance
= HardwareInstance
208 FmpCapsuleImage
= FmpCapsuleImageHeader
.Encode ()
209 FmpCapsuleData
= FmpCapsuleData
+ FmpCapsuleImage
211 self
._ItemOffsetList
.append (Offset
)
212 self
._FmpCapsuleImageHeaderList
.append (FmpCapsuleImageHeader
)
214 Offset
= Offset
+ len (FmpCapsuleImage
)
217 for Offset
in self
._ItemOffsetList
:
218 FmpCapsuleHeader
= FmpCapsuleHeader
+ struct
.pack (self
._ItemOffsetFormat
, Offset
)
221 return FmpCapsuleHeader
+ FmpCapsuleData
223 def Decode (self
, Buffer
):
224 if len (Buffer
) < self
._StructSize
:
226 (Version
, EmbeddedDriverCount
, PayloadItemCount
) = \
229 Buffer
[0:self
._StructSize
]
231 if Version
< self
.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION
:
234 self
.Version
= Version
235 self
.EmbeddedDriverCount
= EmbeddedDriverCount
236 self
.PayloadItemCount
= PayloadItemCount
237 self
._ItemOffsetList
= []
238 self
._EmbeddedDriverList
= []
239 self
._PayloadList
= []
240 self
._FmpCapsuleImageHeaderList
= []
243 # Parse the ItemOffsetList values
245 Offset
= self
._StructSize
246 for Index
in range (0, EmbeddedDriverCount
+ PayloadItemCount
):
247 ItemOffset
= struct
.unpack (self
._ItemOffsetFormat
, Buffer
[Offset
:Offset
+ self
._ItemOffsetSize
])[0]
248 if ItemOffset
>= len (Buffer
):
250 self
._ItemOffsetList
.append (ItemOffset
)
251 Offset
= Offset
+ self
._ItemOffsetSize
252 Result
= Buffer
[Offset
:]
255 # Parse the EmbeddedDrivers
257 for Index
in range (0, EmbeddedDriverCount
):
258 Offset
= self
._ItemOffsetList
[Index
]
259 if Index
< (len (self
._ItemOffsetList
) - 1):
260 Length
= self
._ItemOffsetList
[Index
+ 1] - Offset
262 Length
= len (Buffer
) - Offset
263 self
.AddEmbeddedDriver (Buffer
[Offset
:Offset
+ Length
])
266 # Parse the Payloads that are FMP Capsule Images
268 for Index
in range (EmbeddedDriverCount
, EmbeddedDriverCount
+ PayloadItemCount
):
269 Offset
= self
._ItemOffsetList
[Index
]
270 if Index
< (len (self
._ItemOffsetList
) - 1):
271 Length
= self
._ItemOffsetList
[Index
+ 1] - Offset
273 Length
= len (Buffer
) - Offset
274 FmpCapsuleImageHeader
= FmpCapsuleImageHeaderClass ()
275 FmpCapsuleImageHeader
.Decode (Buffer
[Offset
:Offset
+ Length
])
277 FmpCapsuleImageHeader
.UpdateImageTypeId
,
278 FmpCapsuleImageHeader
.Payload
,
279 FmpCapsuleImageHeader
.VendorCodeBytes
281 self
._FmpCapsuleImageHeaderList
.append (FmpCapsuleImageHeader
)
289 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version
= self
.Version
))
290 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount
= self
.EmbeddedDriverCount
))
291 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount
= self
.PayloadItemCount
))
292 print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')
293 for Offset
in self
._ItemOffsetList
:
294 print (' {Offset:016X}'.format (Offset
= Offset
))
295 for FmpCapsuleImageHeader
in self
._FmpCapsuleImageHeaderList
:
296 FmpCapsuleImageHeader
.DumpInfo ()