| /*++ | |
| Copyright (c) 2004-2007, 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 UTILITY_NAME "GenCrc32Section" | |
| #define UTILITY_MAJOR_VERSION 0 | |
| #define UTILITY_MINOR_VERSION 2 | |
| 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 | |
| Version ( | |
| VOID | |
| ) | |
| /*++ | |
| Routine Description: | |
| Displays the standard utility information to SDTOUT | |
| Arguments: | |
| None | |
| Returns: | |
| None | |
| --*/ | |
| { | |
| printf ( | |
| "%s v%d.%d -Utility for generating Firmware File System files.\n", | |
| UTILITY_NAME, | |
| UTILITY_MAJOR_VERSION, | |
| UTILITY_MINOR_VERSION | |
| ); | |
| } | |
| VOID | |
| Usage ( | |
| VOID | |
| ) | |
| { | |
| Version(); | |
| printf ("\nUsage:\n"); | |
| printf (UTILITY_NAME " -i Inputfile1 Inputfile2 -o Outputfile\n"); | |
| printf (" -i Inputfile: specifies the input files signed to CRC32 Guided section.\n"); | |
| printf (" -o Outputfile: 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) { | |
| Usage (); | |
| return -1; | |
| } | |
| if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0) || | |
| (strcmp(argv[1], "-?") == 0) || (strcmp(argv[1], "/?") == 0)) { | |
| Usage(); | |
| return -1; | |
| } | |
| if ((strcmp(argv[1], "-V") == 0) || (strcmp(argv[1], "--version") == 0)) { | |
| Version(); | |
| 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; | |
| } |