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