* [Patch v3 00/10] Add Capsule Generation Tools
@ 2018-08-01 6:33 Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 01/10] BaseTools/Capsule: " Kinney, Michael D
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=945
Based on content from the following branch
https://github.com/Microsoft/MS_UEFI/tree/share/beta/CapsuleTools
Command line unit tests for python modules available from following branch:
https://github.com/mdkinney/edk2/tree/Bug_945_StandAloneCapsuleTools_V2/BaseToolsUnitTest
Further development and testing of Capsule Generation Tools was performed at:
https://github.com/tianocore/edk2-staging/tree/FmpDevicePkg-master
https://github.com/tianocore/edk2-staging/tree/FmpDevicePkg-UDK2018
Summary of changes since original version
* 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
* Add max value checks to Capsule Generation tools
https://bugzilla.tianocore.org/show_bug.cgi?id=1021
https://bugzilla.tianocore.org/show_bug.cgi?id=1022
https://bugzilla.tianocore.org/show_bug.cgi?id=1026
* Remove support for PopulateSystemTable
https://bugzilla.tianocore.org/show_bug.cgi?id=1030
* Fix CertType GUID byte order
https://bugzilla.tianocore.org/show_bug.cgi?id=1024
* Do not support -o with --dump-info
https://bugzilla.tianocore.org/show_bug.cgi?id=1025
* Update help for --fw-version and --lsv
https://bugzilla.tianocore.org/show_bug.cgi?id=1029
* Update file header with tool limitations
https://bugzilla.tianocore.org/show_bug.cgi?id=1031
* Prevent traceback during signing operations
https://bugzilla.tianocore.org/show_bug.cgi?id=1046
https://bugzilla.tianocore.org/show_bug.cgi?id=1048
https://bugzilla.tianocore.org/show_bug.cgi?id=1050
* Support capsules without a payload header
https://bugzilla.tianocore.org/show_bug.cgi?id=1028
usage: GenerateCapsule [-h] [-o OUTPUTFILE] (-e | -d | --dump-info)
[--capflag {PersistAcrossReset,InitiateReset}]
[--capoemflag CAPSULEOEMFLAG] [--guid GUID]
[--hardware-instance HARDWAREINSTANCE]
[--monotonic-count MONOTONICCOUNT]
[--fw-version FWVERSION] [--lsv LOWESTSUPPORTEDVERSION]
[--pfx-file SIGNTOOLPFXFILE]
[--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE]
[--other-public-cert OPENSSLOTHERPUBLICCERTFILE]
[--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE]
[--signing-tool-path SIGNINGTOOLPATH] [--version] [-v]
[-q] [--debug [0-9]]
InputFile
Generate a capsule. Copyright (c) 2018, Intel Corporation. All rights
reserved.
positional arguments:
InputFile Input binary payload filename.
optional arguments:
-h, --help show this help message and exit
-o OUTPUTFILE, --output OUTPUTFILE
Output filename.
-e, --encode Encode file
-d, --decode Decode file
--dump-info Display FMP Payload Header information
--capflag {PersistAcrossReset,InitiateReset}
Capsule flag can be PersistAcrossReset or
InitiateReset or not set
--capoemflag CAPSULEOEMFLAG
Capsule OEM Flag is an integer between 0x0000 and
0xffff.
--guid GUID The FMP/ESRT GUID in registry format. Required for
encode operations.
--hardware-instance HARDWAREINSTANCE
The 64-bit hardware instance. The default is
0x0000000000000000
--monotonic-count MONOTONICCOUNT
64-bit monotonic count value in header. Default is
0x0000000000000000.
--fw-version FWVERSION
The 32-bit version of the binary payload (e.g.
0x11223344 or 5678). Required for encode operations
that sign a payload.
--lsv LOWESTSUPPORTEDVERSION
The 32-bit lowest supported version of the binary
payload (e.g. 0x11223344 or 5678). Required for encode
operations that sign a payload.
--pfx-file SIGNTOOLPFXFILE
signtool PFX certificate filename.
--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE
OpenSSL signer private certificate filename.
--other-public-cert OPENSSLOTHERPUBLICCERTFILE
OpenSSL other public certificate filename.
--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE
OpenSSL trusted public certificate filename.
--signing-tool-path SIGNINGTOOLPATH
Path to signtool or OpenSSL tool. Optional if path to
tools are already in PATH.
--version show program's version number and exit
-v, --verbose Turn on verbose output with informational messages
printed, including capsule headers and warning
messages.
-q, --quiet Disable all messages except fatal errors.
--debug [0-9] Set debug level
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Kinney, Michael D (9):
BaseTools/Capsule: Add Capsule Generation Tools
BaseTools/Capsule: Add max value checks to Capsule Generation tools
BaseTools/Capsule: Remove support for PopulateSystemTable
BaseTools/Capsule: Fix CertType GUID byte order
BaseTools/Capsule: Do not support -o with --dump-info
BaseTools/Capsule: Update help for --fw-version and --lsv
BaseTools/Capsule: Update file header with tool limitations
BaseTools/Capsule: Prevent traceback during signing operations
BaseTools/Capsule: Support capsules without a payload header
Star Zeng (1):
BaseTools GenerateCapsule: Change property to executable for Linux
BaseTools/BinWrappers/PosixLike/GenerateCapsule | 14 +
.../BinWrappers/WindowsLike/GenerateCapsule.bat | 1 +
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 555 +++++++++++++++++++++
.../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, 1343 insertions(+)
create mode 100755 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/FmpPayloadHeader.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/FmpAuthHeader.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/__init__.py
--
2.14.2.windows.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Patch v3 01/10] BaseTools/Capsule: Add Capsule Generation Tools
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 02/10] BaseTools GenerateCapsule: Change property to executable for Linux Kinney, Michael D
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=945
Based on content from the following branch
https://github.com/Microsoft/MS_UEFI/tree/share/beta/CapsuleTools
* Convert C tools to Python
* Add common python modules to:
BaseTools/Source/Python/Common/Uefi/Capsule
BaseTools/Source/Python/Common/Edk2/Capsule
* Add GenerateCapsule.py to BaseTools/Source/Python/Capsule
* Add Windows and Posix wrappers for GenerateCapsule.py
usage: GenerateCapsule [-h] [-o OUTPUTFILE] (-e | -d | --dump-info)
[--capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset}]
[--capoemflag CAPSULEOEMFLAG] [--guid GUID]
[--hardware-instance HARDWAREINSTANCE]
[--monotonic-count MONOTONICCOUNT]
[--fw-version FWVERSION] [--lsv LOWESTSUPPORTEDVERSION]
[--pfx-file SIGNTOOLPFXFILE]
[--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE]
[--other-public-cert OPENSSLOTHERPUBLICCERTFILE]
[--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE]
[--signing-tool-path SIGNINGTOOLPATH] [--version] [-v]
[-q] [--debug [0-9]]
InputFile
Generate a capsule. Copyright (c) 2018, Intel Corporation. All rights
reserved.
positional arguments:
InputFile Input binary payload filename.
optional arguments:
-h, --help show this help message and exit
-o OUTPUTFILE, --output OUTPUTFILE
Output filename.
-e, --encode Encode file
-d, --decode Decode file
--dump-info Display FMP Payload Header information
--capflag {PersistAcrossReset,PopulateSystemTable,InitiateReset}
Capsule flag can be PersistAcrossReset, or
PopulateSystemTable or InitiateReset or not set
--capoemflag CAPSULEOEMFLAG
Capsule OEM Flag is an integer between 0x0000 and
0xffff.
--guid GUID The FMP/ESRT GUID in registry format. Required for
encode operations.
--hardware-instance HARDWAREINSTANCE
The 64-bit hardware instance. The default is
0x0000000000000000
--monotonic-count MONOTONICCOUNT
64-bit monotonic count value in header. Default is
0x0000000000000000.
--fw-version FWVERSION
The 32-bit version of the binary payload (e.g.
0x11223344 or 5678).
--lsv LOWESTSUPPORTEDVERSION
The 32-bit lowest supported version of the binary
payload (e.g. 0x11223344 or 5678).
--pfx-file SIGNTOOLPFXFILE
signtool PFX certificate filename.
--signer-private-cert OPENSSLSIGNERPRIVATECERTFILE
OpenSSL signer private certificate filename.
--other-public-cert OPENSSLOTHERPUBLICCERTFILE
OpenSSL other public certificate filename.
--trusted-public-cert OPENSSLTRUSTEDPUBLICCERTFILE
OpenSSL trusted public certificate filename.
--signing-tool-path SIGNINGTOOLPATH
Path to signtool or OpenSSL tool. Optional if path to
tools are already in PATH.
--version show program's version number and exit
-v, --verbose Turn on verbose output with informational messages
printed, including capsule headers and warning
messages.
-q, --quiet Disable all messages except fatal errors.
--debug [0-9] Set debug level
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
---
BaseTools/BinWrappers/PosixLike/GenerateCapsule | 14 +
.../BinWrappers/WindowsLike/GenerateCapsule.bat | 1 +
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 522 +++++++++++++++++++++
| 91 ++++
.../Source/Python/Common/Edk2/Capsule/__init__.py | 15 +
BaseTools/Source/Python/Common/Edk2/__init__.py | 15 +
| 184 ++++++++
| 302 ++++++++++++
| 136 ++++++
.../Source/Python/Common/Uefi/Capsule/__init__.py | 15 +
BaseTools/Source/Python/Common/Uefi/__init__.py | 15 +
11 files changed, 1310 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/FmpPayloadHeader.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/FmpAuthHeader.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
create mode 100644 BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.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:+:"$PYTHONPATH"}"
+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..4018dc0420
--- /dev/null
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -0,0 +1,522 @@
+## @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
+import platform
+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'
+__version__ = '0.9'
+__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 ("--fw-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 OpenSSL tool. Optional if path to tools are already in PATH.")
+
+ #
+ # Add optional arguments common to all operations
+ #
+ parser.add_argument ('--version', action='version', version='%(prog)s ' + __version__)
+ parser.add_argument ("-v", "--verbose", dest = 'Verbose', action = "store_true",
+ help = "Turn on verbose output with informational messages printed, including capsule headers and warning messages.")
+ parser.add_argument ("-q", "--quiet", dest = 'Quiet', action = "store_true",
+ help = "Disable all messages except fatal errors.")
+ 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 args.Encode:
+ if args.Guid is None:
+ parser.error ('the following option is required: --guid')
+ if 'PersistAcrossReset' not in args.CapsuleFlag:
+ if 'PopulateSystemTable' in args.CapsuleFlag:
+ parser.error ('--capflag PopulateSystemTable also requires --capflag PersistAcrossReset')
+ if 'InitiateReset' in args.CapsuleFlag:
+ parser.error ('--capflag InitiateReset also requires --capflag PersistAcrossReset')
+
+ UseSignTool = args.SignToolPfxFile is not None
+ UseOpenSsl = (args.OpenSslSignerPrivateCertFile is not None and
+ args.OpenSslOtherPublicCertFile is not None and
+ args.OpenSslTrustedPublicCertFile is not None)
+ AnyOpenSsl = (args.OpenSslSignerPrivateCertFile is not None or
+ args.OpenSslOtherPublicCertFile is not None or
+ args.OpenSslTrustedPublicCertFile is not None)
+ if args.Encode or args.Decode:
+ if args.OutputFile is None:
+ parser.error ('the following option is required for all encode and decode operations: --output')
+
+ if UseSignTool and AnyOpenSsl:
+ parser.error ('Providing both signtool and OpenSSL options is not supported')
+ if not UseSignTool and not UseOpenSsl and AnyOpenSsl:
+ parser.error ('all the following options are required for OpenSSL: --signer-private-cert, --other-public-cert, --trusted-public-cert')
+ if UseSignTool and platform.system() != 'Windows':
+ parser.error ('Use of signtool is not supported on this operating system.')
+ if args.Encode and (UseSignTool or UseOpenSsl):
+ if args.FwVersion is None or args.LowestSupportedVersion is None:
+ parser.error ('the following options are required: --fw-version, --lsv')
+
+ if UseSignTool:
+ args.SignToolPfxFile.close()
+ args.SignToolPfxFile = args.SignToolPfxFile.name
+ if UseOpenSsl:
+ 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:
+ Result = Buffer
+ if UseSignTool or UseOpenSsl:
+ try:
+ FmpPayloadHeader.FwVersion = args.FwVersion
+ FmpPayloadHeader.LowestSupportedVersion = args.LowestSupportedVersion
+ FmpPayloadHeader.Payload = Result
+ 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 UseSignTool:
+ 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
+ if args.Verbose:
+ print ('========')
+ UefiCapsuleHeader.DumpInfo ()
+ print ('--------')
+ FmpCapsuleHeader.DumpInfo ()
+ if UseSignTool or UseOpenSsl:
+ Result = FmpAuthHeader.Decode (Result)
+
+ #
+ # Verify Image with 64-bit MonotonicCount appended to end of image
+ #
+ try:
+ if UseSignTool:
+ 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 ('--------')
+ FmpAuthHeader.DumpInfo ()
+ print ('--------')
+ FmpPayloadHeader.DumpInfo ()
+ else:
+ if args.Verbose:
+ print ('--------')
+ print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
+ print ('--------')
+ print ('No FMP_PAYLOAD_HEADER')
+ if args.Verbose:
+ 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
+ print ('========')
+ UefiCapsuleHeader.DumpInfo ()
+ print ('--------')
+ FmpCapsuleHeader.DumpInfo ()
+ try:
+ Result = FmpAuthHeader.Decode (Result)
+ Result = FmpPayloadHeader.Decode (Result)
+ print ('--------')
+ FmpAuthHeader.DumpInfo ()
+ print ('--------')
+ FmpPayloadHeader.DumpInfo ()
+ except:
+ print ('--------')
+ print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
+ print ('--------')
+ print ('No FMP_PAYLOAD_HEADER')
+ 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')
--git a/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayloadHeader.py b/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayloadHeader.py
new file mode 100644
index 0000000000..0ed51752d3
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Edk2/Capsule/FmpPayloadHeader.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__.py b/BaseTools/Source/Python/Common/Edk2/Capsule/__init__.py
new file mode 100644
index 0000000000..71c6f06838
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Edk2/Capsule/__init__.py
@@ -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.
+#
--git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
new file mode 100644
index 0000000000..aec52bf772
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.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.dwLength = {dwLength:08X}'.format (dwLength = self.dwLength))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wRevision = {wRevision:04X}'.format (wRevision = self.wRevision))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.Hdr.wCertificateType = {wCertificateType:04X}'.format (wCertificateType = self.wCertificateType))
+ print ('EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertType = {Guid}'.format (Guid = str(self.CertType).upper()))
+ print ('sizeof (EFI_FIRMWARE_IMAGE_AUTHENTICATION.AuthInfo.CertData) = {Size:08X}'.format (Size = len (self.CertData)))
+ print ('sizeof (Payload) = {Size:08X}'.format (Size = len (self.Payload)))
--git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py
new file mode 100644
index 0000000000..2461fb5068
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.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_VERSION 0x00000002
+
+ _StructFormat = '<I16sB3BIIQ'
+ _StructSize = struct.calcsize (_StructFormat)
+
+ EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION = 0x00000002
+
+ def __init__ (self):
+ self._Valid = False
+ self.Version = self.EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER_INIT_VERSION
+ self.UpdateImageTypeId = uuid.UUID ('00000000-0000-0000-0000-000000000000')
+ self.UpdateImageIndex = 0
+ self.UpdateImageSize = 0
+ self.UpdateVendorCodeSize = 0
+ self.UpdateHardwareInstance = 0x0000000000000000
+ self.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_VERSION:
+ raise ValueError
+ if UpdateImageIndex < 1:
+ raise ValueError
+ if UpdateImageSize + UpdateVendorCodeSize != len (Buffer[self._StructSize:]):
+ raise ValueError
+
+ self.Version = Version
+ self.UpdateImageTypeId = uuid.UUID (bytes_le = UpdateImageTypeId)
+ self.UpdateImageIndex = UpdateImageIndex
+ self.UpdateImageSize = UpdateImageSize
+ self.UpdateVendorCodeSize = UpdateVendorCodeSize
+ self.UpdateHardwareInstance = UpdateHardwareInstance
+ self.Payload = Buffer[self._StructSize:self._StructSize + UpdateImageSize]
+ self.VendorCodeBytes = Buffer[self._StructSize + UpdateImageSize:]
+ self._Valid = True
+ return Buffer[self._StructSize:]
+
+ def DumpInfo (self):
+ if not self._Valid:
+ raise ValueError
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.Version = {Version:08X}'.format (Version = self.Version))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageTypeId = {UpdateImageTypeId}'.format (UpdateImageTypeId = str(self.UpdateImageTypeId).upper()))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageIndex = {UpdateImageIndex:08X}'.format (UpdateImageIndex = self.UpdateImageIndex))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateImageSize = {UpdateImageSize:08X}'.format (UpdateImageSize = self.UpdateImageSize))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateVendorCodeSize = {UpdateVendorCodeSize:08X}'.format (UpdateVendorCodeSize = self.UpdateVendorCodeSize))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER.UpdateHardwareInstance = {UpdateHardwareInstance:016X}'.format (UpdateHardwareInstance = self.UpdateHardwareInstance))
+ print ('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.EmbeddedDriverCount = {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount = self.EmbeddedDriverCount))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = {PayloadItemCount:08X}'.format (PayloadItemCount = self.PayloadItemCount))
+ print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = ')
+ for Offset in self._ItemOffsetList:
+ print (' {Offset:016X}'.format (Offset = Offset))
+ for FmpCapsuleImageHeader in self._FmpCapsuleImageHeaderList:
+ FmpCapsuleImageHeader.DumpInfo ()
--git a/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.py
new file mode 100644
index 0000000000..cfe1cb6c46
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/UefiCapsuleHeader.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__.py b/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py
new file mode 100644
index 0000000000..d9db4aa919
--- /dev/null
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/__init__.py
@@ -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
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 02/10] BaseTools GenerateCapsule: Change property to executable for Linux
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 01/10] BaseTools/Capsule: " Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 03/10] BaseTools/Capsule: Add max value checks to Capsule Generation tools Kinney, Michael D
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel; +Cc: Star Zeng, Michael D Kinney
From: Star Zeng <star.zeng@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
---
BaseTools/BinWrappers/PosixLike/GenerateCapsule | 0
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 BaseTools/BinWrappers/PosixLike/GenerateCapsule
diff --git a/BaseTools/BinWrappers/PosixLike/GenerateCapsule b/BaseTools/BinWrappers/PosixLike/GenerateCapsule
old mode 100644
new mode 100755
--
2.14.2.windows.3
^ permalink raw reply [flat|nested] 11+ messages in thread
* [Patch v3 03/10] BaseTools/Capsule: Add max value checks to Capsule Generation tools
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 01/10] BaseTools/Capsule: " Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 02/10] BaseTools GenerateCapsule: Change property to executable for Linux Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 04/10] BaseTools/Capsule: Remove support for PopulateSystemTable Kinney, Michael D
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1021
https://bugzilla.tianocore.org/show_bug.cgi?id=1022
https://bugzilla.tianocore.org/show_bug.cgi?id=1026
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 4018dc0420..5398c12a9c 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -298,6 +298,12 @@ if __name__ == '__main__':
parser.error ('--capflag PopulateSystemTable also requires --capflag PersistAcrossReset')
if 'InitiateReset' in args.CapsuleFlag:
parser.error ('--capflag InitiateReset also requires --capflag PersistAcrossReset')
+ if args.CapsuleOemFlag > 0xFFFF:
+ parser.error ('--capoemflag must be an integer between 0x0000 and 0xffff')
+ if args.HardwareInstance > 0xFFFFFFFFFFFFFFFF:
+ parser.error ('--hardware-instance must be an integer in range 0x0..0xffffffffffffffff')
+ if args.MonotonicCount > 0xFFFFFFFFFFFFFFFF:
+ parser.error ('--monotonic-count must be an integer in range 0x0..0xffffffffffffffff')
UseSignTool = args.SignToolPfxFile is not None
UseOpenSsl = (args.OpenSslSignerPrivateCertFile is not None and
@@ -319,6 +325,10 @@ if __name__ == '__main__':
if args.Encode and (UseSignTool or UseOpenSsl):
if args.FwVersion is None or args.LowestSupportedVersion is None:
parser.error ('the following options are required: --fw-version, --lsv')
+ if args.FwVersion > 0xFFFFFFFF:
+ parser.error ('--fw-version must be an integer in range 0x0..0xffffffff')
+ if args.LowestSupportedVersion > 0xFFFFFFFF:
+ parser.error ('--lsv must be an integer in range 0x0..0xffffffff')
if UseSignTool:
args.SignToolPfxFile.close()
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 04/10] BaseTools/Capsule: Remove support for PopulateSystemTable
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (2 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 03/10] BaseTools/Capsule: Add max value checks to Capsule Generation tools Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 05/10] BaseTools/Capsule: Fix CertType GUID byte order Kinney, Michael D
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1030
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 5398c12a9c..34337b2710 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -239,8 +239,8 @@ if __name__ == '__main__':
# 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")
+ choices=['PersistAcrossReset', 'InitiateReset'],
+ help = "Capsule flag can be PersistAcrossReset 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.")
@@ -294,8 +294,6 @@ if __name__ == '__main__':
if args.Guid is None:
parser.error ('the following option is required: --guid')
if 'PersistAcrossReset' not in args.CapsuleFlag:
- if 'PopulateSystemTable' in args.CapsuleFlag:
- parser.error ('--capflag PopulateSystemTable also requires --capflag PersistAcrossReset')
if 'InitiateReset' in args.CapsuleFlag:
parser.error ('--capflag InitiateReset also requires --capflag PersistAcrossReset')
if args.CapsuleOemFlag > 0xFFFF:
@@ -421,7 +419,7 @@ if __name__ == '__main__':
try:
UefiCapsuleHeader.OemFlags = args.CapsuleOemFlag
UefiCapsuleHeader.PersistAcrossReset = 'PersistAcrossReset' in args.CapsuleFlag
- UefiCapsuleHeader.PopulateSystemTable = 'PopulateSystemTable' in args.CapsuleFlag
+ UefiCapsuleHeader.PopulateSystemTable = False
UefiCapsuleHeader.InitiateReset = 'InitiateReset' in args.CapsuleFlag
UefiCapsuleHeader.Payload = Result
Result = UefiCapsuleHeader.Encode ()
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 05/10] BaseTools/Capsule: Fix CertType GUID byte order
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (3 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 04/10] BaseTools/Capsule: Remove support for PopulateSystemTable Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 06/10] BaseTools/Capsule: Do not support -o with --dump-info Kinney, Michael D
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1024
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
| 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
index aec52bf772..ae5c1df8a4 100644
--- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
+++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py
@@ -166,7 +166,7 @@ class FmpAuthHeaderClass (object):
self.dwLength = dwLength
self.wRevision = wRevision
self.wCertificateType = wCertificateType
- self.CertType = uuid.UUID (bytes = CertType)
+ self.CertType = uuid.UUID (bytes_le = CertType)
self.CertData = Buffer[self._StructSize:self._MonotonicCountSize + self.dwLength]
self.Payload = Buffer[self._MonotonicCountSize + self.dwLength:]
self._Valid = True
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 06/10] BaseTools/Capsule: Do not support -o with --dump-info
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (4 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 05/10] BaseTools/Capsule: Fix CertType GUID byte order Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 07/10] BaseTools/Capsule: Update help for --fw-version and --lsv Kinney, Michael D
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1025
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 34337b2710..3c641bdca7 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -339,6 +339,10 @@ if __name__ == '__main__':
args.OpenSslOtherPublicCertFile = args.OpenSslOtherPublicCertFile.name
args.OpenSslTrustedPublicCertFile = args.OpenSslTrustedPublicCertFile.name
+ if args.DumpInfo:
+ if args.OutputFile is not None:
+ parser.error ('the following option is not supported for dumpinfo operations: --output')
+
#
# Read binary input file
#
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 07/10] BaseTools/Capsule: Update help for --fw-version and --lsv
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (5 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 06/10] BaseTools/Capsule: Do not support -o with --dump-info Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 08/10] BaseTools/Capsule: Update file header with tool limitations Kinney, Michael D
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
Update help to state that --fw-version and -=-lsv are required
for encode operations that sign a payload.
https://bugzilla.tianocore.org/show_bug.cgi?id=1029
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 3c641bdca7..76426dcf66 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -254,9 +254,9 @@ if __name__ == '__main__':
help = "64-bit monotonic count value in header. Default is 0x0000000000000000.")
parser.add_argument ("--fw-version", dest = 'FwVersion', type = ValidateUnsignedInteger,
- help = "The 32-bit version of the binary payload (e.g. 0x11223344 or 5678).")
+ help = "The 32-bit version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations that sign a payload.")
parser.add_argument ("--lsv", dest = 'LowestSupportedVersion', type = ValidateUnsignedInteger,
- help = "The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678).")
+ help = "The 32-bit lowest supported version of the binary payload (e.g. 0x11223344 or 5678). Required for encode operations that sign a payload.")
parser.add_argument ("--pfx-file", dest='SignToolPfxFile', type=argparse.FileType('rb'),
help="signtool PFX certificate filename.")
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 08/10] BaseTools/Capsule: Update file header with tool limitations
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (6 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 07/10] BaseTools/Capsule: Update help for --fw-version and --lsv Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 09/10] BaseTools/Capsule: Prevent traceback during signing operations Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 10/10] BaseTools/Capsule: Support capsules without a payload header Kinney, Michael D
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
Update file header to state that the tool does not support:
* Multiple payloads
* Drivers
* Vendor code bytes
https://bugzilla.tianocore.org/show_bug.cgi?id=1031
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 76426dcf66..d829000849 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -1,6 +1,17 @@
## @file
# Generate a capsule.
#
+# This tool generates a UEFI Capsule around an FMP Capsule. The capsule payload
+# be signed using signtool or OpenSSL and if it is signed the signed content
+# includes an FMP Payload Header.
+#
+# This tool is intended to be used to generate UEFI Capsules to update the
+# system firmware or device firmware for integrated devices. In order to
+# keep the tool as simple as possible, it has the following limitations:
+# * Do not support multiple payloads in a capsule.
+# * Do not support optional drivers in a capsule.
+# * Do not support vendor code bytes in 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
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 09/10] BaseTools/Capsule: Prevent traceback during signing operations
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (7 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 08/10] BaseTools/Capsule: Update file header with tool limitations Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 10/10] BaseTools/Capsule: Support capsules without a payload header Kinney, Michael D
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1046
https://bugzilla.tianocore.org/show_bug.cgi?id=1048
https://bugzilla.tianocore.org/show_bug.cgi?id=1050
Remove raise statements that generate Tracebacks that were only
intended for development/debug. With the raise statements removed
proper error messages are shown.
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index d829000849..42cd1fb8ba 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -408,7 +408,6 @@ if __name__ == '__main__':
)
except:
print ('GenerateCapsule: error: can not sign payload')
- raise
sys.exit (1)
try:
@@ -496,7 +495,6 @@ if __name__ == '__main__':
print ('========')
except:
print ('GenerateCapsule: error: can not decode capsule')
- raise
sys.exit (1)
elif args.DumpInfo:
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [Patch v3 10/10] BaseTools/Capsule: Support capsules without a payload header
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
` (8 preceding siblings ...)
2018-08-01 6:33 ` [Patch v3 09/10] BaseTools/Capsule: Prevent traceback during signing operations Kinney, Michael D
@ 2018-08-01 6:33 ` Kinney, Michael D
9 siblings, 0 replies; 11+ messages in thread
From: Kinney, Michael D @ 2018-08-01 6:33 UTC (permalink / raw)
To: edk2-devel
Cc: Sean Brogan, Jiewen Yao, Yonghong Zhu, Liming Gao,
Michael D Kinney
https://bugzilla.tianocore.org/show_bug.cgi?id=1028
Update --dump-info and --decode to show auth header information
even if a payload header is not present. The --decode operation
still fails if a payload header is not present.
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
BaseTools/Source/Python/Capsule/GenerateCapsule.py | 34 +++++++++++++++-------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
index 42cd1fb8ba..7b08918857 100644
--- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py
+++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py
@@ -455,6 +455,9 @@ if __name__ == '__main__':
FmpCapsuleHeader.DumpInfo ()
if UseSignTool or UseOpenSsl:
Result = FmpAuthHeader.Decode (Result)
+ if args.Verbose:
+ print ('--------')
+ FmpAuthHeader.DumpInfo ()
#
# Verify Image with 64-bit MonotonicCount appended to end of image
@@ -479,20 +482,25 @@ if __name__ == '__main__':
except ValueError:
print ('GenerateCapsule: warning: can not verify payload.')
- Result = FmpPayloadHeader.Decode (Result)
- if args.Verbose:
- print ('--------')
- FmpAuthHeader.DumpInfo ()
- print ('--------')
- FmpPayloadHeader.DumpInfo ()
+ try:
+ Result = FmpPayloadHeader.Decode (Result)
+ if args.Verbose:
+ print ('--------')
+ FmpPayloadHeader.DumpInfo ()
+ print ('========')
+ except:
+ if args.Verbose:
+ print ('--------')
+ print ('No FMP_PAYLOAD_HEADER')
+ print ('========')
+ raise
else:
if args.Verbose:
print ('--------')
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
print ('--------')
print ('No FMP_PAYLOAD_HEADER')
- if args.Verbose:
- print ('========')
+ print ('========')
except:
print ('GenerateCapsule: error: can not decode capsule')
sys.exit (1)
@@ -508,11 +516,15 @@ if __name__ == '__main__':
FmpCapsuleHeader.DumpInfo ()
try:
Result = FmpAuthHeader.Decode (Result)
- Result = FmpPayloadHeader.Decode (Result)
print ('--------')
FmpAuthHeader.DumpInfo ()
- print ('--------')
- FmpPayloadHeader.DumpInfo ()
+ try:
+ Result = FmpPayloadHeader.Decode (Result)
+ print ('--------')
+ FmpPayloadHeader.DumpInfo ()
+ except:
+ print ('--------')
+ print ('No FMP_PAYLOAD_HEADER')
except:
print ('--------')
print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')
--
2.14.2.windows.3
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2018-08-01 6:34 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-01 6:33 [Patch v3 00/10] Add Capsule Generation Tools Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 01/10] BaseTools/Capsule: " Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 02/10] BaseTools GenerateCapsule: Change property to executable for Linux Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 03/10] BaseTools/Capsule: Add max value checks to Capsule Generation tools Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 04/10] BaseTools/Capsule: Remove support for PopulateSystemTable Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 05/10] BaseTools/Capsule: Fix CertType GUID byte order Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 06/10] BaseTools/Capsule: Do not support -o with --dump-info Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 07/10] BaseTools/Capsule: Update help for --fw-version and --lsv Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 08/10] BaseTools/Capsule: Update file header with tool limitations Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 09/10] BaseTools/Capsule: Prevent traceback during signing operations Kinney, Michael D
2018-08-01 6:33 ` [Patch v3 10/10] BaseTools/Capsule: Support capsules without a payload header Kinney, Michael D
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox