]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Sample/Tools/Source/GenCRC32Section/GenCRC32Section.c
Add in the 1st version of ECP.
[mirror_edk2.git] / EdkCompatibilityPkg / Sample / Tools / Source / GenCRC32Section / GenCRC32Section.c
1 /*++
2
3 Copyright (c) 2004 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 GenCRC32Section.c
15
16 Abstract:
17
18 This file contains functions required to generate a Firmware File System
19 file. The code is compliant with the Tiano C Coding standards.
20
21 --*/
22
23 #include "TianoCommon.h"
24 #include "EfiFirmwareFileSystem.h"
25 #include "EfiFirmwareVolumeHeader.h"
26 #include "ParseInf.h"
27 #include "crc32.h"
28 #include "EfiUtilityMsgs.h"
29 #include "GenCRC32Section.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34 #include "CommonLib.h"
35
36 #include EFI_PROTOCOL_DEFINITION (GuidedSectionExtraction)
37
38 #define TOOLVERSION "0.2"
39
40 #define UTILITY_NAME "GenCrc32Section"
41
42 EFI_GUID gEfiCrc32SectionGuid = EFI_CRC32_GUIDED_SECTION_EXTRACTION_PROTOCOL_GUID;
43
44 EFI_STATUS
45 SignSectionWithCrc32 (
46 IN OUT UINT8 *FileBuffer,
47 IN OUT UINT32 *BufferSize,
48 IN UINT32 DataSize
49 )
50 /*++
51
52 Routine Description:
53
54 Signs the section with CRC32 and add GUIDed section header for the
55 signed data. data stays in same location (overwrites source data).
56
57 Arguments:
58
59 FileBuffer - Buffer containing data to sign
60
61 BufferSize - On input, the size of FileBuffer. On output, the size of
62 actual section data (including added section header).
63
64 DataSize - Length of data to Sign
65
66 Key - Key to use when signing. Currently only CRC32 is supported.
67
68 Returns:
69
70 EFI_SUCCESS - Successful
71 EFI_OUT_OF_RESOURCES - Not enough resource to complete the operation.
72
73 --*/
74 {
75
76 UINT32 Crc32Checksum;
77 EFI_STATUS Status;
78 UINT32 TotalSize;
79 CRC32_SECTION_HEADER Crc32Header;
80 UINT8 *SwapBuffer;
81
82 Crc32Checksum = 0;
83 SwapBuffer = NULL;
84
85 if (DataSize == 0) {
86 *BufferSize = 0;
87
88 return EFI_SUCCESS;
89 }
90
91 Status = CalculateCrc32 (FileBuffer, DataSize, &Crc32Checksum);
92 if (EFI_ERROR (Status)) {
93 return Status;
94 }
95
96 TotalSize = DataSize + CRC32_SECTION_HEADER_SIZE;
97 Crc32Header.GuidSectionHeader.CommonHeader.Type = EFI_SECTION_GUID_DEFINED;
98 Crc32Header.GuidSectionHeader.CommonHeader.Size[0] = (UINT8) (TotalSize & 0xff);
99 Crc32Header.GuidSectionHeader.CommonHeader.Size[1] = (UINT8) ((TotalSize & 0xff00) >> 8);
100 Crc32Header.GuidSectionHeader.CommonHeader.Size[2] = (UINT8) ((TotalSize & 0xff0000) >> 16);
101 memcpy (&(Crc32Header.GuidSectionHeader.SectionDefinitionGuid), &gEfiCrc32SectionGuid, sizeof (EFI_GUID));
102 Crc32Header.GuidSectionHeader.Attributes = EFI_GUIDED_SECTION_AUTH_STATUS_VALID;
103 Crc32Header.GuidSectionHeader.DataOffset = CRC32_SECTION_HEADER_SIZE;
104 Crc32Header.CRC32Checksum = Crc32Checksum;
105
106 SwapBuffer = (UINT8 *) malloc (DataSize);
107 if (SwapBuffer == NULL) {
108 return EFI_OUT_OF_RESOURCES;
109 }
110
111 memcpy (SwapBuffer, FileBuffer, DataSize);
112 memcpy (FileBuffer, &Crc32Header, CRC32_SECTION_HEADER_SIZE);
113 memcpy (FileBuffer + CRC32_SECTION_HEADER_SIZE, SwapBuffer, DataSize);
114
115 //
116 // Make sure section ends on a DWORD boundary
117 //
118 while ((TotalSize & 0x03) != 0) {
119 FileBuffer[TotalSize] = 0;
120 TotalSize++;
121 }
122
123 *BufferSize = TotalSize;
124
125 if (SwapBuffer != NULL) {
126 free (SwapBuffer);
127 }
128
129 return EFI_SUCCESS;
130 }
131
132 VOID
133 PrintUsage (
134 VOID
135 )
136 {
137 printf ("Usage:\n");
138 printf (UTILITY_NAME " -i \"inputfile1\" \"inputfile2\" -o \"outputfile\" \n");
139 printf (" -i \"inputfile\":\n ");
140 printf (" specifies the input files that would be signed to CRC32 Guided section.\n");
141 printf (" -o \"outputfile\":\n");
142 printf (" specifies the output file that is a CRC32 Guided section.\n");
143 }
144
145 INT32
146 ReadFilesContentsIntoBuffer (
147 IN CHAR8 *argv[],
148 IN INT32 Start,
149 IN OUT UINT8 **FileBuffer,
150 IN OUT UINT32 *BufferSize,
151 OUT UINT32 *ContentSize,
152 IN INT32 MaximumArguments
153 )
154 {
155 INT32 Index;
156 CHAR8 *FileName;
157 FILE *InputFile;
158 UINT8 Temp;
159 UINT32 Size;
160
161 FileName = NULL;
162 InputFile = NULL;
163 Size = 0;
164 Index = 0;
165
166 //
167 // read all input files into one file buffer
168 //
169 while (argv[Start + Index][0] != '-') {
170
171 FileName = argv[Start + Index];
172 InputFile = fopen (FileName, "rb");
173 if (InputFile == NULL) {
174 Error (NULL, 0, 0, FileName, "failed to open input binary file");
175 return -1;
176 }
177
178 fread (&Temp, sizeof (UINT8), 1, InputFile);
179 while (!feof (InputFile)) {
180 (*FileBuffer)[Size++] = Temp;
181 fread (&Temp, sizeof (UINT8), 1, InputFile);
182 }
183
184 fclose (InputFile);
185 InputFile = NULL;
186
187 //
188 // Make sure section ends on a DWORD boundary
189 //
190 while ((Size & 0x03) != 0) {
191 (*FileBuffer)[Size] = 0;
192 Size++;
193 }
194
195 Index++;
196 if (Index == MaximumArguments) {
197 break;
198 }
199 }
200
201 *ContentSize = Size;
202 return Index;
203 }
204
205 INT32
206 main (
207 INT32 argc,
208 CHAR8 *argv[]
209 )
210 {
211 FILE *OutputFile;
212 UINT8 *FileBuffer;
213 UINT32 BufferSize;
214 EFI_STATUS Status;
215 UINT32 ContentSize;
216 CHAR8 *OutputFileName;
217 INT32 ReturnValue;
218 INT32 Index;
219
220 OutputFile = NULL;
221 FileBuffer = NULL;
222 ContentSize = 0;
223 OutputFileName = NULL;
224
225 SetUtilityName (UTILITY_NAME);
226
227 if (argc == 1) {
228 PrintUsage ();
229 return -1;
230 }
231
232 BufferSize = 1024 * 1024 * 16;
233 FileBuffer = (UINT8 *) malloc (BufferSize * sizeof (UINT8));
234 if (FileBuffer == NULL) {
235 Error (NULL, 0, 0, "memory allocation failed", NULL);
236 return -1;
237 }
238
239 ZeroMem (FileBuffer, BufferSize);
240
241 for (Index = 0; Index < argc; Index++) {
242 if (_strcmpi (argv[Index], "-i") == 0) {
243 ReturnValue = ReadFilesContentsIntoBuffer (
244 argv,
245 (Index + 1),
246 &FileBuffer,
247 &BufferSize,
248 &ContentSize,
249 (argc - (Index + 1))
250 );
251 if (ReturnValue == -1) {
252 Error (NULL, 0, 0, "failed to read file contents", NULL);
253 return -1;
254 }
255
256 Index += ReturnValue;
257 }
258
259 if (_strcmpi (argv[Index], "-o") == 0) {
260 OutputFileName = argv[Index + 1];
261 }
262 }
263
264 OutputFile = fopen (OutputFileName, "wb");
265 if (OutputFile == NULL) {
266 Error (NULL, 0, 0, OutputFileName, "failed to open output binary file");
267 free (FileBuffer);
268 return -1;
269 }
270
271 /*
272 //
273 // make sure section ends on a DWORD boundary ??
274 //
275 while ( (Size & 0x03) != 0 ) {
276 FileBuffer[Size] = 0;
277 Size ++;
278 }
279 */
280 Status = SignSectionWithCrc32 (FileBuffer, &BufferSize, ContentSize);
281 if (EFI_ERROR (Status)) {
282 Error (NULL, 0, 0, "failed to sign section", NULL);
283 free (FileBuffer);
284 fclose (OutputFile);
285 return -1;
286 }
287
288 ContentSize = fwrite (FileBuffer, sizeof (UINT8), BufferSize, OutputFile);
289 if (ContentSize != BufferSize) {
290 Error (NULL, 0, 0, "failed to write output buffer", NULL);
291 ReturnValue = -1;
292 } else {
293 ReturnValue = 0;
294 }
295
296 free (FileBuffer);
297 fclose (OutputFile);
298 return ReturnValue;
299 }