--- /dev/null
+/*++\r
+\r
+Copyright (c) 2004 - 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+ \r
+ GenCRC32Section.c\r
+\r
+Abstract:\r
+\r
+ This file contains functions required to generate a Firmware File System \r
+ file. The code is compliant with the Tiano C Coding standards.\r
+\r
+--*/\r
+\r
+#include "TianoCommon.h"\r
+#include "EfiFirmwareFileSystem.h"\r
+#include "EfiFirmwareVolumeHeader.h"\r
+#include "ParseInf.h"\r
+#include "crc32.h"\r
+#include "EfiUtilityMsgs.h"\r
+#include "GenCRC32Section.h"\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <assert.h>\r
+#include "CommonLib.h"\r
+\r
+#include EFI_PROTOCOL_DEFINITION (GuidedSectionExtraction)\r
+\r
+#define TOOLVERSION "0.2"\r
+\r
+#define UTILITY_NAME "GenCrc32Section"\r
+\r
+EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;\r
+\r
+EFI_STATUS\r
+SignSectionWithCrc32 (\r
+ IN OUT UINT8 *FileBuffer,\r
+ IN OUT UINT32 *BufferSize,\r
+ IN UINT32 DataSize\r
+ )\r
+/*++\r
+ \r
+Routine Description:\r
+ \r
+ Signs the section with CRC32 and add GUIDed section header for the \r
+ signed data. data stays in same location (overwrites source data).\r
+ \r
+Arguments:\r
+ \r
+ FileBuffer - Buffer containing data to sign\r
+ \r
+ BufferSize - On input, the size of FileBuffer. On output, the size of \r
+ actual section data (including added section header). \r
+\r
+ DataSize - Length of data to Sign\r
+\r
+ Key - Key to use when signing. Currently only CRC32 is supported.\r
+ \r
+Returns:\r
+ \r
+ EFI_SUCCESS - Successful\r
+ EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation.\r
+ \r
+--*/\r
+{\r
+\r
+ UINT32 Crc32Checksum;\r
+ EFI_STATUS Status;\r
+ UINT32 TotalSize;\r
+ CRC32_SECTION_HEADER Crc32Header;\r
+ UINT8 *SwapBuffer;\r
+\r
+ Crc32Checksum = 0;\r
+ SwapBuffer = NULL;\r
+\r
+ if (DataSize == 0) {\r
+ *BufferSize = 0;\r
+\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;\r
+ Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;\r
+ Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);\r
+ Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);\r
+ Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);\r
+ memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));\r
+ Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;\r
+ Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE;\r
+ Crc32Header.CRC32Checksum = Crc32Checksum;\r
+\r
+ SwapBuffer = (UINT8 *) malloc (DataSize);\r
+ if (SwapBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ memcpy (SwapBuffer, FileBuffer, DataSize);\r
+ memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);\r
+ memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);\r
+\r
+ //\r
+ // Make sure section ends on a DWORD boundary\r
+ //\r
+ while ((TotalSize & 0x03) != 0) {\r
+ FileBuffer[TotalSize] = 0;\r
+ TotalSize++;\r
+ }\r
+\r
+ *BufferSize = TotalSize;\r
+\r
+ if (SwapBuffer != NULL) {\r
+ free (SwapBuffer);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+VOID\r
+PrintUsage (\r
+ VOID\r
+ )\r
+{\r
+ printf ("Usage:\n");\r
+ printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n");\r
+ printf (" -i \"inputfile\":\n ");\r
+ printf (" specifies the input files that would be signed to CRC32 Guided section.\n");\r
+ printf (" -o \"outputfile\":\n");\r
+ printf (" specifies the output file that is a CRC32 Guided section.\n");\r
+}\r
+\r
+INT32\r
+ReadFilesContentsIntoBuffer (\r
+ IN CHAR8 *argv[],\r
+ IN INT32 Start,\r
+ IN OUT UINT8 **FileBuffer,\r
+ IN OUT UINT32 *BufferSize,\r
+ OUT UINT32 *ContentSize,\r
+ IN INT32 MaximumArguments\r
+ )\r
+{\r
+ INT32 Index;\r
+ CHAR8 *FileName;\r
+ FILE *InputFile;\r
+ UINT8 Temp;\r
+ UINT32 Size;\r
+\r
+ FileName = NULL;\r
+ InputFile = NULL;\r
+ Size = 0;\r
+ Index = 0;\r
+\r
+ //\r
+ // read all input files into one file buffer\r
+ //\r
+ while (argv[Start + Index][0] != '-') {\r
+\r
+ FileName = argv[Start + Index];\r
+ InputFile = fopen (FileName, "rb");\r
+ if (InputFile == NULL) {\r
+ Error (NULL, 0, 0, FileName, "failed to open input binary file");\r
+ return -1;\r
+ }\r
+\r
+ fread (&Temp, sizeof (UINT8), 1, InputFile);\r
+ while (!feof (InputFile)) {\r
+ (*FileBuffer)[Size++] = Temp;\r
+ fread (&Temp, sizeof (UINT8), 1, InputFile);\r
+ }\r
+\r
+ fclose (InputFile);\r
+ InputFile = NULL;\r
+\r
+ //\r
+ // Make sure section ends on a DWORD boundary\r
+ //\r
+ while ((Size & 0x03) != 0) {\r
+ (*FileBuffer)[Size] = 0;\r
+ Size++;\r
+ }\r
+\r
+ Index++;\r
+ if (Index == MaximumArguments) {\r
+ break;\r
+ }\r
+ }\r
+\r
+ *ContentSize = Size;\r
+ return Index;\r
+}\r
+\r
+INT32\r
+main (\r
+ INT32 argc,\r
+ CHAR8 *argv[]\r
+ )\r
+{\r
+ FILE *OutputFile;\r
+ UINT8 *FileBuffer;\r
+ UINT32 BufferSize;\r
+ EFI_STATUS Status;\r
+ UINT32 ContentSize;\r
+ CHAR8 *OutputFileName;\r
+ INT32 ReturnValue;\r
+ INT32 Index;\r
+\r
+ OutputFile = NULL;\r
+ FileBuffer = NULL;\r
+ ContentSize = 0;\r
+ OutputFileName = NULL;\r
+\r
+ SetUtilityName (UTILITY_NAME);\r
+\r
+ if (argc == 1) {\r
+ PrintUsage ();\r
+ return -1;\r
+ }\r
+\r
+ BufferSize = 1024 * 1024 * 16;\r
+ FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8));\r
+ if (FileBuffer == NULL) {\r
+ Error (NULL, 0, 0, "memory allocation failed", NULL);\r
+ return -1;\r
+ }\r
+\r
+ ZeroMem (FileBuffer, BufferSize);\r
+\r
+ for (Index = 0; Index < argc; Index++) {\r
+ if (_strcmpi (argv[Index], "-i") == 0) {\r
+ ReturnValue = ReadFilesContentsIntoBuffer (\r
+ argv,\r
+ (Index + 1),\r
+ &FileBuffer,\r
+ &BufferSize,\r
+ &ContentSize,\r
+ (argc - (Index + 1))\r
+ );\r
+ if (ReturnValue == -1) {\r
+ Error (NULL, 0, 0, "failed to read file contents", NULL);\r
+ return -1;\r
+ }\r
+\r
+ Index += ReturnValue;\r
+ }\r
+\r
+ if (_strcmpi (argv[Index], "-o") == 0) {\r
+ OutputFileName = argv[Index + 1];\r
+ }\r
+ }\r
+\r
+ OutputFile = fopen (OutputFileName, "wb");\r
+ if (OutputFile == NULL) {\r
+ Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");\r
+ free (FileBuffer);\r
+ return -1;\r
+ }\r
+\r
+ /* \r
+ //\r
+ // make sure section ends on a DWORD boundary ??\r
+ //\r
+ while ( (Size & 0x03) != 0 ) {\r
+ FileBuffer[Size] = 0;\r
+ Size ++;\r
+ }\r
+*/\r
+ Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 0, "failed to sign section", NULL);\r
+ free (FileBuffer);\r
+ fclose (OutputFile);\r
+ return -1;\r
+ }\r
+\r
+ ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);\r
+ if (ContentSize != BufferSize) {\r
+ Error (NULL, 0, 0, "failed to write output buffer", NULL);\r
+ ReturnValue = -1;\r
+ } else {\r
+ ReturnValue = 0;\r
+ }\r
+\r
+ free (FileBuffer);\r
+ fclose (OutputFile);\r
+ return ReturnValue;\r
+}\r