From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: liming.gao@intel.com) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by groups.io with SMTP; Mon, 27 May 2019 06:58:27 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2019 06:58:27 -0700 X-ExtLoop1: 1 Received: from fmsmsx105.amr.corp.intel.com ([10.18.124.203]) by fmsmga007.fm.intel.com with ESMTP; 27 May 2019 06:58:27 -0700 Received: from fmsmsx111.amr.corp.intel.com (10.18.116.5) by FMSMSX105.amr.corp.intel.com (10.18.124.203) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 27 May 2019 06:58:27 -0700 Received: from shsmsx102.ccr.corp.intel.com (10.239.4.154) by fmsmsx111.amr.corp.intel.com (10.18.116.5) with Microsoft SMTP Server (TLS) id 14.3.408.0; Mon, 27 May 2019 06:58:26 -0700 Received: from shsmsx104.ccr.corp.intel.com ([169.254.5.33]) by shsmsx102.ccr.corp.intel.com ([169.254.2.249]) with mapi id 14.03.0415.000; Mon, 27 May 2019 21:58:24 +0800 From: "Liming Gao" To: "devel@edk2.groups.io" , "Jin, Eric" CC: "Feng, Bob C" , "Kinney, Michael D" , "Kinney, Michael D" Subject: Re: [edk2-devel] [Patch] BaseTools/Capsule: Supports UEFI Capsule with multiple payloads and embedded drivers Thread-Topic: [edk2-devel] [Patch] BaseTools/Capsule: Supports UEFI Capsule with multiple payloads and embedded drivers Thread-Index: AQHVFF5r7oPak56JM0OmL7BzTXkvZqZ+/4CA Date: Mon, 27 May 2019 13:58:23 +0000 Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E45488B@SHSMSX104.ccr.corp.intel.com> References: <20190527072807.11592-1-eric.jin@intel.com> In-Reply-To: <20190527072807.11592-1-eric.jin@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ctpclassification: CTP_NT x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNThjZjAxY2QtNGU2Mi00NDFjLWJiOWYtNjFhY2M4MzFhNjhmIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoibHZSS0VwUEVPYnMwemZBWG9zQnpUS3FBNkRRaEV6RllBRVwvdXJ5UktcL2JSRTdSdWtJYitsVTBnRjY1ZlF1aGRaIn0= dlp-product: dlpe-windows dlp-version: 11.0.600.7 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Return-Path: liming.gao@intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Seemly, this is new feature implementation. It will not be for Q2 stable ta= g. Right? > -----Original Message----- > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of Eri= c Jin > Sent: Monday, May 27, 2019 3:28 PM > To: devel@edk2.groups.io > Cc: Feng, Bob C ; Gao, Liming ; Kinney; Kinney, Michael D > Subject: [edk2-devel] [Patch] BaseTools/Capsule: Supports UEFI Capsule wi= th multiple payloads and embedded drivers >=20 > https://bugzilla.tianocore.org/show_bug.cgi?id=3D1834 >=20 > * Add arguments "--embedded-driver" to support embedded driver in command= line. > * Add arguments "--update-image-index" to identify ImageIndex within the = device > in command line. > * Add arguments "-j JSONFILE" to support multiple payloads and embedded d= rivers > with JSON file. >=20 > The update is in a backwards compatible manner, so all command line optio= ns to > support single payload are still supported. But all the options associate= d with > multiple payloads should be provided in a JSON file. >=20 > Cc: Bob Feng > Cc: Liming Gao > Cc: Kinney, Michael D > Signed-off-by: Eric Jin > --- > BaseTools/Source/Python/Capsule/GenerateCapsule.py | 961 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++ > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++-------------------------------------- > -------------------------------------------------------------------------= ---------------------------------------------------------------------------= ------------------------------------------------- > -------- > BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py | 14 ++= +++++++++++- > BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py | 12 ++= +++++----- > 3 files changed, 730 insertions(+), 257 deletions(-) >=20 > diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseToo= ls/Source/Python/Capsule/GenerateCapsule.py > index 4de3635298..ee95c4cc2e 100644 > --- a/BaseTools/Source/Python/Capsule/GenerateCapsule.py > +++ b/BaseTools/Source/Python/Capsule/GenerateCapsule.py > @@ -1,18 +1,16 @@ > ## @file >=20 > # Generate a capsule. >=20 > # >=20 > -# This tool generates a UEFI Capsule around an FMP Capsule. The capsule= payload >=20 > +# This tool generates a UEFI Capsule around an FMP Capsule. The capsule = payload >=20 > # be signed using signtool or OpenSSL and if it is signed the signed con= tent >=20 > # includes an FMP Payload Header. >=20 > # >=20 > # This tool is intended to be used to generate UEFI Capsules to update t= he >=20 > -# system firmware or device firmware for integrated devices. In order t= o >=20 > +# system firmware or device firmware for integrated devices. In order to >=20 > # keep the tool as simple as possible, it has the following limitations: >=20 > -# * Do not support multiple payloads in a capsule. >=20 > -# * Do not support optional drivers in a capsule. >=20 > # * Do not support vendor code bytes in a capsule. >=20 > # >=20 > -# Copyright (c) 2018, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
>=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 >=20 >=20 > @@ -29,6 +27,7 @@ import os > import tempfile >=20 > import shutil >=20 > import platform >=20 > +import json >=20 > from Common.Uefi.Capsule.UefiCapsuleHeader import UefiCapsuleHeaderClass >=20 > from Common.Uefi.Capsule.FmpCapsuleHeader import FmpCapsuleHeaderClass >=20 > from Common.Uefi.Capsule.FmpAuthHeader import FmpAuthHeaderClass >=20 > @@ -42,7 +41,7 @@ __version__ =3D '0.9' > __copyright__ =3D 'Copyright (c) 2018, Intel Corporation. All rights r= eserved.' >=20 > __description__ =3D 'Generate a capsule.\n' >=20 >=20 >=20 > -def SignPayloadSignTool (Payload, ToolPath, PfxFile): >=20 > +def SignPayloadSignTool (Payload, ToolPath, PfxFile, Verbose =3D False): >=20 > # >=20 > # Create a temporary directory >=20 > # >=20 > @@ -75,6 +74,8 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile): > Command =3D Command + '/p7 {TempDir} '.format (TempDir =3D TempDirec= toryName) >=20 > Command =3D Command + '/f {PfxFile} '.format (PfxFile =3D PfxFile) >=20 > Command =3D Command + TempFileName >=20 > + if Verbose: >=20 > + print (Command) >=20 >=20 >=20 > # >=20 > # Sign the input file using the specified private key >=20 > @@ -88,7 +89,7 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile): >=20 >=20 > if Process.returncode !=3D 0: >=20 > shutil.rmtree (TempDirectoryName) >=20 > - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore')) >=20 > + print (Result[1].decode()) >=20 > raise ValueError ('GenerateCapsule: error: signtool failed.') >=20 >=20 >=20 > # >=20 > @@ -105,11 +106,11 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile= ): > shutil.rmtree (TempDirectoryName) >=20 > return Signature >=20 >=20 >=20 > -def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile): >=20 > +def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, Verbose= =3D False): >=20 > print ('signtool verify is not supported.') >=20 > raise ValueError ('GenerateCapsule: error: signtool verify is not su= pported.') >=20 >=20 >=20 > -def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherP= ublicCertFile, TrustedPublicCertFile): >=20 > +def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherP= ublicCertFile, TrustedPublicCertFile, Verbose =3D False): >=20 > # >=20 > # Build openssl command >=20 > # >=20 > @@ -119,6 +120,8 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPriv= ateCertFile, OtherPublicCer > Command =3D Command + '"{Path}" '.format (Path =3D os.path.join (Too= lPath, 'openssl')) >=20 > Command =3D Command + 'smime -sign -binary -outform DER -md sha256 ' >=20 > Command =3D Command + '-signer "{Private}" -certfile "{Public}"'.for= mat (Private =3D SignerPrivateCertFile, Public =3D OtherPublicCertFile) >=20 > + if Verbose: >=20 > + print (Command) >=20 >=20 >=20 > # >=20 > # Sign the input file using the specified private key and capture si= gnature from STDOUT >=20 > @@ -131,12 +134,12 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPr= ivateCertFile, OtherPublicCer > raise ValueError ('GenerateCapsule: error: can not run openssl.'= ) >=20 >=20 >=20 > if Process.returncode !=3D 0: >=20 > - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore')) >=20 > + print (Result[1].decode()) >=20 > raise ValueError ('GenerateCapsule: error: openssl failed.') >=20 >=20 >=20 > return Signature >=20 >=20 >=20 > -def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCert= File, OtherPublicCertFile, TrustedPublicCertFile): >=20 > +def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCert= File, OtherPublicCertFile, TrustedPublicCertFile, Verbose =3D False): >=20 > # >=20 > # Create a temporary directory >=20 > # >=20 > @@ -167,6 +170,8 @@ def VerifyPayloadOpenSsl (Payload, CertData, ToolPath= , SignerPrivateCertFile, Ot > Command =3D Command + '"{Path}" '.format (Path =3D os.path.join (Too= lPath, 'openssl')) >=20 > Command =3D Command + 'smime -verify -inform DER ' >=20 > Command =3D Command + '-content {Content} -CAfile "{Public}"'.format= (Content =3D TempFileName, Public =3D TrustedPublicCertFile) >=20 > + if Verbose: >=20 > + print (Command) >=20 >=20 >=20 > # >=20 > # Verify signature >=20 > @@ -180,7 +185,7 @@ def VerifyPayloadOpenSsl (Payload, CertData, ToolPath= , SignerPrivateCertFile, Ot >=20 >=20 > if Process.returncode !=3D 0: >=20 > shutil.rmtree (TempDirectoryName) >=20 > - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore')) >=20 > + print (Result[1].decode()) >=20 > raise ValueError ('GenerateCapsule: error: openssl failed.') >=20 >=20 >=20 > shutil.rmtree (TempDirectoryName) >=20 > @@ -212,6 +217,660 @@ if __name__ =3D=3D '__main__': > raise argparse.ArgumentTypeError (Message) >=20 > return Value >=20 >=20 >=20 > + def ConvertJsonValue (Config, FieldName, Convert, Required =3D True,= Default =3D None, Open =3D False): >=20 > + if FieldName not in Config: >=20 > + if Required: >=20 > + print ('GenerateCapsule: error: Payload descriptor inval= id syntax. Could not find {Key} in payload > descriptor.'.format(Key =3D FieldName)) >=20 > + sys.exit (1) >=20 > + return Default >=20 > + try: >=20 > + Value =3D Convert (Config[FieldName]) >=20 > + except Exception as Message: >=20 > + print ('GenerateCapsule: error: {Key} in payload descriptor = has invalid syntax. '.format (Key =3D FieldName) + str(Message)) >=20 > + sys.exit (1) >=20 > + if Open: >=20 > + try: >=20 > + Value =3D open (Value, "rb") >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not open file {File}= '.format (File =3D FieldName)) >=20 > + sys.exit (1) >=20 > + return Value >=20 > + >=20 > + def DecodeJsonFileParse (Json): >=20 > + if 'Payloads' not in Json: >=20 > + print ('GenerateCapsule: error "Payloads" section not found = in JSON file {File}'.format (File =3D args.JsonFile.name)) >=20 > + sys.exit (1) >=20 > + for Config in Json['Payloads']: >=20 > + # >=20 > + # Parse fields from JSON >=20 > + # >=20 > + PayloadFile =3D ConvertJsonValue (Config, '= Payload', os.path.expandvars, Required =3D False) >=20 > + Guid =3D ConvertJsonValue (Config, '= Guid', ValidateRegistryFormatGuid, Required =3D False) >=20 > + FwVersion =3D ConvertJsonValue (Config, '= FwVersion', ValidateUnsignedInteger, Required =3D False) >=20 > + LowestSupportedVersion =3D ConvertJsonValue (Config, '= LowestSupportedVersion', ValidateUnsignedInteger, Required > =3D False) >=20 > + HardwareInstance =3D ConvertJsonValue (Config, '= HardwareInstance', ValidateUnsignedInteger, Required =3D > False, Default =3D 0) >=20 > + MonotonicCount =3D ConvertJsonValue (Config, '= MonotonicCount', ValidateUnsignedInteger, Required =3D > False, Default =3D 0) >=20 > + SignToolPfxFile =3D ConvertJsonValue (Config, '= SignToolPfxFile', os.path.expandvars, Required =3D False, Default > =3D None, Open =3D True) >=20 > + OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, '= OpenSslSignerPrivateCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, '= OpenSslOtherPublicCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, '= OpenSslTrustedPublicCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + SigningToolPath =3D ConvertJsonValue (Config, '= SigningToolPath', os.path.expandvars, Required =3D False, > Default =3D None) >=20 > + UpdateImageIndex =3D ConvertJsonValue (Config, '= UpdateImageIndex', ValidateUnsignedInteger, Required =3D > False, Default =3D 1) >=20 > + >=20 > + PayloadDescriptorList.append (PayloadDescriptor ( >=20 > + PayloadFile, >=20 > + Guid, >=20 > + FwVersion, >=20 > + LowestSupportedVersion, >=20 > + MonotonicCount, >=20 > + HardwareInstance, >=20 > + UpdateImageIndex, >=20 > + SignToolPfxFile, >=20 > + OpenSslSignerPrivateCertFile= , >=20 > + OpenSslOtherPublicCertFile, >=20 > + OpenSslTrustedPublicCertFile= , >=20 > + SigningToolPath >=20 > + )) >=20 > + >=20 > + def EncodeJsonFileParse (Json): >=20 > + if 'EmbeddedDrivers' not in Json: >=20 > + print ('GenerateCapsule: warning "EmbeddedDrivers" section n= ot found in JSON file {File}'.format (File =3D > args.JsonFile.name)) >=20 > + else: >=20 > + for Config in Json['EmbeddedDrivers']: >=20 > + EmbeddedDriverFile =3D ConvertJsonValue(Config, 'Dr= iver', os.path.expandvars, Open =3D True) >=20 > + # >=20 > + #Read EmbeddedDriver file >=20 > + # >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Read EmbeddedDriver file {File}'.format = (File =3D EmbeddedDriverFile.name)) >=20 > + Driver =3D EmbeddedDriverFile.read() >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not read Embedde= dDriver file {File}'.format (File =3D EmbeddedDriverFile.name)) >=20 > + sys.exit(1) >=20 > + EmbeddedDriverDescriptorList.append (Driver) >=20 > + >=20 > + if 'Payloads' not in Json: >=20 > + print ('GenerateCapsule: error: "Payloads" section not found= in JSON file {File}'.format (File =3D args.JsonFile.name)) >=20 > + sys.exit (1) >=20 > + for Config in Json['Payloads']: >=20 > + # >=20 > + # Parse fields from JSON >=20 > + # >=20 > + PayloadFile =3D ConvertJsonValue (Config, '= Payload', os.path.expandvars, Open =3D True) >=20 > + Guid =3D ConvertJsonValue (Config, '= Guid', ValidateRegistryFormatGuid) >=20 > + FwVersion =3D ConvertJsonValue (Config, '= FwVersion', ValidateUnsignedInteger) >=20 > + LowestSupportedVersion =3D ConvertJsonValue (Config, '= LowestSupportedVersion', ValidateUnsignedInteger) >=20 > + HardwareInstance =3D ConvertJsonValue (Config, '= HardwareInstance', ValidateUnsignedInteger, Required =3D > False, Default =3D 0) >=20 > + UpdateImageIndex =3D ConvertJsonValue (Config, '= UpdateImageIndex', ValidateUnsignedInteger, Required =3D > False, Default =3D 1) >=20 > + MonotonicCount =3D ConvertJsonValue (Config, '= MonotonicCount', ValidateUnsignedInteger, Required =3D > False, Default =3D 0) >=20 > + SignToolPfxFile =3D ConvertJsonValue (Config, '= SignToolPfxFile', os.path.expandvars, Required =3D False, Default > =3D None, Open =3D True) >=20 > + OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, '= OpenSslSignerPrivateCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, '= OpenSslOtherPublicCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, '= OpenSslTrustedPublicCertFile', os.path.expandvars, Required =3D > False, Default =3D None, Open =3D True) >=20 > + SigningToolPath =3D ConvertJsonValue (Config, '= SigningToolPath', os.path.expandvars, Required =3D False, > Default =3D None) >=20 > + >=20 > + # >=20 > + # Read binary input file >=20 > + # >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Read binary input file {File}'.format (File = =3D PayloadFile.name)) >=20 > + Payload =3D PayloadFile.read() >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not read binary inpu= t file {File}'.format (File =3D PayloadFile.name)) >=20 > + sys.exit (1) >=20 > + PayloadDescriptorList.append (PayloadDescriptor ( >=20 > + Payload, >=20 > + Guid, >=20 > + FwVersion, >=20 > + LowestSupportedVersion, >=20 > + MonotonicCount, >=20 > + HardwareInstance, >=20 > + UpdateImageIndex, >=20 > + SignToolPfxFile, >=20 > + OpenSslSignerPrivateCertFile= , >=20 > + OpenSslOtherPublicCertFile, >=20 > + OpenSslTrustedPublicCertFile= , >=20 > + SigningToolPath >=20 > + )) >=20 > + >=20 > + def GenerateOutputJson (PayloadJsonDescriptorList): >=20 > + PayloadJson =3D { >=20 > + "Payloads" : [ >=20 > + { >=20 > + "Guid": str(PayloadDescriptor.Guid).up= per(), >=20 > + "FwVersion": str(PayloadDescriptor.FwV= ersion), >=20 > + "LowestSupportedVersion": str(PayloadD= escriptor.LowestSupportedVersion), >=20 > + "MonotonicCount": str(PayloadDescripto= r.MonotonicCount), >=20 > + "Payload": PayloadDescriptor.Payload, >=20 > + "HardwareInstance": str(PayloadDescrip= tor.HardwareInstance), >=20 > + "UpdateImageIndex": str(PayloadDescrip= tor.UpdateImageIndex), >=20 > + "SignToolPfxFile": str(PayloadDescript= or.SignToolPfxFile), >=20 > + "OpenSslSignerPrivateCertFile": str(Pa= yloadDescriptor.OpenSslSignerPrivateCertFile), >=20 > + "OpenSslOtherPublicCertFile": str(Payl= oadDescriptor.OpenSslOtherPublicCertFile), >=20 > + "OpenSslTrustedPublicCertFile": str(Pa= yloadDescriptor.OpenSslTrustedPublicCertFile), >=20 > + "SigningToolPath": str(PayloadDescript= or.SigningToolPath) >=20 > + }for PayloadDescriptor in PayloadJsonDescr= iptorList >=20 > + ] >=20 > + } >=20 > + OutputJsonFile =3D args.OutputFile.name + '.json' >=20 > + if 'Payloads' in PayloadJson: >=20 > + PayloadSection =3D PayloadJson ['Payloads'] >=20 > + Index =3D 0 >=20 > + for PayloadField in PayloadSection: >=20 > + if PayloadJsonDescriptorList[Index].SignToolPfxFile is None: >=20 > + del PayloadField ['SignToolPfxFile'] >=20 > + if PayloadJsonDescriptorList[Index].OpenSslSignerPrivateCert= File is None: >=20 > + del PayloadField ['OpenSslSignerPrivateCertFile'] >=20 > + if PayloadJsonDescriptorList[Index].OpenSslOtherPublicCertFi= le is None: >=20 > + del PayloadField ['OpenSslOtherPublicCertFile'] >=20 > + if PayloadJsonDescriptorList[Index].OpenSslTrustedPublicCert= File is None: >=20 > + del PayloadField ['OpenSslTrustedPublicCertFile'] >=20 > + if PayloadJsonDescriptorList[Index].SigningToolPath is None: >=20 > + del PayloadField ['SigningToolPath'] >=20 > + Index =3D Index + 1 >=20 > + Result =3D json.dumps (PayloadJson, indent=3D4, sort_keys=3DTrue= , separators=3D(',', ': ')) >=20 > + OutputFile =3D open (OutputJsonFile, 'w') >=20 > + OutputFile.write (Result) >=20 > + OutputFile.close () >=20 > + >=20 > + def CheckArgumentConflict (args): >=20 > + if args.Encode: >=20 > + if args.InputFile: >=20 > + print ('GenerateCapsule: error: Argument InputFile confl= icts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.EmbeddedDriver: >=20 > + print ('GenerateCapsule: error: Argument --embedded-driv= er conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.Guid: >=20 > + print ('GenerateCapsule: error: Argument --guid conflicts wi= th Argument -j') >=20 > + sys.exit (1) >=20 > + if args.FwVersion: >=20 > + print ('GenerateCapsule: error: Argument --fw-version confli= cts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.LowestSupportedVersion: >=20 > + print ('GenerateCapsule: error: Argument --lsv conflicts wit= h Argument -j') >=20 > + sys.exit (1) >=20 > + if args.MonotonicCount: >=20 > + print ('GenerateCapsule: error: Argument --monotonic-count c= onflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.HardwareInstance: >=20 > + print ('GenerateCapsule: error: Argument --hardware-instance= conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.SignToolPfxFile: >=20 > + print ('GenerateCapsule: error: Argument --pfx-file conflict= s with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.OpenSslSignerPrivateCertFile: >=20 > + print ('GenerateCapsule: error: Argument --signer-private-ce= rt conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.OpenSslOtherPublicCertFile: >=20 > + print ('GenerateCapsule: error: Argument --other-public-cert= conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.OpenSslTrustedPublicCertFile: >=20 > + print ('GenerateCapsule: error: Argument --trusted-public-ce= rt conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + if args.SigningToolPath: >=20 > + print ('GenerateCapsule: error: Argument --signing-tool-path= conflicts with Argument -j') >=20 > + sys.exit (1) >=20 > + >=20 > + class PayloadDescriptor (object): >=20 > + def __init__(self, >=20 > + Payload, >=20 > + Guid, >=20 > + FwVersion, >=20 > + LowestSupportedVersion, >=20 > + MonotonicCount =3D 0, >=20 > + HardwareInstance =3D 0, >=20 > + UpdateImageIndex =3D 1, >=20 > + SignToolPfxFile =3D None, >=20 > + OpenSslSignerPrivateCertFile =3D None, >=20 > + OpenSslOtherPublicCertFile =3D None, >=20 > + OpenSslTrustedPublicCertFile =3D None, >=20 > + SigningToolPath =3D None >=20 > + ): >=20 > + self.Payload =3D Payload >=20 > + self.Guid =3D Guid >=20 > + self.FwVersion =3D FwVersion >=20 > + self.LowestSupportedVersion =3D LowestSupportedVersion >=20 > + self.MonotonicCount =3D MonotonicCount >=20 > + self.HardwareInstance =3D HardwareInstance >=20 > + self.UpdateImageIndex =3D UpdateImageIndex >=20 > + self.SignToolPfxFile =3D SignToolPfxFile >=20 > + self.OpenSslSignerPrivateCertFile =3D OpenSslSignerPrivateCe= rtFile >=20 > + self.OpenSslOtherPublicCertFile =3D OpenSslOtherPublicCert= File >=20 > + self.OpenSslTrustedPublicCertFile =3D OpenSslTrustedPublicCe= rtFile >=20 > + self.SigningToolPath =3D SigningToolPath >=20 > + >=20 > + self.UseSignTool =3D self.SignToolPfxFile is not None >=20 > + self.UseOpenSsl =3D (self.OpenSslSignerPrivateCertFile is n= ot None and >=20 > + self.OpenSslOtherPublicCertFile is not N= one and >=20 > + self.OpenSslTrustedPublicCertFile is not= None) >=20 > + self.AnyOpenSsl =3D (self.OpenSslSignerPrivateCertFile is n= ot None or >=20 > + self.OpenSslOtherPublicCertFile is not N= one or >=20 > + self.OpenSslTrustedPublicCertFile is not= None) >=20 > + >=20 > + def Validate(self, args): >=20 > + if self.UseSignTool and self.AnyOpenSsl: >=20 > + raise argparse.ArgumentTypeError ('Providing both signto= ol and OpenSSL options is not supported') >=20 > + if not self.UseSignTool and not self.UseOpenSsl and self.Any= OpenSsl: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('the following JSO= N fields are required for OpenSSL: > OpenSslSignerPrivateCertFile, OpenSslOtherPublicCertFile, OpenSslTrustedP= ublicCertFile') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('the following opt= ions are required for OpenSSL: --signer-private-cert, > --other-public-cert, --trusted-public-cert') >=20 > + if self.UseSignTool and platform.system() !=3D 'Windows': >=20 > + raise argparse.ArgumentTypeError ('Use of signtool is no= t supported on this operating system.') >=20 > + if args.Encode: >=20 > + if self.FwVersion is None or self.LowestSupportedVersion= is None: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('the following= JSON fields are required: FwVersion, > LowestSupportedVersion') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('the following= options are required: --fw-version, --lsv') >=20 > + if self.FwVersion > 0xFFFFFFFF: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('JSON field Fw= Version must be an integer in range 0x0..0xffffffff') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('--fw-version = must be an integer in range 0x0..0xffffffff') >=20 > + if self.LowestSupportedVersion > 0xFFFFFFFF: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('JSON field Lo= westSupportedVersion must be an integer in range > 0x0..0xffffffff') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('--lsv must be= an integer in range 0x0..0xffffffff') >=20 > + >=20 > + if args.Encode: >=20 > + if self.Guid is None: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('the following= JSON field is required: Guid') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('the following= option is required: --guid') >=20 > + if self.HardwareInstance > 0xFFFFFFFFFFFFFFFF: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('JSON field Ha= rdwareInstance must be an integer in range > 0x0..0xffffffffffffffff') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('--hardware-in= stance must be an integer in range 0x0..0xffffffffffffffff') >=20 > + if self.MonotonicCount > 0xFFFFFFFFFFFFFFFF: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('JSON field Mo= notonicCount must be an integer in range > 0x0..0xffffffffffffffff') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('--monotonic-c= ount must be an integer in range 0x0..0xffffffffffffffff') >=20 > + if self.UpdateImageIndex >0xFF: >=20 > + if args.JsonFile: >=20 > + raise argparse.ArgumentTypeError ('JSON field Up= dateImageIndex must be an integer in range 0x0..0xff') >=20 > + else: >=20 > + raise argparse.ArgumentTypeError ('--update-imag= e-index must be an integer in range 0x0..0xff') >=20 > + >=20 > + if self.UseSignTool: >=20 > + self.SignToolPfxFile.close() >=20 > + self.SignToolPfxFile =3D self.SignToolPfxFile.name >=20 > + if self.UseOpenSsl: >=20 > + self.OpenSslSignerPrivateCertFile.close() >=20 > + self.OpenSslOtherPublicCertFile.close() >=20 > + self.OpenSslTrustedPublicCertFile.close() >=20 > + self.OpenSslSignerPrivateCertFile =3D self.OpenSslSigner= PrivateCertFile.name >=20 > + self.OpenSslOtherPublicCertFile =3D self.OpenSslOtherP= ublicCertFile.name >=20 > + self.OpenSslTrustedPublicCertFile =3D self.OpenSslTruste= dPublicCertFile.name >=20 > + >=20 > + # >=20 > + # Perform additional argument verification >=20 > + # >=20 > + if args.Encode: >=20 > + if 'PersistAcrossReset' not in args.CapsuleFlag: >=20 > + if 'InitiateReset' in args.CapsuleFlag: >=20 > + raise argparse.ArgumentTypeError ('--capflag Ini= tiateReset also requires --capflag PersistAcrossReset') >=20 > + if args.CapsuleOemFlag > 0xFFFF: >=20 > + raise argparse.ArgumentTypeError ('--capoemflag must= be an integer between 0x0000 and 0xffff') >=20 > + >=20 > + return True >=20 > + >=20 > + >=20 > + def Encode (PayloadDescriptorList, EmbeddedDriverDescriptorList, Buf= fer): >=20 > + if args.JsonFile: >=20 > + CheckArgumentConflict(args) >=20 > + try: >=20 > + Json =3D json.loads (args.JsonFile.read ()) >=20 > + except Exception as Message: >=20 > + print ('GenerateCapsule: error: ' + str(Message)) >=20 > + sys.exit (1) >=20 > + EncodeJsonFileParse(Json) >=20 > + else: >=20 > + for Driver in args.EmbeddedDriver: >=20 > + EmbeddedDriverDescriptorList.append (Driver.read()) >=20 > + PayloadDescriptorList.append (PayloadDescriptor ( >=20 > + Buffer, >=20 > + args.Guid, >=20 > + args.FwVersion, >=20 > + args.LowestSupportedVersion, >=20 > + args.MonotonicCount, >=20 > + args.HardwareInstance, >=20 > + args.UpdateImageIndex, >=20 > + args.SignToolPfxFile, >=20 > + args.OpenSslSignerPrivateCer= tFile, >=20 > + args.OpenSslOtherPublicCertF= ile, >=20 > + args.OpenSslTrustedPublicCer= tFile, >=20 > + args.SigningToolPath >=20 > + )) >=20 > + for SinglePayloadDescriptor in PayloadDescriptorList: >=20 > + try: >=20 > + SinglePayloadDescriptor.Validate (args) >=20 > + except Exception as Message: >=20 > + print ('GenerateCapsule: error: ' + str(Message)) >=20 > + sys.exit (1) >=20 > + for SinglePayloadDescriptor in PayloadDescriptorList: >=20 > + Result =3D SinglePayloadDescriptor.Payload >=20 > + try: >=20 > + FmpPayloadHeader.FwVersion =3D SinglePayloa= dDescriptor.FwVersion >=20 > + FmpPayloadHeader.LowestSupportedVersion =3D SinglePayloa= dDescriptor.LowestSupportedVersion >=20 > + FmpPayloadHeader.Payload =3D SinglePayloa= dDescriptor.Payload >=20 > + Result =3D FmpPayloadHeader.Encode () >=20 > + if args.Verbose: >=20 > + FmpPayloadHeader.DumpInfo () >=20 > + except: >=20 > + raise >=20 > + print ('GenerateCapsule: error: can not encode FMP Paylo= ad Header') >=20 > + sys.exit (1) >=20 > + if SinglePayloadDescriptor.UseOpenSsl or SinglePayloadDescri= ptor.UseSignTool: >=20 > + # >=20 > + # Sign image with 64-bit MonotonicCount appended to end = of image >=20 > + # >=20 > + try: >=20 > + if SinglePayloadDescriptor.UseSignTool: >=20 > + CertData =3D SignPayloadSignTool ( >=20 > + Result + struct.pack ('=20 > + SinglePayloadDescriptor.SigningToolPath, >=20 > + SinglePayloadDescriptor.SignToolPfxFile, >=20 > + Verbose =3D args.Verbose >=20 > + ) >=20 > + else: >=20 > + CertData =3D SignPayloadOpenSsl ( >=20 > + Result + struct.pack ('=20 > + SinglePayloadDescriptor.SigningToolPath, >=20 > + SinglePayloadDescriptor.OpenSslSignerPrivate= CertFile, >=20 > + SinglePayloadDescriptor.OpenSslOtherPublicCe= rtFile, >=20 > + SinglePayloadDescriptor.OpenSslTrustedPublic= CertFile, >=20 > + Verbose =3D args.Verbose >=20 > + ) >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not sign payload= ') >=20 > + sys.exit (1) >=20 > + >=20 > + try: >=20 > + FmpAuthHeader.MonotonicCount =3D SinglePayloadDescri= ptor.MonotonicCount >=20 > + FmpAuthHeader.CertData =3D CertData >=20 > + FmpAuthHeader.Payload =3D Result >=20 > + Result =3D FmpAuthHeader.Encode () >=20 > + if args.Verbose: >=20 > + FmpAuthHeader.DumpInfo () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not encode FMP A= uth Header') >=20 > + sys.exit (1) >=20 > + FmpCapsuleHeader.AddPayload (SinglePayloadDescriptor.Guid, R= esult, HardwareInstance =3D > SinglePayloadDescriptor.HardwareInstance, UpdateImageIndex =3D SinglePayl= oadDescriptor.UpdateImageIndex) >=20 > + try: >=20 > + for EmbeddedDriver in EmbeddedDriverDescriptorList: >=20 > + FmpCapsuleHeader.AddEmbeddedDriver(EmbeddedDriver) >=20 > + >=20 > + Result =3D FmpCapsuleHeader.Encode () >=20 > + if args.Verbose: >=20 > + FmpCapsuleHeader.DumpInfo () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not encode FMP Capsule H= eader') >=20 > + sys.exit (1) >=20 > + >=20 > + try: >=20 > + UefiCapsuleHeader.OemFlags =3D args.CapsuleOemFla= g >=20 > + UefiCapsuleHeader.PersistAcrossReset =3D 'PersistAcrossRese= t' in args.CapsuleFlag >=20 > + UefiCapsuleHeader.PopulateSystemTable =3D False >=20 > + UefiCapsuleHeader.InitiateReset =3D 'InitiateReset' = in args.CapsuleFlag >=20 > + UefiCapsuleHeader.Payload =3D Result >=20 > + Result =3D UefiCapsuleHeader.Encode () >=20 > + if args.Verbose: >=20 > + UefiCapsuleHeader.DumpInfo () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not encode UEFI Capsule = Header') >=20 > + sys.exit (1) >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Write binary output file {File}'.format (File = =3D args.OutputFile.name)) >=20 > + args.OutputFile.write (Result) >=20 > + args.OutputFile.close () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not write binary output = file {File}'.format (File =3D args.OutputFile.name)) >=20 > + sys.exit (1) >=20 > + >=20 > + def Decode (PayloadDescriptorList, PayloadJsonDescriptorList, Buffer= ): >=20 > + if args.JsonFile: >=20 > + CheckArgumentConflict(args) >=20 > + # >=20 > + # Parse payload descriptors from JSON >=20 > + # >=20 > + try: >=20 > + Json =3D json.loads (args.JsonFile.read()) >=20 > + except Exception as Message: >=20 > + print ('GenerateCapsule: error: ' + str(Message)) >=20 > + sys.exit (1) >=20 > + DecodeJsonFileParse (Json) >=20 > + else: >=20 > + PayloadDescriptorList.append (PayloadDescriptor ( >=20 > + Buffer, >=20 > + args.Guid, >=20 > + args.FwVersion, >=20 > + args.LowestSupportedVersion, >=20 > + args.MonotonicCount, >=20 > + args.HardwareInstance, >=20 > + args.UpdateImageIndex, >=20 > + args.SignToolPfxFile, >=20 > + args.OpenSslSignerPrivateCer= tFile, >=20 > + args.OpenSslOtherPublicCertF= ile, >=20 > + args.OpenSslTrustedPublicCer= tFile, >=20 > + args.SigningToolPath >=20 > + )) >=20 > + # >=20 > + # Perform additional verification on payload descriptors >=20 > + # >=20 > + for SinglePayloadDescriptor in PayloadDescriptorList: >=20 > + try: >=20 > + SinglePayloadDescriptor.Validate (args) >=20 > + except Exception as Message: >=20 > + print ('GenerateCapsule: error: ' + str(Message)) >=20 > + sys.exit (1) >=20 > + try: >=20 > + Result =3D UefiCapsuleHeader.Decode (Buffer) >=20 > + if len (Result) > 0: >=20 > + Result =3D FmpCapsuleHeader.Decode (Result) >=20 > + if args.JsonFile: >=20 > + if FmpCapsuleHeader.PayloadItemCount !=3D len (Paylo= adDescriptorList): >=20 > + CapsulePayloadNum =3D FmpCapsuleHeader.PayloadIt= emCount >=20 > + JsonPayloadNum =3D len (PayloadDescriptorList) >=20 > + print ('GenerateCapsule: Decode error: {JsonPayl= oadNumber} payloads in JSON file {File} and > {CapsulePayloadNumber} payloads in Capsule {CapsuleName}'.format (JsonPay= loadNumber =3D JsonPayloadNum, File =3D args.JsonFile.name, > CapsulePayloadNumber =3D CapsulePayloadNum, CapsuleName =3D args.InputFil= e.name)) >=20 > + sys.exit (1) >=20 > + for Index in range (0, FmpCapsuleHeader.PayloadItemC= ount): >=20 > + if Index < len (PayloadDescriptorList): >=20 > + GUID =3D FmpCapsuleHeader.GetFmpCapsuleImage= Header (Index).UpdateImageTypeId >=20 > + HardwareInstance =3D FmpCapsuleHeader.GetFmp= CapsuleImageHeader (Index).UpdateHardwareInstance >=20 > + UpdateImageIndex =3D FmpCapsuleHeader.GetFmp= CapsuleImageHeader (Index).UpdateImageIndex >=20 > + if PayloadDescriptorList[Index].Guid !=3D GU= ID or PayloadDescriptorList[Index].HardwareInstance !=3D > HardwareInstance: >=20 > + print ('GenerateCapsule: Decode error: G= uid or HardwareInstance pair in input JSON file {File} does > not match the payload {PayloadIndex} in Capsule {InputCapsule}'.format (F= ile =3D args.JsonFile.name, PayloadIndex =3D Index + 1, InputCapsule > =3D args.InputFile.name)) >=20 > + sys.exit (1) >=20 > + PayloadDescriptorList[Index].Payload =3D Fmp= CapsuleHeader.GetFmpCapsuleImageHeader (Index).Payload >=20 > + DecodeJsonOutput =3D args.OutputFile.name + = '.Payload.{Index:d}.bin'.format (Index =3D Index + 1) >=20 > + PayloadJsonDescriptorList.append (PayloadDes= criptor ( >=20 > + DecodeJs= onOutput, >=20 > + GUID, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + Hardware= Instance, >=20 > + UpdateIm= ageIndex, >=20 > + PayloadD= escriptorList[Index].SignToolPfxFile, >=20 > + PayloadD= escriptorList[Index].OpenSslSignerPrivateCertFile, >=20 > + PayloadD= escriptorList[Index].OpenSslOtherPublicCertFile, >=20 > + PayloadD= escriptorList[Index].OpenSslTrustedPublicCertFile, >=20 > + PayloadD= escriptorList[Index].SigningToolPath >=20 > + )) >=20 > + else: >=20 > + PayloadDescriptorList[0].Payload =3D FmpCapsuleHeade= r.GetFmpCapsuleImageHeader (0).Payload >=20 > + for Index in range (0, FmpCapsuleHeader.PayloadItemC= ount): >=20 > + if Index > 0: >=20 > + PayloadDecodeFile =3D FmpCapsuleHeader.GetFm= pCapsuleImageHeader (Index).Payload >=20 > + PayloadDescriptorList.append (PayloadDescrip= tor (PayloadDecodeFile, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + None >=20 > + )) >=20 > + GUID =3D FmpCapsuleHeader.GetFmpCapsuleImageHead= er (Index).UpdateImageTypeId >=20 > + HardwareInstance =3D FmpCapsuleHeader.GetFmpCaps= uleImageHeader (Index).UpdateHardwareInstance >=20 > + UpdateImageIndex =3D FmpCapsuleHeader.GetFmpCaps= uleImageHeader (Index).UpdateImageIndex >=20 > + DecodeJsonOutput =3D args.OutputFile.name + '.Pa= yload.{Index:d}.bin'.format (Index =3D Index + 1) >=20 > + PayloadJsonDescriptorList.append (PayloadDescrip= tor ( >=20 > + DecodeJsonOu= tput, >=20 > + GUID, >=20 > + None, >=20 > + None, >=20 > + None, >=20 > + HardwareInst= ance, >=20 > + UpdateImageI= ndex, >=20 > + PayloadDescr= iptorList[Index].SignToolPfxFile, >=20 > + PayloadDescr= iptorList[Index].OpenSslSignerPrivateCertFile, >=20 > + PayloadDescr= iptorList[Index].OpenSslOtherPublicCertFile, >=20 > + PayloadDescr= iptorList[Index].OpenSslTrustedPublicCertFile, >=20 > + PayloadDescr= iptorList[Index].SigningToolPath >=20 > + )) >=20 > + JsonIndex =3D 0 >=20 > + for SinglePayloadDescriptor in PayloadDescriptorList: >=20 > + if args.Verbose: >=20 > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > + UefiCapsuleHeader.DumpInfo () >=20 > + print ('--------') >=20 > + FmpCapsuleHeader.DumpInfo () >=20 > + if FmpAuthHeader.IsSigned(SinglePayloadDescriptor.Pa= yload): >=20 > + if not SinglePayloadDescriptor.UseOpenSsl and no= t SinglePayloadDescriptor.UseSignTool: >=20 > + print ('GenerateCapsule: decode warning: can= not verify singed payload without cert or pfx file. Index =3D > {Index}'.format (Index =3D JsonIndex + 1)) >=20 > + SinglePayloadDescriptor.Payload =3D FmpAuthHeade= r.Decode (SinglePayloadDescriptor.Payload) >=20 > + PayloadJsonDescriptorList[JsonIndex].MonotonicCo= unt =3D FmpAuthHeader.MonotonicCount >=20 > + if args.Verbose: >=20 > + print ('--------') >=20 > + FmpAuthHeader.DumpInfo () >=20 > + >=20 > + # >=20 > + # Verify Image with 64-bit MonotonicCount append= ed to end of image >=20 > + # >=20 > + try: >=20 > + if SinglePayloadDescriptor.UseSignTool: >=20 > + CertData =3D VerifyPayloadSignTool ( >=20 > + FmpAuthHeader.Payload + struc= t.pack ('=20 > + FmpAuthHeader.CertData, >=20 > + SinglePayloadDescriptor.Signi= ngToolPath, >=20 > + SinglePayloadDescriptor.SignT= oolPfxFile, >=20 > + Verbose =3D args.Verbose >=20 > + ) >=20 > + else: >=20 > + CertData =3D VerifyPayloadOpenSsl ( >=20 > + FmpAuthHeader.Payload + struc= t.pack ('=20 > + FmpAuthHeader.CertData, >=20 > + SinglePayloadDescriptor.Signi= ngToolPath, >=20 > + SinglePayloadDescriptor.OpenS= slSignerPrivateCertFile, >=20 > + SinglePayloadDescriptor.OpenS= slOtherPublicCertFile, >=20 > + SinglePayloadDescriptor.OpenS= slTrustedPublicCertFile, >=20 > + Verbose =3D args.Verbose >=20 > + ) >=20 > + except ValueError: >=20 > + print ('GenerateCapsule: warning: payload ve= rification failed Index =3D {Index}'.format (Index =3D JsonIndex + > 1)) >=20 > + else: >=20 > + if args.Verbose: >=20 > + print ('--------') >=20 > + print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION= ') >=20 > + try: >=20 > + SinglePayloadDescriptor.Payload =3D FmpPayloadHe= ader.Decode (SinglePayloadDescriptor.Payload) >=20 > + PayloadJsonDescriptorList[JsonIndex].FwVersion = =3D FmpPayloadHeader.FwVersion >=20 > + PayloadJsonDescriptorList[JsonIndex].LowestSuppo= rtedVersion =3D > FmpPayloadHeader.LowestSupportedVersion >=20 > + JsonIndex =3D JsonIndex + 1 >=20 > + if args.Verbose: >=20 > + print ('--------') >=20 > + FmpPayloadHeader.DumpInfo () >=20 > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > + except: >=20 > + if args.Verbose: >=20 > + print ('--------') >=20 > + print ('No FMP_PAYLOAD_HEADER') >=20 > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > + raise >=20 > + # >=20 > + # Write embedded driver file(s) >=20 > + # >=20 > + for Index in range (0, FmpCapsuleHeader.EmbeddedDriverCo= unt): >=20 > + EmbeddedDriverBuffer =3D FmpCapsuleHeader.GetEmbedde= dDriver (Index) >=20 > + EmbeddedDriverPath =3D args.OutputFile.name + '.Embe= ddedDriver.{Index:d}.efi'.format (Index =3D Index + 1) >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Write embedded driver file {File}'.f= ormat (File =3D EmbeddedDriverPath)) >=20 > + EmbeddedDriverFile =3D open (EmbeddedDriverPath,= 'wb') >=20 > + EmbeddedDriverFile.write (EmbeddedDriverBuffer) >=20 > + EmbeddedDriverFile.close () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not write em= bedded driver file {File}'.format (File =3D EmbeddedDriverPath)) >=20 > + sys.exit (1) >=20 > + >=20 > + except: >=20 > + raise >=20 > + print ('GenerateCapsule: error: can not decode capsule') >=20 > + sys.exit (1) >=20 > + GenerateOutputJson(PayloadJsonDescriptorList) >=20 > + PayloadIndex =3D 0 >=20 > + for SinglePayloadDescriptor in PayloadDescriptorList: >=20 > + if args.OutputFile is None: >=20 > + print ('GenerateCapsule: Decode error: OutputFile is nee= ded for decode output') >=20 > + sys.exit (1) >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Write binary output file {File}'.format (Fil= e =3D args.OutputFile.name)) >=20 > + PayloadDecodePath =3D args.OutputFile.name + '.Payload.{= Index:d}.bin'.format (Index =3D PayloadIndex + 1) >=20 > + PayloadDecodeFile =3D open (PayloadDecodePath, 'wb') >=20 > + PayloadDecodeFile.write (SinglePayloadDescriptor.Payload= ) >=20 > + PayloadDecodeFile.close () >=20 > + PayloadIndex =3D PayloadIndex + 1 >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not write binary out= put file {File}'.format (File =3D > SinglePayloadDescriptor.OutputFile.name)) >=20 > + sys.exit (1) >=20 > + >=20 > + def DumpInfo (Buffer, args): >=20 > + if args.OutputFile is not None: >=20 > + raise argparse.ArgumentTypeError ('the following option is n= ot supported for dumpinfo operations: --output') >=20 > + try: >=20 > + Result =3D UefiCapsuleHeader.Decode (Buffer) >=20 > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > + UefiCapsuleHeader.DumpInfo () >=20 > + if len (Result) > 0: >=20 > + FmpCapsuleHeader.Decode (Result) >=20 > + print ('--------') >=20 > + FmpCapsuleHeader.DumpInfo () >=20 > + for Index in range (0, FmpCapsuleHeader.PayloadItemCount= ): >=20 > + Result =3D FmpCapsuleHeader.GetFmpCapsuleImageHeader= (Index).Payload >=20 > + try: >=20 > + Result =3D FmpAuthHeader.Decode (Result) >=20 > + print ('--------') >=20 > + FmpAuthHeader.DumpInfo () >=20 > + except: >=20 > + print ('--------') >=20 > + print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION') >=20 > + try: >=20 > + Result =3D FmpPayloadHeader.Decode (Result) >=20 > + print ('--------') >=20 > + FmpPayloadHeader.DumpInfo () >=20 > + except: >=20 > + print ('--------') >=20 > + print ('No FMP_PAYLOAD_HEADER') >=20 > + print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not decode capsule') >=20 > + sys.exit (1) >=20 > + >=20 > # >=20 > # Create command line argument parser object >=20 > # >=20 > @@ -226,7 +885,7 @@ if __name__ =3D=3D '__main__': > # >=20 > # Add input and output file arguments >=20 > # >=20 > - parser.add_argument("InputFile", type =3D argparse.FileType('rb'), >=20 > + parser.add_argument("InputFile", type =3D argparse.FileType('rb'), = nargs=3D'?', >=20 > help =3D "Input binary payload filename.") >=20 > parser.add_argument("-o", "--output", dest =3D 'OutputFile', type = =3D argparse.FileType('wb'), >=20 > help =3D "Output filename.") >=20 > @@ -243,6 +902,8 @@ if __name__ =3D=3D '__main__': > # >=20 > # Add optional arguments for this command >=20 > # >=20 > + parser.add_argument ("-j", "--json-file", dest =3D 'JsonFile', type= =3Dargparse.FileType('r'), >=20 > + help =3D "JSON configuration file for multiple = payloads and embedded drivers.") >=20 > parser.add_argument ("--capflag", dest =3D 'CapsuleFlag', action=3D'= append', default =3D [], >=20 > choices=3D['PersistAcrossReset', 'InitiateReset= '], >=20 > help =3D "Capsule flag can be PersistAcrossRese= t or InitiateReset or not set") >=20 > @@ -250,7 +911,7 @@ if __name__ =3D=3D '__main__': > help =3D "Capsule OEM Flag is an integer betwee= n 0x0000 and 0xffff.") >=20 >=20 >=20 > parser.add_argument ("--guid", dest =3D 'Guid', type =3D ValidateReg= istryFormatGuid, >=20 > - help =3D "The FMP/ESRT GUID in registry format.= Required for encode operations.") >=20 > + help =3D "The FMP/ESRT GUID in registry format.= Required for single payload encode operations.") >=20 > parser.add_argument ("--hardware-instance", dest =3D 'HardwareInstan= ce', type =3D ValidateUnsignedInteger, default =3D > 0x0000000000000000, >=20 > help =3D "The 64-bit hardware instance. The de= fault is 0x0000000000000000") >=20 >=20 >=20 > @@ -259,9 +920,9 @@ if __name__ =3D=3D '__main__': > help =3D "64-bit monotonic count value in heade= r. Default is 0x0000000000000000.") >=20 >=20 >=20 > parser.add_argument ("--fw-version", dest =3D 'FwVersion', type =3D = ValidateUnsignedInteger, >=20 > - help =3D "The 32-bit version of the binary payl= oad (e.g. 0x11223344 or 5678). Required for encode > operations that sign a payload.") >=20 > + help =3D "The 32-bit version of the binary payl= oad (e.g. 0x11223344 or 5678). Required for encode > operations.") >=20 > parser.add_argument ("--lsv", dest =3D 'LowestSupportedVersion', typ= e =3D ValidateUnsignedInteger, >=20 > - help =3D "The 32-bit lowest supported version o= f the binary payload (e.g. 0x11223344 or 5678). Required for > encode operations that sign a payload.") >=20 > + help =3D "The 32-bit lowest supported version o= f the binary payload (e.g. 0x11223344 or 5678). Required for > encode operations.") >=20 >=20 >=20 > parser.add_argument ("--pfx-file", dest=3D'SignToolPfxFile', type=3D= argparse.FileType('rb'), >=20 > help=3D"signtool PFX certificate filename.") >=20 > @@ -276,6 +937,9 @@ if __name__ =3D=3D '__main__': > parser.add_argument ("--signing-tool-path", dest =3D 'SigningToolPat= h', >=20 > help =3D "Path to signtool or OpenSSL tool. Op= tional if path to tools are already in PATH.") >=20 >=20 >=20 > + parser.add_argument ("--embedded-driver", dest =3D 'EmbeddedDriver',= type =3D argparse.FileType('rb'), action=3D'append', default =3D [], >=20 > + help =3D "Path to embedded UEFI driver to add t= o capsule.") >=20 > + >=20 > # >=20 > # Add optional arguments common to all operations >=20 > # >=20 > @@ -286,79 +950,29 @@ if __name__ =3D=3D '__main__': > help =3D "Disable all messages except fatal err= ors.") >=20 > parser.add_argument ("--debug", dest =3D 'Debug', type =3D int, meta= var =3D '[0-9]', choices =3D range (0, 10), default =3D 0, >=20 > help =3D "Set debug level") >=20 > + parser.add_argument ("--update-image-index", dest =3D 'UpdateImageIn= dex', type =3D ValidateUnsignedInteger, default =3D 0x01, help =3D > "unique number identifying the firmware image within the device ") >=20 >=20 >=20 > # >=20 > # Parse command line arguments >=20 > # >=20 > args =3D parser.parse_args() >=20 >=20 >=20 > - # >=20 > - # Perform additional argument verification >=20 > - # >=20 > - if args.Encode: >=20 > - if args.Guid is None: >=20 > - parser.error ('the following option is required: --guid') >=20 > - if 'PersistAcrossReset' not in args.CapsuleFlag: >=20 > - if 'InitiateReset' in args.CapsuleFlag: >=20 > - parser.error ('--capflag InitiateReset also requires --c= apflag PersistAcrossReset') >=20 > - if args.CapsuleOemFlag > 0xFFFF: >=20 > - parser.error ('--capoemflag must be an integer between 0x000= 0 and 0xffff') >=20 > - if args.HardwareInstance > 0xFFFFFFFFFFFFFFFF: >=20 > - parser.error ('--hardware-instance must be an integer in ran= ge 0x0..0xffffffffffffffff') >=20 > - if args.MonotonicCount > 0xFFFFFFFFFFFFFFFF: >=20 > - parser.error ('--monotonic-count must be an integer in range= 0x0..0xffffffffffffffff') >=20 > - >=20 > - UseSignTool =3D args.SignToolPfxFile is not None >=20 > - UseOpenSsl =3D (args.OpenSslSignerPrivateCertFile is not None and >=20 > - args.OpenSslOtherPublicCertFile is not None and >=20 > - args.OpenSslTrustedPublicCertFile is not None) >=20 > - AnyOpenSsl =3D (args.OpenSslSignerPrivateCertFile is not None or >=20 > - args.OpenSslOtherPublicCertFile is not None or >=20 > - args.OpenSslTrustedPublicCertFile is not None) >=20 > - if args.Encode or args.Decode: >=20 > - if args.OutputFile is None: >=20 > - parser.error ('the following option is required for all enco= de and decode operations: --output') >=20 > - >=20 > - if UseSignTool and AnyOpenSsl: >=20 > - parser.error ('Providing both signtool and OpenSSL options i= s not supported') >=20 > - if not UseSignTool and not UseOpenSsl and AnyOpenSsl: >=20 > - parser.error ('all the following options are required for Op= enSSL: --signer-private-cert, --other-public-cert, > --trusted-public-cert') >=20 > - if UseSignTool and platform.system() !=3D 'Windows': >=20 > - parser.error ('Use of signtool is not supported on this oper= ating system.') >=20 > - if args.Encode and (UseSignTool or UseOpenSsl): >=20 > - if args.FwVersion is None or args.LowestSupportedVersion is = None: >=20 > - parser.error ('the following options are required: --fw-= version, --lsv') >=20 > - if args.FwVersion > 0xFFFFFFFF: >=20 > - parser.error ('--fw-version must be an integer in range = 0x0..0xffffffff') >=20 > - if args.LowestSupportedVersion > 0xFFFFFFFF: >=20 > - parser.error ('--lsv must be an integer in range 0x0..0x= ffffffff') >=20 > - >=20 > - if UseSignTool: >=20 > - args.SignToolPfxFile.close() >=20 > - args.SignToolPfxFile =3D args.SignToolPfxFile.name >=20 > - if UseOpenSsl: >=20 > - args.OpenSslSignerPrivateCertFile.close() >=20 > - args.OpenSslOtherPublicCertFile.close() >=20 > - args.OpenSslTrustedPublicCertFile.close() >=20 > - args.OpenSslSignerPrivateCertFile =3D args.OpenSslSignerPriv= ateCertFile.name >=20 > - args.OpenSslOtherPublicCertFile =3D args.OpenSslOtherPubli= cCertFile.name >=20 > - args.OpenSslTrustedPublicCertFile =3D args.OpenSslTrustedPub= licCertFile.name >=20 > - >=20 > - if args.DumpInfo: >=20 > - if args.OutputFile is not None: >=20 > - parser.error ('the following option is not supported for dum= pinfo operations: --output') >=20 > - >=20 > # >=20 > # Read binary input file >=20 > # >=20 > - try: >=20 > - if args.Verbose: >=20 > - print ('Read binary input file {File}'.format (File =3D args= .InputFile.name)) >=20 > - Buffer =3D args.InputFile.read () >=20 > - args.InputFile.close () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not read binary input file {= File}'.format (File =3D args.InputFile.name)) >=20 > - sys.exit (1) >=20 > + Buffer =3D '' >=20 > + if args.InputFile: >=20 > + if os.path.getsize (args.InputFile.name) =3D=3D 0: >=20 > + print ('GenerateCapsule: error: InputFile {File} is empty'.f= ormat (File =3D args.InputFile.name)) >=20 > + sys.exit (1) >=20 > + try: >=20 > + if args.Verbose: >=20 > + print ('Read binary input file {File}'.format (File =3D = args.InputFile.name)) >=20 > + Buffer =3D args.InputFile.read () >=20 > + args.InputFile.close () >=20 > + except: >=20 > + print ('GenerateCapsule: error: can not read binary input fi= le {File}'.format (File =3D args.InputFile.name)) >=20 > + sys.exit (1) >=20 >=20 >=20 > # >=20 > # Create objects >=20 > @@ -368,182 +982,27 @@ if __name__ =3D=3D '__main__': > FmpAuthHeader =3D FmpAuthHeaderClass () >=20 > FmpPayloadHeader =3D FmpPayloadHeaderClass () >=20 >=20 >=20 > - if args.Encode: >=20 > - Result =3D Buffer >=20 > - if UseSignTool or UseOpenSsl: >=20 > - try: >=20 > - FmpPayloadHeader.FwVersion =3D args.FwVersi= on >=20 > - FmpPayloadHeader.LowestSupportedVersion =3D args.LowestS= upportedVersion >=20 > - FmpPayloadHeader.Payload =3D Result >=20 > - Result =3D FmpPayloadHeader.Encode () >=20 > - if args.Verbose: >=20 > - FmpPayloadHeader.DumpInfo () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not encode FMP Paylo= ad Header') >=20 > - sys.exit (1) >=20 > - >=20 > - # >=20 > - # Sign image with 64-bit MonotonicCount appended to end of i= mage >=20 > - # >=20 > - try: >=20 > - if UseSignTool: >=20 > - CertData =3D SignPayloadSignTool ( >=20 > - Result + struct.pack ('=20 > - args.SigningToolPath, >=20 > - args.SignToolPfxFile >=20 > - ) >=20 > - else: >=20 > - CertData =3D SignPayloadOpenSsl ( >=20 > - Result + struct.pack ('=20 > - args.SigningToolPath, >=20 > - args.OpenSslSignerPrivateCertFile, >=20 > - args.OpenSslOtherPublicCertFile, >=20 > - args.OpenSslTrustedPublicCertFile >=20 > - ) >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not sign payload') >=20 > - sys.exit (1) >=20 > - >=20 > - try: >=20 > - FmpAuthHeader.MonotonicCount =3D args.MonotonicCount >=20 > - FmpAuthHeader.CertData =3D CertData >=20 > - FmpAuthHeader.Payload =3D Result >=20 > - Result =3D FmpAuthHeader.Encode () >=20 > - if args.Verbose: >=20 > - FmpAuthHeader.DumpInfo () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not encode FMP Auth = Header') >=20 > - sys.exit (1) >=20 > - >=20 > - try: >=20 > - FmpCapsuleHeader.AddPayload (args.Guid, Result, HardwareInst= ance =3D args.HardwareInstance) >=20 > - Result =3D FmpCapsuleHeader.Encode () >=20 > - if args.Verbose: >=20 > - FmpCapsuleHeader.DumpInfo () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not encode FMP Capsule H= eader') >=20 > - sys.exit (1) >=20 > - >=20 > - try: >=20 > - UefiCapsuleHeader.OemFlags =3D args.CapsuleOemFla= g >=20 > - UefiCapsuleHeader.PersistAcrossReset =3D 'PersistAcrossRese= t' in args.CapsuleFlag >=20 > - UefiCapsuleHeader.PopulateSystemTable =3D False >=20 > - UefiCapsuleHeader.InitiateReset =3D 'InitiateReset' = in args.CapsuleFlag >=20 > - UefiCapsuleHeader.Payload =3D Result >=20 > - Result =3D UefiCapsuleHeader.Encode () >=20 > - if args.Verbose: >=20 > - UefiCapsuleHeader.DumpInfo () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not encode UEFI Capsule = Header') >=20 > - sys.exit (1) >=20 > - >=20 > - elif args.Decode: >=20 > - try: >=20 > - Result =3D UefiCapsuleHeader.Decode (Buffer) >=20 > - FmpCapsuleHeader.Decode (Result) >=20 > - Result =3D FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Pay= load >=20 > - if args.Verbose: >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - UefiCapsuleHeader.DumpInfo () >=20 > - print ('--------') >=20 > - FmpCapsuleHeader.DumpInfo () >=20 > - if UseSignTool or UseOpenSsl: >=20 > - Result =3D FmpAuthHeader.Decode (Result) >=20 > - if args.Verbose: >=20 > - print ('--------') >=20 > - FmpAuthHeader.DumpInfo () >=20 > + EmbeddedDriverDescriptorList =3D [] >=20 > + PayloadDescriptorList =3D [] >=20 > + PayloadJsonDescriptorList =3D [] >=20 >=20 >=20 > - # >=20 > - # Verify Image with 64-bit MonotonicCount appended to en= d of image >=20 > - # >=20 > - try: >=20 > - if UseSignTool: >=20 > - CertData =3D VerifyPayloadSignTool ( >=20 > - FmpAuthHeader.Payload + struct.pack (= '=20 > - FmpAuthHeader.CertData, >=20 > - args.SigningToolPath, >=20 > - args.SignToolPfxFile >=20 > - ) >=20 > - else: >=20 > - CertData =3D VerifyPayloadOpenSsl ( >=20 > - FmpAuthHeader.Payload + struct.pack (= '=20 > - FmpAuthHeader.CertData, >=20 > - args.SigningToolPath, >=20 > - args.OpenSslSignerPrivateCertFile, >=20 > - args.OpenSslOtherPublicCertFile, >=20 > - args.OpenSslTrustedPublicCertFile >=20 > - ) >=20 > - except ValueError: >=20 > - print ('GenerateCapsule: warning: can not verify pay= load.') >=20 > - >=20 > - try: >=20 > - Result =3D FmpPayloadHeader.Decode (Result) >=20 > - if args.Verbose: >=20 > - print ('--------') >=20 > - FmpPayloadHeader.DumpInfo () >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - except: >=20 > - if args.Verbose: >=20 > - print ('--------') >=20 > - print ('No FMP_PAYLOAD_HEADER') >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - raise >=20 > - else: >=20 > - if args.Verbose: >=20 > - print ('--------') >=20 > - print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION') >=20 > - print ('--------') >=20 > - print ('No FMP_PAYLOAD_HEADER') >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not decode capsule') >=20 > - sys.exit (1) >=20 > + # >=20 > + #Encode Operation >=20 > + # >=20 > + if args.Encode: >=20 > + Encode (PayloadDescriptorList, EmbeddedDriverDescriptorList, Buf= fer) >=20 >=20 >=20 > - elif args.DumpInfo: >=20 > - try: >=20 > - Result =3D UefiCapsuleHeader.Decode (Buffer) >=20 > - FmpCapsuleHeader.Decode (Result) >=20 > - Result =3D FmpCapsuleHeader.GetFmpCapsuleImageHeader (0).Pay= load >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - UefiCapsuleHeader.DumpInfo () >=20 > - print ('--------') >=20 > - FmpCapsuleHeader.DumpInfo () >=20 > - try: >=20 > - Result =3D FmpAuthHeader.Decode (Result) >=20 > - print ('--------') >=20 > - FmpAuthHeader.DumpInfo () >=20 > - try: >=20 > - Result =3D FmpPayloadHeader.Decode (Result) >=20 > - print ('--------') >=20 > - FmpPayloadHeader.DumpInfo () >=20 > - except: >=20 > - print ('--------') >=20 > - print ('No FMP_PAYLOAD_HEADER') >=20 > - except: >=20 > - print ('--------') >=20 > - print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION') >=20 > - print ('--------') >=20 > - print ('No FMP_PAYLOAD_HEADER') >=20 > - print ('=3D=3D=3D=3D=3D=3D=3D=3D') >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not decode capsule') >=20 > - sys.exit (1) >=20 > - else: >=20 > - print('GenerateCapsule: error: invalid options') >=20 > - sys.exit (1) >=20 > + # >=20 > + #Decode Operation >=20 > + # >=20 > + if args.Decode: >=20 > + Decode (PayloadDescriptorList, PayloadJsonDescriptorList, Buffer= ) >=20 >=20 >=20 > # >=20 > - # Write binary output file >=20 > + #Dump Info Operation >=20 > # >=20 > - if args.OutputFile is not None: >=20 > - try: >=20 > - if args.Verbose: >=20 > - print ('Write binary output file {File}'.format (File = =3D args.OutputFile.name)) >=20 > - args.OutputFile.write (Result) >=20 > - args.OutputFile.close () >=20 > - except: >=20 > - print ('GenerateCapsule: error: can not write binary output = file {File}'.format (File =3D args.OutputFile.name)) >=20 > - sys.exit (1) >=20 > + if args.DumpInfo: >=20 > + DumpInfo (Buffer, args) >=20 >=20 >=20 > if args.Verbose: >=20 > print('Success') >=20 > diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py > index 4b8c6da26a..48c605faa8 100644 > --- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py > +++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpAuthHeader.py > @@ -2,7 +2,7 @@ > # Module that encodes and decodes a EFI_FIRMWARE_IMAGE_AUTHENTICATION wi= th >=20 > # certificate data and payload data. >=20 > # >=20 > -# Copyright (c) 2018, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
>=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 >=20 >=20 > @@ -166,6 +166,18 @@ class FmpAuthHeaderClass (object): > self._Valid =3D True >=20 > return self.Payload >=20 >=20 >=20 > + def IsSigned (self, Buffer): >=20 > + if len (Buffer) < self._StructSize: >=20 > + return False >=20 > + (MonotonicCount, dwLength, wRevision, wCertificateType, CertType= ) =3D \ >=20 > + struct.unpack ( >=20 > + self._StructFormat, >=20 > + Buffer[0:self._StructSize] >=20 > + ) >=20 > + if CertType !=3D self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le: >=20 > + return False >=20 > + return True >=20 > + >=20 > def DumpInfo (self): >=20 > if not self._Valid: >=20 > raise ValueError >=20 > diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader= .py > b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py > index c24258d047..91d24919c4 100644 > --- a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py > +++ b/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.py > @@ -2,7 +2,7 @@ > # Module that encodes and decodes a EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEAD= ER with >=20 > # a payload. >=20 > # >=20 > -# Copyright (c) 2018, Intel Corporation. All rights reserved.
>=20 > +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
>=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 >=20 >=20 > @@ -172,8 +172,8 @@ class FmpCapsuleHeaderClass (object): > raise ValueError >=20 > return self._EmbeddedDriverList[Index] >=20 >=20 >=20 > - def AddPayload (self, UpdateImageTypeId, Payload =3D b'', VendorCode= Bytes =3D b'', HardwareInstance =3D 0): >=20 > - self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCod= eBytes, HardwareInstance)) >=20 > + def AddPayload (self, UpdateImageTypeId, Payload =3D b'', VendorCode= Bytes =3D b'', HardwareInstance =3D 0, UpdateImageIndex =3D 1): >=20 > + self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCod= eBytes, HardwareInstance, UpdateImageIndex)) >=20 >=20 >=20 > def GetFmpCapsuleImageHeader (self, Index): >=20 > if Index >=3D len (self._FmpCapsuleImageHeaderList): >=20 > @@ -198,10 +198,10 @@ class FmpCapsuleHeaderClass (object): > self._ItemOffsetList.append (Offset) >=20 > Offset =3D Offset + len (EmbeddedDriver) >=20 > Index =3D 1 >=20 > - for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstan= ce) in self._PayloadList: >=20 > + for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstan= ce, UpdateImageIndex) in self._PayloadList: >=20 > FmpCapsuleImageHeader =3D FmpCapsuleImageHeaderClass () >=20 > FmpCapsuleImageHeader.UpdateImageTypeId =3D UpdateImage= TypeId >=20 > - FmpCapsuleImageHeader.UpdateImageIndex =3D Index >=20 > + FmpCapsuleImageHeader.UpdateImageIndex =3D UpdateImage= Index >=20 > FmpCapsuleImageHeader.Payload =3D Payload >=20 > FmpCapsuleImageHeader.VendorCodeBytes =3D VendorCodeB= ytes >=20 > FmpCapsuleImageHeader.UpdateHardwareInstance =3D HardwareIns= tance >=20 > @@ -288,6 +288,8 @@ class FmpCapsuleHeaderClass (object): > raise ValueError >=20 > print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = =3D {Version:08X}'.format (Version =3D self.Version)) >=20 > print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCou= nt =3D {EmbeddedDriverCount:08X}'.format > (EmbeddedDriverCount =3D self.EmbeddedDriverCount)) >=20 > + for EmbeddedDriver in self._EmbeddedDriverList: >=20 > + print (' sizeof (EmbeddedDriver) = =3D {Size:08X}'.format (Size =3D len (EmbeddedDriver))) >=20 > print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = =3D {PayloadItemCount:08X}'.format > (PayloadItemCount =3D self.PayloadItemCount)) >=20 > print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = =3D ') >=20 > for Offset in self._ItemOffsetList: >=20 > -- > 2.20.0.windows.1 >=20 >=20 > -=3D-=3D-=3D-=3D-=3D-=3D > Groups.io Links: You receive all messages sent to this group. >=20 > View/Reply Online (#41406): https://edk2.groups.io/g/devel/message/41406 > Mute This Topic: https://groups.io/mt/31807319/1759384 > Group Owner: devel+owner@edk2.groups.io > Unsubscribe: https://edk2.groups.io/g/devel/unsub [liming.gao@intel.com] > -=3D-=3D-=3D-=3D-=3D-=3D