summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/CapsuleDependency.py409
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py190
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py310
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py130
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py9
-rw-r--r--src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/__init__.py9
6 files changed, 1057 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/CapsuleDependency.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/CapsuleDependency.py
new file mode 100755
index 00000000..96cf4b40
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/CapsuleDependency.py
@@ -0,0 +1,409 @@
+## @file
+# Module that encodes and decodes a capsule dependency.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+import struct
+import json
+import sys
+import uuid
+import re
+
+'''
+CapsuleDependency
+'''
+
+class OpConvert (object):
+ def __init__ (self):
+ # Opcode: (OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert)
+ self._DepexOperations = {0x00: (16, 16, 's', self.Str2Guid, self.Guid2Str),
+ 0x01: (4, 1, 'I', self.Str2Uint, self.Uint2Str),
+ 0x02: (1, 0, 's', self.Str2Utf8, self.Byte2Str),
+ }
+
+ def Str2Uint (self, Data):
+ try:
+ Value = int (Data, 16)
+ except:
+ Message = '{Data} is not a valid integer value.'.format (Data = Data)
+ raise ValueError (Message)
+ if Value < 0 or Value > 0xFFFFFFFF:
+ Message = '{Data} is not an UINT32.'.format (Data = Data)
+ raise ValueError (Message)
+ return Value
+
+ def Uint2Str (self, Data):
+ if Data < 0 or Data > 0xFFFFFFFF:
+ Message = '{Data} is not an UINT32.'.format (Data = Data)
+ raise ValueError (Message)
+ return "0x{Data:08x}".format (Data = Data)
+
+ def Str2Guid (self, Data):
+ try:
+ Guid = uuid.UUID (Data)
+ except:
+ Message = '{Data} is not a valid registry format GUID value.'.format (Data = Data)
+ raise ValueError (Message)
+ return Guid.bytes_le
+
+ def Guid2Str (self, Data):
+ try:
+ Guid = uuid.UUID (bytes_le = Data)
+ except:
+ Message = '{Data} is not a valid binary format GUID value.'.format (Data = Data)
+ raise ValueError (Message)
+ return str (Guid).upper ()
+
+ def Str2Utf8 (self, Data):
+ if isinstance (Data, str):
+ return Data.encode ('utf-8')
+ else:
+ Message = '{Data} is not a valid string.'.format (Data = Data)
+ raise ValueError (Message)
+
+ def Byte2Str (self, Data):
+ if isinstance (Data, bytes):
+ if Data[-1:] == b'\x00':
+ return str (Data[:-1], 'utf-8')
+ else:
+ return str (Data, 'utf-8')
+ else:
+ Message = '{Data} is not a valid binary string.'.format (Data = Data)
+ raise ValueError (Message)
+
+ def OpEncode (self, Opcode, Operand = None):
+ BinTemp = struct.pack ('<b', Opcode)
+ if Opcode <= 0x02 and Operand != None:
+ OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert = self._DepexOperations[Opcode]
+ Value = EncodeConvert (Operand)
+ if Opcode == 0x02:
+ PackSize = len (Value) + 1
+ BinTemp += struct.pack ('<{PackSize}{PackFmt}'.format (PackSize = PackSize, PackFmt = PackFmt), Value)
+ return BinTemp
+
+ def OpDecode (self, Buffer):
+ Opcode = struct.unpack ('<b', Buffer[0:1])[0]
+ if Opcode <= 0x02:
+ OperandSize, PackSize, PackFmt, EncodeConvert, DecodeConvert = self._DepexOperations[Opcode]
+ if Opcode == 0x02:
+ try:
+ PackSize = Buffer[1:].index (b'\x00') + 1
+ OperandSize = PackSize
+ except:
+ Message = 'CapsuleDependency: OpConvert: error: decode failed with wrong opcode/string.'
+ raise ValueError (Message)
+ try:
+ Operand = DecodeConvert (struct.unpack ('<{PackSize}{PackFmt}'.format (PackSize = PackSize, PackFmt = PackFmt), Buffer[1:1+OperandSize])[0])
+ except:
+ Message = 'CapsuleDependency: OpConvert: error: decode failed with unpack failure.'
+ raise ValueError (Message)
+ else:
+ Operand = None
+ OperandSize = 0
+ return (Opcode, Operand, OperandSize)
+
+class CapsuleDependencyClass (object):
+ # //**************************************************************
+ # // Image Attribute - Dependency
+ # //**************************************************************
+ # typedef struct {
+ # UINT8 Dependencies[];
+ # } EFI_FIRMWARE_IMAGE_DEP
+
+ # {expression operator : [precedence, opcode, type (1:unary/2:binocular)]}
+ _opReference = {'&&': [2, 0x03, 2],
+ '||': [1, 0x04, 2],
+ '~': [5, 0x05, 1],
+ '==': [3, 0x08, 2],
+ '>': [4, 0x09, 2],
+ '>=': [4, 0x0A, 2],
+ '<': [4, 0x0B, 2],
+ '<=': [4, 0x0C, 2],
+ }
+
+ def __init__ (self):
+ self.Payload = b''
+ self._DepexExp = None
+ self._DepexList = []
+ self._DepexDump = []
+ self.Depex = b''
+ self._Valid = False
+ self._DepexSize = 0
+ self._opReferenceReverse = {v[1] : k for k, v in self._opReference.items ()}
+ self.OpConverter = OpConvert ()
+
+ @property
+ def DepexExp (self):
+ return self._DepexExp
+
+ @DepexExp.setter
+ def DepexExp (self, DepexExp = ''):
+ if isinstance (DepexExp, str):
+ DepexExp = re.sub (r'\n',r' ',DepexExp)
+ DepexExp = re.sub (r'\(',r' ( ',DepexExp)
+ DepexExp = re.sub (r'\)',r' ) ',DepexExp)
+ DepexExp = re.sub (r'~',r' ~ ',DepexExp)
+ self._DepexList = re.findall(r"[^\s\"\']+|\"[^\"]*\"|\'[^\']*\'",DepexExp)
+ self._DepexExp = " ".join(self._DepexList)
+
+ else:
+ Msg = 'Input Depex Expression is not valid string.'
+ raise ValueError (Msg)
+
+ def IsValidOperator (self, op):
+ return op in self._opReference.keys ()
+
+ def IsValidUnaryOperator (self, op):
+ return op in self._opReference.keys () and self._opReference[op][2] == 1
+
+ def IsValidBinocularOperator (self, op):
+ return op in self._opReference.keys () and self._opReference[op][2] == 2
+
+ def IsValidGuid (self, operand):
+ try:
+ uuid.UUID (operand)
+ except:
+ return False
+ return True
+
+ def IsValidVersion (self, operand):
+ try:
+ Value = int (operand, 16)
+ if Value < 0 or Value > 0xFFFFFFFF:
+ return False
+ except:
+ return False
+ return True
+
+ def IsValidBoolean (self, operand):
+ try:
+ return operand.upper () in ['TRUE', 'FALSE']
+ except:
+ return False
+
+ def IsValidOperand (self, operand):
+ return self.IsValidVersion (operand) or self.IsValidGuid (operand) or self.IsValidBoolean (operand)
+
+ def IsValidString (self, operand):
+ return operand[0] == "\"" and operand[-1] == "\"" and len(operand) >= 2
+
+ # Check if priority of current operater is greater than pervious op
+ def PriorityNotGreater (self, prevOp, currOp):
+ return self._opReference[currOp][0] <= self._opReference[prevOp][0]
+
+ def ValidateDepex (self):
+ OpList = self._DepexList
+
+ i = 0
+ while i < len (OpList):
+ Op = OpList[i]
+
+ if Op == 'DECLARE':
+ i += 1
+ if i >= len (OpList):
+ Msg = 'No more Operand after {Op}.'.format (Op = OpList[i-1])
+ raise IndexError (Msg)
+ # Check valid string
+ if not self.IsValidString(OpList[i]):
+ Msg = '{Operand} after {Op} is not a valid expression input.'.format (Operand = OpList[i], Op = OpList[i-1])
+ raise ValueError (Msg)
+
+ elif Op == '(':
+ # Expression cannot end with (
+ if i == len (OpList) - 1:
+ Msg = 'Expression cannot end with \'(\''
+ raise ValueError (Msg)
+ # The previous op after '(' cannot be a binocular operator
+ if self.IsValidBinocularOperator (OpList[i+1]) :
+ Msg = '{Op} after \'(\' is not a valid expression input.'.format (Op = OpList[i+1])
+ raise ValueError (Msg)
+
+ elif Op == ')':
+ # Expression cannot start with )
+ if i == 0:
+ Msg = 'Expression cannot start with \')\''
+ raise ValueError (Msg)
+ # The previous op before ')' cannot be an operator
+ if self.IsValidOperator (OpList[i-1]):
+ Msg = '{Op} before \')\' is not a valid expression input.'.format (Op = OpList[i-1])
+ raise ValueError (Msg)
+ # The next op after ')' cannot be operand or unary operator
+ if (i + 1) < len (OpList) and (self.IsValidOperand (OpList[i+1]) or self.IsValidUnaryOperator (OpList[i+1])):
+ Msg = '{Op} after \')\' is not a valid expression input.'.format (Op = OpList[i+1])
+ raise ValueError (Msg)
+
+ elif self.IsValidOperand (Op):
+ # The next expression of operand cannot be operand or unary operator
+ if (i + 1) < len (OpList) and (self.IsValidOperand (OpList[i+1]) or self.IsValidUnaryOperator (OpList[i+1])):
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)
+ raise ValueError (Msg)
+
+ elif self.IsValidOperator (Op):
+ # The next op of operator cannot binocular operator
+ if (i + 1) < len (OpList) and self.IsValidBinocularOperator (OpList[i+1]):
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)
+ raise ValueError (Msg)
+ # The first op can not be binocular operator
+ if i == 0 and self.IsValidBinocularOperator (Op):
+ Msg = 'Expression cannot start with an operator {Op}.'.format (Op = Op)
+ raise ValueError (Msg)
+ # The last op can not be operator
+ if i == len (OpList) - 1:
+ Msg = 'Expression cannot ended with an operator {Op}.'.format (Op = Op)
+ raise ValueError (Msg)
+ # The next op of unary operator cannot be guid / version
+ if self.IsValidUnaryOperator (Op) and (self.IsValidGuid (OpList[i+1]) or self.IsValidVersion (OpList[i+1])):
+ Msg = '{Op} after {PrevOp} is not a valid expression input.'.format (Op = OpList[i+1], PrevOp = Op)
+ raise ValueError (Msg)
+
+ else:
+ Msg = '{Op} is not a valid expression input.'.format (Op = Op)
+ raise ValueError (Msg)
+ i += 1
+
+ def Encode (self):
+ # initialize
+ self.Depex = b''
+ self._DepexDump = []
+ OperandStack = []
+ OpeartorStack = []
+ OpList = self._DepexList
+
+ self.ValidateDepex ()
+
+ # convert
+ i = 0
+ while i < len (OpList):
+ Op = OpList[i]
+ if Op == 'DECLARE':
+ # This declare next expression value is a VERSION_STRING
+ i += 1
+ self.Depex += self.OpConverter.OpEncode (0x02, OpList[i][1:-1])
+
+ elif Op == '(':
+ OpeartorStack.append (Op)
+
+ elif Op == ')':
+ while (OpeartorStack and OpeartorStack[-1] != '('):
+ Operator = OpeartorStack.pop ()
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])
+ try:
+ OpeartorStack.pop () # pop out '('
+ except:
+ Msg = 'Pop out \'(\' failed, too many \')\''
+ raise ValueError (Msg)
+
+ elif self.IsValidGuid (Op):
+ if not OperandStack:
+ OperandStack.append (self.OpConverter.OpEncode (0x00, Op))
+ else:
+ # accroding to uefi spec 2.8, the guid/version operands is a reversed order in firmware comparison.
+ self.Depex += self.OpConverter.OpEncode (0x00, Op)
+ self.Depex += OperandStack.pop ()
+
+ elif self.IsValidVersion (Op):
+ if not OperandStack:
+ OperandStack.append (self.OpConverter.OpEncode (0x01, Op))
+ else:
+ # accroding to uefi spec 2.8, the guid/version operands is a reversed order in firmware comparison.
+ self.Depex += self.OpConverter.OpEncode (0x01, Op)
+ self.Depex += OperandStack.pop ()
+
+ elif self.IsValidBoolean (Op):
+ if Op.upper () == 'FALSE':
+ self.Depex += self.OpConverter.OpEncode (0x07)
+ elif Op.upper () == 'TRUE':
+ self.Depex += self.OpConverter.OpEncode (0x06)
+
+ elif self.IsValidOperator (Op):
+ while (OpeartorStack and OpeartorStack[-1] != '(' and self.PriorityNotGreater (OpeartorStack[-1], Op)):
+ Operator = OpeartorStack.pop ()
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])
+ OpeartorStack.append (Op)
+
+ i += 1
+
+ while OpeartorStack:
+ Operator = OpeartorStack.pop ()
+ if Operator == '(':
+ Msg = 'Too many \'(\'.'
+ raise ValueError (Msg)
+ self.Depex += self.OpConverter.OpEncode (self._opReference[Operator][1])
+ self.Depex += self.OpConverter.OpEncode (0x0D)
+
+ self._Valid = True
+ self._DepexSize = len (self.Depex)
+ return self.Depex + self.Payload
+
+ def Decode (self, Buffer):
+ # initialize
+ self.Depex = Buffer
+ OperandStack = []
+ DepexLen = 0
+
+ while True:
+ Opcode, Operand, OperandSize = self.OpConverter.OpDecode (Buffer[DepexLen:])
+ DepexLen += OperandSize + 1
+
+ if Opcode == 0x0D:
+ break
+
+ elif Opcode == 0x02:
+ if not OperandStack:
+ OperandStack.append ('DECLARE \"{String}\"'.format (String = Operand))
+ else:
+ PrevOperand = OperandStack.pop ()
+ OperandStack.append ('{Operand} DECLARE \"{String}\"'.format (Operand = PrevOperand, String = Operand))
+
+ elif Opcode in [0x00, 0x01]:
+ OperandStack.append (Operand)
+
+ elif Opcode == 0x06:
+ OperandStack.append ('TRUE')
+
+ elif Opcode == 0x07:
+ OperandStack.append ('FALSE')
+
+ elif self.IsValidOperator (self._opReferenceReverse[Opcode]):
+ Operator = self._opReferenceReverse[Opcode]
+ if self.IsValidUnaryOperator (self._opReferenceReverse[Opcode]) and len (OperandStack) >= 1:
+ Oprand = OperandStack.pop ()
+ OperandStack.append (' ( {Operator} {Oprand} )'.format (Operator = Operator, Oprand = Oprand))
+ elif self.IsValidBinocularOperator (self._opReferenceReverse[Opcode]) and len (OperandStack) >= 2:
+ Oprand1 = OperandStack.pop ()
+ Oprand2 = OperandStack.pop ()
+ OperandStack.append (' ( {Oprand1} {Operator} {Oprand2} )'.format (Operator = Operator, Oprand1 = Oprand1, Oprand2 = Oprand2))
+ else:
+ Msg = 'No enough Operands for {Opcode:02X}.'.format (Opcode = Opcode)
+ raise ValueError (Msg)
+
+ else:
+ Msg = '{Opcode:02X} is not a valid OpCode.'.format (Opcode = Opcode)
+ raise ValueError (Msg)
+
+ self.DepexExp = OperandStack[0].strip (' ')
+ self.Payload = Buffer[DepexLen:]
+ self._Valid = True
+ self._DepexSize = DepexLen
+ return self.Payload
+
+
+ def DumpInfo (self):
+ DepexLen = 0
+ Opcode = None
+ Buffer = self.Depex
+
+ if self._Valid == True:
+ print ('EFI_FIRMWARE_IMAGE_DEP.Dependencies = {')
+ while Opcode != 0x0D:
+ Opcode, Operand, OperandSize = self.OpConverter.OpDecode (Buffer[DepexLen:])
+ DepexLen += OperandSize + 1
+ if Operand:
+ print (' {Opcode:02X}, {Operand},'.format (Opcode = Opcode, Operand = Operand))
+ else:
+ print (' {Opcode:02X},'.format (Opcode = Opcode))
+ print ('}')
+
+ print ('sizeof (EFI_FIRMWARE_IMAGE_DEP.Dependencies) = {Size:08X}'.format (Size = self._DepexSize))
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
new file mode 100755
index 00000000..cd64cc7a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
@@ -0,0 +1,190 @@
+## @file
+# Module that encodes and decodes a EFI_FIRMWARE_IMAGE_AUTHENTICATION with
+# certificate data and payload data.
+#
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+'''
+FmpAuthHeader
+'''
+
+import struct
+import uuid
+
+class FmpAuthHeaderClass (object):
+ # ///
+ # /// Image Attribute -Authentication Required
+ # ///
+ # typedef struct {
+ # ///
+ # /// It is included in the signature of AuthInfo. It is used to ensure freshness/no replay.
+ # /// It is incremented during each firmware image operation.
+ # ///
+ # UINT64 MonotonicCount;
+ # ///
+ # /// Provides the authorization for the firmware image operations. It is a signature across
+ # /// the image data and the Monotonic Count value. Caller uses the private key that is
+ # /// associated with a public key that has been provisioned via the key exchange.
+ # /// Because this is defined as a signature, WIN_CERTIFICATE_UEFI_GUID.CertType must
+ # /// be EFI_CERT_TYPE_PKCS7_GUID.
+ # ///
+ # WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+ # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
+ #
+ # ///
+ # /// Certificate which encapsulates a GUID-specific digital signature
+ # ///
+ # typedef struct {
+ # ///
+ # /// This is the standard WIN_CERTIFICATE header, where
+ # /// wCertificateType is set to WIN_CERT_TYPE_EFI_GUID.
+ # ///
+ # WIN_CERTIFICATE Hdr;
+ # ///
+ # /// This is the unique id which determines the
+ # /// format of the CertData. .
+ # ///
+ # EFI_GUID CertType;
+ # ///
+ # /// The following is the certificate data. The format of
+ # /// the data is determined by the CertType.
+ # /// If CertType is EFI_CERT_TYPE_RSA2048_SHA256_GUID,
+ # /// the CertData will be EFI_CERT_BLOCK_RSA_2048_SHA256 structure.
+ # ///
+ # UINT8 CertData[1];
+ # } WIN_CERTIFICATE_UEFI_GUID;
+ #
+ # ///
+ # /// The WIN_CERTIFICATE structure is part of the PE/COFF specification.
+ # ///
+ # typedef struct {
+ # ///
+ # /// The length of the entire certificate,
+ # /// including the length of the header, in bytes.
+ # ///
+ # UINT32 dwLength;
+ # ///
+ # /// The revision level of the WIN_CERTIFICATE
+ # /// structure. The current revision level is 0x0200.
+ # ///
+ # UINT16 wRevision;
+ # ///
+ # /// The certificate type. See WIN_CERT_TYPE_xxx for the UEFI
+ # /// certificate types. The UEFI specification reserves the range of
+ # /// certificate type values from 0x0EF0 to 0x0EFF.
+ # ///
+ # UINT16 wCertificateType;
+ # ///
+ # /// The following is the actual certificate. The format of
+ # /// the certificate depends on wCertificateType.
+ # ///
+ # /// UINT8 bCertificate[ANYSIZE_ARRAY];
+ # ///
+ # } WIN_CERTIFICATE;
+ #
+ # #define WIN_CERT_TYPE_EFI_GUID 0x0EF1
+ #
+ # ///
+ # /// This identifies a signature containing a DER-encoded PKCS #7 version 1.5 [RFC2315]
+ # /// SignedData value.
+ # ///
+ # #define EFI_CERT_TYPE_PKCS7_GUID \
+ # { \
+ # 0x4aafd29d, 0x68df, 0x49ee, {0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7} \
+ # }
+
+ _StructFormat = '<QIHH16s'
+ _StructSize = struct.calcsize (_StructFormat)
+
+ _MonotonicCountFormat = '<Q'
+ _MonotonicCountSize = struct.calcsize (_MonotonicCountFormat)
+
+ _StructAuthInfoFormat = '<IHH16s'
+ _StructAuthInfoSize = struct.calcsize (_StructAuthInfoFormat)
+
+ _WIN_CERT_REVISION = 0x0200
+ _WIN_CERT_TYPE_EFI_GUID = 0x0EF1
+ _EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID ('4aafd29d-68df-49ee-8aa9-347d375665a7')
+
+ def __init__ (self):
+ self._Valid = False
+ self.MonotonicCount = 0
+ self.dwLength = self._StructAuthInfoSize
+ self.wRevision = self._WIN_CERT_REVISION
+ self.wCertificateType = self._WIN_CERT_TYPE_EFI_GUID
+ self.CertType = self._EFI_CERT_TYPE_PKCS7_GUID
+ self.CertData = b''
+ self.Payload = b''
+
+
+ def Encode (self):
+ if self.wRevision != self._WIN_CERT_REVISION:
+ raise ValueError
+ if self.wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:
+ raise ValueError
+ if self.CertType != self._EFI_CERT_TYPE_PKCS7_GUID:
+ raise ValueError
+ self.dwLength = self._StructAuthInfoSize + len (self.CertData)
+
+ FmpAuthHeader = struct.pack (
+ self._StructFormat,
+ self.MonotonicCount,
+ self.dwLength,
+ self.wRevision,
+ self.wCertificateType,
+ self.CertType.bytes_le
+ )
+ self._Valid = True
+
+ return FmpAuthHeader + self.CertData + self.Payload
+
+ def Decode (self, Buffer):
+ if len (Buffer) < self._StructSize:
+ raise ValueError
+ (MonotonicCount, dwLength, wRevision, wCertificateType, CertType) = \
+ struct.unpack (
+ self._StructFormat,
+ Buffer[0:self._StructSize]
+ )
+ if dwLength < self._StructAuthInfoSize:
+ raise ValueError
+ if wRevision != self._WIN_CERT_REVISION:
+ raise ValueError
+ if wCertificateType != self._WIN_CERT_TYPE_EFI_GUID:
+ raise ValueError
+ if CertType != self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le:
+ raise ValueError
+ self.MonotonicCount = MonotonicCount
+ self.dwLength = dwLength
+ self.wRevision = wRevision
+ self.wCertificateType = wCertificateType
+ self.CertType = uuid.UUID (bytes_le = CertType)
+ self.CertData = Buffer[self._StructSize:self._MonotonicCountSize + self.dwLength]
+ self.Payload = Buffer[self._MonotonicCountSize + self.dwLength:]
+ self._Valid = True
+ return self.Payload
+
+ def IsSigned (self, Buffer):
+ if len (Buffer) < self._StructSize:
+ return False
+ (MonotonicCount, dwLength, wRevision, wCertificateType, CertType) = \
+ struct.unpack (
+ self._StructFormat,
+ Buffer[0:self._StructSize]
+ )
+ if CertType != self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le:
+ return False
+ return True
+
+ def DumpInfo (self):
+ if not self._Valid:
+ raise ValueError
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount = {MonotonicCount:016X}'.format (MonotonicCount = self.MonotonicCount))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.dwLength = {dwLength:08X}'.format (dwLength = self.dwLength))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevision = {wRevision:04X}'.format (wRevision = self.wRevision))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertificateType = {wCertificateType:04X}'.format (wCertificateType = self.wCertificateType))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType = {Guid}'.format (Guid = str(self.CertType).upper()))
+ print ('sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) = {Size:08X}'.format (Size = len (self.CertData)))
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))
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 ()
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
new file mode 100755
index 00000000..109c1e49
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
@@ -0,0 +1,130 @@
+## @file
+# Module that encodes and decodes a EFI_CAPSULE_HEADER with a payload
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+'''
+UefiCapsuleHeader
+'''
+
+import struct
+import uuid
+
+class UefiCapsuleHeaderClass (object):
+ # typedef struct {
+ # ///
+ # /// A GUID that defines the contents of a capsule.
+ # ///
+ # EFI_GUID CapsuleGuid;
+ # ///
+ # /// The size of the capsule header. This may be larger than the size of
+ # /// the EFI_CAPSULE_HEADER since CapsuleGuid may imply
+ # /// extended header entries
+ # ///
+ # UINT32 HeaderSize;
+ # ///
+ # /// Bit-mapped list describing the capsule attributes. The Flag values
+ # /// of 0x0000 - 0xFFFF are defined by CapsuleGuid. Flag values
+ # /// of 0x10000 - 0xFFFFFFFF are defined by this specification
+ # ///
+ # UINT32 Flags;
+ # ///
+ # /// Size in bytes of the capsule.
+ # ///
+ # UINT32 CapsuleImageSize;
+ # } EFI_CAPSULE_HEADER;
+ #
+ # #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
+ # #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
+ # #define CAPSULE_FLAGS_INITIATE_RESET 0x00040000
+ #
+ _StructFormat = '<16sIIII'
+ _StructSize = struct.calcsize (_StructFormat)
+
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID = uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')
+
+ _CAPSULE_FLAGS_PERSIST_ACROSS_RESET = 0x00010000
+ _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE = 0x00020000
+ _CAPSULE_FLAGS_INITIATE_RESET = 0x00040000
+
+ def __init__ (self):
+ self._Valid = False
+ self.CapsuleGuid = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID
+ self.HeaderSize = self._StructSize
+ self.OemFlags = 0x0000
+ self.PersistAcrossReset = False
+ self.PopulateSystemTable = False
+ self.InitiateReset = False
+ self.CapsuleImageSize = self.HeaderSize
+ self.Payload = b''
+
+ def Encode (self):
+ Flags = self.OemFlags
+ if self.PersistAcrossReset:
+ Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET
+ if self.PopulateSystemTable:
+ Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
+ if self.InitiateReset:
+ Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET
+
+ self.CapsuleImageSize = self.HeaderSize + len (self.Payload)
+
+ UefiCapsuleHeader = struct.pack (
+ self._StructFormat,
+ self.CapsuleGuid.bytes_le,
+ self.HeaderSize,
+ Flags,
+ self.CapsuleImageSize,
+ 0
+ )
+ self._Valid = True
+ return UefiCapsuleHeader + self.Payload
+
+ def Decode (self, Buffer):
+ if len (Buffer) < self._StructSize:
+ raise ValueError
+ (CapsuleGuid, HeaderSize, Flags, CapsuleImageSize, Reserved) = \
+ struct.unpack (
+ self._StructFormat,
+ Buffer[0:self._StructSize]
+ )
+ if HeaderSize < self._StructSize:
+ raise ValueError
+ if CapsuleImageSize != len (Buffer):
+ raise ValueError
+ self.CapsuleGuid = uuid.UUID (bytes_le = CapsuleGuid)
+ self.HeaderSize = HeaderSize
+ self.OemFlags = Flags & 0xffff
+ self.PersistAcrossReset = (Flags & self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0
+ self.PopulateSystemTable = (Flags & self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) != 0
+ self.InitiateReset = (Flags & self._CAPSULE_FLAGS_INITIATE_RESET) != 0
+ self.CapsuleImageSize = CapsuleImageSize
+ self.Payload = Buffer[self.HeaderSize:]
+
+ self._Valid = True
+ return self.Payload
+
+ def DumpInfo (self):
+ if not self._Valid:
+ raise ValueError
+ Flags = self.OemFlags
+ if self.PersistAcrossReset:
+ Flags = Flags | self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET
+ if self.PopulateSystemTable:
+ Flags = Flags | self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE
+ if self.InitiateReset:
+ Flags = Flags | self._CAPSULE_FLAGS_INITIATE_RESET
+ print ('EFI_CAPSULE_HEADER.CapsuleGuid = {Guid}'.format (Guid = str(self.CapsuleGuid).upper()))
+ print ('EFI_CAPSULE_HEADER.HeaderSize = {Size:08X}'.format (Size = self.HeaderSize))
+ print ('EFI_CAPSULE_HEADER.Flags = {Flags:08X}'.format (Flags = Flags))
+ print (' OEM Flags = {Flags:04X}'.format (Flags = self.OemFlags))
+ if self.PersistAcrossReset:
+ print (' CAPSULE_FLAGS_PERSIST_ACROSS_RESET')
+ if self.PopulateSystemTable:
+ print (' CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE')
+ if self.InitiateReset:
+ print (' CAPSULE_FLAGS_INITIATE_RESET')
+ print ('EFI_CAPSULE_HEADER.CapsuleImageSize = {Size:08X}'.format (Size = self.CapsuleImageSize))
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py
new file mode 100644
index 00000000..f9a73858
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py
@@ -0,0 +1,9 @@
+## @file
+# Python 'Common.Uefi.Capsule' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/__init__.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/__init__.py
new file mode 100644
index 00000000..47322db6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/Common/Uefi/__init__.py
@@ -0,0 +1,9 @@
+## @file
+# Python 'Common.Uefi' package initialization file.
+#
+# This file is required to make Python interpreter treat the directory
+# as containing package.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#