]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/GenCRC32Section.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenCRC32Section / GenCRC32Section.c
diff --git a/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/GenCRC32Section.c b/EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/GenCRC32Section.c
new file mode 100644 (file)
index 0000000..27a02a4
--- /dev/null
@@ -0,0 +1,299 @@
+/*++\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