diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:17:27 +0000 |
commit | f215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch) | |
tree | 6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py | |
parent | Initial commit. (diff) | |
download | virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip |
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rwxr-xr-x | src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py new file mode 100755 index 00000000..44bdcbc4 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py @@ -0,0 +1,310 @@ +## @file +# Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with +# a payload. +# +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +''' +FmpCapsuleHeader +''' + +import struct +import uuid + +class FmpCapsuleImageHeaderClass (object): + # typedef struct { + # UINT32 Version; + # + # /// + # /// Used to identify device firmware targeted by this update. This guid is matched by + # /// system firmware against ImageTypeId field within a EFI_FIRMWARE_IMAGE_DESCRIPTOR + # /// + # EFI_GUID UpdateImageTypeId; + # + # /// + # /// Passed as ImageIndex in call to EFI_FIRMWARE_MANAGEMENT_PROTOCOL.SetImage () + # /// + # UINT8 UpdateImageIndex; + # UINT8 reserved_bytes[3]; + # + # /// + # /// Size of the binary update image which immediately follows this structure + # /// + # UINT32 UpdateImageSize; + # + # /// + # /// Size of the VendorCode bytes which optionally immediately follow binary update image in the capsule + # /// + # UINT32 UpdateVendorCodeSize; + # + # /// + # /// The HardwareInstance to target with this update. If value is zero it means match all + # /// HardwareInstances. This field allows update software to target only a single device in + # /// cases where there are more than one device with the same ImageTypeId GUID. + # /// This header is outside the signed data of the Authentication Info structure and + # /// therefore can be modified without changing the Auth data. + # /// + # UINT64 UpdateHardwareInstance; + # + # /// + # /// Bits which indicate authentication and depex information for the image that follows this structure + # /// + # UINT64 ImageCapsuleSupport + # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER; + # + # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION 0x00000003 + + _StructFormat = '<I16sB3BIIQQ' + _StructSize = struct.calcsize (_StructFormat) + + EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000003 + + def __init__ (self): + self._Valid = False + self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION + self.UpdateImageTypeId = uuid.UUID ('00000000-0000-0000-0000-000000000000') + self.UpdateImageIndex = 0 + self.UpdateImageSize = 0 + self.UpdateVendorCodeSize = 0 + self.UpdateHardwareInstance = 0x0000000000000000 + self.ImageCapsuleSupport = 0x0000000000000000 + self.Payload = b'' + self.VendorCodeBytes = b'' + + def Encode (self): + self.UpdateImageSize = len (self.Payload) + self.UpdateVendorCodeSize = len (self.VendorCodeBytes) + FmpCapsuleImageHeader = struct.pack ( + self._StructFormat, + self.Version, + self.UpdateImageTypeId.bytes_le, + self.UpdateImageIndex, + 0,0,0, + self.UpdateImageSize, + self.UpdateVendorCodeSize, + self.UpdateHardwareInstance, + self.ImageCapsuleSupport + ) + self._Valid = True + return FmpCapsuleImageHeader + self.Payload + self.VendorCodeBytes + + def Decode (self, Buffer): + if len (Buffer) < self._StructSize: + raise ValueError + (Version, UpdateImageTypeId, UpdateImageIndex, r0, r1, r2, UpdateImageSize, UpdateVendorCodeSize, UpdateHardwareInstance, ImageCapsuleSupport) = \ + struct.unpack ( + self._StructFormat, + Buffer[0:self._StructSize] + ) + + if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION: + raise ValueError + if UpdateImageIndex < 1: + raise ValueError + if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]): + raise ValueError + + self.Version = Version + self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId) + self.UpdateImageIndex = UpdateImageIndex + self.UpdateImageSize = UpdateImageSize + self.UpdateVendorCodeSize = UpdateVendorCodeSize + self.UpdateHardwareInstance = UpdateHardwareInstance + self.ImageCapsuleSupport = ImageCapsuleSupport + self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize] + self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:] + self._Valid = True + return Buffer[self._StructSize:] + + def DumpInfo (self): + if not self._Valid: + raise ValueError + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper())) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.ImageCapsuleSupport = {ImageCapsuleSupport:016X}'.format (ImageCapsuleSupport = self.ImageCapsuleSupport)) + print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload))) + print ('sizeof (VendorCodeBytes) = {Size:08X}'.format (Size = len (self.VendorCodeBytes))) + +class FmpCapsuleHeaderClass (object): + # typedef struct { + # UINT32 Version; + # + # /// + # /// The number of drivers included in the capsule and the number of corresponding + # /// offsets stored in ItemOffsetList array. + # /// + # UINT16 EmbeddedDriverCount; + # + # /// + # /// The number of payload items included in the capsule and the number of + # /// corresponding offsets stored in the ItemOffsetList array. + # /// + # UINT16 PayloadItemCount; + # + # /// + # /// Variable length array of dimension [EmbeddedDriverCount + PayloadItemCount] + # /// containing offsets of each of the drivers and payload items contained within the capsule + # /// + # // UINT64 ItemOffsetList[]; + # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER; + # + # #define EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION 0x00000001 + _StructFormat = '<IHH' + _StructSize = struct.calcsize (_StructFormat) + + _ItemOffsetFormat = '<Q' + _ItemOffsetSize = struct.calcsize (_ItemOffsetFormat) + + EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION = 0x00000001 + CAPSULE_SUPPORT_AUTHENTICATION = 0x0000000000000001 + CAPSULE_SUPPORT_DEPENDENCY = 0x0000000000000002 + + def __init__ (self): + self._Valid = False + self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION + self.EmbeddedDriverCount = 0 + self.PayloadItemCount = 0 + self._ItemOffsetList = [] + self._EmbeddedDriverList = [] + self._PayloadList = [] + self._FmpCapsuleImageHeaderList = [] + + def AddEmbeddedDriver (self, EmbeddedDriver): + self._EmbeddedDriverList.append (EmbeddedDriver) + + def GetEmbeddedDriver (self, Index): + if Index > len (self._EmbeddedDriverList): + raise ValueError + return self._EmbeddedDriverList[Index] + + def AddPayload (self, UpdateImageTypeId, Payload = b'', VendorCodeBytes = b'', HardwareInstance = 0, UpdateImageIndex = 1, CapsuleSupport = 0): + self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport)) + + def GetFmpCapsuleImageHeader (self, Index): + if Index >= len (self._FmpCapsuleImageHeaderList): + raise ValueError + return self._FmpCapsuleImageHeaderList[Index] + + def Encode (self): + self.EmbeddedDriverCount = len (self._EmbeddedDriverList) + self.PayloadItemCount = len (self._PayloadList) + + FmpCapsuleHeader = struct.pack ( + self._StructFormat, + self.Version, + self.EmbeddedDriverCount, + self.PayloadItemCount + ) + + FmpCapsuleData = b'' + Offset = self._StructSize + (self.EmbeddedDriverCount + self.PayloadItemCount) * self._ItemOffsetSize + for EmbeddedDriver in self._EmbeddedDriverList: + FmpCapsuleData = FmpCapsuleData + EmbeddedDriver + self._ItemOffsetList.append (Offset) + Offset = Offset + len (EmbeddedDriver) + Index = 1 + for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance, UpdateImageIndex, CapsuleSupport) in self._PayloadList: + FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass () + FmpCapsuleImageHeader.UpdateImageTypeId = UpdateImageTypeId + FmpCapsuleImageHeader.UpdateImageIndex = UpdateImageIndex + FmpCapsuleImageHeader.Payload = Payload + FmpCapsuleImageHeader.VendorCodeBytes = VendorCodeBytes + FmpCapsuleImageHeader.UpdateHardwareInstance = HardwareInstance + FmpCapsuleImageHeader.ImageCapsuleSupport = CapsuleSupport + FmpCapsuleImage = FmpCapsuleImageHeader.Encode () + FmpCapsuleData = FmpCapsuleData + FmpCapsuleImage + + self._ItemOffsetList.append (Offset) + self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader) + + Offset = Offset + len (FmpCapsuleImage) + Index = Index + 1 + + for Offset in self._ItemOffsetList: + FmpCapsuleHeader = FmpCapsuleHeader + struct.pack (self._ItemOffsetFormat, Offset) + + self._Valid = True + return FmpCapsuleHeader + FmpCapsuleData + + def Decode (self, Buffer): + if len (Buffer) < self._StructSize: + raise ValueError + (Version, EmbeddedDriverCount, PayloadItemCount) = \ + struct.unpack ( + self._StructFormat, + Buffer[0:self._StructSize] + ) + if Version < self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION: + raise ValueError + + self.Version = Version + self.EmbeddedDriverCount = EmbeddedDriverCount + self.PayloadItemCount = PayloadItemCount + self._ItemOffsetList = [] + self._EmbeddedDriverList = [] + self._PayloadList = [] + self._FmpCapsuleImageHeaderList = [] + + # + # Parse the ItemOffsetList values + # + Offset = self._StructSize + for Index in range (0, EmbeddedDriverCount + PayloadItemCount): + ItemOffset = struct.unpack (self._ItemOffsetFormat, Buffer[Offset:Offset + self._ItemOffsetSize])[0] + if ItemOffset >= len (Buffer): + raise ValueError + self._ItemOffsetList.append (ItemOffset) + Offset = Offset + self._ItemOffsetSize + Result = Buffer[Offset:] + + # + # Parse the EmbeddedDrivers + # + for Index in range (0, EmbeddedDriverCount): + Offset = self._ItemOffsetList[Index] + if Index < (len (self._ItemOffsetList) - 1): + Length = self._ItemOffsetList[Index + 1] - Offset + else: + Length = len (Buffer) - Offset + self.AddEmbeddedDriver (Buffer[Offset:Offset + Length]) + + # + # Parse the Payloads that are FMP Capsule Images + # + for Index in range (EmbeddedDriverCount, EmbeddedDriverCount + PayloadItemCount): + Offset = self._ItemOffsetList[Index] + if Index < (len (self._ItemOffsetList) - 1): + Length = self._ItemOffsetList[Index + 1] - Offset + else: + Length = len (Buffer) - Offset + FmpCapsuleImageHeader = FmpCapsuleImageHeaderClass () + FmpCapsuleImageHeader.Decode (Buffer[Offset:Offset + Length]) + self.AddPayload ( + FmpCapsuleImageHeader.UpdateImageTypeId, + FmpCapsuleImageHeader.Payload, + FmpCapsuleImageHeader.VendorCodeBytes + ) + self._FmpCapsuleImageHeaderList.append (FmpCapsuleImageHeader) + + self._Valid = True + return Result + + def DumpInfo (self): + if not self._Valid: + raise ValueError + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = {Version:08X}'.format (Version = self.Version)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount)) + for EmbeddedDriver in self._EmbeddedDriverList: + print (' sizeof (EmbeddedDriver) = {Size:08X}'.format (Size = len (EmbeddedDriver))) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount = self.PayloadItemCount)) + print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ') + for Offset in self._ItemOffsetList: + print (' {Offset:016X}'.format (Offset = Offset)) + for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList: + FmpCapsuleImageHeader.DumpInfo () |