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