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>
|
2019-04-04 01:03:11 +02:00
|
|
|
# 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)))
|