]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/FwVol/Ffs.c
199c7f821b874b724139300e924a2dca08bc9847
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVol / Ffs.c
1 /** @file
2 FFS file access utilities.
3
4 Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9
10 #include "DxeMain.h"
11 #include "FwVolDriver.h"
12
13
14 /**
15 Get the FFS file state by checking the highest bit set in the header's state field.
16
17 @param ErasePolarity Erase polarity attribute of the firmware volume
18 @param FfsHeader Points to the FFS file header
19
20 @return FFS File state
21
22 **/
23 EFI_FFS_FILE_STATE
24 GetFileState (
25 IN UINT8 ErasePolarity,
26 IN EFI_FFS_FILE_HEADER *FfsHeader
27 )
28 {
29 EFI_FFS_FILE_STATE FileState;
30 UINT8 HighestBit;
31
32 FileState = FfsHeader->State;
33
34 if (ErasePolarity != 0) {
35 FileState = (EFI_FFS_FILE_STATE)~FileState;
36 }
37
38 HighestBit = 0x80;
39 while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
40 HighestBit >>= 1;
41 }
42
43 return (EFI_FFS_FILE_STATE) HighestBit;
44 }
45
46
47
48 /**
49 Check if a block of buffer is erased.
50
51 @param ErasePolarity Erase polarity attribute of the firmware volume
52 @param InBuffer The buffer to be checked
53 @param BufferSize Size of the buffer in bytes
54
55 @retval TRUE The block of buffer is erased
56 @retval FALSE The block of buffer is not erased
57
58 **/
59 BOOLEAN
60 IsBufferErased (
61 IN UINT8 ErasePolarity,
62 IN VOID *InBuffer,
63 IN UINTN BufferSize
64 )
65 {
66 UINTN Count;
67 UINT8 EraseByte;
68 UINT8 *Buffer;
69
70 if(ErasePolarity == 1) {
71 EraseByte = 0xFF;
72 } else {
73 EraseByte = 0;
74 }
75
76 Buffer = InBuffer;
77 for (Count = 0; Count < BufferSize; Count++) {
78 if (Buffer[Count] != EraseByte) {
79 return FALSE;
80 }
81 }
82
83 return TRUE;
84 }
85
86
87
88 /**
89 Verify checksum of the firmware volume header.
90
91 @param FvHeader Points to the firmware volume header to be checked
92
93 @retval TRUE Checksum verification passed
94 @retval FALSE Checksum verification failed
95
96 **/
97 BOOLEAN
98 VerifyFvHeaderChecksum (
99 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
100 )
101 {
102 UINT16 Checksum;
103
104 Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
105
106 if (Checksum == 0) {
107 return TRUE;
108 } else {
109 return FALSE;
110 }
111 }
112
113
114 /**
115 Verify checksum of the FFS file header.
116
117 @param FfsHeader Points to the FFS file header to be checked
118
119 @retval TRUE Checksum verification passed
120 @retval FALSE Checksum verification failed
121
122 **/
123 BOOLEAN
124 VerifyHeaderChecksum (
125 IN EFI_FFS_FILE_HEADER *FfsHeader
126 )
127 {
128 UINT8 HeaderChecksum;
129
130 if (IS_FFS_FILE2 (FfsHeader)) {
131 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2));
132 } else {
133 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
134 }
135 HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
136
137 if (HeaderChecksum == 0) {
138 return TRUE;
139 } else {
140 return FALSE;
141 }
142 }
143
144
145
146 /**
147 Check if it's a valid FFS file header.
148
149 @param ErasePolarity Erase polarity attribute of the firmware volume
150 @param FfsHeader Points to the FFS file header to be checked
151 @param FileState FFS file state to be returned
152
153 @retval TRUE Valid FFS file header
154 @retval FALSE Invalid FFS file header
155
156 **/
157 BOOLEAN
158 IsValidFfsHeader (
159 IN UINT8 ErasePolarity,
160 IN EFI_FFS_FILE_HEADER *FfsHeader,
161 OUT EFI_FFS_FILE_STATE *FileState
162 )
163 {
164 *FileState = GetFileState (ErasePolarity, FfsHeader);
165
166 switch (*FileState) {
167 case EFI_FILE_HEADER_VALID:
168 case EFI_FILE_DATA_VALID:
169 case EFI_FILE_MARKED_FOR_UPDATE:
170 case EFI_FILE_DELETED:
171 //
172 // Here we need to verify header checksum
173 //
174 return VerifyHeaderChecksum (FfsHeader);
175
176 case EFI_FILE_HEADER_CONSTRUCTION:
177 case EFI_FILE_HEADER_INVALID:
178 default:
179 return FALSE;
180 }
181 }
182
183
184 /**
185 Check if it's a valid FFS file.
186 Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
187
188 @param ErasePolarity Erase polarity attribute of the firmware volume
189 @param FfsHeader Points to the FFS file to be checked
190
191 @retval TRUE Valid FFS file
192 @retval FALSE Invalid FFS file
193
194 **/
195 BOOLEAN
196 IsValidFfsFile (
197 IN UINT8 ErasePolarity,
198 IN EFI_FFS_FILE_HEADER *FfsHeader
199 )
200 {
201 EFI_FFS_FILE_STATE FileState;
202 UINT8 DataCheckSum;
203
204 FileState = GetFileState (ErasePolarity, FfsHeader);
205 switch (FileState) {
206
207 case EFI_FILE_DELETED:
208 case EFI_FILE_DATA_VALID:
209 case EFI_FILE_MARKED_FOR_UPDATE:
210 DataCheckSum = FFS_FIXED_CHECKSUM;
211 if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
212 if (IS_FFS_FILE2 (FfsHeader)) {
213 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2));
214 } else {
215 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER));
216 }
217 }
218 if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
219 return TRUE;
220 }
221
222 default:
223 return FALSE;
224 }
225 }
226
227