From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.100; helo=mga07.intel.com; envelope-from=michael.d.kinney@intel.com; receiver=edk2-devel@lists.01.org Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id E0C7A207E4DEC for ; Thu, 31 May 2018 09:36:07 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 May 2018 09:36:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,463,1520924400"; d="scan'208";a="59291819" Received: from orsmsx101.amr.corp.intel.com ([10.22.225.128]) by fmsmga004.fm.intel.com with ESMTP; 31 May 2018 09:36:07 -0700 Received: from orsmsx111.amr.corp.intel.com (10.22.240.12) by ORSMSX101.amr.corp.intel.com (10.22.225.128) with Microsoft SMTP Server (TLS) id 14.3.319.2; Thu, 31 May 2018 09:36:06 -0700 Received: from orsmsx113.amr.corp.intel.com ([169.254.9.88]) by ORSMSX111.amr.corp.intel.com ([169.254.12.50]) with mapi id 14.03.0319.002; Thu, 31 May 2018 09:36:06 -0700 From: "Kinney, Michael D" To: "Gao, Liming" , "edk2-devel@lists.01.org" , "Kinney, Michael D" CC: Sean Brogan , "Yao, Jiewen" , "Zhu, Yonghong" Thread-Topic: [RFC 1/1] BaseTools/Capsule: Add Capsule Generation Tools Thread-Index: AQHT96BP+mIl8+Mh0E+fBZ5GI4LJYKRKXJEA//+u3JA= Date: Thu, 31 May 2018 16:36:06 +0000 Message-ID: References: <20180529225635.22536-1-michael.d.kinney@intel.com> <20180529225635.22536-2-michael.d.kinney@intel.com> <4A89E2EF3DFEDB4C8BFDE51014F606A14E291226@SHSMSX104.ccr.corp.intel.com> In-Reply-To: <4A89E2EF3DFEDB4C8BFDE51014F606A14E291226@SHSMSX104.ccr.corp.intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [10.22.254.138] MIME-Version: 1.0 Subject: Re: [RFC 1/1] BaseTools/Capsule: Add Capsule Generation Tools X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 May 2018 16:36:08 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Liming, The C code was in the original content from MS_UEFI. It may be possible to update GenFds to use the new python modules. I have not investigated this yet. Mike > -----Original Message----- > From: Gao, Liming > Sent: Thursday, May 31, 2018 7:26 AM > To: Kinney, Michael D ; > edk2-devel@lists.01.org > Cc: Sean Brogan ; Yao, Jiewen > ; Zhu, Yonghong > > Subject: RE: [RFC 1/1] BaseTools/Capsule: Add Capsule > Generation Tools >=20 > Mike: > Which C tool is converted? Does it support all capsule > generation functionality in GenFv tool? >=20 > And, GenFds has the logic to generate FMP capsule. Can > they share same logic? >=20 > Thanks > Liming > > -----Original Message----- > > From: Kinney, Michael D > > Sent: Wednesday, May 30, 2018 6:57 AM > > To: edk2-devel@lists.01.org > > Cc: Kinney, Michael D ; > Sean Brogan ; Yao, Jiewen > > ; Zhu, Yonghong > ; Gao, Liming > > > Subject: [RFC 1/1] BaseTools/Capsule: Add Capsule > Generation Tools > > > > From: "Kinney, Michael D" > > > > https://bugzilla.tianocore.org/show_bug.cgi?id=3D945 > > > > Based on content from the following branch > > > > > https://github.com/Microsoft/MS_UEFI/tree/share/beta/Cap > suleTools > > > > * 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] > > [--version FWVERSION] [--lsv > LOWESTSUPPORTEDVERSION] > > [--pfx-file SIGNTOOLPFXFILE] > > [--signer-private-cert > OPENSSLSIGNERPRIVATECERTFILE] > > [--other-public-cert > OPENSSLOTHERPUBLICCERTFILE] > > [--trusted-public-cert > OPENSSLTRUSTEDPUBLICCERTFILE] > > [--signing-tool-path > SIGNINGTOOLPATH] [-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. > > --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 Open SLL > tool. Optional if path to > > tools are already in PATH. > > -v, --verbose Increase output messages > > -q, --quiet Reduce output messages > > --debug [0-9] Set debug level > > > > Cc: Sean Brogan > > Cc: Jiewen Yao > > Cc: Yonghong Zhu > > Cc: Liming Gao > > Contributed-under: TianoCore Contribution Agreement > 1.1 > > Signed-off-by: Michael D Kinney > > > --- > > BaseTools/BinWrappers/PosixLike/GenerateCapsule | > 14 + > > .../BinWrappers/WindowsLike/GenerateCapsule.bat | > 1 + > > BaseTools/Source/Python/Capsule/GenerateCapsule.py | > 500 +++++++++++++++++++++ > > .../Python/Common/Edk2/Capsule/FmpPayloadHeader.py | > 91 ++++ > > .../Source/Python/Common/Edk2/Capsule/__init__.py | > 15 + > > BaseTools/Source/Python/Common/Edk2/__init__.py | > 15 + > > .../Python/Common/Uefi/Capsule/FmpAuthHeader.py | > 184 ++++++++ > > .../Python/Common/Uefi/Capsule/FmpCapsuleHeader.py | > 302 +++++++++++++ > > .../Common/Uefi/Capsule/UefiCapsuleHeader.py | > 136 ++++++ > > .../Source/Python/Common/Uefi/Capsule/__init__.py | > 15 + > > BaseTools/Source/Python/Common/Uefi/__init__.py | > 15 + > > 11 files changed, 1288 insertions(+) > > create mode 100644 > BaseTools/BinWrappers/PosixLike/GenerateCapsule > > create mode 100644 > BaseTools/BinWrappers/WindowsLike/GenerateCapsule.bat > > create mode 100644 > BaseTools/Source/Python/Capsule/GenerateCapsule.py > > create mode 100644 > BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayloadHe > ader.py > > create mode 100644 > BaseTools/Source/Python/Common/Edk2/Capsule/__init__.py > > create mode 100644 > BaseTools/Source/Python/Common/Edk2/__init__.py > > create mode 100644 > BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeade > r.py > > create mode 100644 > BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHe > ader.py > > create mode 100644 > BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleH > eader.py > > create mode 100644 > BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py > > create mode 100644 > BaseTools/Source/Python/Common/Uefi/__init__.py > > > > diff --git > a/BaseTools/BinWrappers/PosixLike/GenerateCapsule > b/BaseTools/BinWrappers/PosixLike/GenerateCapsule > > new file mode 100644 > > index 0000000000..59a6c8ba43 > > --- /dev/null > > +++ b/BaseTools/BinWrappers/PosixLike/GenerateCapsule > > @@ -0,0 +1,14 @@ > > +#!/usr/bin/env bash > > +#python `dirname $0`/RunToolFromSource.py `basename > $0` $* > > + > > +# If a python2 command is available, use it in > preference to python > > +if command -v python2 >/dev/null 2>&1; then > > + python_exe=3Dpython2 > > +fi > > + > > +full_cmd=3D${BASH_SOURCE:-$0} # see > http://mywiki.wooledge.org/BashFAQ/028 for a discussion > of why $0 is not a good choice here > > +dir=3D$(dirname "$full_cmd") > > +cmd=3D${full_cmd##*/} > > + > > +export > PYTHONPATH=3D"$dir/../../Source/Python${PYTHONPATH:+:"$PYT > HONPATH"}" > > +exec "${python_exe:-python}" > "$dir/../../Source/Python/Capsule/$cmd.py" "$@" > > diff --git > a/BaseTools/BinWrappers/WindowsLike/GenerateCapsule.bat > b/BaseTools/BinWrappers/WindowsLike/GenerateCapsule.bat > > new file mode 100644 > > index 0000000000..ca442d181b > > --- /dev/null > > +++ > b/BaseTools/BinWrappers/WindowsLike/GenerateCapsule.bat > > @@ -0,0 +1 @@ > > +@%PYTHON_HOME%\python.exe > %BASE_TOOLS_PATH%\Source\Python\Capsule\GenerateCapsule. > py %* > > diff --git > a/BaseTools/Source/Python/Capsule/GenerateCapsule.py > b/BaseTools/Source/Python/Capsule/GenerateCapsule.py > > new file mode 100644 > > index 0000000000..32ab95c3e0 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Capsule/GenerateCapsule.py > > @@ -0,0 +1,500 @@ > > +## @file > > +# Generate a capsule. > > +# > > +# Copyright (c) 2018, Intel Corporation. All rights > reserved.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > + > > +''' > > +GenerateCapsule > > +''' > > + > > +import sys > > +import argparse > > +import uuid > > +import struct > > +import subprocess > > +import os > > +import tempfile > > +import shutil > > +from Common.Uefi.Capsule.UefiCapsuleHeader import > UefiCapsuleHeaderClass > > +from Common.Uefi.Capsule.FmpCapsuleHeader import > FmpCapsuleHeaderClass > > +from Common.Uefi.Capsule.FmpAuthHeader import > FmpAuthHeaderClass > > +from Common.Edk2.Capsule.FmpPayloadHeader import > FmpPayloadHeaderClass > > + > > +# > > +# Globals for help information > > +# > > +__prog__ =3D 'GenerateCapsule' > > +__copyright__ =3D 'Copyright (c) 2018, Intel > Corporation. All rights reserved.' > > +__description__ =3D 'Generate a capsule.\n' > > + > > +def SignPayloadSignTool (Payload, ToolPath, PfxFile): > > + # > > + # Create a temporary directory > > + # > > + TempDirectoryName =3D tempfile.mkdtemp() > > + > > + # > > + # Generate temp file name for the payload > contents > > + # > > + TempFileName =3D os.path.join (TempDirectoryName, > 'Payload.bin') > > + > > + # > > + # Create temporary payload file for signing > > + # > > + try: > > + File =3D open (TempFileName, mode=3D'wb') > > + File.write (Payload) > > + File.close () > > + except: > > + shutil.rmtree (TempDirectoryName) > > + raise ValueError ('GenerateCapsule: error: > can not write temporary payload file.') > > + > > + # > > + # Build signtool command > > + # > > + if ToolPath is None: > > + ToolPath =3D '' > > + Command =3D '' > > + Command =3D Command + '"{Path}" '.format (Path =3D > os.path.join (ToolPath, 'signtool.exe')) > > + Command =3D Command + 'sign /fd sha256 /p7ce > DetachedSignedData /p7co 1.2.840.113549.1.7.2 ' > > + Command =3D Command + '/p7 {TempDir} '.format > (TempDir =3D TempDirectoryName) > > + Command =3D Command + '/f {PfxFile} '.format > (PfxFile =3D PfxFile) > > + Command =3D Command + TempFileName > > + > > + # > > + # Sign the input file using the specified private > key > > + # > > + try: > > + Process =3D subprocess.Popen (Command, stdin =3D > subprocess.PIPE, stdout =3D subprocess.PIPE, stderr =3D > subprocess.PIPE, shell =3D > > True) > > + Result =3D Process.communicate('') > > + except: > > + shutil.rmtree (TempDirectoryName) > > + raise ValueError ('GenerateCapsule: error: > can not run signtool.') > > + > > + if Process.returncode !=3D 0: > > + shutil.rmtree (TempDirectoryName) > > + print (Result[1].decode()) > > + raise ValueError ('GenerateCapsule: error: > signtool failed.') > > + > > + # > > + # Read the signature from the generated output > file > > + # > > + try: > > + File =3D open (TempFileName + '.p7', mode=3D'rb') > > + Signature =3D File.read () > > + File.close () > > + except: > > + shutil.rmtree (TempDirectoryName) > > + raise ValueError ('GenerateCapsule: error: > can not read signature file.') > > + > > + shutil.rmtree (TempDirectoryName) > > + return Signature > > + > > +def VerifyPayloadSignTool (Payload, CertData, > ToolPath, PfxFile): > > + print ('signtool verify is not supported.') > > + raise ValueError ('GenerateCapsule: error: > signtool verify is not supported.') > > + > > +def SignPayloadOpenSsl (Payload, ToolPath, > SignerPrivateCertFile, OtherPublicCertFile, > TrustedPublicCertFile): > > + # > > + # Build openssl command > > + # > > + if ToolPath is None: > > + ToolPath =3D '' > > + Command =3D '' > > + Command =3D Command + '"{Path}" '.format (Path =3D > os.path.join (ToolPath, 'openssl')) > > + Command =3D Command + 'smime -sign -binary -outform > DER -md sha256 ' > > + Command =3D Command + '-signer "{Private}" - > certfile "{Public}"'.format (Private =3D > SignerPrivateCertFile, Public =3D > > OtherPublicCertFile) > > + > > + # > > + # Sign the input file using the specified private > key and capture signature from STDOUT > > + # > > + try: > > + Process =3D subprocess.Popen (Command, stdin =3D > subprocess.PIPE, stdout =3D subprocess.PIPE, stderr =3D > subprocess.PIPE, shell =3D > > True) > > + Result =3D Process.communicate(input =3D Payload) > > + Signature =3D Result[0] > > + except: > > + raise ValueError ('GenerateCapsule: error: > can not run openssl.') > > + > > + if Process.returncode !=3D 0: > > + print (Result[1].decode()) > > + raise ValueError ('GenerateCapsule: error: > openssl failed.') > > + > > + return Signature > > + > > +def VerifyPayloadOpenSsl (Payload, CertData, > ToolPath, SignerPrivateCertFile, OtherPublicCertFile, > TrustedPublicCertFile): > > + # > > + # Create a temporary directory > > + # > > + TempDirectoryName =3D tempfile.mkdtemp() > > + > > + # > > + # Generate temp file name for the payload > contents > > + # > > + TempFileName =3D os.path.join (TempDirectoryName, > 'Payload.bin') > > + > > + # > > + # Create temporary payload file for verification > > + # > > + try: > > + File =3D open (TempFileName, mode=3D'wb') > > + File.write (Payload) > > + File.close () > > + except: > > + shutil.rmtree (TempDirectoryName) > > + raise ValueError ('GenerateCapsule: error: > can not write temporary payload file.') > > + > > + # > > + # Build openssl command > > + # > > + if ToolPath is None: > > + ToolPath =3D '' > > + Command =3D '' > > + Command =3D Command + '"{Path}" '.format (Path =3D > os.path.join (ToolPath, 'openssl')) > > + Command =3D Command + 'smime -verify -inform DER ' > > + Command =3D Command + '-content {Content} -CAfile > "{Public}"'.format (Content =3D TempFileName, Public =3D > TrustedPublicCertFile) > > + > > + # > > + # Verify signature > > + # > > + try: > > + Process =3D subprocess.Popen (Command, stdin =3D > subprocess.PIPE, stdout =3D subprocess.PIPE, stderr =3D > subprocess.PIPE, shell =3D > > True) > > + Result =3D Process.communicate(input =3D > CertData) > > + except: > > + shutil.rmtree (TempDirectoryName) > > + raise ValueError ('GenerateCapsule: error: > can not run openssl.') > > + > > + if Process.returncode !=3D 0: > > + shutil.rmtree (TempDirectoryName) > > + print (Result[1].decode()) > > + raise ValueError ('GenerateCapsule: error: > openssl failed.') > > + > > + shutil.rmtree (TempDirectoryName) > > + return Payload > > + > > +if __name__ =3D=3D '__main__': > > + def convert_arg_line_to_args(arg_line): > > + for arg in arg_line.split(): > > + if not arg.strip(): > > + continue > > + yield arg > > + > > + def ValidateUnsignedInteger (Argument): > > + try: > > + Value =3D int (Argument, 0) > > + except: > > + Message =3D '{Argument} is not a valid > integer value.'.format (Argument =3D Argument) > > + raise argparse.ArgumentTypeError > (Message) > > + if Value < 0: > > + Message =3D '{Argument} is a negative > value.'.format (Argument =3D Argument) > > + raise argparse.ArgumentTypeError > (Message) > > + return Value > > + > > + def ValidateRegistryFormatGuid (Argument): > > + try: > > + Value =3D uuid.UUID (Argument) > > + except: > > + Message =3D '{Argument} is not a valid > registry format GUID value.'.format (Argument =3D > Argument) > > + raise argparse.ArgumentTypeError > (Message) > > + return Value > > + > > + # > > + # Create command line argument parser object > > + # > > + parser =3D argparse.ArgumentParser ( > > + prog =3D __prog__, > > + description =3D __description__ > + __copyright__, > > + conflict_handler =3D 'resolve', > > + fromfile_prefix_chars =3D '@' > > + ) > > + parser.convert_arg_line_to_args =3D > convert_arg_line_to_args > > + > > + # > > + # Add input and output file arguments > > + # > > + parser.add_argument("InputFile", type =3D > argparse.FileType('rb'), > > + help =3D "Input binary payload > filename.") > > + parser.add_argument("-o", "--output", dest =3D > 'OutputFile', type =3D argparse.FileType('wb'), > > + help =3D "Output filename.") > > + # > > + # Add group for -e and -d flags that are mutually > exclusive and required > > + # > > + group =3D parser.add_mutually_exclusive_group > (required =3D True) > > + group.add_argument ("-e", "--encode", dest =3D > 'Encode', action =3D "store_true", > > + help =3D "Encode file") > > + group.add_argument ("-d", "--decode", dest =3D > 'Decode', action =3D "store_true", > > + help =3D "Decode file") > > + group.add_argument ("--dump-info", dest =3D > 'DumpInfo', action =3D "store_true", > > + help =3D "Display FMP Payload > Header information") > > + # > > + # Add optional arguments for this command > > + # > > + parser.add_argument ("--capflag", dest =3D > 'CapsuleFlag', action=3D'append', default =3D [], > > + > choices=3D['PersistAcrossReset', 'PopulateSystemTable', > 'InitiateReset'], > > + help =3D "Capsule flag can be > PersistAcrossReset, or PopulateSystemTable or > InitiateReset or not set") > > + parser.add_argument ("--capoemflag", dest =3D > 'CapsuleOemFlag', type =3D ValidateUnsignedInteger, > default =3D 0x0000, > > + help =3D "Capsule OEM Flag is > an integer between 0x0000 and 0xffff.") > > + > > + parser.add_argument ("--guid", dest =3D 'Guid', > type =3D ValidateRegistryFormatGuid, > > + help =3D "The FMP/ESRT GUID in > registry format. Required for encode operations.") > > + parser.add_argument ("--hardware-instance", dest > =3D 'HardwareInstance', type =3D ValidateUnsignedInteger, > default =3D > > 0x0000000000000000, > > + help =3D "The 64-bit hardware > instance. The default is 0x0000000000000000") > > + > > + > > + parser.add_argument ("--monotonic-count", dest =3D > 'MonotonicCount', type =3D ValidateUnsignedInteger, > default =3D > > 0x0000000000000000, > > + help =3D "64-bit monotonic > count value in header. Default is 0x0000000000000000.") > > + > > + parser.add_argument ("--version", dest =3D > 'FwVersion', type =3D ValidateUnsignedInteger, > > + help =3D "The 32-bit version > of the binary payload (e.g. 0x11223344 or 5678).") > > + parser.add_argument ("--lsv", dest =3D > 'LowestSupportedVersion', type =3D > ValidateUnsignedInteger, > > + help =3D "The 32-bit lowest > supported version of the binary payload (e.g. 0x11223344 > or 5678).") > > + > > + parser.add_argument ("--pfx-file", > dest=3D'SignToolPfxFile', type=3Dargparse.FileType('rb'), > > + help=3D"signtool PFX > certificate filename.") > > + > > + parser.add_argument ("--signer-private-cert", > dest=3D'OpenSslSignerPrivateCertFile', > type=3Dargparse.FileType('rb'), > > + help=3D"OpenSSL signer private > certificate filename.") > > + parser.add_argument ("--other-public-cert", > dest=3D'OpenSslOtherPublicCertFile', > type=3Dargparse.FileType('rb'), > > + help=3D"OpenSSL other public > certificate filename.") > > + parser.add_argument ("--trusted-public-cert", > dest=3D'OpenSslTrustedPublicCertFile', > type=3Dargparse.FileType('rb'), > > + help=3D"OpenSSL trusted public > certificate filename.") > > + > > + parser.add_argument ("--signing-tool-path", dest > =3D 'SigningToolPath', > > + help =3D "Path to signtool or > Open SLL tool. Optional if path to tools are already in > PATH.") > > + > > + # > > + # Add optional arguments common to all commands > > + # > > + parser.add_argument("-v", "--verbose", dest =3D > 'Verbose', action =3D "store_true", > > + help =3D "Increase output > messages") > > + parser.add_argument("-q", "--quiet", dest =3D > 'Quiet', action =3D "store_true", > > + help =3D "Reduce output > messages") > > + parser.add_argument("--debug", dest =3D 'Debug', > type =3D int, metavar =3D '[0-9]', choices =3D range(0,10), > default =3D 0, > > + help =3D "Set debug level") > > + > > + # > > + # Parse command line arguments > > + # > > + args =3D parser.parse_args() > > + > > + # > > + # Perform additional argument verification > > + # > > + if not args.DumpInfo and args.OutputFile is None: > > + parser.error ('the following arguments are > required for all commands except --dump-info: --output') > > + > > + if args.Encode and (args.Guid is None or > args.FwVersion is None or args.LowestSupportedVersion is > None): > > + parser.error ('the following arguments are > required: --version, --lsv, --guid') > > + > > + if not args.DumpInfo and not args.OutputFile: > > + parser.error ('the following arguments are > required: --output') > > + > > + if not args.DumpInfo: > > + if args.SignToolPfxFile is None and > args.OpenSslSignerPrivateCertFile is None and > args.OpenSslOtherPublicCertFile is None > > and args.OpenSslTrustedPublicCertFile is None: > > + parser.error ('certificate file arguments > are required: --pfx-file | [--signer-private-cert -- > other-public-cert > > --trusted-public-cert]') > > + > > + if args.SignToolPfxFile is not None: > > + if args.OpenSslSignerPrivateCertFile is not > None: > > + parser.error ('Providing both signtool > and OpenSSL options is not supported') > > + if args.OpenSslOtherPublicCertFile is not > None: > > + parser.error ('Providing both signtool > and OpenSSL options is not supported') > > + if args.OpenSslTrustedPublicCertFile is not > None: > > + parser.error ('Providing both signtool > and OpenSSL options is not supported') > > + args.SignToolPfxFile.close() > > + args.SignToolPfxFile =3D > args.SignToolPfxFile.name > > + > > + if not args.DumpInfo: > > + if args.SignToolPfxFile is None: > > + if args.OpenSslSignerPrivateCertFile is > None: > > + parser.error ('the following > arguments are required: --signer-private-cert') > > + if args.OpenSslOtherPublicCertFile is > None: > > + parser.error ('the following > arguments are required: --other-public-cert') > > + if args.OpenSslTrustedPublicCertFile is > None: > > + parser.error ('the following > arguments are required: --trusted-public-cert') > > + args.OpenSslSignerPrivateCertFile.close() > > + args.OpenSslOtherPublicCertFile.close() > > + args.OpenSslTrustedPublicCertFile.close() > > + args.OpenSslSignerPrivateCertFile =3D > args.OpenSslSignerPrivateCertFile.name > > + args.OpenSslOtherPublicCertFile =3D > args.OpenSslOtherPublicCertFile.name > > + args.OpenSslTrustedPublicCertFile =3D > args.OpenSslTrustedPublicCertFile.name > > + > > + # > > + # Read binary input file > > + # > > + try: > > + if args.Verbose: > > + print ('Read binary input file > {File}'.format (File =3D args.InputFile.name)) > > + Buffer =3D args.InputFile.read () > > + args.InputFile.close () > > + except: > > + print ('GenerateCapsule: error: can not read > binary input file {File}'.format (File =3D > args.InputFile.name)) > > + sys.exit (1) > > + > > + # > > + # Create objects > > + # > > + UefiCapsuleHeader =3D UefiCapsuleHeaderClass () > > + FmpCapsuleHeader =3D FmpCapsuleHeaderClass () > > + FmpAuthHeader =3D FmpAuthHeaderClass () > > + FmpPayloadHeader =3D FmpPayloadHeaderClass () > > + > > + if args.Encode: > > + try: > > + FmpPayloadHeader.FwVersion =3D > args.FwVersion > > + FmpPayloadHeader.LowestSupportedVersion =3D > args.LowestSupportedVersion > > + FmpPayloadHeader.Payload =3D > Buffer > > + Result =3D FmpPayloadHeader.Encode () > > + if args.Verbose: > > + FmpPayloadHeader.DumpInfo () > > + except: > > + print ('GenerateCapsule: error: can not > encode FMP Payload Header') > > + sys.exit (1) > > + > > + # > > + # Sign image with 64-bit MonotonicCount > appended to end of image > > + # > > + try: > > + if args.SignToolPfxFile is not None: > > + CertData =3D SignPayloadSignTool ( > > + Result + struct.pack > (' > + args.SigningToolPath, > > + args.SignToolPfxFile > > + ) > > + else: > > + CertData =3D SignPayloadOpenSsl ( > > + Result + struct.pack > (' > + args.SigningToolPath, > > + > args.OpenSslSignerPrivateCertFile, > > + > args.OpenSslOtherPublicCertFile, > > + > args.OpenSslTrustedPublicCertFile > > + ) > > + except: > > + print ('GenerateCapsule: error: can not > sign payload') > > + raise > > + sys.exit (1) > > + > > + try: > > + FmpAuthHeader.MonotonicCount =3D > args.MonotonicCount > > + FmpAuthHeader.CertData =3D CertData > > + FmpAuthHeader.Payload =3D Result > > + Result =3D FmpAuthHeader.Encode () > > + if args.Verbose: > > + FmpAuthHeader.DumpInfo () > > + except: > > + print ('GenerateCapsule: error: can not > encode FMP Auth Header') > > + sys.exit (1) > > + > > + try: > > + FmpCapsuleHeader.AddPayload (args.Guid, > Result, HardwareInstance =3D args.HardwareInstance) > > + Result =3D FmpCapsuleHeader.Encode () > > + if args.Verbose: > > + FmpCapsuleHeader.DumpInfo () > > + except: > > + print ('GenerateCapsule: error: can not > encode FMP Capsule Header') > > + sys.exit (1) > > + > > + try: > > + UefiCapsuleHeader.OemFlags =3D > args.CapsuleOemFlag > > + UefiCapsuleHeader.PersistAcrossReset =3D > 'PersistAcrossReset' in args.CapsuleFlag > > + UefiCapsuleHeader.PopulateSystemTable =3D > 'PopulateSystemTable' in args.CapsuleFlag > > + UefiCapsuleHeader.InitiateReset =3D > 'InitiateReset' in args.CapsuleFlag > > + UefiCapsuleHeader.Payload =3D > Result > > + Result =3D UefiCapsuleHeader.Encode () > > + if args.Verbose: > > + UefiCapsuleHeader.DumpInfo () > > + except: > > + print ('GenerateCapsule: error: can not > encode UEFI Capsule Header') > > + sys.exit (1) > > + > > + elif args.Decode: > > + try: > > + Result =3D UefiCapsuleHeader.Decode > (Buffer) > > + FmpCapsuleHeader.Decode (Result) > > + Result =3D > FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload > > + Result =3D FmpAuthHeader.Decode (Result) > > + > > + # > > + # Verify Image with 64-bit MonotonicCount > appended to end of image > > + # > > + try: > > + if args.SignToolPfxFile is not None: > > + CertData =3D VerifyPayloadSignTool ( > > + FmpAuthHeader.Payload > + struct.pack (' > + > FmpAuthHeader.CertData, > > + args.SigningToolPath, > > + args.SignToolPfxFile > > + ) > > + else: > > + CertData =3D VerifyPayloadOpenSsl ( > > + FmpAuthHeader.Payload > + struct.pack (' > + > FmpAuthHeader.CertData, > > + args.SigningToolPath, > > + > args.OpenSslSignerPrivateCertFile, > > + > args.OpenSslOtherPublicCertFile, > > + > args.OpenSslTrustedPublicCertFile > > + ) > > + except ValueError: > > + print ('GenerateCapsule: warning: can > not verify payload.') > > + > > + Result =3D FmpPayloadHeader.Decode (Result) > > + if args.Verbose: > > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') > > + UefiCapsuleHeader.DumpInfo () > > + print ('--------') > > + FmpCapsuleHeader.DumpInfo () > > + print ('--------') > > + FmpAuthHeader.DumpInfo () > > + print ('--------') > > + FmpPayloadHeader.DumpInfo () > > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') > > + except: > > + print ('GenerateCapsule: error: can not > decode capsule') > > + raise > > + sys.exit (1) > > + > > + elif args.DumpInfo: > > + try: > > + Result =3D UefiCapsuleHeader.Decode > (Buffer) > > + FmpCapsuleHeader.Decode (Result) > > + Result =3D > FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload > > + Result =3D FmpAuthHeader.Decode (Result) > > + Result =3D FmpPayloadHeader.Decode (Result) > > + > > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') > > + UefiCapsuleHeader.DumpInfo () > > + print ('--------') > > + FmpCapsuleHeader.DumpInfo () > > + print ('--------') > > + FmpAuthHeader.DumpInfo () > > + print ('--------') > > + FmpPayloadHeader.DumpInfo () > > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') > > + except: > > + print ('GenerateCapsule: error: can not > decode capsule') > > + sys.exit (1) > > + else: > > + print('GenerateCapsule: error: invalid > options') > > + sys.exit (1) > > + > > + # > > + # Write binary output file > > + # > > + if args.OutputFile is not None: > > + try: > > + if args.Verbose: > > + print ('Write binary output file > {File}'.format (File =3D args.OutputFile.name)) > > + args.OutputFile.write (Result) > > + args.OutputFile.close () > > + except: > > + print ('GenerateCapsule: error: can not > write binary output file {File}'.format (File =3D > args.OutputFile.name)) > > + sys.exit (1) > > + > > + if args.Verbose: > > + print('Success') > > diff --git > a/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayload > Header.py > > > b/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayload > Header.py > > new file mode 100644 > > index 0000000000..0ed51752d3 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayload > Header.py > > @@ -0,0 +1,91 @@ > > +## @file > > +# Module that encodes and decodes a > FMP_PAYLOAD_HEADER with a payload. > > +# The FMP_PAYLOAD_HEADER is processed by the > FmpPayloadHeaderLib in the > > +# FmpDevicePkg. > > +# > > +# Copyright (c) 2018, Intel Corporation. All rights > reserved.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > + > > +''' > > +FmpPayloadHeader > > +''' > > + > > +import struct > > + > > +def _SIGNATURE_32 (A, B, C, D): > > + return struct.unpack ('=3DI',bytearray (A + B + C + > D, 'ascii'))[0] > > + > > +def _SIGNATURE_32_TO_STRING (Signature): > > + return struct.pack (" > + > > +class FmpPayloadHeaderClass (object): > > + # > > + # typedef struct { > > + # UINT32 Signature; > > + # UINT32 HeaderSize; > > + # UINT32 FwVersion; > > + # UINT32 LowestSupportedVersion; > > + # } FMP_PAYLOAD_HEADER; > > + # > > + # #define FMP_PAYLOAD_HEADER_SIGNATURE > SIGNATURE_32 ('M', 'S', 'S', '1') > > + # > > + _StructFormat =3D ' > + _StructSize =3D struct.calcsize (_StructFormat) > > + > > + _FMP_PAYLOAD_HEADER_SIGNATURE =3D _SIGNATURE_32 > ('M', 'S', 'S', '1') > > + > > + def __init__ (self): > > + self._Valid =3D False > > + self.Signature =3D > self._FMP_PAYLOAD_HEADER_SIGNATURE > > + self.HeaderSize =3D > self._StructSize > > + self.FwVersion =3D 0x00000000 > > + self.LowestSupportedVersion =3D 0x00000000 > > + self.Payload =3D b'' > > + > > + def Encode (self): > > + FmpPayloadHeader =3D struct.pack ( > > + > self._StructFormat, > > + self.Signature, > > + self.HeaderSize, > > + self.FwVersion, > > + > self.LowestSupportedVersion > > + ) > > + self._Valid =3D True > > + return FmpPayloadHeader + self.Payload > > + > > + def Decode (self, Buffer): > > + if len (Buffer) < self._StructSize: > > + raise ValueError > > + (Signature, HeaderSize, FwVersion, > LowestSupportedVersion) =3D \ > > + struct.unpack ( > > + self._StructFormat, > > + Buffer[0:self._StructSize] > > + ) > > + if Signature !=3D > self._FMP_PAYLOAD_HEADER_SIGNATURE: > > + raise ValueError > > + if HeaderSize < self._StructSize: > > + raise ValueError > > + self.Signature =3D Signature > > + self.HeaderSize =3D HeaderSize > > + self.FwVersion =3D FwVersion > > + self.LowestSupportedVersion =3D > LowestSupportedVersion > > + self.Payload =3D > Buffer[self.HeaderSize:] > > + > > + self._Valid =3D True > > + return self.Payload > > + > > + def DumpInfo (self): > > + if not self._Valid: > > + raise ValueError > > + print ('FMP_PAYLOAD_HEADER.Signature > =3D {Signature:08X} ({SignatureString})'.format (Signature > =3D > > self.Signature, SignatureString =3D > _SIGNATURE_32_TO_STRING (self.Signature))) > > + print ('FMP_PAYLOAD_HEADER.HeaderSize > =3D {HeaderSize:08X}'.format (HeaderSize =3D > self.HeaderSize)) > > + print ('FMP_PAYLOAD_HEADER.FwVersion > =3D {FwVersion:08X}'.format (FwVersion =3D self.FwVersion)) > > + print > ('FMP_PAYLOAD_HEADER.LowestSupportedVersion =3D > {LowestSupportedVersion:08X}'.format > > (LowestSupportedVersion =3D > self.LowestSupportedVersion)) > > + print ('sizeof (Payload) > =3D {Size:08X}'.format (Size =3D len (self.Payload))) > > diff --git > a/BaseTools/Source/Python/Common/Edk2/Capsule/__init__.p > y > > > b/BaseTools/Source/Python/Common/Edk2/Capsule/__init__.p > y > > new file mode 100644 > > index 0000000000..71c6f06838 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Edk2/Capsule/__init__.p > y > > @@ -0,0 +1,15 @@ > > +## @file > > +# Python 'Common.Edk2.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.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > diff --git > a/BaseTools/Source/Python/Common/Edk2/__init__.py > b/BaseTools/Source/Python/Common/Edk2/__init__.py > > new file mode 100644 > > index 0000000000..97d925cbf8 > > --- /dev/null > > +++ b/BaseTools/Source/Python/Common/Edk2/__init__.py > > @@ -0,0 +1,15 @@ > > +## @file > > +# Python 'Common.Edk2' 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.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > diff --git > a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHea > der.py > > > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHea > der.py > > new file mode 100644 > > index 0000000000..aec52bf772 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHea > der.py > > @@ -0,0 +1,184 @@ > > +## @file > > +# Module that encodes and decodes a > EFI_FIRMWARE_IMAGE_AUTHENTICATION with > > +# certificate data and payload data. > > +# > > +# Copyright (c) 2018, Intel Corporation. All rights > reserved.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > + > > +''' > > +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 =3D ' > + _StructSize =3D struct.calcsize (_StructFormat) > > + > > + _MonotonicCountFormat =3D ' > + _MonotonicCountSize =3D struct.calcsize > (_MonotonicCountFormat) > > + > > + _StructAuthInfoFormat =3D ' > + _StructAuthInfoSize =3D struct.calcsize > (_StructAuthInfoFormat) > > + > > + _WIN_CERT_REVISION =3D 0x0200 > > + _WIN_CERT_TYPE_EFI_GUID =3D 0x0EF1 > > + _EFI_CERT_TYPE_PKCS7_GUID =3D uuid.UUID ('4aafd29d- > 68df-49ee-8aa9-347d375665a7') > > + > > + def __init__ (self): > > + self._Valid =3D False > > + self.MonotonicCount =3D 0 > > + self.dwLength =3D > self._StructAuthInfoSize > > + self.wRevision =3D > self._WIN_CERT_REVISION > > + self.wCertificateType =3D > self._WIN_CERT_TYPE_EFI_GUID > > + self.CertType =3D > self._EFI_CERT_TYPE_PKCS7_GUID > > + self.CertData =3D b'' > > + self.Payload =3D b'' > > + > > + > > + def Encode (self): > > + if self.wRevision !=3D self._WIN_CERT_REVISION: > > + raise ValueError > > + if self.wCertificateType !=3D > self._WIN_CERT_TYPE_EFI_GUID: > > + raise ValueError > > + if self.CertType !=3D > self._EFI_CERT_TYPE_PKCS7_GUID: > > + raise ValueError > > + self.dwLength =3D self._StructAuthInfoSize + > len (self.CertData) > > + > > + FmpAuthHeader =3D struct.pack ( > > + self._StructFormat, > > + self.MonotonicCount, > > + self.dwLength, > > + self.wRevision, > > + > self.wCertificateType, > > + > self.CertType.bytes_le > > + ) > > + self._Valid =3D True > > + > > + return FmpAuthHeader + self.CertData + > self.Payload > > + > > + def Decode (self, Buffer): > > + if len (Buffer) < self._StructSize: > > + raise ValueError > > + (MonotonicCount, dwLength, wRevision, > wCertificateType, CertType) =3D \ > > + struct.unpack ( > > + self._StructFormat, > > + Buffer[0:self._StructSize] > > + ) > > + if dwLength < self._StructAuthInfoSize: > > + raise ValueError > > + if wRevision !=3D self._WIN_CERT_REVISION: > > + raise ValueError > > + if wCertificateType !=3D > self._WIN_CERT_TYPE_EFI_GUID: > > + raise ValueError > > + if CertType !=3D > self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le: > > + raise ValueError > > + self.MonotonicCount =3D MonotonicCount > > + self.dwLength =3D dwLength > > + self.wRevision =3D wRevision > > + self.wCertificateType =3D wCertificateType > > + self.CertType =3D uuid.UUID (bytes =3D > CertType) > > + self.CertData =3D > Buffer[self._StructSize:self._MonotonicCountSize + > self.dwLength] > > + self.Payload =3D > Buffer[self._MonotonicCountSize + self.dwLength:] > > + self._Valid =3D True > > + return self.Payload > > + > > + def DumpInfo (self): > > + if not self._Valid: > > + raise ValueError > > + print > ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.MonotonicCount > =3D {MonotonicCount:016X}'.format > > (MonotonicCount =3D self.MonotonicCount)) > > + print > ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.dwLengt > h =3D {dwLength:08X}'.format (dwLength =3D > > self.dwLength)) > > + print > ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevisi > on =3D {wRevision:04X}'.format (wRevision =3D > > self.wRevision)) > > + print > ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertif > icateType =3D {wCertificateType:04X}'.format > > (wCertificateType =3D self.wCertificateType)) > > + print > ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType > =3D {Guid}'.format (Guid =3D > > str(self.CertType).upper())) > > + print ('sizeof > (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) > =3D {Size:08X}'.format (Size =3D len > > (self.CertData))) > > + print ('sizeof (Payload) > =3D {Size:08X}'.format (Size =3D len > > (self.Payload))) > > diff --git > a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsule > Header.py > > > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsule > Header.py > > new file mode 100644 > > index 0000000000..2461fb5068 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsule > Header.py > > @@ -0,0 +1,302 @@ > > +## @file > > +# Module that encodes and decodes a > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER with > > +# a payload. > > +# > > +# Copyright (c) 2018, Intel Corporation. All rights > reserved.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > + > > +''' > > +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; > > + # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER; > > + # > > + # #define > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSIO > N 0x00000002 > > + > > + _StructFormat =3D ' > + _StructSize =3D struct.calcsize (_StructFormat) > > + > > + > EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSIO > N =3D 0x00000002 > > + > > + def __init__ (self): > > + self._Valid =3D False > > + self.Version =3D > self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_V > ERSION > > + self.UpdateImageTypeId =3D uuid.UUID > ('00000000-0000-0000-0000-000000000000') > > + self.UpdateImageIndex =3D 0 > > + self.UpdateImageSize =3D 0 > > + self.UpdateVendorCodeSize =3D 0 > > + self.UpdateHardwareInstance =3D > 0x0000000000000000 > > + self.Payload =3D b'' > > + self.VendorCodeBytes =3D b'' > > + > > + def Encode (self): > > + self.UpdateImageSize =3D len > (self.Payload) > > + self.UpdateVendorCodeSize =3D len > (self.VendorCodeBytes) > > + FmpCapsuleImageHeader =3D struct.pack ( > > + > self._StructFormat, > > + > self.Version, > > + > self.UpdateImageTypeId.bytes_le, > > + > self.UpdateImageIndex, > > + 0,0,0, > > + > self.UpdateImageSize, > > + > self.UpdateVendorCodeSize, > > + > self.UpdateHardwareInstance > > + ) > > + self._Valid =3D 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) =3D \ > > + struct.unpack ( > > + self._StructFormat, > > + Buffer[0:self._StructSize] > > + ) > > + > > + if Version < > self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_V > ERSION: > > + raise ValueError > > + if UpdateImageIndex < 1: > > + raise ValueError > > + if UpdateImageSize + UpdateVendorCodeSize !=3D > len (Buffer[self._StructSize:]): > > + raise ValueError > > + > > + self.Version =3D Version > > + self.UpdateImageTypeId =3D uuid.UUID > (bytes_le =3D UpdateImageTypeId) > > + self.UpdateImageIndex =3D > UpdateImageIndex > > + self.UpdateImageSize =3D UpdateImageSize > > + self.UpdateVendorCodeSize =3D > UpdateVendorCodeSize > > + self.UpdateHardwareInstance =3D > UpdateHardwareInstance > > + self.Payload =3D > Buffer[self._StructSize:self._StructSize + > UpdateImageSize] > > + self.VendorCodeBytes =3D > Buffer[self._StructSize + UpdateImageSize:] > > + self._Valid =3D True > > + return Buffer[self._StructSize:] > > + > > + def DumpInfo (self): > > + if not self._Valid: > > + raise ValueError > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version > =3D {Version:08X}'.format > > (Version =3D self.Version)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateIma > geTypeId =3D > > {UpdateImageTypeId}'.format (UpdateImageTypeId =3D > str(self.UpdateImageTypeId).upper())) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateIma > geIndex =3D > > {UpdateImageIndex:08X}'.format (UpdateImageIndex =3D > self.UpdateImageIndex)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateIma > geSize =3D > > {UpdateImageSize:08X}'.format (UpdateImageSize =3D > self.UpdateImageSize)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVen > dorCodeSize =3D > > {UpdateVendorCodeSize:08X}'.format > (UpdateVendorCodeSize =3D self.UpdateVendorCodeSize)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHar > dwareInstance =3D > > {UpdateHardwareInstance:016X}'.format > (UpdateHardwareInstance =3D self.UpdateHardwareInstance)) > > + print ('sizeof (Payload) > =3D {Size:08X}'.format (Size =3D len > > (self.Payload))) > > + print ('sizeof (VendorCodeBytes) > =3D {Size:08X}'.format (Size =3D 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 =3D ' > + _StructSize =3D struct.calcsize (_StructFormat) > > + > > + _ItemOffsetFormat =3D ' > + _ItemOffsetSize =3D struct.calcsize > (_ItemOffsetFormat) > > + > > + > EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION =3D > 0x00000001 > > + > > + def __init__ (self): > > + self._Valid =3D False > > + self.Version =3D > self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION > > + self.EmbeddedDriverCount =3D 0 > > + self.PayloadItemCount =3D 0 > > + self._ItemOffsetList =3D [] > > + self._EmbeddedDriverList =3D [] > > + self._PayloadList =3D [] > > + self._FmpCapsuleImageHeaderList =3D [] > > + > > + 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 > =3D b'', VendorCodeBytes =3D b'', HardwareInstance =3D 0): > > + self._PayloadList.append ((UpdateImageTypeId, > Payload, VendorCodeBytes, HardwareInstance)) > > + > > + def GetFmpCapsuleImageHeader (self, Index): > > + if Index >=3D len > (self._FmpCapsuleImageHeaderList): > > + raise ValueError > > + return self._FmpCapsuleImageHeaderList[Index] > > + > > + def Encode (self): > > + self.EmbeddedDriverCount =3D len > (self._EmbeddedDriverList) > > + self.PayloadItemCount =3D len > (self._PayloadList) > > + > > + FmpCapsuleHeader =3D struct.pack ( > > + > self._StructFormat, > > + self.Version, > > + > self.EmbeddedDriverCount, > > + > self.PayloadItemCount > > + ) > > + > > + FmpCapsuleData =3D b'' > > + Offset =3D self._StructSize + > (self.EmbeddedDriverCount + self.PayloadItemCount) * > self._ItemOffsetSize > > + for EmbeddedDriver in > self._EmbeddedDriverList: > > + FmpCapsuleData =3D FmpCapsuleData + > EmbeddedDriver > > + self._ItemOffsetList.append (Offset) > > + Offset =3D Offset + len (EmbeddedDriver) > > + Index =3D 1 > > + for (UpdateImageTypeId, Payload, > VendorCodeBytes, HardwareInstance) in self._PayloadList: > > + FmpCapsuleImageHeader =3D > FmpCapsuleImageHeaderClass () > > + FmpCapsuleImageHeader.UpdateImageTypeId > =3D UpdateImageTypeId > > + FmpCapsuleImageHeader.UpdateImageIndex > =3D Index > > + FmpCapsuleImageHeader.Payload > =3D Payload > > + FmpCapsuleImageHeader.VendorCodeBytes > =3D VendorCodeBytes > > + > FmpCapsuleImageHeader.UpdateHardwareInstance =3D > HardwareInstance > > + FmpCapsuleImage =3D > FmpCapsuleImageHeader.Encode () > > + FmpCapsuleData =3D FmpCapsuleData + > FmpCapsuleImage > > + > > + self._ItemOffsetList.append (Offset) > > + self._FmpCapsuleImageHeaderList.append > (FmpCapsuleImageHeader) > > + > > + Offset =3D Offset + len (FmpCapsuleImage) > > + Index =3D Index + 1 > > + > > + for Offset in self._ItemOffsetList: > > + FmpCapsuleHeader =3D FmpCapsuleHeader + > struct.pack (self._ItemOffsetFormat, Offset) > > + > > + self._Valid =3D True > > + return FmpCapsuleHeader + FmpCapsuleData > > + > > + def Decode (self, Buffer): > > + if len (Buffer) < self._StructSize: > > + raise ValueError > > + (Version, EmbeddedDriverCount, > PayloadItemCount) =3D \ > > + struct.unpack ( > > + self._StructFormat, > > + Buffer[0:self._StructSize] > > + ) > > + if Version < > self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER_INIT_VERSION > : > > + raise ValueError > > + > > + self.Version =3D Version > > + self.EmbeddedDriverCount =3D > EmbeddedDriverCount > > + self.PayloadItemCount =3D > PayloadItemCount > > + self._ItemOffsetList =3D [] > > + self._EmbeddedDriverList =3D [] > > + self._PayloadList =3D [] > > + self._FmpCapsuleImageHeaderList =3D [] > > + > > + # > > + # Parse the ItemOffsetList values > > + # > > + Offset =3D self._StructSize > > + for Index in range (0, EmbeddedDriverCount + > PayloadItemCount): > > + ItemOffset =3D struct.unpack > (self._ItemOffsetFormat, Buffer[Offset:Offset + > self._ItemOffsetSize])[0] > > + if ItemOffset >=3D len (Buffer): > > + raise ValueError > > + self._ItemOffsetList.append (ItemOffset) > > + Offset =3D Offset + self._ItemOffsetSize > > + Result =3D Buffer[Offset:] > > + > > + # > > + # Parse the EmbeddedDrivers > > + # > > + for Index in range (0, EmbeddedDriverCount): > > + Offset =3D self._ItemOffsetList[Index] > > + if Index < (len (self._ItemOffsetList) - > 1): > > + Length =3D self._ItemOffsetList[Index + > 1] - Offset > > + else: > > + Length =3D 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 =3D self._ItemOffsetList[Index] > > + if Index < (len (self._ItemOffsetList) - > 1): > > + Length =3D self._ItemOffsetList[Index + > 1] - Offset > > + else: > > + Length =3D len (Buffer) - Offset > > + FmpCapsuleImageHeader =3D > FmpCapsuleImageHeaderClass () > > + FmpCapsuleImageHeader.Decode > (Buffer[Offset:Offset + Length]) > > + self.AddPayload ( > > + > FmpCapsuleImageHeader.UpdateImageTypeId, > > + FmpCapsuleImageHeader.Payload, > > + > FmpCapsuleImageHeader.VendorCodeBytes > > + ) > > + self._FmpCapsuleImageHeaderList.append > (FmpCapsuleImageHeader) > > + > > + self._Valid =3D True > > + return Result > > + > > + def DumpInfo (self): > > + if not self._Valid: > > + raise ValueError > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version > =3D {Version:08X}'.format (Version =3D > > self.Version)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverC > ount =3D {EmbeddedDriverCount:08X}'.format > > (EmbeddedDriverCount =3D self.EmbeddedDriverCount)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCoun > t =3D {PayloadItemCount:08X}'.format > > (PayloadItemCount =3D self.PayloadItemCount)) > > + print > ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList > =3D ') > > + for Offset in self._ItemOffsetList: > > + print (' {Offset:016X}'.format (Offset =3D > Offset)) > > + for FmpCapsuleImageHeader in > self._FmpCapsuleImageHeaderList: > > + FmpCapsuleImageHeader.DumpInfo () > > diff --git > a/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsul > eHeader.py > > > b/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsul > eHeader.py > > new file mode 100644 > > index 0000000000..cfe1cb6c46 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsul > eHeader.py > > @@ -0,0 +1,136 @@ > > +## @file > > +# Module that encodes and decodes a > EFI_CAPSULE_HEADER with a payload > > +# > > +# Copyright (c) 2018, Intel Corporation. All rights > reserved.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > + > > +''' > > +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 =3D '<16sIIII' > > + _StructSize =3D struct.calcsize (_StructFormat) > > + > > + EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID =3D > uuid.UUID ('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A') > > + > > + _CAPSULE_FLAGS_PERSIST_ACROSS_RESET =3D 0x00010000 > > + _CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE =3D 0x00020000 > > + _CAPSULE_FLAGS_INITIATE_RESET =3D 0x00040000 > > + > > + def __init__ (self): > > + self._Valid =3D False > > + self.CapsuleGuid =3D > self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID > > + self.HeaderSize =3D self._StructSize > > + self.OemFlags =3D 0x0000 > > + self.PersistAcrossReset =3D False > > + self.PopulateSystemTable =3D False > > + self.InitiateReset =3D False > > + self.CapsuleImageSize =3D self.HeaderSize > > + self.Payload =3D b'' > > + > > + def Encode (self): > > + Flags =3D self.OemFlags > > + if self.PersistAcrossReset: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET > > + if self.PopulateSystemTable: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE > > + if self.InitiateReset: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_INITIATE_RESET > > + > > + self.CapsuleImageSize =3D self.HeaderSize + len > (self.Payload) > > + > > + UefiCapsuleHeader =3D struct.pack ( > > + > self._StructFormat, > > + > self.CapsuleGuid.bytes_le, > > + self.HeaderSize, > > + Flags, > > + > self.CapsuleImageSize, > > + 0 > > + ) > > + self._Valid =3D True > > + return UefiCapsuleHeader + self.Payload > > + > > + def Decode (self, Buffer): > > + if len (Buffer) < self._StructSize: > > + raise ValueError > > + (CapsuleGuid, HeaderSize, Flags, > CapsuleImageSize, Reserved) =3D \ > > + struct.unpack ( > > + self._StructFormat, > > + Buffer[0:self._StructSize] > > + ) > > + if HeaderSize < self._StructSize: > > + raise ValueError > > + if CapsuleImageSize !=3D len (Buffer): > > + raise ValueError > > + self.CapsuleGuid =3D uuid.UUID > (bytes_le =3D CapsuleGuid) > > + self.HeaderSize =3D HeaderSize > > + self.OemFlags =3D Flags & 0xffff > > + self.PersistAcrossReset =3D (Flags & > self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET) !=3D 0 > > + self.PopulateSystemTable =3D (Flags & > self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) !=3D 0 > > + self.InitiateReset =3D (Flags & > self._CAPSULE_FLAGS_INITIATE_RESET) !=3D 0 > > + self.CapsuleImageSize =3D CapsuleImageSize > > + self.Payload =3D > Buffer[self.HeaderSize:] > > + > > + self._Valid =3D True > > + return self.Payload > > + > > + def DumpInfo (self): > > + if not self._Valid: > > + raise ValueError > > + Flags =3D self.OemFlags > > + if self.PersistAcrossReset: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_PERSIST_ACROSS_RESET > > + if self.PopulateSystemTable: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE > > + if self.InitiateReset: > > + Flags =3D Flags | > self._CAPSULE_FLAGS_INITIATE_RESET > > + print ('EFI_CAPSULE_HEADER.CapsuleGuid =3D > {Guid}'.format (Guid =3D str(self.CapsuleGuid).upper())) > > + print ('EFI_CAPSULE_HEADER.HeaderSize =3D > {Size:08X}'.format (Size =3D self.HeaderSize)) > > + print ('EFI_CAPSULE_HEADER.Flags =3D > {Flags:08X}'.format (Flags =3D Flags)) > > + print (' OEM Flags =3D > {Flags:04X}'.format (Flags =3D 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 =3D > {Size:08X}'.format (Size =3D self.CapsuleImageSize)) > > + print ('sizeof (Payload) =3D > {Size:08X}'.format (Size =3D len (self.Payload))) > > diff --git > a/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.p > y > > > b/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.p > y > > new file mode 100644 > > index 0000000000..d9db4aa919 > > --- /dev/null > > +++ > b/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.p > y > > @@ -0,0 +1,15 @@ > > +## @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.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > diff --git > a/BaseTools/Source/Python/Common/Uefi/__init__.py > b/BaseTools/Source/Python/Common/Uefi/__init__.py > > new file mode 100644 > > index 0000000000..d80219dcb3 > > --- /dev/null > > +++ b/BaseTools/Source/Python/Common/Uefi/__init__.py > > @@ -0,0 +1,15 @@ > > +## @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.
> > +# This program and the accompanying materials > > +# are licensed and made available under the terms and > conditions of the BSD License > > +# which accompanies this distribution. The full text > of the license may be found at > > +# http://opensource.org/licenses/bsd-license.php > > +# > > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON > AN "AS IS" BASIS, > > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, > EITHER EXPRESS OR IMPLIED. > > +# > > -- > > 2.14.2.windows.3