]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/CheckSum.c
a902620b56af03fd866964cee8b8f13374ca32d8
[mirror_edk2.git] / MdePkg / Library / BaseLib / CheckSum.c
1 /** @file
2 Utility functions to generate checksum based on 2's complement
3 algorithm.
4
5 Copyright (c) 2007, Intel Corporation<BR>
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 Module Name: CheckSum.c
15
16 **/
17
18 //
19 // Include common header file for this module.
20 //
21 #include <BaseLibInternals.h>
22
23
24 /**
25 Calculate the sum of all elements in a buffer in unit of UINT8.
26 During calculation, the carry bits are dropped.
27
28 This function calculates the sum of all elements in a buffer
29 in unit of UINT8. The carry bits in result of addition are dropped.
30 The result is returned as UINT8. If Length is Zero, then Zero is
31 returned.
32
33 If Buffer is NULL, then ASSERT().
34 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
35
36 @param Buffer Pointer to the buffer to carry out the sum operation.
37 @param Length The size, in bytes, of Buffer .
38
39 @return Sum The sum of Buffer with carry bits dropped during additions.
40
41 **/
42 UINT8
43 EFIAPI
44 CalculateSum8 (
45 IN CONST UINT8 *Buffer,
46 IN UINTN Length
47 )
48 {
49 UINT8 Sum;
50 UINTN Count;
51
52 ASSERT (Buffer != NULL);
53 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
54
55 for (Sum = 0, Count = 0; Count < Length; Count++) {
56 Sum = (UINT8) (Sum + *(Buffer + Count));
57 }
58
59 return Sum;
60 }
61
62
63 /**
64 Returns the two's complement checksum of all elements in a buffer
65 of 8-bit values.
66
67 This function first calculates the sum of the 8-bit values in the
68 buffer specified by Buffer and Length. The carry bits in the result
69 of addition are dropped. Then, the two's complement of the sum is
70 returned. If Length is 0, then 0 is returned.
71
72 If Buffer is NULL, then ASSERT().
73 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
74
75
76 @param Buffer Pointer to the buffer to carry out the checksum operation.
77 @param Length The size, in bytes, of Buffer.
78
79 @return Checksum The 2's complement checksum of Buffer.
80
81 **/
82 UINT8
83 EFIAPI
84 CalculateCheckSum8 (
85 IN CONST UINT8 *Buffer,
86 IN UINTN Length
87 )
88 {
89 UINT8 CheckSum;
90
91 CheckSum = CalculateSum8 (Buffer, Length);
92
93 //
94 // Return the checksum based on 2's complement.
95 //
96 return (UINT8) (0x100 - CheckSum);
97 }
98
99 /**
100 Returns the sum of all elements in a buffer of 16-bit values. During
101 calculation, the carry bits are dropped.
102
103 This function calculates the sum of the 16-bit values in the buffer
104 specified by Buffer and Length. The carry bits in result of addition are dropped.
105 The 16-bit result is returned. If Length is 0, then 0 is returned.
106
107 If Buffer is NULL, then ASSERT().
108 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
109 If Length is not aligned on a 16-bit boundary, then ASSERT().
110 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
111
112 @param Buffer Pointer to the buffer to carry out the sum operation.
113 @param Length The size, in bytes, of Buffer.
114
115 @return Sum The sum of Buffer with carry bits dropped during additions.
116
117 **/
118 UINT16
119 EFIAPI
120 CalculateSum16 (
121 IN CONST UINT16 *Buffer,
122 IN UINTN Length
123 )
124 {
125 UINT16 Sum;
126 UINTN Count;
127
128 ASSERT (Buffer != NULL);
129 ASSERT (((UINTN) Buffer & 0x1) == 0);
130 ASSERT ((Length & 0x1) == 0);
131 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
132
133
134 for (Sum = 0, Count = 0; Count < Length; Count++) {
135 Sum = (UINT16) (Sum + *(Buffer + Count));
136 }
137
138 return Sum;
139 }
140
141
142 /**
143 Returns the two's complement checksum of all elements in a buffer of
144 16-bit values.
145
146 This function first calculates the sum of the 16-bit values in the buffer
147 specified by Buffer and Length. The carry bits in the result of addition
148 are dropped. Then, the two's complement of the sum is returned. If Length
149 is 0, then 0 is returned.
150
151 If Buffer is NULL, then ASSERT().
152 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
153 If Length is not aligned on a 16-bit boundary, then ASSERT().
154 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
155
156 @param Buffer Pointer to the buffer to carry out the checksum operation.
157 @param Length The size, in bytes, of Buffer.
158
159 @return Checksum The 2's complement checksum of Buffer.
160
161 **/
162 UINT16
163 EFIAPI
164 CalculateCheckSum16 (
165 IN CONST UINT16 *Buffer,
166 IN UINTN Length
167 )
168 {
169 UINT16 CheckSum;
170
171 CheckSum = CalculateSum16 (Buffer, Length);
172
173 //
174 // Return the checksum based on 2's complement.
175 //
176 return (UINT16) (0x10000 - CheckSum);
177 }
178
179
180 /**
181 Returns the sum of all elements in a buffer of 32-bit values. During
182 calculation, the carry bits are dropped.
183
184 This function calculates the sum of the 32-bit values in the buffer
185 specified by Buffer and Length. The carry bits in result of addition are dropped.
186 The 32-bit result is returned. If Length is 0, then 0 is returned.
187
188 If Buffer is NULL, then ASSERT().
189 If Buffer is not aligned on a 32-bit boundary, then ASSERT().
190 If Length is not aligned on a 32-bit boundary, then ASSERT().
191 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
192
193 @param Buffer Pointer to the buffer to carry out the sum operation.
194 @param Length The size, in bytes, of Buffer.
195
196 @return Sum The sum of Buffer with carry bits dropped during additions.
197
198 **/
199 UINT32
200 EFIAPI
201 CalculateSum32 (
202 IN CONST UINT32 *Buffer,
203 IN UINTN Length
204 )
205 {
206 UINT32 Sum;
207 UINTN Count;
208
209 ASSERT (Buffer != NULL);
210 ASSERT (((UINTN) Buffer & 0x3) == 0);
211 ASSERT ((Length & 0x3) == 0);
212 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
213
214
215 for (Sum = 0, Count = 0; Count < Length; Count++) {
216 Sum = Sum + *(Buffer + Count);
217 }
218
219 return Sum;
220 }
221
222
223 /**
224 Returns the two's complement checksum of all elements in a buffer of
225 32-bit values.
226
227 This function first calculates the sum of the 32-bit values in the buffer
228 specified by Buffer and Length. The carry bits in the result of addition
229 are dropped. Then, the two's complement of the sum is returned. If Length
230 is 0, then 0 is returned.
231
232 If Buffer is NULL, then ASSERT().
233 If Buffer is not aligned on a 32-bit boundary, then ASSERT().
234 If Length is not aligned on a 32-bit boundary, then ASSERT().
235 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
236
237 @param Buffer Pointer to the buffer to carry out the checksum operation.
238 @param Length The size, in bytes, of Buffer.
239
240 @return Checksum The 2's complement checksum of Buffer.
241
242 **/
243 UINT32
244 EFIAPI
245 CalculateCheckSum32 (
246 IN CONST UINT32 *Buffer,
247 IN UINTN Length
248 )
249 {
250 UINT32 CheckSum;
251
252 CheckSum = CalculateSum32 (Buffer, Length);
253
254 //
255 // Return the checksum based on 2's complement.
256 //
257 return (UINT32) ((UINT32)(-1) - CheckSum + 1);
258 }
259
260
261 /**
262 Returns the sum of all elements in a buffer of 64-bit values. During
263 calculation, the carry bits are dropped.
264
265 This function calculates the sum of the 64-bit values in the buffer
266 specified by Buffer and Length. The carry bits in result of addition are dropped.
267 The 64-bit result is returned. If Length is 0, then 0 is returned.
268
269 If Buffer is NULL, then ASSERT().
270 If Buffer is not aligned on a 64-bit boundary, then ASSERT().
271 If Length is not aligned on a 64-bit boundary, then ASSERT().
272 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
273
274 @param Buffer Pointer to the buffer to carry out the sum operation.
275 @param Length The size, in bytes, of Buffer.
276
277 @return Sum The sum of Buffer with carry bits dropped during additions.
278
279 **/
280 UINT64
281 EFIAPI
282 CalculateSum64 (
283 IN CONST UINT64 *Buffer,
284 IN UINTN Length
285 )
286 {
287 UINT64 Sum;
288 UINTN Count;
289
290 ASSERT (Buffer != NULL);
291 ASSERT (((UINTN) Buffer & 0x7) == 0);
292 ASSERT ((Length & 0x7) == 0);
293 ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1));
294
295 for (Sum = 0, Count = 0; Count < Length; Count++) {
296 Sum = Sum + *(Buffer + Count);
297 }
298
299 return Sum;
300 }
301
302
303 /**
304 Returns the two's complement checksum of all elements in a buffer of
305 64-bit values.
306
307 This function first calculates the sum of the 64-bit values in the buffer
308 specified by Buffer and Length. The carry bits in the result of addition
309 are dropped. Then, the two's complement of the sum is returned. If Length
310 is 0, then 0 is returned.
311
312 If Buffer is NULL, then ASSERT().
313 If Buffer is not aligned on a 64-bit boundary, then ASSERT().
314 If Length is not aligned on a 64-bit boundary, then ASSERT().
315 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
316
317 @param Buffer Pointer to the buffer to carry out the checksum operation.
318 @param Length The size, in bytes, of Buffer.
319
320 @return Checksum The 2's complement checksum of Buffer.
321
322 **/
323 UINT64
324 EFIAPI
325 CalculateCheckSum64 (
326 IN CONST UINT64 *Buffer,
327 IN UINTN Length
328 )
329 {
330 UINT64 CheckSum;
331
332 CheckSum = CalculateSum64 (Buffer, Length);
333
334 //
335 // Return the checksum based on 2's complement.
336 //
337 return (UINT64) ((UINT64)(-1) - CheckSum + 1);
338 }
339
340