git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1676 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			287 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			287 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| Copyright (c) 2004, Intel Corporation                                                         
 | |
| All rights reserved. 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                                            
 | |
|                                                                                           
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
 | |
| 
 | |
| Module Name:
 | |
|   
 | |
|     GenCRC32Section.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   This file contains functions required to generate a Firmware File System 
 | |
|   file. The code is compliant with the Tiano C Coding standards.
 | |
| 
 | |
| --*/
 | |
| 
 | |
| #include "GenCRC32Section.h"
 | |
| 
 | |
| #define TOOLVERSION   "0.2"
 | |
| 
 | |
| #define UTILITY_NAME  "GenCrc32Section"
 | |
| 
 | |
| EFI_GUID  gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
 | |
| 
 | |
| EFI_STATUS
 | |
| SignSectionWithCrc32 (
 | |
|   IN OUT UINT8  *FileBuffer,
 | |
|   IN OUT UINT32 *BufferSize,
 | |
|   IN UINT32     DataSize
 | |
|   )
 | |
| /*++
 | |
|         
 | |
| Routine Description:
 | |
|            
 | |
|   Signs the section with CRC32 and add GUIDed section header for the 
 | |
|   signed data. data stays in same location (overwrites source data).
 | |
|             
 | |
| Arguments:
 | |
|                
 | |
|   FileBuffer  - Buffer containing data to sign
 | |
|                 
 | |
|   BufferSize  - On input, the size of FileBuffer. On output, the size of 
 | |
|                 actual section data (including added section header).              
 | |
| 
 | |
|   DataSize    - Length of data to Sign
 | |
| 
 | |
|   Key         - Key to use when signing. Currently only CRC32 is supported.
 | |
|                                        
 | |
| Returns:
 | |
|                        
 | |
|   EFI_SUCCESS           - Successful
 | |
|   EFI_OUT_OF_RESOURCES  - Not enough resource to complete the operation.
 | |
|                         
 | |
| --*/
 | |
| {
 | |
| 
 | |
|   UINT32                Crc32Checksum;
 | |
|   EFI_STATUS            Status;
 | |
|   UINT32                TotalSize;
 | |
|   CRC32_SECTION_HEADER  Crc32Header;
 | |
|   UINT8                 *SwapBuffer;
 | |
| 
 | |
|   Crc32Checksum = 0;
 | |
|   SwapBuffer    = NULL;
 | |
| 
 | |
|   if (DataSize == 0) {
 | |
|     *BufferSize = 0;
 | |
| 
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;
 | |
|   Crc32Header.GuidSectionHeader.CommonHeader.Type     = EFI_SECTION_GUID_DEFINED;
 | |
|   Crc32Header.GuidSectionHeader.CommonHeader.Size[0]  = (UINT8) (TotalSize & 0xff);
 | |
|   Crc32Header.GuidSectionHeader.CommonHeader.Size[1]  = (UINT8) ((TotalSize & 0xff00) >> 8);
 | |
|   Crc32Header.GuidSectionHeader.CommonHeader.Size[2]  = (UINT8) ((TotalSize & 0xff0000) >> 16);
 | |
|   memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));
 | |
|   Crc32Header.GuidSectionHeader.Attributes  = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
 | |
|   Crc32Header.GuidSectionHeader.DataOffset  = CRC32_SECTION_HEADER_SIZE;
 | |
|   Crc32Header.CRC32Checksum                 = Crc32Checksum;
 | |
| 
 | |
|   SwapBuffer = (UINT8 *) malloc (DataSize);
 | |
|   if (SwapBuffer == NULL) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   memcpy (SwapBuffer, FileBuffer, DataSize);
 | |
|   memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);
 | |
|   memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);
 | |
| 
 | |
|   //
 | |
|   // Make sure section ends on a DWORD boundary
 | |
|   //
 | |
|   while ((TotalSize & 0x03) != 0) {
 | |
|     FileBuffer[TotalSize] = 0;
 | |
|     TotalSize++;
 | |
|   }
 | |
| 
 | |
|   *BufferSize = TotalSize;
 | |
| 
 | |
|   if (SwapBuffer != NULL) {
 | |
|     free (SwapBuffer);
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| PrintUsage (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   printf ("Usage:\n");
 | |
|   printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n");
 | |
|   printf ("   -i \"inputfile\":\n ");
 | |
|   printf ("       specifies the input files that would be signed to CRC32 Guided section.\n");
 | |
|   printf ("   -o \"outputfile\":\n");
 | |
|   printf ("       specifies the output file that is a CRC32 Guided section.\n");
 | |
| }
 | |
| 
 | |
| INT32
 | |
| ReadFilesContentsIntoBuffer (
 | |
|   IN      CHAR8   *argv[],
 | |
|   IN      INT32   Start,
 | |
|   IN OUT  UINT8   **FileBuffer,
 | |
|   IN OUT  UINT32  *BufferSize,
 | |
|   OUT     UINT32  *ContentSize,
 | |
|   IN      INT32   MaximumArguments
 | |
|   )
 | |
| {
 | |
|   INT32   Index;
 | |
|   CHAR8   *FileName;
 | |
|   FILE    *InputFile;
 | |
|   UINT8   Temp;
 | |
|   UINT32  Size;
 | |
| 
 | |
|   FileName  = NULL;
 | |
|   InputFile = NULL;
 | |
|   Size      = 0;
 | |
|   Index     = 0;
 | |
| 
 | |
|   //
 | |
|   // read all input files into one file buffer
 | |
|   //
 | |
|   while (argv[Start + Index][0] != '-') {
 | |
| 
 | |
|     FileName  = argv[Start + Index];
 | |
|     InputFile = fopen (FileName, "rb");
 | |
|     if (InputFile == NULL) {
 | |
|       Error (NULL, 0, 0, FileName, "failed to open input binary file");
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|     fread (&Temp, sizeof (UINT8), 1, InputFile);
 | |
|     while (!feof (InputFile)) {
 | |
|       (*FileBuffer)[Size++] = Temp;
 | |
|       fread (&Temp, sizeof (UINT8), 1, InputFile);
 | |
|     }
 | |
| 
 | |
|     fclose (InputFile);
 | |
|     InputFile = NULL;
 | |
| 
 | |
|     //
 | |
|     // Make sure section ends on a DWORD boundary
 | |
|     //
 | |
|     while ((Size & 0x03) != 0) {
 | |
|       (*FileBuffer)[Size] = 0;
 | |
|       Size++;
 | |
|     }
 | |
| 
 | |
|     Index++;
 | |
|     if (Index == MaximumArguments) {
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   *ContentSize = Size;
 | |
|   return Index;
 | |
| }
 | |
| 
 | |
| int
 | |
| main (
 | |
|   INT32 argc,
 | |
|   CHAR8 *argv[]
 | |
|   )
 | |
| {
 | |
|   FILE        *OutputFile;
 | |
|   UINT8       *FileBuffer;
 | |
|   UINT32      BufferSize;
 | |
|   EFI_STATUS  Status;
 | |
|   UINT32      ContentSize;
 | |
|   CHAR8       *OutputFileName;
 | |
|   INT32       ReturnValue;
 | |
|   INT32       Index;
 | |
| 
 | |
|   OutputFile      = NULL;
 | |
|   FileBuffer      = NULL;
 | |
|   ContentSize     = 0;
 | |
|   OutputFileName  = NULL;
 | |
| 
 | |
|   SetUtilityName (UTILITY_NAME);
 | |
| 
 | |
|   if (argc == 1) {
 | |
|     PrintUsage ();
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   BufferSize  = 1024 * 1024 * 16;
 | |
|   FileBuffer  = (UINT8 *) malloc (BufferSize * sizeof (UINT8));
 | |
|   if (FileBuffer == NULL) {
 | |
|     Error (NULL, 0, 0, "memory allocation failed", NULL);
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   ZeroMem (FileBuffer, BufferSize);
 | |
| 
 | |
|   for (Index = 0; Index < argc; Index++) {
 | |
|     if (strcmpi (argv[Index], "-i") == 0) {
 | |
|       ReturnValue = ReadFilesContentsIntoBuffer (
 | |
|                       argv,
 | |
|                       (Index + 1),
 | |
|                       &FileBuffer,
 | |
|                       &BufferSize,
 | |
|                       &ContentSize,
 | |
|                       (argc - (Index + 1))
 | |
|                       );
 | |
|       if (ReturnValue == -1) {
 | |
|         Error (NULL, 0, 0, "failed to read file contents", NULL);
 | |
|         return -1;
 | |
|       }
 | |
| 
 | |
|       Index += ReturnValue;
 | |
|     }
 | |
| 
 | |
|     if (strcmpi (argv[Index], "-o") == 0) {
 | |
|       OutputFileName = argv[Index + 1];
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   OutputFile = fopen (OutputFileName, "wb");
 | |
|   if (OutputFile == NULL) {
 | |
|     Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");
 | |
|     free (FileBuffer);
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   /*  
 | |
|   //
 | |
|   // make sure section ends on a DWORD boundary ??
 | |
|   //
 | |
|   while ( (Size & 0x03) != 0 ) {
 | |
|     FileBuffer[Size] = 0;
 | |
|     Size ++;
 | |
|   }
 | |
| */
 | |
|   Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     Error (NULL, 0, 0, "failed to sign section", NULL);
 | |
|     free (FileBuffer);
 | |
|     fclose (OutputFile);
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);
 | |
|   if (ContentSize != BufferSize) {
 | |
|     Error (NULL, 0, 0, "failed to write output buffer", NULL);
 | |
|     ReturnValue = -1;
 | |
|   } else {
 | |
|     ReturnValue = 0;
 | |
|   }
 | |
| 
 | |
|   free (FileBuffer);
 | |
|   fclose (OutputFile);
 | |
|   return ReturnValue;
 | |
| }
 |