public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Yonghong Zhu <yonghong.zhu@intel.com>
To: edk2-devel@lists.01.org
Cc: Liming Gao <liming.gao@intel.com>
Subject: [Patch 3/3] BaseTools: FMP capsule add the support to generate auth info
Date: Mon, 15 Aug 2016 16:17:39 +0800	[thread overview]
Message-ID: <1471249059-95652-4-git-send-email-yonghong.zhu@intel.com> (raw)
In-Reply-To: <1471249059-95652-1-git-send-email-yonghong.zhu@intel.com>

Current BaseTools cannot generate EFI_FIRMWARE_IMAGE_AUTHENTICATION
for FMP capsule. this patch fix it by FDF spec's update to add the
definition for CERTIFICATE_GUID and  MONOTONIC_COUNT. BaseTools call
the tool by CERTIFICATE_GUID to generate the certdata and fill the header
info.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
---
 BaseTools/Source/Python/GenFds/Capsule.py     | 80 +++++++++++++++++++++++++--
 BaseTools/Source/Python/GenFds/CapsuleData.py |  4 +-
 BaseTools/Source/Python/GenFds/FdfParser.py   | 64 ++++++++++++++++++---
 BaseTools/Source/Python/GenFds/GenFds.py      | 59 +++++++++++++++++++-
 BaseTools/Source/Python/GenFds/GuidSection.py | 59 +-------------------
 5 files changed, 194 insertions(+), 72 deletions(-)

diff --git a/BaseTools/Source/Python/GenFds/Capsule.py b/BaseTools/Source/Python/GenFds/Capsule.py
index 1683433..f8af12a 100644
--- a/BaseTools/Source/Python/GenFds/Capsule.py
+++ b/BaseTools/Source/Python/GenFds/Capsule.py
@@ -1,9 +1,9 @@
 ## @file
 # generate capsule
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -23,13 +23,20 @@ import StringIO
 from Common.Misc import SaveFileOnChange
 from GenFds import GenFds
 from Common.Misc import PackRegistryFormatGuid
 import uuid
 from struct import pack
+from GenFds import FindExtendTool
+from Common import EdkLogger
+from Common.BuildToolError import *
 
 
 T_CHAR_LF = '\n'
+WIN_CERT_REVISION      = 0x0200
+WIN_CERT_TYPE_EFI_GUID = 0x0EF1
+EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}')
+EFI_CERT_TYPE_RSA2048_SHA256_GUID = uuid.UUID('{a7717414-c616-4977-9420-844712a735bf}')
 
 ## create inf file describes what goes into capsule and call GenFv to generate capsule
 #
 #
 class Capsule (CapsuleClassObject) :
@@ -96,24 +103,87 @@ class Capsule (CapsuleClassObject) :
         else:
             FwMgrHdr.write(pack('=I', 0x00000001))
         FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList)))
         FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList))
 
+        #
+        # typedef struct _WIN_CERTIFICATE {
+        #   UINT32 dwLength;
+        #   UINT16 wRevision;
+        #   UINT16 wCertificateType;
+        # //UINT8 bCertificate[ANYSIZE_ARRAY];
+        # } WIN_CERTIFICATE;
+        #
+        # typedef struct _WIN_CERTIFICATE_UEFI_GUID {
+        #   WIN_CERTIFICATE Hdr;
+        #   EFI_GUID        CertType;
+        # //UINT8 CertData[ANYSIZE_ARRAY];
+        # } WIN_CERTIFICATE_UEFI_GUID;
+        #
+        # typedef struct {
+        #   UINT64                    MonotonicCount;
+        #   WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+        # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
+        #
+        # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
+        #   EFI_GUID HashType;
+        #   UINT8 PublicKey[256];
+        #   UINT8 Signature[256];
+        # } EFI_CERT_BLOCK_RSA_2048_SHA256;
+        #
+
         PreSize = FwMgrHdrSize
         Content = StringIO.StringIO()
         for driver in self.CapsuleDataList:
             FileName = driver.GenCapsuleSubItem()
             FwMgrHdr.write(pack('=Q', PreSize))
             PreSize += os.path.getsize(FileName)
             File = open(FileName, 'rb')
             Content.write(File.read())
             File.close()
         for fmp in self.FmpPayloadList:
-            payload = fmp.GenCapsuleSubItem()
-            FwMgrHdr.write(pack('=Q', PreSize))
-            PreSize += len(payload)
-            Content.write(payload)
+            if fmp.Certificate_Guid:
+                ExternalTool, ExternalOption = FindExtendTool([], GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid)
+                CmdOption = ''
+                CapInputFile = fmp.ImageFile
+                if not os.path.isabs(fmp.ImageFile):
+                    CapInputFile = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, fmp.ImageFile)
+                CapOutputTmp = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.tmp'
+                if ExternalTool == None:
+                    EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % fmp.Certificate_Guid)
+                else:
+                    CmdOption += ExternalTool
+                if ExternalOption:
+                    CmdOption = CmdOption + ' ' + ExternalOption
+                CmdOption += ' -e ' + ' --monotonic-count ' + str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile
+                CmdList = CmdOption.split()
+                GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed to generate FMP auth capsule")
+                if uuid.UUID(fmp.Certificate_Guid) == EFI_CERT_TYPE_PKCS7_GUID:
+                    dwLength = 4 + 2 + 2 + 16 + os.path.getsize(CapOutputTmp) - os.path.getsize(CapInputFile)
+                else:
+                    dwLength = 4 + 2 + 2 + 16 + 16 + 256 + 256
+                Buffer  = pack('Q', fmp.MonotonicCount)
+                Buffer += pack('I', dwLength)
+                Buffer += pack('H', WIN_CERT_REVISION)
+                Buffer += pack('H', WIN_CERT_TYPE_EFI_GUID)
+                Buffer += uuid.UUID(fmp.Certificate_Guid).get_bytes_le()
+                if os.path.exists(CapOutputTmp):
+                    TmpFile = open(CapOutputTmp, 'rb')
+                    Buffer += TmpFile.read()
+                    TmpFile.close()
+                    if fmp.VendorCodeFile:
+                        VendorFile = open(fmp.VendorCodeFile, 'rb')
+                        Buffer += VendorFile.read()
+                        VendorFile.close()
+                    FwMgrHdr.write(pack('=Q', PreSize))
+                    PreSize += len(Buffer)
+                    Content.write(Buffer)
+            else:
+                payload = fmp.GenCapsuleSubItem()
+                FwMgrHdr.write(pack('=Q', PreSize))
+                PreSize += len(payload)
+                Content.write(payload)
         BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue())
         Header.write(pack('=I', HdrSize + BodySize))
         #
         # The real capsule header structure is 28 bytes
         #
diff --git a/BaseTools/Source/Python/GenFds/CapsuleData.py b/BaseTools/Source/Python/GenFds/CapsuleData.py
index efc2812..2a5c454 100644
--- a/BaseTools/Source/Python/GenFds/CapsuleData.py
+++ b/BaseTools/Source/Python/GenFds/CapsuleData.py
@@ -1,9 +1,9 @@
 ## @file
 # generate capsule
 #
-#  Copyright (c) 2007-2013, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007-2016, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD License
 #  which accompanies this distribution.  The full text of the license may be found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -178,10 +178,12 @@ class CapsulePayload(CapsuleData):
         self.ImageTypeId = None
         self.ImageIndex = None
         self.HardwareInstance = None
         self.ImageFile = None
         self.VendorCodeFile = None
+        self.Certificate_Guid = None
+        self.MonotonicCount = None
 
     def GenCapsuleSubItem(self):
         if not self.Version:
             self.Version = 0x00000002
         ImageFileSize = os.path.getsize(self.ImageFile)
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 8709cfc..02ae7c9 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -50,15 +50,17 @@ from Common.Misc import PathClass
 from Common.String import NormPath
 import Common.GlobalData as GlobalData
 from Common.Expression import *
 from Common import GlobalData
 from Common.String import ReplaceMacro
-
+import uuid
 from Common.Misc import tdict
 
 import Common.LongFilePathOs as os
 from Common.LongFilePathSupport import OpenLongFilePath as open
+from Capsule import EFI_CERT_TYPE_PKCS7_GUID
+from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID
 
 ##define T_CHAR_SPACE                ' '
 ##define T_CHAR_NULL                 '\0'
 ##define T_CHAR_CR                   '\r'
 ##define T_CHAR_TAB                  '\t'
@@ -1122,10 +1124,30 @@ class FdfParser:
             return True
         else:
             self.__UndoToken()
             return False
 
+    def __Verify(self, Name, Value, Scope):
+        if Scope in ['UINT64', 'UINT8']:
+            ValueNumber = 0
+            try:
+                if Value.upper().startswith('0X'):
+                    ValueNumber = int (Value, 16)
+                else:
+                    ValueNumber = int (Value)
+            except:
+                EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)
+            if ValueNumber < 0:
+                EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)
+            if Scope == 'UINT64':
+                if ValueNumber >= 0x10000000000000000:
+                    EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
+            if Scope == 'UINT8':
+                if ValueNumber >= 0x100:
+                    EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
+            return True
+
     ## __UndoToken() method
     #
     #   Go back one token unit in file buffer
     #
     #   @param  self        The object pointer
@@ -3185,44 +3207,70 @@ class FdfParser:
         if not self.__IsToken( "]"):
             raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
 
         if not self.__GetNextToken():
             raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
-        FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
+        FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
         while self.__Token in FmpKeyList:
             Name = self.__Token
             FmpKeyList.remove(Name)
             if not self.__IsToken("="):
                 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
             if Name == 'IMAGE_TYPE_ID':
                 if not self.__GetNextGuid():
-                    raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)
+                    raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)
                 FmpData.ImageTypeId = self.__Token
+            elif Name == 'CERTIFICATE_GUID':
+                if not self.__GetNextGuid():
+                    raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
+                FmpData.Certificate_Guid = self.__Token
+                if uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:
+                    raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
             else:
                 if not self.__GetNextToken():
                     raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)
                 Value = self.__Token
                 if Name == 'IMAGE_HEADER_INIT_VERSION':
-                    FmpData.Version = Value
+                    if self.__Verify(Name, Value, 'UINT8'):
+                        FmpData.Version = Value
                 elif Name == 'IMAGE_INDEX':
-                    FmpData.ImageIndex = Value
+                    if self.__Verify(Name, Value, 'UINT8'):
+                        FmpData.ImageIndex = Value
                 elif Name == 'HARDWARE_INSTANCE':
-                    FmpData.HardwareInstance = Value
+                    if self.__Verify(Name, Value, 'UINT8'):
+                        FmpData.HardwareInstance = Value
+                elif Name == 'MONOTONIC_COUNT':
+                    if self.__Verify(Name, Value, 'UINT64'):
+                        FmpData.MonotonicCount = Value
+                        if FmpData.MonotonicCount.upper().startswith('0X'):
+                            FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)
+                        else:
+                            FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)
             if not self.__GetNextToken():
                 break
         else:
             self.__UndoToken()
 
+        if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):
+            EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
+        # remove CERTIFICATE_GUID and MONOTONIC_COUNT from FmpKeyList, since these keys are optional
+        if 'CERTIFICATE_GUID' in FmpKeyList:
+            FmpKeyList.remove('CERTIFICATE_GUID')
+        if 'MONOTONIC_COUNT' in FmpKeyList:
+            FmpKeyList.remove('MONOTONIC_COUNT')
         if FmpKeyList:
-            raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
+            raise Warning("Missing keywords %s in FMP payload section." % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
         ImageFile = self.__ParseRawFileStatement()
         if not ImageFile:
-            raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)
+            raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)
         FmpData.ImageFile = ImageFile
         VendorCodeFile = self.__ParseRawFileStatement()
         if VendorCodeFile:
             FmpData.VendorCodeFile = VendorCodeFile
+        AdditionalFile = self.__ParseRawFileStatement()
+        if AdditionalFile:
+            raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber)
         self.Profile.FmpPayloadDict[FmpUiName] = FmpData
         return True
 
     ## __GetCapsule() method
     #
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 68232c5..1a0ec7a 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -410,11 +410,68 @@ def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Val
             Value = '1'
         elif Value == 'FALSE' or Value == '0':
             Value = '0'
     return  Value
 
-        
+## FindExtendTool()
+#
+#  Find location of tools to process data
+#
+#  @param  KeyStringList    Filter for inputs of section generation
+#  @param  CurrentArchList  Arch list
+#  @param  NameGuid         The Guid name
+#
+def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
+    # if user not specify filter, try to deduce it from global data.
+    if KeyStringList == None or KeyStringList == []:
+        Target = GenFdsGlobalVariable.TargetName
+        ToolChain = GenFdsGlobalVariable.ToolChainTag
+        ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase
+        if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
+            EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
+        KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]
+        for Arch in CurrentArchList:
+            if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
+                KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)
+
+    if GenFdsGlobalVariable.GuidToolDefinition:
+        if NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():
+            return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]
+
+    ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary
+    ToolPathTmp = None
+    ToolOption = None
+    for ToolDef in ToolDefinition.items():
+        if NameGuid == ToolDef[1]:
+            KeyList = ToolDef[0].split('_')
+            Key = KeyList[0] + \
+                  '_' + \
+                  KeyList[1] + \
+                  '_' + \
+                  KeyList[2]
+            if Key in KeyStringList and KeyList[4] == 'GUID':
+
+                ToolPath = ToolDefinition.get(Key + \
+                                               '_' + \
+                                               KeyList[3] + \
+                                               '_' + \
+                                               'PATH')
+
+                ToolOption = ToolDefinition.get(Key + \
+                                                '_' + \
+                                                KeyList[3] + \
+                                                '_' + \
+                                                'FLAGS')
+                if ToolPathTmp == None:
+                    ToolPathTmp = ToolPath
+                else:
+                    if ToolPathTmp != ToolPath:
+                        EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))
+
+    GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
+    return ToolPathTmp, ToolOption
+
 ## Parse command line options
 #
 # Using standard Python module optparse to parse command line option of this tool.
 #
 #   @retval Opt   A optparse.Values object containing the parsed options
diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py
index ac5ae58..f199dcd 100644
--- a/BaseTools/Source/Python/GenFds/GuidSection.py
+++ b/BaseTools/Source/Python/GenFds/GuidSection.py
@@ -25,10 +25,11 @@ from Common import ToolDefClassObject
 import sys
 from Common import EdkLogger
 from Common.BuildToolError import *
 from FvImageSection import FvImageSection
 from Common.LongFilePathSupport import OpenLongFilePath as open
+from GenFds import FindExtendTool
 
 ## generate GUIDed section
 #
 #
 class GuidSection(GuidSectionClassObject) :
@@ -126,11 +127,11 @@ class GuidSection(GuidSectionClassObject) :
         OutputFile = os.path.normpath(OutputFile)
 
         ExternalTool = None
         ExternalOption = None
         if self.NameGuid != None:
-            ExternalTool, ExternalOption = self.__FindExtendTool__()
+            ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)
 
         #
         # If not have GUID , call default
         # GENCRC32 section
         #
@@ -247,63 +248,7 @@ class GuidSection(GuidSectionClassObject) :
                 self.Alignment = None
                 self.IncludeFvSection = False
                 self.ProcessRequired = "TRUE"
             return OutputFileList, self.Alignment
 
-    ## __FindExtendTool()
-    #
-    #    Find location of tools to process section data
-    #
-    #   @param  self        The object pointer
-    #
-    def __FindExtendTool__(self):
-        # if user not specify filter, try to deduce it from global data.
-        if self.KeyStringList == None or self.KeyStringList == []:
-            Target = GenFdsGlobalVariable.TargetName
-            ToolChain = GenFdsGlobalVariable.ToolChainTag
-            ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase
-            if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
-                EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
-            self.KeyStringList = [Target + '_' + ToolChain + '_' + self.CurrentArchList[0]]
-            for Arch in self.CurrentArchList:
-                if Target + '_' + ToolChain + '_' + Arch not in self.KeyStringList:
-                    self.KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)
-
-        if GenFdsGlobalVariable.GuidToolDefinition:
-            if self.NameGuid in GenFdsGlobalVariable.GuidToolDefinition.keys():
-                return GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid]
-
-        ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary
-        ToolPathTmp = None
-        ToolOption = None
-        for ToolDef in ToolDefinition.items():
-            if self.NameGuid == ToolDef[1]:
-                KeyList = ToolDef[0].split('_')
-                Key = KeyList[0] + \
-                      '_' + \
-                      KeyList[1] + \
-                      '_' + \
-                      KeyList[2]
-                if Key in self.KeyStringList and KeyList[4] == 'GUID':
-
-                    ToolPath = ToolDefinition.get(Key + \
-                                                   '_' + \
-                                                   KeyList[3] + \
-                                                   '_' + \
-                                                   'PATH')
-
-                    ToolOption = ToolDefinition.get(Key + \
-                                                    '_' + \
-                                                    KeyList[3] + \
-                                                    '_' + \
-                                                    'FLAGS')
-                    if ToolPathTmp == None:
-                        ToolPathTmp = ToolPath
-                    else:
-                        if ToolPathTmp != ToolPath:
-                            EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath))
-
-        GenFdsGlobalVariable.GuidToolDefinition[self.NameGuid] = (ToolPathTmp, ToolOption)
-        return ToolPathTmp, ToolOption
-
 
 
-- 
2.6.1.windows.1



  parent reply	other threads:[~2016-08-15  8:18 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-15  8:17 [Patch 0/3] BaseTools: Add the support for FMP capsule generate auth info Yonghong Zhu
2016-08-15  8:17 ` [Patch 1/3] BaseTools: Add the PKCS7 tool Yonghong Zhu
2016-08-15  8:32   ` Yao, Jiewen
2016-08-15  8:34     ` Zhu, Yonghong
2016-08-15  8:17 ` [Patch 2/3] BaseTools: Rsa2048Sha256Sign add new option to support Monotonic count Yonghong Zhu
2016-08-19  5:41   ` Gao, Liming
2016-08-15  8:17 ` Yonghong Zhu [this message]
2016-08-19  5:41   ` [Patch 3/3] BaseTools: FMP capsule add the support to generate auth info Gao, Liming

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1471249059-95652-4-git-send-email-yonghong.zhu@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox