From: "Kinney, Michael D" <michael.d.kinney@intel.com>
To: "Gao, Liming" <liming.gao@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>,
"Yao, Jiewen" <jiewen.yao@intel.com>,
"Zhu, Yonghong" <yonghong.zhu@intel.com>
Subject: Re: [RFC 1/1] BaseTools/Capsule: Add Capsule Generation Tools
Date: Thu, 31 May 2018 16:36:06 +0000 [thread overview]
Message-ID: <E92EE9817A31E24EB0585FDF735412F5B8A644DE@ORSMSX113.amr.corp.intel.com> (raw)
In-Reply-To: <4A89E2EF3DFEDB4C8BFDE51014F606A14E291226@SHSMSX104.ccr.corp.intel.com>
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 <michael.d.kinney@intel.com>;
> edk2-devel@lists.01.org
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Zhu, Yonghong
> <yonghong.zhu@intel.com>
> Subject: RE: [RFC 1/1] BaseTools/Capsule: Add Capsule
> Generation Tools
>
> Mike:
> Which C tool is converted? Does it support all capsule
> generation functionality in GenFv tool?
>
> And, GenFds has the logic to generate FMP capsule. Can
> they share same logic?
>
> 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 <michael.d.kinney@intel.com>;
> Sean Brogan <sean.brogan@microsoft.com>; Yao, Jiewen
> > <jiewen.yao@intel.com>; Zhu, Yonghong
> <yonghong.zhu@intel.com>; Gao, Liming
> <liming.gao@intel.com>
> > Subject: [RFC 1/1] BaseTools/Capsule: Add Capsule
> Generation Tools
> >
> > From: "Kinney, Michael D" <michael.d.kinney@intel.com>
> >
> > 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/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 <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>
> > ---
> > 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=python2
> > +fi
> > +
> > +full_cmd=${BASH_SOURCE:-$0} # see
> http://mywiki.wooledge.org/BashFAQ/028 for a discussion
> of why $0 is not a good choice here
> > +dir=$(dirname "$full_cmd")
> > +cmd=${full_cmd##*/}
> > +
> > +export
> PYTHONPATH="$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.<BR>
> > +# 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__ = 'GenerateCapsule'
> > +__copyright__ = 'Copyright (c) 2018, Intel
> Corporation. All rights reserved.'
> > +__description__ = 'Generate a capsule.\n'
> > +
> > +def SignPayloadSignTool (Payload, ToolPath, PfxFile):
> > + #
> > + # Create a temporary directory
> > + #
> > + TempDirectoryName = tempfile.mkdtemp()
> > +
> > + #
> > + # Generate temp file name for the payload
> contents
> > + #
> > + TempFileName = os.path.join (TempDirectoryName,
> 'Payload.bin')
> > +
> > + #
> > + # Create temporary payload file for signing
> > + #
> > + try:
> > + File = open (TempFileName, mode='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 = ''
> > + Command = ''
> > + Command = Command + '"{Path}" '.format (Path =
> os.path.join (ToolPath, 'signtool.exe'))
> > + Command = Command + 'sign /fd sha256 /p7ce
> DetachedSignedData /p7co 1.2.840.113549.1.7.2 '
> > + Command = Command + '/p7 {TempDir} '.format
> (TempDir = TempDirectoryName)
> > + Command = Command + '/f {PfxFile} '.format
> (PfxFile = PfxFile)
> > + Command = Command + TempFileName
> > +
> > + #
> > + # Sign the input file using the specified private
> key
> > + #
> > + try:
> > + Process = subprocess.Popen (Command, stdin =
> subprocess.PIPE, stdout = subprocess.PIPE, stderr =
> subprocess.PIPE, shell =
> > True)
> > + Result = Process.communicate('')
> > + except:
> > + shutil.rmtree (TempDirectoryName)
> > + raise ValueError ('GenerateCapsule: error:
> can not run signtool.')
> > +
> > + if Process.returncode != 0:
> > + shutil.rmtree (TempDirectoryName)
> > + print (Result[1].decode())
> > + raise ValueError ('GenerateCapsule: error:
> signtool failed.')
> > +
> > + #
> > + # Read the signature from the generated output
> file
> > + #
> > + try:
> > + File = open (TempFileName + '.p7', mode='rb')
> > + Signature = 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 = ''
> > + Command = ''
> > + Command = Command + '"{Path}" '.format (Path =
> os.path.join (ToolPath, 'openssl'))
> > + Command = Command + 'smime -sign -binary -outform
> DER -md sha256 '
> > + Command = Command + '-signer "{Private}" -
> certfile "{Public}"'.format (Private =
> SignerPrivateCertFile, Public =
> > OtherPublicCertFile)
> > +
> > + #
> > + # Sign the input file using the specified private
> key and capture signature from STDOUT
> > + #
> > + try:
> > + Process = subprocess.Popen (Command, stdin =
> subprocess.PIPE, stdout = subprocess.PIPE, stderr =
> subprocess.PIPE, shell =
> > True)
> > + Result = Process.communicate(input = Payload)
> > + Signature = Result[0]
> > + except:
> > + raise ValueError ('GenerateCapsule: error:
> can not run openssl.')
> > +
> > + if Process.returncode != 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 = tempfile.mkdtemp()
> > +
> > + #
> > + # Generate temp file name for the payload
> contents
> > + #
> > + TempFileName = os.path.join (TempDirectoryName,
> 'Payload.bin')
> > +
> > + #
> > + # Create temporary payload file for verification
> > + #
> > + try:
> > + File = open (TempFileName, mode='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 = ''
> > + Command = ''
> > + Command = Command + '"{Path}" '.format (Path =
> os.path.join (ToolPath, 'openssl'))
> > + Command = Command + 'smime -verify -inform DER '
> > + Command = Command + '-content {Content} -CAfile
> "{Public}"'.format (Content = TempFileName, Public =
> TrustedPublicCertFile)
> > +
> > + #
> > + # Verify signature
> > + #
> > + try:
> > + Process = subprocess.Popen (Command, stdin =
> subprocess.PIPE, stdout = subprocess.PIPE, stderr =
> subprocess.PIPE, shell =
> > True)
> > + Result = Process.communicate(input =
> CertData)
> > + except:
> > + shutil.rmtree (TempDirectoryName)
> > + raise ValueError ('GenerateCapsule: error:
> can not run openssl.')
> > +
> > + if Process.returncode != 0:
> > + shutil.rmtree (TempDirectoryName)
> > + print (Result[1].decode())
> > + raise ValueError ('GenerateCapsule: error:
> openssl failed.')
> > +
> > + shutil.rmtree (TempDirectoryName)
> > + return Payload
> > +
> > +if __name__ == '__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 = int (Argument, 0)
> > + except:
> > + Message = '{Argument} is not a valid
> integer value.'.format (Argument = Argument)
> > + raise argparse.ArgumentTypeError
> (Message)
> > + if Value < 0:
> > + Message = '{Argument} is a negative
> value.'.format (Argument = Argument)
> > + raise argparse.ArgumentTypeError
> (Message)
> > + return Value
> > +
> > + def ValidateRegistryFormatGuid (Argument):
> > + try:
> > + Value = uuid.UUID (Argument)
> > + except:
> > + Message = '{Argument} is not a valid
> registry format GUID value.'.format (Argument =
> Argument)
> > + raise argparse.ArgumentTypeError
> (Message)
> > + return Value
> > +
> > + #
> > + # Create command line argument parser object
> > + #
> > + parser = argparse.ArgumentParser (
> > + prog = __prog__,
> > + description = __description__
> + __copyright__,
> > + conflict_handler = 'resolve',
> > + fromfile_prefix_chars = '@'
> > + )
> > + parser.convert_arg_line_to_args =
> convert_arg_line_to_args
> > +
> > + #
> > + # Add input and output file arguments
> > + #
> > + parser.add_argument("InputFile", type =
> argparse.FileType('rb'),
> > + help = "Input binary payload
> filename.")
> > + parser.add_argument("-o", "--output", dest =
> 'OutputFile', type = argparse.FileType('wb'),
> > + help = "Output filename.")
> > + #
> > + # Add group for -e and -d flags that are mutually
> exclusive and required
> > + #
> > + group = parser.add_mutually_exclusive_group
> (required = True)
> > + group.add_argument ("-e", "--encode", dest =
> 'Encode', action = "store_true",
> > + help = "Encode file")
> > + group.add_argument ("-d", "--decode", dest =
> 'Decode', action = "store_true",
> > + help = "Decode file")
> > + group.add_argument ("--dump-info", dest =
> 'DumpInfo', action = "store_true",
> > + help = "Display FMP Payload
> Header information")
> > + #
> > + # Add optional arguments for this command
> > + #
> > + parser.add_argument ("--capflag", dest =
> 'CapsuleFlag', action='append', default = [],
> > +
> choices=['PersistAcrossReset', 'PopulateSystemTable',
> 'InitiateReset'],
> > + help = "Capsule flag can be
> PersistAcrossReset, or PopulateSystemTable or
> InitiateReset or not set")
> > + parser.add_argument ("--capoemflag", dest =
> 'CapsuleOemFlag', type = ValidateUnsignedInteger,
> default = 0x0000,
> > + help = "Capsule OEM Flag is
> an integer between 0x0000 and 0xffff.")
> > +
> > + parser.add_argument ("--guid", dest = 'Guid',
> type = ValidateRegistryFormatGuid,
> > + help = "The FMP/ESRT GUID in
> registry format. Required for encode operations.")
> > + parser.add_argument ("--hardware-instance", dest
> = 'HardwareInstance', type = ValidateUnsignedInteger,
> default =
> > 0x0000000000000000,
> > + help = "The 64-bit hardware
> instance. The default is 0x0000000000000000")
> > +
> > +
> > + parser.add_argument ("--monotonic-count", dest =
> 'MonotonicCount', type = ValidateUnsignedInteger,
> default =
> > 0x0000000000000000,
> > + help = "64-bit monotonic
> count value in header. Default is 0x0000000000000000.")
> > +
> > + parser.add_argument ("--version", dest =
> 'FwVersion', type = ValidateUnsignedInteger,
> > + help = "The 32-bit version
> of the binary payload (e.g. 0x11223344 or 5678).")
> > + parser.add_argument ("--lsv", dest =
> 'LowestSupportedVersion', type =
> ValidateUnsignedInteger,
> > + help = "The 32-bit lowest
> supported version of the binary payload (e.g. 0x11223344
> or 5678).")
> > +
> > + parser.add_argument ("--pfx-file",
> dest='SignToolPfxFile', type=argparse.FileType('rb'),
> > + help="signtool PFX
> certificate filename.")
> > +
> > + parser.add_argument ("--signer-private-cert",
> dest='OpenSslSignerPrivateCertFile',
> type=argparse.FileType('rb'),
> > + help="OpenSSL signer private
> certificate filename.")
> > + parser.add_argument ("--other-public-cert",
> dest='OpenSslOtherPublicCertFile',
> type=argparse.FileType('rb'),
> > + help="OpenSSL other public
> certificate filename.")
> > + parser.add_argument ("--trusted-public-cert",
> dest='OpenSslTrustedPublicCertFile',
> type=argparse.FileType('rb'),
> > + help="OpenSSL trusted public
> certificate filename.")
> > +
> > + parser.add_argument ("--signing-tool-path", dest
> = 'SigningToolPath',
> > + help = "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 =
> 'Verbose', action = "store_true",
> > + help = "Increase output
> messages")
> > + parser.add_argument("-q", "--quiet", dest =
> 'Quiet', action = "store_true",
> > + help = "Reduce output
> messages")
> > + parser.add_argument("--debug", dest = 'Debug',
> type = int, metavar = '[0-9]', choices = range(0,10),
> default = 0,
> > + help = "Set debug level")
> > +
> > + #
> > + # Parse command line arguments
> > + #
> > + args = 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 =
> 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 =
> args.OpenSslSignerPrivateCertFile.name
> > + args.OpenSslOtherPublicCertFile =
> args.OpenSslOtherPublicCertFile.name
> > + args.OpenSslTrustedPublicCertFile =
> args.OpenSslTrustedPublicCertFile.name
> > +
> > + #
> > + # Read binary input file
> > + #
> > + try:
> > + if args.Verbose:
> > + print ('Read binary input file
> {File}'.format (File = args.InputFile.name))
> > + Buffer = args.InputFile.read ()
> > + args.InputFile.close ()
> > + except:
> > + print ('GenerateCapsule: error: can not read
> binary input file {File}'.format (File =
> args.InputFile.name))
> > + sys.exit (1)
> > +
> > + #
> > + # Create objects
> > + #
> > + UefiCapsuleHeader = UefiCapsuleHeaderClass ()
> > + FmpCapsuleHeader = FmpCapsuleHeaderClass ()
> > + FmpAuthHeader = FmpAuthHeaderClass ()
> > + FmpPayloadHeader = FmpPayloadHeaderClass ()
> > +
> > + if args.Encode:
> > + try:
> > + FmpPayloadHeader.FwVersion =
> args.FwVersion
> > + FmpPayloadHeader.LowestSupportedVersion =
> args.LowestSupportedVersion
> > + FmpPayloadHeader.Payload =
> Buffer
> > + Result = 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 = SignPayloadSignTool (
> > + Result + struct.pack
> ('<Q', args.MonotonicCount),
> > + args.SigningToolPath,
> > + args.SignToolPfxFile
> > + )
> > + else:
> > + CertData = SignPayloadOpenSsl (
> > + Result + struct.pack
> ('<Q', args.MonotonicCount),
> > + args.SigningToolPath,
> > +
> args.OpenSslSignerPrivateCertFile,
> > +
> args.OpenSslOtherPublicCertFile,
> > +
> args.OpenSslTrustedPublicCertFile
> > + )
> > + except:
> > + print ('GenerateCapsule: error: can not
> sign payload')
> > + raise
> > + sys.exit (1)
> > +
> > + try:
> > + FmpAuthHeader.MonotonicCount =
> args.MonotonicCount
> > + FmpAuthHeader.CertData = CertData
> > + FmpAuthHeader.Payload = Result
> > + Result = 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 = args.HardwareInstance)
> > + Result = FmpCapsuleHeader.Encode ()
> > + if args.Verbose:
> > + FmpCapsuleHeader.DumpInfo ()
> > + except:
> > + print ('GenerateCapsule: error: can not
> encode FMP Capsule Header')
> > + sys.exit (1)
> > +
> > + try:
> > + UefiCapsuleHeader.OemFlags =
> args.CapsuleOemFlag
> > + UefiCapsuleHeader.PersistAcrossReset =
> 'PersistAcrossReset' in args.CapsuleFlag
> > + UefiCapsuleHeader.PopulateSystemTable =
> 'PopulateSystemTable' in args.CapsuleFlag
> > + UefiCapsuleHeader.InitiateReset =
> 'InitiateReset' in args.CapsuleFlag
> > + UefiCapsuleHeader.Payload =
> Result
> > + Result = 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 = UefiCapsuleHeader.Decode
> (Buffer)
> > + FmpCapsuleHeader.Decode (Result)
> > + Result =
> FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload
> > + Result = FmpAuthHeader.Decode (Result)
> > +
> > + #
> > + # Verify Image with 64-bit MonotonicCount
> appended to end of image
> > + #
> > + try:
> > + if args.SignToolPfxFile is not None:
> > + CertData = VerifyPayloadSignTool (
> > + FmpAuthHeader.Payload
> + struct.pack ('<Q', FmpAuthHeader.MonotonicCount),
> > +
> FmpAuthHeader.CertData,
> > + args.SigningToolPath,
> > + args.SignToolPfxFile
> > + )
> > + else:
> > + CertData = VerifyPayloadOpenSsl (
> > + FmpAuthHeader.Payload
> + struct.pack ('<Q', FmpAuthHeader.MonotonicCount),
> > +
> FmpAuthHeader.CertData,
> > + args.SigningToolPath,
> > +
> args.OpenSslSignerPrivateCertFile,
> > +
> args.OpenSslOtherPublicCertFile,
> > +
> args.OpenSslTrustedPublicCertFile
> > + )
> > + except ValueError:
> > + print ('GenerateCapsule: warning: can
> not verify payload.')
> > +
> > + Result = FmpPayloadHeader.Decode (Result)
> > + if args.Verbose:
> > + print ('========')
> > + UefiCapsuleHeader.DumpInfo ()
> > + print ('--------')
> > + FmpCapsuleHeader.DumpInfo ()
> > + print ('--------')
> > + FmpAuthHeader.DumpInfo ()
> > + print ('--------')
> > + FmpPayloadHeader.DumpInfo ()
> > + print ('========')
> > + except:
> > + print ('GenerateCapsule: error: can not
> decode capsule')
> > + raise
> > + sys.exit (1)
> > +
> > + elif args.DumpInfo:
> > + try:
> > + Result = UefiCapsuleHeader.Decode
> (Buffer)
> > + FmpCapsuleHeader.Decode (Result)
> > + Result =
> FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Payload
> > + Result = FmpAuthHeader.Decode (Result)
> > + Result = FmpPayloadHeader.Decode (Result)
> > +
> > + print ('========')
> > + UefiCapsuleHeader.DumpInfo ()
> > + print ('--------')
> > + FmpCapsuleHeader.DumpInfo ()
> > + print ('--------')
> > + FmpAuthHeader.DumpInfo ()
> > + print ('--------')
> > + FmpPayloadHeader.DumpInfo ()
> > + print ('========')
> > + 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 = args.OutputFile.name))
> > + args.OutputFile.write (Result)
> > + args.OutputFile.close ()
> > + except:
> > + print ('GenerateCapsule: error: can not
> write binary output file {File}'.format (File =
> 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.<BR>
> > +# 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 ('=I',bytearray (A + B + C +
> D, 'ascii'))[0]
> > +
> > +def _SIGNATURE_32_TO_STRING (Signature):
> > + return struct.pack ("<I", Signature).decode ()
> > +
> > +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 = '<IIII'
> > + _StructSize = struct.calcsize (_StructFormat)
> > +
> > + _FMP_PAYLOAD_HEADER_SIGNATURE = _SIGNATURE_32
> ('M', 'S', 'S', '1')
> > +
> > + def __init__ (self):
> > + self._Valid = False
> > + self.Signature =
> self._FMP_PAYLOAD_HEADER_SIGNATURE
> > + self.HeaderSize =
> self._StructSize
> > + self.FwVersion = 0x00000000
> > + self.LowestSupportedVersion = 0x00000000
> > + self.Payload = b''
> > +
> > + def Encode (self):
> > + FmpPayloadHeader = struct.pack (
> > +
> self._StructFormat,
> > + self.Signature,
> > + self.HeaderSize,
> > + self.FwVersion,
> > +
> self.LowestSupportedVersion
> > + )
> > + self._Valid = True
> > + return FmpPayloadHeader + self.Payload
> > +
> > + def Decode (self, Buffer):
> > + if len (Buffer) < self._StructSize:
> > + raise ValueError
> > + (Signature, HeaderSize, FwVersion,
> LowestSupportedVersion) = \
> > + struct.unpack (
> > + self._StructFormat,
> > + Buffer[0:self._StructSize]
> > + )
> > + if Signature !=
> self._FMP_PAYLOAD_HEADER_SIGNATURE:
> > + raise ValueError
> > + if HeaderSize < self._StructSize:
> > + raise ValueError
> > + self.Signature = Signature
> > + self.HeaderSize = HeaderSize
> > + self.FwVersion = FwVersion
> > + self.LowestSupportedVersion =
> LowestSupportedVersion
> > + self.Payload =
> Buffer[self.HeaderSize:]
> > +
> > + self._Valid = True
> > + return self.Payload
> > +
> > + def DumpInfo (self):
> > + if not self._Valid:
> > + raise ValueError
> > + print ('FMP_PAYLOAD_HEADER.Signature
> = {Signature:08X} ({SignatureString})'.format (Signature
> =
> > self.Signature, SignatureString =
> _SIGNATURE_32_TO_STRING (self.Signature)))
> > + print ('FMP_PAYLOAD_HEADER.HeaderSize
> = {HeaderSize:08X}'.format (HeaderSize =
> self.HeaderSize))
> > + print ('FMP_PAYLOAD_HEADER.FwVersion
> = {FwVersion:08X}'.format (FwVersion = self.FwVersion))
> > + print
> ('FMP_PAYLOAD_HEADER.LowestSupportedVersion =
> {LowestSupportedVersion:08X}'.format
> > (LowestSupportedVersion =
> self.LowestSupportedVersion))
> > + print ('sizeof (Payload)
> = {Size:08X}'.format (Size = 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.<BR>
> > +# 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.<BR>
> > +# 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.<BR>
> > +# 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 = '<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 =
> CertType)
> > + self.CertData =
> Buffer[self._StructSize:self._MonotonicCountSize +
> self.dwLength]
> > + self.Payload =
> Buffer[self._MonotonicCountSize + self.dwLength:]
> > + self._Valid = True
> > + return self.Payload
> > +
> > + 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.dwLengt
> h = {dwLength:08X}'.format (dwLength =
> > self.dwLength))
> > + print
> ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevisi
> on = {wRevision:04X}'.format (wRevision =
> > self.wRevision))
> > + print
> ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertif
> icateType = {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/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.<BR>
> > +# 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 = '<I16sB3BIIQ'
> > + _StructSize = struct.calcsize (_StructFormat)
> > +
> > +
> EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSIO
> N = 0x00000002
> > +
> > + def __init__ (self):
> > + self._Valid = False
> > + self.Version =
> self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_V
> ERSION
> > + self.UpdateImageTypeId = uuid.UUID
> ('00000000-0000-0000-0000-000000000000')
> > + self.UpdateImageIndex = 0
> > + self.UpdateImageSize = 0
> > + self.UpdateVendorCodeSize = 0
> > + self.UpdateHardwareInstance =
> 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._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) = \
> > + 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 !=
> 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.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.UpdateIma
> geTypeId =
> > {UpdateImageTypeId}'.format (UpdateImageTypeId =
> str(self.UpdateImageTypeId).upper()))
> > + print
> ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateIma
> geIndex =
> > {UpdateImageIndex:08X}'.format (UpdateImageIndex =
> self.UpdateImageIndex))
> > + print
> ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateIma
> geSize =
> > {UpdateImageSize:08X}'.format (UpdateImageSize =
> self.UpdateImageSize))
> > + print
> ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVen
> dorCodeSize =
> > {UpdateVendorCodeSize:08X}'.format
> (UpdateVendorCodeSize = self.UpdateVendorCodeSize))
> > + print
> ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHar
> dwareInstance =
> > {UpdateHardwareInstance:016X}'.format
> (UpdateHardwareInstance = self.UpdateHardwareInstance))
> > + 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
> > +
> > + 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):
> > + self._PayloadList.append ((UpdateImageTypeId,
> Payload, VendorCodeBytes, HardwareInstance))
> > +
> > + 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) in self._PayloadList:
> > + FmpCapsuleImageHeader =
> FmpCapsuleImageHeaderClass ()
> > + FmpCapsuleImageHeader.UpdateImageTypeId
> = UpdateImageTypeId
> > + FmpCapsuleImageHeader.UpdateImageIndex
> = Index
> > + FmpCapsuleImageHeader.Payload
> = Payload
> > + FmpCapsuleImageHeader.VendorCodeBytes
> = VendorCodeBytes
> > +
> FmpCapsuleImageHeader.UpdateHardwareInstance =
> HardwareInstance
> > + 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.EmbeddedDriverC
> ount = {EmbeddedDriverCount:08X}'.format
> > (EmbeddedDriverCount = self.EmbeddedDriverCount))
> > + print
> ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCoun
> t = {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/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.<BR>
> > +# 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 = '<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/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.<BR>
> > +# 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.<BR>
> > +# 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
prev parent reply other threads:[~2018-05-31 16:36 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-29 22:56 [RFC 0/1] Add Capsule Generation Tools Michael D Kinney
2018-05-29 22:56 ` [RFC 1/1] BaseTools/Capsule: " Michael D Kinney
2018-05-31 14:25 ` Gao, Liming
2018-05-31 16:36 ` Kinney, Michael D [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E92EE9817A31E24EB0585FDF735412F5B8A644DE@ORSMSX113.amr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox