## @file\r
# generate capsule\r
#\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
from Common.Misc import PackRegistryFormatGuid\r
import uuid\r
from struct import pack\r
+from GenFds import FindExtendTool\r
+from Common import EdkLogger\r
+from Common.BuildToolError import *\r
\r
\r
T_CHAR_LF = '\n'\r
+WIN_CERT_REVISION = 0x0200\r
+WIN_CERT_TYPE_EFI_GUID = 0x0EF1\r
+EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}')\r
+EFI_CERT_TYPE_RSA2048_SHA256_GUID = uuid.UUID('{a7717414-c616-4977-9420-844712a735bf}')\r
\r
## create inf file describes what goes into capsule and call GenFv to generate capsule\r
#\r
FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList)))\r
FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList))\r
\r
+ #\r
+ # typedef struct _WIN_CERTIFICATE {\r
+ # UINT32 dwLength;\r
+ # UINT16 wRevision;\r
+ # UINT16 wCertificateType;\r
+ # //UINT8 bCertificate[ANYSIZE_ARRAY];\r
+ # } WIN_CERTIFICATE;\r
+ #\r
+ # typedef struct _WIN_CERTIFICATE_UEFI_GUID {\r
+ # WIN_CERTIFICATE Hdr;\r
+ # EFI_GUID CertType;\r
+ # //UINT8 CertData[ANYSIZE_ARRAY];\r
+ # } WIN_CERTIFICATE_UEFI_GUID;\r
+ #\r
+ # typedef struct {\r
+ # UINT64 MonotonicCount;\r
+ # WIN_CERTIFICATE_UEFI_GUID AuthInfo;\r
+ # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;\r
+ #\r
+ # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {\r
+ # EFI_GUID HashType;\r
+ # UINT8 PublicKey[256];\r
+ # UINT8 Signature[256];\r
+ # } EFI_CERT_BLOCK_RSA_2048_SHA256;\r
+ #\r
+\r
PreSize = FwMgrHdrSize\r
Content = StringIO.StringIO()\r
for driver in self.CapsuleDataList:\r
Content.write(File.read())\r
File.close()\r
for fmp in self.FmpPayloadList:\r
- payload = fmp.GenCapsuleSubItem()\r
- FwMgrHdr.write(pack('=Q', PreSize))\r
- PreSize += len(payload)\r
- Content.write(payload)\r
+ if fmp.Certificate_Guid:\r
+ ExternalTool, ExternalOption = FindExtendTool([], GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid)\r
+ CmdOption = ''\r
+ CapInputFile = fmp.ImageFile\r
+ if not os.path.isabs(fmp.ImageFile):\r
+ CapInputFile = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, fmp.ImageFile)\r
+ CapOutputTmp = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.tmp'\r
+ if ExternalTool == None:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % fmp.Certificate_Guid)\r
+ else:\r
+ CmdOption += ExternalTool\r
+ if ExternalOption:\r
+ CmdOption = CmdOption + ' ' + ExternalOption\r
+ CmdOption += ' -e ' + ' --monotonic-count ' + str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile\r
+ CmdList = CmdOption.split()\r
+ GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed to generate FMP auth capsule")\r
+ if uuid.UUID(fmp.Certificate_Guid) == EFI_CERT_TYPE_PKCS7_GUID:\r
+ dwLength = 4 + 2 + 2 + 16 + os.path.getsize(CapOutputTmp) - os.path.getsize(CapInputFile)\r
+ else:\r
+ dwLength = 4 + 2 + 2 + 16 + 16 + 256 + 256\r
+ Buffer = pack('Q', fmp.MonotonicCount)\r
+ Buffer += pack('I', dwLength)\r
+ Buffer += pack('H', WIN_CERT_REVISION)\r
+ Buffer += pack('H', WIN_CERT_TYPE_EFI_GUID)\r
+ Buffer += uuid.UUID(fmp.Certificate_Guid).get_bytes_le()\r
+ if os.path.exists(CapOutputTmp):\r
+ TmpFile = open(CapOutputTmp, 'rb')\r
+ Buffer += TmpFile.read()\r
+ TmpFile.close()\r
+ if fmp.VendorCodeFile:\r
+ VendorFile = open(fmp.VendorCodeFile, 'rb')\r
+ Buffer += VendorFile.read()\r
+ VendorFile.close()\r
+ FwMgrHdr.write(pack('=Q', PreSize))\r
+ PreSize += len(Buffer)\r
+ Content.write(Buffer)\r
+ else:\r
+ payload = fmp.GenCapsuleSubItem()\r
+ FwMgrHdr.write(pack('=Q', PreSize))\r
+ PreSize += len(payload)\r
+ Content.write(payload)\r
BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue())\r
Header.write(pack('=I', HdrSize + BodySize))\r
#\r
## @file\r
# generate capsule\r
#\r
-# Copyright (c) 2007-2013, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007-2016, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
self.HardwareInstance = None\r
self.ImageFile = None\r
self.VendorCodeFile = None\r
+ self.Certificate_Guid = None\r
+ self.MonotonicCount = None\r
\r
def GenCapsuleSubItem(self):\r
if not self.Version:\r
from Common.Expression import *\r
from Common import GlobalData\r
from Common.String import ReplaceMacro\r
-\r
+import uuid\r
from Common.Misc import tdict\r
\r
import Common.LongFilePathOs as os\r
from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from Capsule import EFI_CERT_TYPE_PKCS7_GUID\r
+from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID\r
\r
##define T_CHAR_SPACE ' '\r
##define T_CHAR_NULL '\0'\r
self.__UndoToken()\r
return False\r
\r
+ def __Verify(self, Name, Value, Scope):\r
+ if Scope in ['UINT64', 'UINT8']:\r
+ ValueNumber = 0\r
+ try:\r
+ if Value.upper().startswith('0X'):\r
+ ValueNumber = int (Value, 16)\r
+ else:\r
+ ValueNumber = int (Value)\r
+ except:\r
+ EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)\r
+ if ValueNumber < 0:\r
+ EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)\r
+ if Scope == 'UINT64':\r
+ if ValueNumber >= 0x10000000000000000:\r
+ EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
+ if Scope == 'UINT8':\r
+ if ValueNumber >= 0x100:\r
+ EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
+ return True\r
+\r
## __UndoToken() method\r
#\r
# Go back one token unit in file buffer\r
\r
if not self.__GetNextToken():\r
raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
- FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']\r
+ FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
while self.__Token in FmpKeyList:\r
Name = self.__Token\r
FmpKeyList.remove(Name)\r
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)\r
if Name == 'IMAGE_TYPE_ID':\r
if not self.__GetNextGuid():\r
- raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)\r
+ raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
FmpData.ImageTypeId = self.__Token\r
+ elif Name == 'CERTIFICATE_GUID':\r
+ if not self.__GetNextGuid():\r
+ raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
+ FmpData.Certificate_Guid = self.__Token\r
+ if uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
+ raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
else:\r
if not self.__GetNextToken():\r
raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
Value = self.__Token\r
if Name == 'IMAGE_HEADER_INIT_VERSION':\r
- FmpData.Version = Value\r
+ if self.__Verify(Name, Value, 'UINT8'):\r
+ FmpData.Version = Value\r
elif Name == 'IMAGE_INDEX':\r
- FmpData.ImageIndex = Value\r
+ if self.__Verify(Name, Value, 'UINT8'):\r
+ FmpData.ImageIndex = Value\r
elif Name == 'HARDWARE_INSTANCE':\r
- FmpData.HardwareInstance = Value\r
+ if self.__Verify(Name, Value, 'UINT8'):\r
+ FmpData.HardwareInstance = Value\r
+ elif Name == 'MONOTONIC_COUNT':\r
+ if self.__Verify(Name, Value, 'UINT64'):\r
+ FmpData.MonotonicCount = Value\r
+ if FmpData.MonotonicCount.upper().startswith('0X'):\r
+ FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)\r
+ else:\r
+ FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)\r
if not self.__GetNextToken():\r
break\r
else:\r
self.__UndoToken()\r
\r
+ if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
+ EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
+ # remove CERTIFICATE_GUID and MONOTONIC_COUNT from FmpKeyList, since these keys are optional\r
+ if 'CERTIFICATE_GUID' in FmpKeyList:\r
+ FmpKeyList.remove('CERTIFICATE_GUID')\r
+ if 'MONOTONIC_COUNT' in FmpKeyList:\r
+ FmpKeyList.remove('MONOTONIC_COUNT')\r
if FmpKeyList:\r
- raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)\r
+ raise Warning("Missing keywords %s in FMP payload section." % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)\r
ImageFile = self.__ParseRawFileStatement()\r
if not ImageFile:\r
- raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)\r
+ raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
FmpData.ImageFile = ImageFile\r
VendorCodeFile = self.__ParseRawFileStatement()\r
if VendorCodeFile:\r
FmpData.VendorCodeFile = VendorCodeFile\r
+ AdditionalFile = self.__ParseRawFileStatement()\r
+ if AdditionalFile:\r
+ raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
return True\r
\r
Value = '0'\r
return Value\r
\r
- \r
+## FindExtendTool()\r
+#\r
+# Find location of tools to process data\r
+#\r
+# @param KeyStringList Filter for inputs of section generation\r
+# @param CurrentArchList Arch list\r
+# @param NameGuid The Guid name\r
+#\r
+def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):\r
+ # if user not specify filter, try to deduce it from global data.\r
+ if KeyStringList == None or KeyStringList == []:\r
+ Target = GenFdsGlobalVariable.TargetName\r
+ ToolChain = GenFdsGlobalVariable.ToolChainTag\r
+ ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
+ if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
+ KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]\r
+ for Arch in CurrentArchList:\r
+ if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:\r
+ KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
+\r
+ if GenFdsGlobalVariable.GuidToolDefinition:\r
+ if NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():\r
+ return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]\r
+\r
+ ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
+ ToolPathTmp = None\r
+ ToolOption = None\r
+ for ToolDef in ToolDefinition.items():\r
+ if NameGuid == ToolDef[1]:\r
+ KeyList = ToolDef[0].split('_')\r
+ Key = KeyList[0] + \\r
+ '_' + \\r
+ KeyList[1] + \\r
+ '_' + \\r
+ KeyList[2]\r
+ if Key in KeyStringList and KeyList[4] == 'GUID':\r
+\r
+ ToolPath = ToolDefinition.get(Key + \\r
+ '_' + \\r
+ KeyList[3] + \\r
+ '_' + \\r
+ 'PATH')\r
+\r
+ ToolOption = ToolDefinition.get(Key + \\r
+ '_' + \\r
+ KeyList[3] + \\r
+ '_' + \\r
+ 'FLAGS')\r
+ if ToolPathTmp == None:\r
+ ToolPathTmp = ToolPath\r
+ else:\r
+ if ToolPathTmp != ToolPath:\r
+ EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
+\r
+ GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)\r
+ return ToolPathTmp, ToolOption\r
+\r
## Parse command line options\r
#\r
# Using standard Python module optparse to parse command line option of this tool.\r
from Common.BuildToolError import *\r
from FvImageSection import FvImageSection\r
from Common.LongFilePathSupport import OpenLongFilePath as open\r
+from GenFds import FindExtendTool\r
\r
## generate GUIDed section\r
#\r
ExternalTool = None\r
ExternalOption = None\r
if self.NameGuid != None:\r
- ExternalTool, ExternalOption = self.__FindExtendTool__()\r
+ ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)\r
\r
#\r
# If not have GUID , call default\r
self.ProcessRequired = "TRUE"\r
return OutputFileList, self.Alignment\r
\r
- ## __FindExtendTool()\r
- #\r
- # Find location of tools to process section data\r
- #\r
- # @param self The object pointer\r
- #\r
- def __FindExtendTool__(self):\r
- # if user not specify filter, try to deduce it from global data.\r
- if self.KeyStringList == None or self.KeyStringList == []:\r
- Target = GenFdsGlobalVariable.TargetName\r
- ToolChain = GenFdsGlobalVariable.ToolChainTag\r
- ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase\r
- if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:\r
- EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)\r
- self.KeyStringList = [Target + '_' + ToolChain + '_' + self.CurrentArchList[0]]\r
- for Arch in self.CurrentArchList:\r
- if Target + '_' + ToolChain + '_' + Arch not in self.KeyStringList:\r
- self.KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)\r
-\r
- if GenFdsGlobalVariable.GuidToolDefinition:\r
- if self.NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():\r
- return GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid]\r
-\r
- ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary\r
- ToolPathTmp = None\r
- ToolOption = None\r
- for ToolDef in ToolDefinition.items():\r
- if self.NameGuid == ToolDef[1]:\r
- KeyList = ToolDef[0].split('_')\r
- Key = KeyList[0] + \\r
- '_' + \\r
- KeyList[1] + \\r
- '_' + \\r
- KeyList[2]\r
- if Key in self.KeyStringList and KeyList[4] == 'GUID':\r
-\r
- ToolPath = ToolDefinition.get(Key + \\r
- '_' + \\r
- KeyList[3] + \\r
- '_' + \\r
- 'PATH')\r
-\r
- ToolOption = ToolDefinition.get(Key + \\r
- '_' + \\r
- KeyList[3] + \\r
- '_' + \\r
- 'FLAGS')\r
- if ToolPathTmp == None:\r
- ToolPathTmp = ToolPath\r
- else:\r
- if ToolPathTmp != ToolPath:\r
- EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))\r
-\r
- GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid] = (ToolPathTmp, ToolOption)\r
- return ToolPathTmp, ToolOption\r
-\r
\r
\r