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.120, mailfrom: eric.jin@intel.com) Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by groups.io with SMTP; Mon, 27 May 2019 00:32:58 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2019 00:32:58 -0700 X-ExtLoop1: 1 Received: from jjin9-mobl.ccr.corp.intel.com ([10.239.192.117]) by fmsmga008.fm.intel.com with ESMTP; 27 May 2019 00:32:56 -0700 From: "Eric Jin" To: devel@edk2.groups.io Cc: Bob Feng , Liming Gao , Kinney, Michael D Subject: [Patch] BaseTools/Capsule: Supports UEFI Capsule with multiple payloads and embedded drivers Date: Mon, 27 May 2019 15:28:07 +0800 Message-Id: <20190527072807.11592-1-eric.jin@intel.com> X-Mailer: git-send-email 2.20.1.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable https://bugzilla.tianocore.org/show_bug.cgi?id=3D1834 * Add arguments "--embedded-driver" to support embedded driver in command l= ine. * Add arguments "--update-image-index" to identify ImageIndex within the de= vice in command line. * Add arguments "-j JSONFILE" to support multiple payloads and embedded dri= vers with JSON file. The update is in a backwards compatible manner, so all command line options= to support single payload are still supported. But all the options associated = with multiple payloads should be provided in a JSON file. 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(-) diff --git a/BaseTools/Source/Python/Capsule/GenerateCapsule.py b/BaseTools= /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=0D # Generate a capsule.=0D #=0D -# This tool generates a UEFI Capsule around an FMP Capsule. The capsule p= ayload=0D +# This tool generates a UEFI Capsule around an FMP Capsule. The capsule pa= yload=0D # be signed using signtool or OpenSSL and if it is signed the signed conte= nt=0D # includes an FMP Payload Header.=0D #=0D # This tool is intended to be used to generate UEFI Capsules to update the= =0D -# system firmware or device firmware for integrated devices. In order to= =0D +# system firmware or device firmware for integrated devices. In order to=0D # keep the tool as simple as possible, it has the following limitations:=0D -# * Do not support multiple payloads in a capsule.=0D -# * Do not support optional drivers in a capsule.=0D # * Do not support vendor code bytes in a capsule.=0D #=0D -# Copyright (c) 2018, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D #=0D =0D @@ -29,6 +27,7 @@ import os import tempfile=0D import shutil=0D import platform=0D +import json=0D from Common.Uefi.Capsule.UefiCapsuleHeader import UefiCapsuleHeaderClass=0D from Common.Uefi.Capsule.FmpCapsuleHeader import FmpCapsuleHeaderClass=0D from Common.Uefi.Capsule.FmpAuthHeader import FmpAuthHeaderClass=0D @@ -42,7 +41,7 @@ __version__ =3D '0.9' __copyright__ =3D 'Copyright (c) 2018, Intel Corporation. All rights res= erved.'=0D __description__ =3D 'Generate a capsule.\n'=0D =0D -def SignPayloadSignTool (Payload, ToolPath, PfxFile):=0D +def SignPayloadSignTool (Payload, ToolPath, PfxFile, Verbose =3D False):=0D #=0D # Create a temporary directory=0D #=0D @@ -75,6 +74,8 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile): Command =3D Command + '/p7 {TempDir} '.format (TempDir =3D TempDirecto= ryName)=0D Command =3D Command + '/f {PfxFile} '.format (PfxFile =3D PfxFile)=0D Command =3D Command + TempFileName=0D + if Verbose:=0D + print (Command)=0D =0D #=0D # Sign the input file using the specified private key=0D @@ -88,7 +89,7 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile): =0D if Process.returncode !=3D 0:=0D shutil.rmtree (TempDirectoryName)=0D - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore'))=0D + print (Result[1].decode())=0D raise ValueError ('GenerateCapsule: error: signtool failed.')=0D =0D #=0D @@ -105,11 +106,11 @@ def SignPayloadSignTool (Payload, ToolPath, PfxFile): shutil.rmtree (TempDirectoryName)=0D return Signature=0D =0D -def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile):=0D +def VerifyPayloadSignTool (Payload, CertData, ToolPath, PfxFile, Verbose = =3D False):=0D print ('signtool verify is not supported.')=0D raise ValueError ('GenerateCapsule: error: signtool verify is not supp= orted.')=0D =0D -def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPub= licCertFile, TrustedPublicCertFile):=0D +def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivateCertFile, OtherPub= licCertFile, TrustedPublicCertFile, Verbose =3D False):=0D #=0D # Build openssl command=0D #=0D @@ -119,6 +120,8 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPrivat= eCertFile, OtherPublicCer Command =3D Command + '"{Path}" '.format (Path =3D os.path.join (ToolP= ath, 'openssl'))=0D Command =3D Command + 'smime -sign -binary -outform DER -md sha256 '=0D Command =3D Command + '-signer "{Private}" -certfile "{Public}"'.forma= t (Private =3D SignerPrivateCertFile, Public =3D OtherPublicCertFile)=0D + if Verbose:=0D + print (Command)=0D =0D #=0D # Sign the input file using the specified private key and capture sign= ature from STDOUT=0D @@ -131,12 +134,12 @@ def SignPayloadOpenSsl (Payload, ToolPath, SignerPriv= ateCertFile, OtherPublicCer raise ValueError ('GenerateCapsule: error: can not run openssl.')= =0D =0D if Process.returncode !=3D 0:=0D - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore'))=0D + print (Result[1].decode())=0D raise ValueError ('GenerateCapsule: error: openssl failed.')=0D =0D return Signature=0D =0D -def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFi= le, OtherPublicCertFile, TrustedPublicCertFile):=0D +def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, SignerPrivateCertFi= le, OtherPublicCertFile, TrustedPublicCertFile, Verbose =3D False):=0D #=0D # Create a temporary directory=0D #=0D @@ -167,6 +170,8 @@ def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, = SignerPrivateCertFile, Ot Command =3D Command + '"{Path}" '.format (Path =3D os.path.join (ToolP= ath, 'openssl'))=0D Command =3D Command + 'smime -verify -inform DER '=0D Command =3D Command + '-content {Content} -CAfile "{Public}"'.format (= Content =3D TempFileName, Public =3D TrustedPublicCertFile)=0D + if Verbose:=0D + print (Command)=0D =0D #=0D # Verify signature=0D @@ -180,7 +185,7 @@ def VerifyPayloadOpenSsl (Payload, CertData, ToolPath, = SignerPrivateCertFile, Ot =0D if Process.returncode !=3D 0:=0D shutil.rmtree (TempDirectoryName)=0D - print (Result[1].decode(encoding=3D'utf-8', errors=3D'ignore'))=0D + print (Result[1].decode())=0D raise ValueError ('GenerateCapsule: error: openssl failed.')=0D =0D shutil.rmtree (TempDirectoryName)=0D @@ -212,6 +217,660 @@ if __name__ =3D=3D '__main__': raise argparse.ArgumentTypeError (Message)=0D return Value=0D =0D + def ConvertJsonValue (Config, FieldName, Convert, Required =3D True, D= efault =3D None, Open =3D False):=0D + if FieldName not in Config:=0D + if Required:=0D + print ('GenerateCapsule: error: Payload descriptor invalid= syntax. Could not find {Key} in payload descriptor.'.format(Key =3D FieldN= ame))=0D + sys.exit (1)=0D + return Default=0D + try:=0D + Value =3D Convert (Config[FieldName])=0D + except Exception as Message:=0D + print ('GenerateCapsule: error: {Key} in payload descriptor ha= s invalid syntax. '.format (Key =3D FieldName) + str(Message))=0D + sys.exit (1)=0D + if Open:=0D + try:=0D + Value =3D open (Value, "rb")=0D + except:=0D + print ('GenerateCapsule: error: can not open file {File}'.= format (File =3D FieldName))=0D + sys.exit (1)=0D + return Value=0D +=0D + def DecodeJsonFileParse (Json):=0D + if 'Payloads' not in Json:=0D + print ('GenerateCapsule: error "Payloads" section not found in= JSON file {File}'.format (File =3D args.JsonFile.name))=0D + sys.exit (1)=0D + for Config in Json['Payloads']:=0D + #=0D + # Parse fields from JSON=0D + #=0D + PayloadFile =3D ConvertJsonValue (Config, 'Pa= yload', os.path.expandvars, Required =3D False)=0D + Guid =3D ConvertJsonValue (Config, 'Gu= id', ValidateRegistryFormatGuid, Required =3D False)=0D + FwVersion =3D ConvertJsonValue (Config, 'Fw= Version', ValidateUnsignedInteger, Required =3D False)=0D + LowestSupportedVersion =3D ConvertJsonValue (Config, 'Lo= westSupportedVersion', ValidateUnsignedInteger, Required =3D False)=0D + HardwareInstance =3D ConvertJsonValue (Config, 'Ha= rdwareInstance', ValidateUnsignedInteger, Required =3D False, Default =3D 0= )=0D + MonotonicCount =3D ConvertJsonValue (Config, 'Mo= notonicCount', ValidateUnsignedInteger, Required =3D False, Default =3D 0)= =0D + SignToolPfxFile =3D ConvertJsonValue (Config, 'Si= gnToolPfxFile', os.path.expandvars, Required =3D False, Default =3D None, O= pen =3D True)=0D + OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, 'Op= enSslSignerPrivateCertFile', os.path.expandvars, Required =3D False, Defaul= t =3D None, Open =3D True)=0D + OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslOtherPublicCertFile', os.path.expandvars, Required =3D False, Default = =3D None, Open =3D True)=0D + OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslTrustedPublicCertFile', os.path.expandvars, Required =3D False, Defaul= t =3D None, Open =3D True)=0D + SigningToolPath =3D ConvertJsonValue (Config, 'Si= gningToolPath', os.path.expandvars, Required =3D False, Default =3D None)=0D + UpdateImageIndex =3D ConvertJsonValue (Config, 'Up= dateImageIndex', ValidateUnsignedInteger, Required =3D False, Default =3D 1= )=0D +=0D + PayloadDescriptorList.append (PayloadDescriptor (=0D + PayloadFile,=0D + Guid,=0D + FwVersion,=0D + LowestSupportedVersion,=0D + MonotonicCount,=0D + HardwareInstance,=0D + UpdateImageIndex,=0D + SignToolPfxFile,=0D + OpenSslSignerPrivateCertFile,= =0D + OpenSslOtherPublicCertFile,=0D + OpenSslTrustedPublicCertFile,= =0D + SigningToolPath=0D + ))=0D +=0D + def EncodeJsonFileParse (Json):=0D + if 'EmbeddedDrivers' not in Json:=0D + print ('GenerateCapsule: warning "EmbeddedDrivers" section not= found in JSON file {File}'.format (File =3D args.JsonFile.name))=0D + else:=0D + for Config in Json['EmbeddedDrivers']:=0D + EmbeddedDriverFile =3D ConvertJsonValue(Config, 'Driv= er', os.path.expandvars, Open =3D True)=0D + #=0D + #Read EmbeddedDriver file=0D + #=0D + try:=0D + if args.Verbose:=0D + print ('Read EmbeddedDriver file {File}'.format (F= ile =3D EmbeddedDriverFile.name))=0D + Driver =3D EmbeddedDriverFile.read()=0D + except:=0D + print ('GenerateCapsule: error: can not read EmbeddedD= river file {File}'.format (File =3D EmbeddedDriverFile.name))=0D + sys.exit(1)=0D + EmbeddedDriverDescriptorList.append (Driver)=0D +=0D + if 'Payloads' not in Json:=0D + print ('GenerateCapsule: error: "Payloads" section not found i= n JSON file {File}'.format (File =3D args.JsonFile.name))=0D + sys.exit (1)=0D + for Config in Json['Payloads']:=0D + #=0D + # Parse fields from JSON=0D + #=0D + PayloadFile =3D ConvertJsonValue (Config, 'Pa= yload', os.path.expandvars, Open =3D True)=0D + Guid =3D ConvertJsonValue (Config, 'Gu= id', ValidateRegistryFormatGuid)=0D + FwVersion =3D ConvertJsonValue (Config, 'Fw= Version', ValidateUnsignedInteger)=0D + LowestSupportedVersion =3D ConvertJsonValue (Config, 'Lo= westSupportedVersion', ValidateUnsignedInteger)=0D + HardwareInstance =3D ConvertJsonValue (Config, 'Ha= rdwareInstance', ValidateUnsignedInteger, Required =3D False, Default =3D 0= )=0D + UpdateImageIndex =3D ConvertJsonValue (Config, 'Up= dateImageIndex', ValidateUnsignedInteger, Required =3D False, Default =3D 1= )=0D + MonotonicCount =3D ConvertJsonValue (Config, 'Mo= notonicCount', ValidateUnsignedInteger, Required =3D False, Default =3D 0)= =0D + SignToolPfxFile =3D ConvertJsonValue (Config, 'Si= gnToolPfxFile', os.path.expandvars, Required =3D False, Default =3D None, O= pen =3D True)=0D + OpenSslSignerPrivateCertFile =3D ConvertJsonValue (Config, 'Op= enSslSignerPrivateCertFile', os.path.expandvars, Required =3D False, Defaul= t =3D None, Open =3D True)=0D + OpenSslOtherPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslOtherPublicCertFile', os.path.expandvars, Required =3D False, Default = =3D None, Open =3D True)=0D + OpenSslTrustedPublicCertFile =3D ConvertJsonValue (Config, 'Op= enSslTrustedPublicCertFile', os.path.expandvars, Required =3D False, Defaul= t =3D None, Open =3D True)=0D + SigningToolPath =3D ConvertJsonValue (Config, 'Si= gningToolPath', os.path.expandvars, Required =3D False, Default =3D None)=0D +=0D + #=0D + # Read binary input file=0D + #=0D + try:=0D + if args.Verbose:=0D + print ('Read binary input file {File}'.format (File = =3D PayloadFile.name))=0D + Payload =3D PayloadFile.read()=0D + except:=0D + print ('GenerateCapsule: error: can not read binary input = file {File}'.format (File =3D PayloadFile.name))=0D + sys.exit (1)=0D + PayloadDescriptorList.append (PayloadDescriptor (=0D + Payload,=0D + Guid,=0D + FwVersion,=0D + LowestSupportedVersion,=0D + MonotonicCount,=0D + HardwareInstance,=0D + UpdateImageIndex,=0D + SignToolPfxFile,=0D + OpenSslSignerPrivateCertFile,= =0D + OpenSslOtherPublicCertFile,=0D + OpenSslTrustedPublicCertFile,= =0D + SigningToolPath=0D + ))=0D +=0D + def GenerateOutputJson (PayloadJsonDescriptorList):=0D + PayloadJson =3D {=0D + "Payloads" : [=0D + {=0D + "Guid": str(PayloadDescriptor.Guid).uppe= r(),=0D + "FwVersion": str(PayloadDescriptor.FwVer= sion),=0D + "LowestSupportedVersion": str(PayloadDes= criptor.LowestSupportedVersion),=0D + "MonotonicCount": str(PayloadDescriptor.= MonotonicCount),=0D + "Payload": PayloadDescriptor.Payload,=0D + "HardwareInstance": str(PayloadDescripto= r.HardwareInstance),=0D + "UpdateImageIndex": str(PayloadDescripto= r.UpdateImageIndex),=0D + "SignToolPfxFile": str(PayloadDescriptor= .SignToolPfxFile),=0D + "OpenSslSignerPrivateCertFile": str(Payl= oadDescriptor.OpenSslSignerPrivateCertFile),=0D + "OpenSslOtherPublicCertFile": str(Payloa= dDescriptor.OpenSslOtherPublicCertFile),=0D + "OpenSslTrustedPublicCertFile": str(Payl= oadDescriptor.OpenSslTrustedPublicCertFile),=0D + "SigningToolPath": str(PayloadDescriptor= .SigningToolPath)=0D + }for PayloadDescriptor in PayloadJsonDescrip= torList=0D + ]=0D + }=0D + OutputJsonFile =3D args.OutputFile.name + '.json'=0D + if 'Payloads' in PayloadJson:=0D + PayloadSection =3D PayloadJson ['Payloads']=0D + Index =3D 0=0D + for PayloadField in PayloadSection:=0D + if PayloadJsonDescriptorList[Index].SignToolPfxFile is None:=0D + del PayloadField ['SignToolPfxFile']=0D + if PayloadJsonDescriptorList[Index].OpenSslSignerPrivateCertFi= le is None:=0D + del PayloadField ['OpenSslSignerPrivateCertFile']=0D + if PayloadJsonDescriptorList[Index].OpenSslOtherPublicCertFile= is None:=0D + del PayloadField ['OpenSslOtherPublicCertFile']=0D + if PayloadJsonDescriptorList[Index].OpenSslTrustedPublicCertFi= le is None:=0D + del PayloadField ['OpenSslTrustedPublicCertFile']=0D + if PayloadJsonDescriptorList[Index].SigningToolPath is None:=0D + del PayloadField ['SigningToolPath']=0D + Index =3D Index + 1=0D + Result =3D json.dumps (PayloadJson, indent=3D4, sort_keys=3DTrue, = separators=3D(',', ': '))=0D + OutputFile =3D open (OutputJsonFile, 'w')=0D + OutputFile.write (Result)=0D + OutputFile.close ()=0D +=0D + def CheckArgumentConflict (args):=0D + if args.Encode:=0D + if args.InputFile:=0D + print ('GenerateCapsule: error: Argument InputFile conflic= ts with Argument -j')=0D + sys.exit (1)=0D + if args.EmbeddedDriver:=0D + print ('GenerateCapsule: error: Argument --embedded-driver= conflicts with Argument -j')=0D + sys.exit (1)=0D + if args.Guid:=0D + print ('GenerateCapsule: error: Argument --guid conflicts with= Argument -j')=0D + sys.exit (1)=0D + if args.FwVersion:=0D + print ('GenerateCapsule: error: Argument --fw-version conflict= s with Argument -j')=0D + sys.exit (1)=0D + if args.LowestSupportedVersion:=0D + print ('GenerateCapsule: error: Argument --lsv conflicts with = Argument -j')=0D + sys.exit (1)=0D + if args.MonotonicCount:=0D + print ('GenerateCapsule: error: Argument --monotonic-count con= flicts with Argument -j')=0D + sys.exit (1)=0D + if args.HardwareInstance:=0D + print ('GenerateCapsule: error: Argument --hardware-instance c= onflicts with Argument -j')=0D + sys.exit (1)=0D + if args.SignToolPfxFile:=0D + print ('GenerateCapsule: error: Argument --pfx-file conflicts = with Argument -j')=0D + sys.exit (1)=0D + if args.OpenSslSignerPrivateCertFile:=0D + print ('GenerateCapsule: error: Argument --signer-private-cert= conflicts with Argument -j')=0D + sys.exit (1)=0D + if args.OpenSslOtherPublicCertFile:=0D + print ('GenerateCapsule: error: Argument --other-public-cert c= onflicts with Argument -j')=0D + sys.exit (1) =0D + if args.OpenSslTrustedPublicCertFile:=0D + print ('GenerateCapsule: error: Argument --trusted-public-cert= conflicts with Argument -j')=0D + sys.exit (1) =0D + if args.SigningToolPath:=0D + print ('GenerateCapsule: error: Argument --signing-tool-path c= onflicts with Argument -j')=0D + sys.exit (1)=0D +=0D + class PayloadDescriptor (object):=0D + def __init__(self,=0D + Payload,=0D + Guid,=0D + FwVersion,=0D + LowestSupportedVersion,=0D + MonotonicCount =3D 0,=0D + HardwareInstance =3D 0,=0D + UpdateImageIndex =3D 1,=0D + SignToolPfxFile =3D None,=0D + OpenSslSignerPrivateCertFile =3D None,=0D + OpenSslOtherPublicCertFile =3D None,=0D + OpenSslTrustedPublicCertFile =3D None,=0D + SigningToolPath =3D None=0D + ):=0D + self.Payload =3D Payload=0D + self.Guid =3D Guid=0D + self.FwVersion =3D FwVersion=0D + self.LowestSupportedVersion =3D LowestSupportedVersion=0D + self.MonotonicCount =3D MonotonicCount=0D + self.HardwareInstance =3D HardwareInstance=0D + self.UpdateImageIndex =3D UpdateImageIndex=0D + self.SignToolPfxFile =3D SignToolPfxFile=0D + self.OpenSslSignerPrivateCertFile =3D OpenSslSignerPrivateCert= File=0D + self.OpenSslOtherPublicCertFile =3D OpenSslOtherPublicCertFi= le=0D + self.OpenSslTrustedPublicCertFile =3D OpenSslTrustedPublicCert= File=0D + self.SigningToolPath =3D SigningToolPath=0D +=0D + self.UseSignTool =3D self.SignToolPfxFile is not None=0D + self.UseOpenSsl =3D (self.OpenSslSignerPrivateCertFile is not= None and=0D + self.OpenSslOtherPublicCertFile is not Non= e and=0D + self.OpenSslTrustedPublicCertFile is not N= one)=0D + self.AnyOpenSsl =3D (self.OpenSslSignerPrivateCertFile is not= None or=0D + self.OpenSslOtherPublicCertFile is not Non= e or=0D + self.OpenSslTrustedPublicCertFile is not N= one)=0D +=0D + def Validate(self, args):=0D + if self.UseSignTool and self.AnyOpenSsl:=0D + raise argparse.ArgumentTypeError ('Providing both signtool= and OpenSSL options is not supported')=0D + if not self.UseSignTool and not self.UseOpenSsl and self.AnyOp= enSsl:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('the following JSON = fields are required for OpenSSL: OpenSslSignerPrivateCertFile, OpenSslOther= PublicCertFile, OpenSslTrustedPublicCertFile')=0D + else:=0D + raise argparse.ArgumentTypeError ('the following optio= ns are required for OpenSSL: --signer-private-cert, --other-public-cert, --= trusted-public-cert')=0D + if self.UseSignTool and platform.system() !=3D 'Windows':=0D + raise argparse.ArgumentTypeError ('Use of signtool is not = supported on this operating system.')=0D + if args.Encode:=0D + if self.FwVersion is None or self.LowestSupportedVersion i= s None:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('the following J= SON fields are required: FwVersion, LowestSupportedVersion')=0D + else:=0D + raise argparse.ArgumentTypeError ('the following o= ptions are required: --fw-version, --lsv')=0D + if self.FwVersion > 0xFFFFFFFF:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('JSON field FwVe= rsion must be an integer in range 0x0..0xffffffff')=0D + else:=0D + raise argparse.ArgumentTypeError ('--fw-version mu= st be an integer in range 0x0..0xffffffff')=0D + if self.LowestSupportedVersion > 0xFFFFFFFF:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('JSON field Lowe= stSupportedVersion must be an integer in range 0x0..0xffffffff')=0D + else:=0D + raise argparse.ArgumentTypeError ('--lsv must be a= n integer in range 0x0..0xffffffff')=0D +=0D + if args.Encode:=0D + if self.Guid is None:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('the following J= SON field is required: Guid')=0D + else:=0D + raise argparse.ArgumentTypeError ('the following o= ption is required: --guid')=0D + if self.HardwareInstance > 0xFFFFFFFFFFFFFFFF:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('JSON field Hard= wareInstance must be an integer in range 0x0..0xffffffffffffffff')=0D + else:=0D + raise argparse.ArgumentTypeError ('--hardware-inst= ance must be an integer in range 0x0..0xffffffffffffffff')=0D + if self.MonotonicCount > 0xFFFFFFFFFFFFFFFF:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('JSON field Mono= tonicCount must be an integer in range 0x0..0xffffffffffffffff')=0D + else:=0D + raise argparse.ArgumentTypeError ('--monotonic-cou= nt must be an integer in range 0x0..0xffffffffffffffff')=0D + if self.UpdateImageIndex >0xFF:=0D + if args.JsonFile:=0D + raise argparse.ArgumentTypeError ('JSON field Upda= teImageIndex must be an integer in range 0x0..0xff')=0D + else:=0D + raise argparse.ArgumentTypeError ('--update-image-= index must be an integer in range 0x0..0xff')=0D +=0D + if self.UseSignTool:=0D + self.SignToolPfxFile.close()=0D + self.SignToolPfxFile =3D self.SignToolPfxFile.name=0D + if self.UseOpenSsl:=0D + self.OpenSslSignerPrivateCertFile.close()=0D + self.OpenSslOtherPublicCertFile.close()=0D + self.OpenSslTrustedPublicCertFile.close()=0D + self.OpenSslSignerPrivateCertFile =3D self.OpenSslSignerPr= ivateCertFile.name=0D + self.OpenSslOtherPublicCertFile =3D self.OpenSslOtherPub= licCertFile.name=0D + self.OpenSslTrustedPublicCertFile =3D self.OpenSslTrustedP= ublicCertFile.name=0D +=0D + #=0D + # Perform additional argument verification=0D + #=0D + if args.Encode:=0D + if 'PersistAcrossReset' not in args.CapsuleFlag:=0D + if 'InitiateReset' in args.CapsuleFlag:=0D + raise argparse.ArgumentTypeError ('--capflag Initi= ateReset also requires --capflag PersistAcrossReset')=0D + if args.CapsuleOemFlag > 0xFFFF:=0D + raise argparse.ArgumentTypeError ('--capoemflag must b= e an integer between 0x0000 and 0xffff')=0D +=0D + return True=0D +=0D +=0D + def Encode (PayloadDescriptorList, EmbeddedDriverDescriptorList, Buffe= r):=0D + if args.JsonFile:=0D + CheckArgumentConflict(args)=0D + try:=0D + Json =3D json.loads (args.JsonFile.read ())=0D + except Exception as Message:=0D + print ('GenerateCapsule: error: ' + str(Message))=0D + sys.exit (1)=0D + EncodeJsonFileParse(Json)=0D + else:=0D + for Driver in args.EmbeddedDriver:=0D + EmbeddedDriverDescriptorList.append (Driver.read())=0D + PayloadDescriptorList.append (PayloadDescriptor (=0D + Buffer,=0D + args.Guid,=0D + args.FwVersion,=0D + args.LowestSupportedVersion,=0D + args.MonotonicCount,=0D + args.HardwareInstance,=0D + args.UpdateImageIndex,=0D + args.SignToolPfxFile,=0D + args.OpenSslSignerPrivateCertF= ile,=0D + args.OpenSslOtherPublicCertFil= e,=0D + args.OpenSslTrustedPublicCertF= ile,=0D + args.SigningToolPath=0D + ))=0D + for SinglePayloadDescriptor in PayloadDescriptorList:=0D + try:=0D + SinglePayloadDescriptor.Validate (args)=0D + except Exception as Message:=0D + print ('GenerateCapsule: error: ' + str(Message))=0D + sys.exit (1)=0D + for SinglePayloadDescriptor in PayloadDescriptorList:=0D + Result =3D SinglePayloadDescriptor.Payload=0D + try:=0D + FmpPayloadHeader.FwVersion =3D SinglePayloadD= escriptor.FwVersion=0D + FmpPayloadHeader.LowestSupportedVersion =3D SinglePayloadD= escriptor.LowestSupportedVersion=0D + FmpPayloadHeader.Payload =3D SinglePayloadD= escriptor.Payload=0D + Result =3D FmpPayloadHeader.Encode ()=0D + if args.Verbose:=0D + FmpPayloadHeader.DumpInfo ()=0D + except:=0D + raise=0D + print ('GenerateCapsule: error: can not encode FMP Payload= Header')=0D + sys.exit (1)=0D + if SinglePayloadDescriptor.UseOpenSsl or SinglePayloadDescript= or.UseSignTool:=0D + #=0D + # Sign image with 64-bit MonotonicCount appended to end of= image=0D + #=0D + try:=0D + if SinglePayloadDescriptor.UseSignTool:=0D + CertData =3D SignPayloadSignTool (=0D + Result + struct.pack (' 0:=0D + Result =3D FmpCapsuleHeader.Decode (Result)=0D + if args.JsonFile:=0D + if FmpCapsuleHeader.PayloadItemCount !=3D len (Payload= DescriptorList):=0D + CapsulePayloadNum =3D FmpCapsuleHeader.PayloadItem= Count=0D + JsonPayloadNum =3D len (PayloadDescriptorList)=0D + print ('GenerateCapsule: Decode error: {JsonPayloa= dNumber} payloads in JSON file {File} and {CapsulePayloadNumber} payloads i= n Capsule {CapsuleName}'.format (JsonPayloadNumber =3D JsonPayloadNum, File= =3D args.JsonFile.name, CapsulePayloadNumber =3D CapsulePayloadNum, Capsul= eName =3D args.InputFile.name))=0D + sys.exit (1)=0D + for Index in range (0, FmpCapsuleHeader.PayloadItemCou= nt):=0D + if Index < len (PayloadDescriptorList):=0D + GUID =3D FmpCapsuleHeader.GetFmpCapsuleImageHe= ader (Index).UpdateImageTypeId=0D + HardwareInstance =3D FmpCapsuleHeader.GetFmpCa= psuleImageHeader (Index).UpdateHardwareInstance=0D + UpdateImageIndex =3D FmpCapsuleHeader.GetFmpCa= psuleImageHeader (Index).UpdateImageIndex=0D + if PayloadDescriptorList[Index].Guid !=3D GUID= or PayloadDescriptorList[Index].HardwareInstance !=3D HardwareInstance:=0D + print ('GenerateCapsule: Decode error: Gui= d or HardwareInstance pair in input JSON file {File} does not match the pay= load {PayloadIndex} in Capsule {InputCapsule}'.format (File =3D args.JsonFi= le.name, PayloadIndex =3D Index + 1, InputCapsule =3D args.InputFile.name))= =0D + sys.exit (1)=0D + PayloadDescriptorList[Index].Payload =3D FmpCa= psuleHeader.GetFmpCapsuleImageHeader (Index).Payload=0D + DecodeJsonOutput =3D args.OutputFile.name + '.= Payload.{Index:d}.bin'.format (Index =3D Index + 1)=0D + PayloadJsonDescriptorList.append (PayloadDescr= iptor (=0D + DecodeJson= Output,=0D + GUID,=0D + None,=0D + None,=0D + None,=0D + HardwareIn= stance,=0D + UpdateImag= eIndex,=0D + PayloadDes= criptorList[Index].SignToolPfxFile,=0D + PayloadDes= criptorList[Index].OpenSslSignerPrivateCertFile,=0D + PayloadDes= criptorList[Index].OpenSslOtherPublicCertFile,=0D + PayloadDes= criptorList[Index].OpenSslTrustedPublicCertFile,=0D + PayloadDes= criptorList[Index].SigningToolPath=0D + ))=0D + else:=0D + PayloadDescriptorList[0].Payload =3D FmpCapsuleHeader.= GetFmpCapsuleImageHeader (0).Payload=0D + for Index in range (0, FmpCapsuleHeader.PayloadItemCou= nt):=0D + if Index > 0:=0D + PayloadDecodeFile =3D FmpCapsuleHeader.GetFmpC= apsuleImageHeader (Index).Payload=0D + PayloadDescriptorList.append (PayloadDescripto= r (PayloadDecodeFile,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None,=0D + None=0D + ))=0D + GUID =3D FmpCapsuleHeader.GetFmpCapsuleImageHeader= (Index).UpdateImageTypeId=0D + HardwareInstance =3D FmpCapsuleHeader.GetFmpCapsul= eImageHeader (Index).UpdateHardwareInstance=0D + UpdateImageIndex =3D FmpCapsuleHeader.GetFmpCapsul= eImageHeader (Index).UpdateImageIndex=0D + DecodeJsonOutput =3D args.OutputFile.name + '.Payl= oad.{Index:d}.bin'.format (Index =3D Index + 1)=0D + PayloadJsonDescriptorList.append (PayloadDescripto= r (=0D + DecodeJsonOutp= ut,=0D + GUID,=0D + None,=0D + None,=0D + None,=0D + HardwareInstan= ce,=0D + UpdateImageInd= ex,=0D + PayloadDescrip= torList[Index].SignToolPfxFile,=0D + PayloadDescrip= torList[Index].OpenSslSignerPrivateCertFile,=0D + PayloadDescrip= torList[Index].OpenSslOtherPublicCertFile,=0D + PayloadDescrip= torList[Index].OpenSslTrustedPublicCertFile,=0D + PayloadDescrip= torList[Index].SigningToolPath=0D + ))=0D + JsonIndex =3D 0=0D + for SinglePayloadDescriptor in PayloadDescriptorList:=0D + if args.Verbose:=0D + print ('=3D=3D=3D=3D=3D=3D=3D=3D')=0D + UefiCapsuleHeader.DumpInfo ()=0D + print ('--------')=0D + FmpCapsuleHeader.DumpInfo ()=0D + if FmpAuthHeader.IsSigned(SinglePayloadDescriptor.Payl= oad):=0D + if not SinglePayloadDescriptor.UseOpenSsl and not = SinglePayloadDescriptor.UseSignTool:=0D + print ('GenerateCapsule: decode warning: can n= ot verify singed payload without cert or pfx file. Index =3D {Index}'.forma= t (Index =3D JsonIndex + 1))=0D + SinglePayloadDescriptor.Payload =3D FmpAuthHeader.= Decode (SinglePayloadDescriptor.Payload)=0D + PayloadJsonDescriptorList[JsonIndex].MonotonicCoun= t =3D FmpAuthHeader.MonotonicCount=0D + if args.Verbose:=0D + print ('--------')=0D + FmpAuthHeader.DumpInfo ()=0D +=0D + #=0D + # Verify Image with 64-bit MonotonicCount appended= to end of image=0D + #=0D + try:=0D + if SinglePayloadDescriptor.UseSignTool:=0D + CertData =3D VerifyPayloadSignTool (=0D + FmpAuthHeader.Payload + struct.= pack (' 0:=0D + FmpCapsuleHeader.Decode (Result)=0D + print ('--------')=0D + FmpCapsuleHeader.DumpInfo ()=0D + for Index in range (0, FmpCapsuleHeader.PayloadItemCount):= =0D + Result =3D FmpCapsuleHeader.GetFmpCapsuleImageHeader (= Index).Payload=0D + try:=0D + Result =3D FmpAuthHeader.Decode (Result)=0D + print ('--------')=0D + FmpAuthHeader.DumpInfo ()=0D + except:=0D + print ('--------')=0D + print ('No EFI_FIRMWARE_IMAGE_AUTHENTICATION')=0D + try:=0D + Result =3D FmpPayloadHeader.Decode (Result)=0D + print ('--------')=0D + FmpPayloadHeader.DumpInfo ()=0D + except:=0D + print ('--------')=0D + print ('No FMP_PAYLOAD_HEADER')=0D + print ('=3D=3D=3D=3D=3D=3D=3D=3D')=0D + except:=0D + print ('GenerateCapsule: error: can not decode capsule')=0D + sys.exit (1)=0D +=0D #=0D # Create command line argument parser object=0D #=0D @@ -226,7 +885,7 @@ if __name__ =3D=3D '__main__': #=0D # Add input and output file arguments=0D #=0D - parser.add_argument("InputFile", type =3D argparse.FileType('rb'),=0D + parser.add_argument("InputFile", type =3D argparse.FileType('rb'), na= rgs=3D'?',=0D help =3D "Input binary payload filename.")=0D parser.add_argument("-o", "--output", dest =3D 'OutputFile', type =3D = argparse.FileType('wb'),=0D help =3D "Output filename.")=0D @@ -243,6 +902,8 @@ if __name__ =3D=3D '__main__': #=0D # Add optional arguments for this command=0D #=0D + parser.add_argument ("-j", "--json-file", dest =3D 'JsonFile', type=3D= argparse.FileType('r'),=0D + help =3D "JSON configuration file for multiple pa= yloads and embedded drivers.")=0D parser.add_argument ("--capflag", dest =3D 'CapsuleFlag', action=3D'ap= pend', default =3D [],=0D choices=3D['PersistAcrossReset', 'InitiateReset']= ,=0D help =3D "Capsule flag can be PersistAcrossReset = or InitiateReset or not set")=0D @@ -250,7 +911,7 @@ if __name__ =3D=3D '__main__': help =3D "Capsule OEM Flag is an integer between = 0x0000 and 0xffff.")=0D =0D parser.add_argument ("--guid", dest =3D 'Guid', type =3D ValidateRegis= tryFormatGuid,=0D - help =3D "The FMP/ESRT GUID in registry format. = Required for encode operations.")=0D + help =3D "The FMP/ESRT GUID in registry format. = Required for single payload encode operations.")=0D parser.add_argument ("--hardware-instance", dest =3D 'HardwareInstance= ', type =3D ValidateUnsignedInteger, default =3D 0x0000000000000000,=0D help =3D "The 64-bit hardware instance. The defa= ult is 0x0000000000000000")=0D =0D @@ -259,9 +920,9 @@ if __name__ =3D=3D '__main__': help =3D "64-bit monotonic count value in header.= Default is 0x0000000000000000.")=0D =0D parser.add_argument ("--fw-version", dest =3D 'FwVersion', type =3D Va= lidateUnsignedInteger,=0D - help =3D "The 32-bit version of the binary payloa= d (e.g. 0x11223344 or 5678). Required for encode operations that sign a pa= yload.")=0D + help =3D "The 32-bit version of the binary payloa= d (e.g. 0x11223344 or 5678). Required for encode operations.")=0D parser.add_argument ("--lsv", dest =3D 'LowestSupportedVersion', type = =3D ValidateUnsignedInteger,=0D - help =3D "The 32-bit lowest supported version of = the binary payload (e.g. 0x11223344 or 5678). Required for encode operatio= ns that sign a payload.")=0D + help =3D "The 32-bit lowest supported version of = the binary payload (e.g. 0x11223344 or 5678). Required for encode operatio= ns.")=0D =0D parser.add_argument ("--pfx-file", dest=3D'SignToolPfxFile', type=3Dar= gparse.FileType('rb'),=0D help=3D"signtool PFX certificate filename.")=0D @@ -276,6 +937,9 @@ if __name__ =3D=3D '__main__': parser.add_argument ("--signing-tool-path", dest =3D 'SigningToolPath'= ,=0D help =3D "Path to signtool or OpenSSL tool. Opti= onal if path to tools are already in PATH.")=0D =0D + parser.add_argument ("--embedded-driver", dest =3D 'EmbeddedDriver', t= ype =3D argparse.FileType('rb'), action=3D'append', default =3D [],=0D + help =3D "Path to embedded UEFI driver to add to = capsule.")=0D +=0D #=0D # Add optional arguments common to all operations=0D #=0D @@ -286,79 +950,29 @@ if __name__ =3D=3D '__main__': help =3D "Disable all messages except fatal error= s.")=0D parser.add_argument ("--debug", dest =3D 'Debug', type =3D int, metava= r =3D '[0-9]', choices =3D range (0, 10), default =3D 0,=0D help =3D "Set debug level")=0D + parser.add_argument ("--update-image-index", dest =3D 'UpdateImageInde= x', type =3D ValidateUnsignedInteger, default =3D 0x01, help =3D "unique nu= mber identifying the firmware image within the device ")=0D =0D #=0D # Parse command line arguments=0D #=0D args =3D parser.parse_args()=0D =0D - #=0D - # Perform additional argument verification=0D - #=0D - if args.Encode:=0D - if args.Guid is None:=0D - parser.error ('the following option is required: --guid')=0D - if 'PersistAcrossReset' not in args.CapsuleFlag:=0D - if 'InitiateReset' in args.CapsuleFlag:=0D - parser.error ('--capflag InitiateReset also requires --cap= flag PersistAcrossReset')=0D - if args.CapsuleOemFlag > 0xFFFF:=0D - parser.error ('--capoemflag must be an integer between 0x0000 = and 0xffff')=0D - if args.HardwareInstance > 0xFFFFFFFFFFFFFFFF:=0D - parser.error ('--hardware-instance must be an integer in range= 0x0..0xffffffffffffffff')=0D - if args.MonotonicCount > 0xFFFFFFFFFFFFFFFF:=0D - parser.error ('--monotonic-count must be an integer in range 0= x0..0xffffffffffffffff')=0D -=0D - UseSignTool =3D args.SignToolPfxFile is not None=0D - UseOpenSsl =3D (args.OpenSslSignerPrivateCertFile is not None and=0D - args.OpenSslOtherPublicCertFile is not None and=0D - args.OpenSslTrustedPublicCertFile is not None)=0D - AnyOpenSsl =3D (args.OpenSslSignerPrivateCertFile is not None or=0D - args.OpenSslOtherPublicCertFile is not None or=0D - args.OpenSslTrustedPublicCertFile is not None)=0D - if args.Encode or args.Decode:=0D - if args.OutputFile is None:=0D - parser.error ('the following option is required for all encode= and decode operations: --output')=0D -=0D - if UseSignTool and AnyOpenSsl:=0D - parser.error ('Providing both signtool and OpenSSL options is = not supported')=0D - if not UseSignTool and not UseOpenSsl and AnyOpenSsl:=0D - parser.error ('all the following options are required for Open= SSL: --signer-private-cert, --other-public-cert, --trusted-public-cert')=0D - if UseSignTool and platform.system() !=3D 'Windows':=0D - parser.error ('Use of signtool is not supported on this operat= ing system.')=0D - if args.Encode and (UseSignTool or UseOpenSsl):=0D - if args.FwVersion is None or args.LowestSupportedVersion is No= ne:=0D - parser.error ('the following options are required: --fw-ve= rsion, --lsv')=0D - if args.FwVersion > 0xFFFFFFFF:=0D - parser.error ('--fw-version must be an integer in range 0x= 0..0xffffffff')=0D - if args.LowestSupportedVersion > 0xFFFFFFFF:=0D - parser.error ('--lsv must be an integer in range 0x0..0xff= ffffff')=0D -=0D - if UseSignTool:=0D - args.SignToolPfxFile.close()=0D - args.SignToolPfxFile =3D args.SignToolPfxFile.name=0D - if UseOpenSsl:=0D - args.OpenSslSignerPrivateCertFile.close()=0D - args.OpenSslOtherPublicCertFile.close()=0D - args.OpenSslTrustedPublicCertFile.close()=0D - args.OpenSslSignerPrivateCertFile =3D args.OpenSslSignerPrivat= eCertFile.name=0D - args.OpenSslOtherPublicCertFile =3D args.OpenSslOtherPublicC= ertFile.name=0D - args.OpenSslTrustedPublicCertFile =3D args.OpenSslTrustedPubli= cCertFile.name=0D -=0D - if args.DumpInfo:=0D - if args.OutputFile is not None:=0D - parser.error ('the following option is not supported for dumpi= nfo operations: --output')=0D -=0D #=0D # Read binary input file=0D #=0D - try:=0D - if args.Verbose:=0D - print ('Read binary input file {File}'.format (File =3D args.I= nputFile.name))=0D - Buffer =3D args.InputFile.read ()=0D - args.InputFile.close ()=0D - except:=0D - print ('GenerateCapsule: error: can not read binary input file {Fi= le}'.format (File =3D args.InputFile.name))=0D - sys.exit (1)=0D + Buffer =3D ''=0D + if args.InputFile:=0D + if os.path.getsize (args.InputFile.name) =3D=3D 0:=0D + print ('GenerateCapsule: error: InputFile {File} is empty'.for= mat (File =3D args.InputFile.name))=0D + sys.exit (1)=0D + try:=0D + if args.Verbose:=0D + print ('Read binary input file {File}'.format (File =3D ar= gs.InputFile.name))=0D + Buffer =3D args.InputFile.read ()=0D + args.InputFile.close ()=0D + except:=0D + print ('GenerateCapsule: error: can not read binary input file= {File}'.format (File =3D args.InputFile.name))=0D + sys.exit (1)=0D =0D #=0D # Create objects=0D @@ -368,182 +982,27 @@ if __name__ =3D=3D '__main__': FmpAuthHeader =3D FmpAuthHeaderClass ()=0D FmpPayloadHeader =3D FmpPayloadHeaderClass ()=0D =0D - if args.Encode:=0D - Result =3D Buffer=0D - if UseSignTool or UseOpenSsl:=0D - try:=0D - FmpPayloadHeader.FwVersion =3D args.FwVersion= =0D - FmpPayloadHeader.LowestSupportedVersion =3D args.LowestSup= portedVersion=0D - FmpPayloadHeader.Payload =3D Result=0D - Result =3D FmpPayloadHeader.Encode ()=0D - if args.Verbose:=0D - FmpPayloadHeader.DumpInfo ()=0D - except:=0D - print ('GenerateCapsule: error: can not encode FMP Payload= Header')=0D - sys.exit (1)=0D -=0D - #=0D - # Sign image with 64-bit MonotonicCount appended to end of ima= ge=0D - #=0D - try:=0D - if UseSignTool:=0D - CertData =3D SignPayloadSignTool (=0D - Result + struct.pack ('=0D +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D #=0D =0D @@ -166,6 +166,18 @@ class FmpAuthHeaderClass (object): self._Valid =3D True=0D return self.Payload=0D =0D + def IsSigned (self, Buffer):=0D + if len (Buffer) < self._StructSize:=0D + return False=0D + (MonotonicCount, dwLength, wRevision, wCertificateType, CertType) = =3D \=0D + struct.unpack (=0D + self._StructFormat,=0D + Buffer[0:self._StructSize]=0D + )=0D + if CertType !=3D self._EFI_CERT_TYPE_PKCS7_GUID.bytes_le:=0D + return False=0D + return True=0D +=0D def DumpInfo (self):=0D if not self._Valid:=0D raise ValueError=0D diff --git a/BaseTools/Source/Python/Common/Uefi/Capsule/FmpCapsuleHeader.p= y 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_HEADER= with=0D # a payload.=0D #=0D -# Copyright (c) 2018, Intel Corporation. All rights reserved.
=0D +# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D #=0D =0D @@ -172,8 +172,8 @@ class FmpCapsuleHeaderClass (object): raise ValueError=0D return self._EmbeddedDriverList[Index]=0D =0D - def AddPayload (self, UpdateImageTypeId, Payload =3D b'', VendorCodeBy= tes =3D b'', HardwareInstance =3D 0):=0D - self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeB= ytes, HardwareInstance))=0D + def AddPayload (self, UpdateImageTypeId, Payload =3D b'', VendorCodeBy= tes =3D b'', HardwareInstance =3D 0, UpdateImageIndex =3D 1):=0D + self._PayloadList.append ((UpdateImageTypeId, Payload, VendorCodeB= ytes, HardwareInstance, UpdateImageIndex))=0D =0D def GetFmpCapsuleImageHeader (self, Index):=0D if Index >=3D len (self._FmpCapsuleImageHeaderList):=0D @@ -198,10 +198,10 @@ class FmpCapsuleHeaderClass (object): self._ItemOffsetList.append (Offset)=0D Offset =3D Offset + len (EmbeddedDriver)=0D Index =3D 1=0D - for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance= ) in self._PayloadList:=0D + for (UpdateImageTypeId, Payload, VendorCodeBytes, HardwareInstance= , UpdateImageIndex) in self._PayloadList:=0D FmpCapsuleImageHeader =3D FmpCapsuleImageHeaderClass ()=0D FmpCapsuleImageHeader.UpdateImageTypeId =3D UpdateImageTy= peId=0D - FmpCapsuleImageHeader.UpdateImageIndex =3D Index=0D + FmpCapsuleImageHeader.UpdateImageIndex =3D UpdateImageIn= dex=0D FmpCapsuleImageHeader.Payload =3D Payload=0D FmpCapsuleImageHeader.VendorCodeBytes =3D VendorCodeByt= es=0D FmpCapsuleImageHeader.UpdateHardwareInstance =3D HardwareInsta= nce=0D @@ -288,6 +288,8 @@ class FmpCapsuleHeaderClass (object): raise ValueError=0D print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.Version = =3D {Version:08X}'.format (Version =3D self.Version))=0D print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.EmbeddedDriverCount= =3D {EmbeddedDriverCount:08X}'.format (EmbeddedDriverCount =3D self.Embedd= edDriverCount))=0D + for EmbeddedDriver in self._EmbeddedDriverList:=0D + print (' sizeof (EmbeddedDriver) = =3D {Size:08X}'.format (Size =3D len (EmbeddedDriver)))=0D print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.PayloadItemCount = =3D {PayloadItemCount:08X}'.format (PayloadItemCount =3D self.PayloadItemC= ount))=0D print ('EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER.ItemOffsetList = =3D ')=0D for Offset in self._ItemOffsetList:=0D --=20 2.20.0.windows.1