audk/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py

131 lines
5.4 KiB
Python
Raw Normal View History

BaseTools/Capsule: Add Capsule Generation Tools https://bugzilla.tianocore.org/show_bug.cgi?id=945 Based on content from the following branch https://github.com/Microsoft/MS_UEFI/tree/share/beta/CapsuleTools * Convert C tools to Python * Add common python modules to: BaseTools/Source/Python/Common/Uefi/Capsule BaseTools/Source/Python/Common/Edk2/Capsule * Add GenerateCapsule.py to BaseTools/Source/Python/Capsule * Add Windows and Posix wrappers for GenerateCapsule.py usage: GenerateCapsule [-h] [-o OUTPUTFILE] (-e | -d | --dump-info) [--capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset}] [--capoemflag CAPSULEOEMFLAG] [--guid GUID] [--hardware-instance HARDWAREINSTANCE] [--monotonic-count MONOTONICCOUNT] [--fw-version FWVERSION] [--lsv LOWESTSUPPORTEDVERSION] [--pfx-file SIGNTOOLPFXFILE] [--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE] [--other-public-cert OPENSSLOTHERPUBLICCERTFILE] [--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE] [--signing-tool-path SIGNINGTOOLPATH] [--version] [-v] [-q] [--debug [0-9]] InputFile Generate a capsule. Copyright (c) 2018, Intel Corporation. All rights reserved. positional arguments: InputFile Input binary payload filename. optional arguments: -h, --help show this help message and exit -o OUTPUTFILE, --output OUTPUTFILE Output filename. -e, --encode Encode file -d, --decode Decode file --dump-info Display FMP Payload Header information --capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset} Capsule flag can be PersistAcrossReset, or PopulateSystemTable or InitiateReset or not set --capoemflag CAPSULEOEMFLAG Capsule OEM Flag is an integer between 0x0000 and 0xffff. --guid GUID The FMP/ESRT GUID in registry format. Required for encode operations. --hardware-instance HARDWAREINSTANCE The 64-bit hardware instance. The default is 0x0000000000000000 --monotonic-count MONOTONICCOUNT 64-bit monotonic count value in header. Default is 0x0000000000000000. --fw-version FWVERSION The 32-bit version of the binary payload (e.g. 0x11223344 or 5678). --lsv LOWESTSUPPORTEDVERSION The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). --pfx-file SIGNTOOLPFXFILE signtool PFX certificate filename. --signer-private-cert OPENSSLSIGNERPRIVATECERTFILE OpenSSL signer private certificate filename. --other-public-cert OPENSSLOTHERPUBLICCERTFILE OpenSSL other public certificate filename. --trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE OpenSSL trusted public certificate filename. --signing-tool-path SIGNINGTOOLPATH Path to signtool or OpenSSL tool. Optional if path to tools are already in PATH. --version show program's version number and exit -v, --verbose Turn on verbose output with informational messages printed, including capsule headers and warning messages. -q, --quiet Disable all messages except fatal errors. --debug [0-9] Set debug level Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yonghong Zhu <yonghong.zhu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
2018-05-02 05:54:46 +02:00
## @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
BaseTools/Capsule: Add Capsule Generation Tools https://bugzilla.tianocore.org/show_bug.cgi?id=945 Based on content from the following branch https://github.com/Microsoft/MS_UEFI/tree/share/beta/CapsuleTools * Convert C tools to Python * Add common python modules to: BaseTools/Source/Python/Common/Uefi/Capsule BaseTools/Source/Python/Common/Edk2/Capsule * Add GenerateCapsule.py to BaseTools/Source/Python/Capsule * Add Windows and Posix wrappers for GenerateCapsule.py usage: GenerateCapsule [-h] [-o OUTPUTFILE] (-e | -d | --dump-info) [--capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset}] [--capoemflag CAPSULEOEMFLAG] [--guid GUID] [--hardware-instance HARDWAREINSTANCE] [--monotonic-count MONOTONICCOUNT] [--fw-version FWVERSION] [--lsv LOWESTSUPPORTEDVERSION] [--pfx-file SIGNTOOLPFXFILE] [--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE] [--other-public-cert OPENSSLOTHERPUBLICCERTFILE] [--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE] [--signing-tool-path SIGNINGTOOLPATH] [--version] [-v] [-q] [--debug [0-9]] InputFile Generate a capsule. Copyright (c) 2018, Intel Corporation. All rights reserved. positional arguments: InputFile Input binary payload filename. optional arguments: -h, --help show this help message and exit -o OUTPUTFILE, --output OUTPUTFILE Output filename. -e, --encode Encode file -d, --decode Decode file --dump-info Display FMP Payload Header information --capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset} Capsule flag can be PersistAcrossReset, or PopulateSystemTable or InitiateReset or not set --capoemflag CAPSULEOEMFLAG Capsule OEM Flag is an integer between 0x0000 and 0xffff. --guid GUID The FMP/ESRT GUID in registry format. Required for encode operations. --hardware-instance HARDWAREINSTANCE The 64-bit hardware instance. The default is 0x0000000000000000 --monotonic-count MONOTONICCOUNT 64-bit monotonic count value in header. Default is 0x0000000000000000. --fw-version FWVERSION The 32-bit version of the binary payload (e.g. 0x11223344 or 5678). --lsv LOWESTSUPPORTEDVERSION The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). --pfx-file SIGNTOOLPFXFILE signtool PFX certificate filename. --signer-private-cert OPENSSLSIGNERPRIVATECERTFILE OpenSSL signer private certificate filename. --other-public-cert OPENSSLOTHERPUBLICCERTFILE OpenSSL other public certificate filename. --trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE OpenSSL trusted public certificate filename. --signing-tool-path SIGNINGTOOLPATH Path to signtool or OpenSSL tool. Optional if path to tools are already in PATH. --version show program's version number and exit -v, --verbose Turn on verbose output with informational messages printed, including capsule headers and warning messages. -q, --quiet Disable all messages except fatal errors. --debug [0-9] Set debug level Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yonghong Zhu <yonghong.zhu@intel.com> Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
2018-05-02 05:54:46 +02:00
#
'''
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)))