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