signimage.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:7k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. //
  2. // Copyright (c) Microsoft Corporation.  All rights reserved.
  3. //
  4. //
  5. // Use of this source code is subject to the terms of the Microsoft end-user
  6. // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
  7. // If you did not accept the terms of the EULA, you are not authorized to use
  8. // this source code. For a copy of the EULA, please see the LICENSE.RTF on your
  9. // install media.
  10. //
  11. /*++
  12. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  13. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  14. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  15. PARTICULAR PURPOSE.
  16. Module Name:  
  17.     signimage.c
  18.     
  19. Abstract:  
  20.         
  21. Functions:
  22. Notes: 
  23. --*/
  24. #include <windows.h>
  25. #include <halether.h>
  26. #include <minasn1.h>
  27. #include <mincrypt.h>
  28. #include <traverse.h>
  29. // Matches BIB file EXTENSION area (note BIB file names are forced to lower case).
  30. const unsigned char WHQLSigExtName[] = "whql_sig";
  31. // Secure loader globals
  32. extern DWORD g_dwROMOffset;
  33. DWORD g_hHash;
  34. BYTE rgbOID_Attr[] =
  35. //OID (1.3.6.1.4.1.311.12.2.1) has the following encoding:
  36. // "1.3.6.1.4.1.311.12.2.1"
  37. {0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0C, 0x02, 0x01};
  38. BYTE  rgbManufacturerTag[] = 
  39. //"Manufacturer" as a BMP string
  40. { 0x00, 0x4D, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x75, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 
  41. 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x72};
  42. BYTE  rgbModelTag[] = 
  43. //"Model" as a BMP string
  44. {0x00, 0x4D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6C};
  45. BOOL UpdateHash(DWORD dwAddr, DWORD dwSize)
  46. {
  47.     CRYPT_DER_BLOB ScratchBlob;
  48.     ScratchBlob.cbData = dwSize;
  49.     ScratchBlob.pbData = (BYTE *)dwAddr;
  50.     if (MinCryptUpdateHashMemory(CALG_SHA1, g_hHash, 1, &ScratchBlob))
  51.     {
  52.         return(FALSE);
  53.     }
  54.     return(TRUE);
  55. }
  56. BOOL CheckSignature(DWORD dwStoreBase, DWORD dwRunBase, BOOL fTestSignature,
  57.                     OPTIONAL IN BYTE* pbDeviceMakeData, OPTIONAL IN DWORD dwDeviceMakeSize,
  58.                     OPTIONAL IN BYTE* pbDeviceModelData, OPTIONAL IN DWORD dwDeviceModelSize)
  59. {
  60. #define REBASE_ADDR(x)   (x + (dwStoreBase - dwRunBase))
  61.     DWORD dwpTOC = 0;
  62.     ROMHDR *pROMHdr = NULL;
  63.     EXTENSION *pExt = NULL;
  64.     BYTE *pSig = NULL;
  65.     DWORD dwSigLen = 0;
  66.     DWORD cbHash = 0;
  67.     DWORD cbAttr = 0;
  68.     LONG rglErr = 0;
  69.     LONG lStatus = 0;
  70.     BYTE rgbHash[MINCRYPT_MAX_HASH_LEN];
  71.     CRYPT_HASH_BLOB rgHashBlob;
  72.     MAP_CAT_INFO rgMapCatInfo;
  73.     CRYPT_DATA_BLOB rgExtensionTagName;
  74.     CRYPT_DATA_BLOB rgExtensionValue;
  75.     CRYPT_DATA_BLOB rgAttrEncodedOIDBlob;
  76.     // Check for TOC signature.
  77.     //
  78.     if (*(LPDWORD)(dwStoreBase + ROM_SIGNATURE_OFFSET) != ROM_SIGNATURE)
  79.     {
  80.         EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rn");
  81.         EdbgOutputDebugString ("! ERROR: Did not find pTOC signature.  ABORTING. !rn");
  82.         EdbgOutputDebugString ("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!rn");
  83.         return(FALSE);
  84.     }
  85.     // Get pointer to TOC.
  86.     //
  87.     dwpTOC = *(LPDWORD)(dwStoreBase + ROM_SIGNATURE_OFFSET + sizeof(ULONG));
  88.     // Locate the WHQL signature record via the ROMHDR extension pointer.
  89.     //
  90.     pROMHdr = (ROMHDR *)REBASE_ADDR(dwpTOC);
  91.     if (!pROMHdr->pExtensions)
  92.     {
  93.         EdbgOutputDebugString("ERROR: No extensions list (NULL pointer).rn");
  94.         return(FALSE);
  95.     }
  96.     pExt = (EXTENSION *)REBASE_ADDR((DWORD)pROMHdr->pExtensions);
  97.     while(pExt && memcmp(pExt->name, WHQLSigExtName, strlen(WHQLSigExtName)))
  98.     {
  99.         if (!pExt->pNextExt)
  100.         {
  101.             pExt = NULL;
  102.             break;
  103.         }
  104.         pExt = (EXTENSION *)REBASE_ADDR((DWORD)pExt->pNextExt);
  105.     }
  106.     if (!pExt)
  107.     {
  108.         EdbgOutputDebugString("ERROR: No signature record in extensions list (an extension block hasn't been reserved in this image)?rn");
  109.         return(FALSE);
  110.     }
  111.     // Get location and length of the signature.
  112.     //
  113.     dwSigLen = pExt->length;
  114.     pSig     = (BYTE *)REBASE_ADDR((DWORD)pExt->pdata);
  115.     if (!dwSigLen)
  116.     {
  117.         EdbgOutputDebugString("ERROR: Signature length is zero.  Was this image stamped with a signature?rn");
  118.         return(FALSE);
  119.     }
  120.     
  121.     EdbgOutputDebugString("INFO: Found signature (Address=0x%x  Length=0x%x).rn", (DWORD)pSig, dwSigLen);
  122.     // Hash memory initialization.
  123.     //
  124.     MinCryptCreateHashMemory(CALG_SHA1, &g_hHash);
  125.     // Traverse the image and compute the hash.
  126.     //
  127.     if (!SigProcessImage((ROMHDR *)dwpTOC, (dwStoreBase - dwRunBase), UpdateHash))
  128.     {
  129.         return(FALSE);
  130.     }
  131.     // Finish computing the hash.
  132.     //
  133.     MinCryptGetHashParam(CALG_SHA1, g_hHash, rgbHash, &cbHash);
  134.     
  135.     rgHashBlob.cbData = cbHash;
  136.     rgHashBlob.pbData = rgbHash;
  137.     memset(&rgMapCatInfo, 0, sizeof(MAP_CAT_INFO));
  138.     
  139.     rgMapCatInfo.FileBlob.cbData = dwSigLen;
  140.     rgMapCatInfo.FileBlob.pbData = pSig;
  141.     rgAttrEncodedOIDBlob.cbData = sizeof(rgbOID_Attr);
  142.     rgAttrEncodedOIDBlob.pbData = rgbOID_Attr;
  143.     // Compute a CAT record for the hashed data and compare against the CAT record stamped in the image.
  144.     //
  145.     lStatus = MinCryptVerifyHashInCatalogBlob(CALG_SHA1, 1, &rgHashBlob, 1, &rgMapCatInfo, fTestSignature, &rglErr);
  146.     if (lStatus || rglErr)
  147.     {
  148.         EdbgOutputDebugString("ERROR: MinCryptVerifyHashInCatalogs returned 0x%x (rglErr=0x%x).rn", lStatus, rglErr);
  149.         return(FALSE);
  150.     }
  151.     // Optionally verify the Make attribute.    
  152.     if (pbDeviceMakeData && dwDeviceMakeSize)
  153.     {
  154.         // Now check the Make string
  155.         rgExtensionTagName.cbData = sizeof(rgbManufacturerTag);
  156.         rgExtensionTagName.pbData = rgbManufacturerTag;
  157.        
  158.         rgExtensionValue.cbData = dwDeviceMakeSize;
  159.         rgExtensionValue.pbData = pbDeviceMakeData;
  160.         
  161.         lStatus = MinCryptVerifyExtension(rgMapCatInfo, rgAttrEncodedOIDBlob, rgExtensionTagName, rgExtensionValue);
  162.         if (lStatus)
  163.         {
  164.             EdbgOutputDebugString("ERROR: MinCryptVerifyExtension failed to verify manufacturerrn");
  165.             return (FALSE);
  166.         }
  167.     }
  168.     
  169.     // Optionally verify the Model attribute.    
  170.     if (pbDeviceModelData && dwDeviceModelSize)
  171.     {
  172.         rgExtensionTagName.cbData = sizeof(rgbModelTag);
  173.         rgExtensionTagName.pbData = rgbModelTag;
  174.        
  175.         rgExtensionValue.cbData = dwDeviceModelSize;
  176.         rgExtensionValue.pbData = pbDeviceModelData;
  177.     
  178.         lStatus = MinCryptVerifyExtension(rgMapCatInfo, rgAttrEncodedOIDBlob, rgExtensionTagName, rgExtensionValue);
  179.         if (lStatus)
  180.         {
  181.             EdbgOutputDebugString("ERROR: MinCryptVerifyExtension failed to verify Modelrn");
  182.             return (FALSE);
  183.         }
  184.     }
  185.     EdbgOutputDebugString("INFO: Signature check passed!rn");
  186.     
  187.     return(TRUE);
  188. }