]> git.proxmox.com Git - mirror_edk2.git/blob - MdePkg/Library/BaseLib/CheckSum.c
28dee5ac6a158ddd40d7cecfca95bcb5cd3f4a4f
[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 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "BaseLibInternals.h"
11
12 /**
13 Returns the sum of all elements in a buffer in unit of UINT8.
14 During calculation, the carry bits are dropped.
15
16 This function calculates the sum of all elements in a buffer
17 in unit of UINT8. The carry bits in result of addition are dropped.
18 The result is returned as UINT8. If Length is Zero, then Zero is
19 returned.
20
21 If Buffer is NULL, then ASSERT().
22 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
23
24 @param Buffer The pointer to the buffer to carry out the sum operation.
25 @param Length The size, in bytes, of Buffer.
26
27 @return Sum The sum of Buffer with carry bits dropped during additions.
28
29 **/
30 UINT8
31 EFIAPI
32 CalculateSum8 (
33 IN CONST UINT8 *Buffer,
34 IN UINTN Length
35 )
36 {
37 UINT8 Sum;
38 UINTN Count;
39
40 ASSERT (Buffer != NULL);
41 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
42
43 for (Sum = 0, Count = 0; Count < Length; Count++) {
44 Sum = (UINT8)(Sum + *(Buffer + Count));
45 }
46
47 return Sum;
48 }
49
50 /**
51 Returns the two's complement checksum of all elements in a buffer
52 of 8-bit values.
53
54 This function first calculates the sum of the 8-bit values in the
55 buffer specified by Buffer and Length. The carry bits in the result
56 of addition are dropped. Then, the two's complement of the sum is
57 returned. If Length is 0, then 0 is returned.
58
59 If Buffer is NULL, then ASSERT().
60 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
61
62 @param Buffer The pointer to the buffer to carry out the checksum operation.
63 @param Length The size, in bytes, of Buffer.
64
65 @return Checksum The 2's complement checksum of Buffer.
66
67 **/
68 UINT8
69 EFIAPI
70 CalculateCheckSum8 (
71 IN CONST UINT8 *Buffer,
72 IN UINTN Length
73 )
74 {
75 UINT8 CheckSum;
76
77 CheckSum = CalculateSum8 (Buffer, Length);
78
79 //
80 // Return the checksum based on 2's complement.
81 //
82 return (UINT8)(0x100 - CheckSum);
83 }
84
85 /**
86 Returns the sum of all elements in a buffer of 16-bit values. During
87 calculation, the carry bits are dropped.
88
89 This function calculates the sum of the 16-bit values in the buffer
90 specified by Buffer and Length. The carry bits in result of addition are dropped.
91 The 16-bit result is returned. If Length is 0, then 0 is returned.
92
93 If Buffer is NULL, then ASSERT().
94 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
95 If Length is not aligned on a 16-bit boundary, then ASSERT().
96 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
97
98 @param Buffer The pointer to the buffer to carry out the sum operation.
99 @param Length The size, in bytes, of Buffer.
100
101 @return Sum The sum of Buffer with carry bits dropped during additions.
102
103 **/
104 UINT16
105 EFIAPI
106 CalculateSum16 (
107 IN CONST UINT16 *Buffer,
108 IN UINTN Length
109 )
110 {
111 UINT16 Sum;
112 UINTN Count;
113 UINTN Total;
114
115 ASSERT (Buffer != NULL);
116 ASSERT (((UINTN)Buffer & 0x1) == 0);
117 ASSERT ((Length & 0x1) == 0);
118 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
119
120 Total = Length / sizeof (*Buffer);
121 for (Sum = 0, Count = 0; Count < Total; Count++) {
122 Sum = (UINT16)(Sum + *(Buffer + Count));
123 }
124
125 return Sum;
126 }
127
128 /**
129 Returns the two's complement checksum of all elements in a buffer of
130 16-bit values.
131
132 This function first calculates the sum of the 16-bit values in the buffer
133 specified by Buffer and Length. The carry bits in the result of addition
134 are dropped. Then, the two's complement of the sum is returned. If Length
135 is 0, then 0 is returned.
136
137 If Buffer is NULL, then ASSERT().
138 If Buffer is not aligned on a 16-bit boundary, then ASSERT().
139 If Length is not aligned on a 16-bit boundary, then ASSERT().
140 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
141
142 @param Buffer The pointer to the buffer to carry out the checksum operation.
143 @param Length The size, in bytes, of Buffer.
144
145 @return Checksum The 2's complement checksum of Buffer.
146
147 **/
148 UINT16
149 EFIAPI
150 CalculateCheckSum16 (
151 IN CONST UINT16 *Buffer,
152 IN UINTN Length
153 )
154 {
155 UINT16 CheckSum;
156
157 CheckSum = CalculateSum16 (Buffer, Length);
158
159 //
160 // Return the checksum based on 2's complement.
161 //
162 return (UINT16)(0x10000 - CheckSum);
163 }
164
165 /**
166 Returns the sum of all elements in a buffer of 32-bit values. During
167 calculation, the carry bits are dropped.
168
169 This function calculates the sum of the 32-bit values in the buffer
170 specified by Buffer and Length. The carry bits in result of addition are dropped.
171 The 32-bit result is returned. If Length is 0, then 0 is returned.
172
173 If Buffer is NULL, then ASSERT().
174 If Buffer is not aligned on a 32-bit boundary, then ASSERT().
175 If Length is not aligned on a 32-bit boundary, then ASSERT().
176 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
177
178 @param Buffer The pointer to the buffer to carry out the sum operation.
179 @param Length The size, in bytes, of Buffer.
180
181 @return Sum The sum of Buffer with carry bits dropped during additions.
182
183 **/
184 UINT32
185 EFIAPI
186 CalculateSum32 (
187 IN CONST UINT32 *Buffer,
188 IN UINTN Length
189 )
190 {
191 UINT32 Sum;
192 UINTN Count;
193 UINTN Total;
194
195 ASSERT (Buffer != NULL);
196 ASSERT (((UINTN)Buffer & 0x3) == 0);
197 ASSERT ((Length & 0x3) == 0);
198 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
199
200 Total = Length / sizeof (*Buffer);
201 for (Sum = 0, Count = 0; Count < Total; Count++) {
202 Sum = Sum + *(Buffer + Count);
203 }
204
205 return Sum;
206 }
207
208 /**
209 Returns the two's complement checksum of all elements in a buffer of
210 32-bit values.
211
212 This function first calculates the sum of the 32-bit values in the buffer
213 specified by Buffer and Length. The carry bits in the result of addition
214 are dropped. Then, the two's complement of the sum is returned. If Length
215 is 0, then 0 is returned.
216
217 If Buffer is NULL, then ASSERT().
218 If Buffer is not aligned on a 32-bit boundary, then ASSERT().
219 If Length is not aligned on a 32-bit boundary, then ASSERT().
220 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
221
222 @param Buffer The pointer to the buffer to carry out the checksum operation.
223 @param Length The size, in bytes, of Buffer.
224
225 @return Checksum The 2's complement checksum of Buffer.
226
227 **/
228 UINT32
229 EFIAPI
230 CalculateCheckSum32 (
231 IN CONST UINT32 *Buffer,
232 IN UINTN Length
233 )
234 {
235 UINT32 CheckSum;
236
237 CheckSum = CalculateSum32 (Buffer, Length);
238
239 //
240 // Return the checksum based on 2's complement.
241 //
242 return (UINT32)((UINT32)(-1) - CheckSum + 1);
243 }
244
245 /**
246 Returns the sum of all elements in a buffer of 64-bit values. During
247 calculation, the carry bits are dropped.
248
249 This function calculates the sum of the 64-bit values in the buffer
250 specified by Buffer and Length. The carry bits in result of addition are dropped.
251 The 64-bit result is returned. If Length is 0, then 0 is returned.
252
253 If Buffer is NULL, then ASSERT().
254 If Buffer is not aligned on a 64-bit boundary, then ASSERT().
255 If Length is not aligned on a 64-bit boundary, then ASSERT().
256 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
257
258 @param Buffer The pointer to the buffer to carry out the sum operation.
259 @param Length The size, in bytes, of Buffer.
260
261 @return Sum The sum of Buffer with carry bits dropped during additions.
262
263 **/
264 UINT64
265 EFIAPI
266 CalculateSum64 (
267 IN CONST UINT64 *Buffer,
268 IN UINTN Length
269 )
270 {
271 UINT64 Sum;
272 UINTN Count;
273 UINTN Total;
274
275 ASSERT (Buffer != NULL);
276 ASSERT (((UINTN)Buffer & 0x7) == 0);
277 ASSERT ((Length & 0x7) == 0);
278 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
279
280 Total = Length / sizeof (*Buffer);
281 for (Sum = 0, Count = 0; Count < Total; Count++) {
282 Sum = Sum + *(Buffer + Count);
283 }
284
285 return Sum;
286 }
287
288 /**
289 Returns the two's complement checksum of all elements in a buffer of
290 64-bit values.
291
292 This function first calculates the sum of the 64-bit values in the buffer
293 specified by Buffer and Length. The carry bits in the result of addition
294 are dropped. Then, the two's complement of the sum is returned. If Length
295 is 0, then 0 is returned.
296
297 If Buffer is NULL, then ASSERT().
298 If Buffer is not aligned on a 64-bit boundary, then ASSERT().
299 If Length is not aligned on a 64-bit boundary, then ASSERT().
300 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
301
302 @param Buffer The pointer to the buffer to carry out the checksum operation.
303 @param Length The size, in bytes, of Buffer.
304
305 @return Checksum The 2's complement checksum of Buffer.
306
307 **/
308 UINT64
309 EFIAPI
310 CalculateCheckSum64 (
311 IN CONST UINT64 *Buffer,
312 IN UINTN Length
313 )
314 {
315 UINT64 CheckSum;
316
317 CheckSum = CalculateSum64 (Buffer, Length);
318
319 //
320 // Return the checksum based on 2's complement.
321 //
322 return (UINT64)((UINT64)(-1) - CheckSum + 1);
323 }
324
325 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 mCrcTable[256] = {
326 0x00000000,
327 0x77073096,
328 0xEE0E612C,
329 0x990951BA,
330 0x076DC419,
331 0x706AF48F,
332 0xE963A535,
333 0x9E6495A3,
334 0x0EDB8832,
335 0x79DCB8A4,
336 0xE0D5E91E,
337 0x97D2D988,
338 0x09B64C2B,
339 0x7EB17CBD,
340 0xE7B82D07,
341 0x90BF1D91,
342 0x1DB71064,
343 0x6AB020F2,
344 0xF3B97148,
345 0x84BE41DE,
346 0x1ADAD47D,
347 0x6DDDE4EB,
348 0xF4D4B551,
349 0x83D385C7,
350 0x136C9856,
351 0x646BA8C0,
352 0xFD62F97A,
353 0x8A65C9EC,
354 0x14015C4F,
355 0x63066CD9,
356 0xFA0F3D63,
357 0x8D080DF5,
358 0x3B6E20C8,
359 0x4C69105E,
360 0xD56041E4,
361 0xA2677172,
362 0x3C03E4D1,
363 0x4B04D447,
364 0xD20D85FD,
365 0xA50AB56B,
366 0x35B5A8FA,
367 0x42B2986C,
368 0xDBBBC9D6,
369 0xACBCF940,
370 0x32D86CE3,
371 0x45DF5C75,
372 0xDCD60DCF,
373 0xABD13D59,
374 0x26D930AC,
375 0x51DE003A,
376 0xC8D75180,
377 0xBFD06116,
378 0x21B4F4B5,
379 0x56B3C423,
380 0xCFBA9599,
381 0xB8BDA50F,
382 0x2802B89E,
383 0x5F058808,
384 0xC60CD9B2,
385 0xB10BE924,
386 0x2F6F7C87,
387 0x58684C11,
388 0xC1611DAB,
389 0xB6662D3D,
390 0x76DC4190,
391 0x01DB7106,
392 0x98D220BC,
393 0xEFD5102A,
394 0x71B18589,
395 0x06B6B51F,
396 0x9FBFE4A5,
397 0xE8B8D433,
398 0x7807C9A2,
399 0x0F00F934,
400 0x9609A88E,
401 0xE10E9818,
402 0x7F6A0DBB,
403 0x086D3D2D,
404 0x91646C97,
405 0xE6635C01,
406 0x6B6B51F4,
407 0x1C6C6162,
408 0x856530D8,
409 0xF262004E,
410 0x6C0695ED,
411 0x1B01A57B,
412 0x8208F4C1,
413 0xF50FC457,
414 0x65B0D9C6,
415 0x12B7E950,
416 0x8BBEB8EA,
417 0xFCB9887C,
418 0x62DD1DDF,
419 0x15DA2D49,
420 0x8CD37CF3,
421 0xFBD44C65,
422 0x4DB26158,
423 0x3AB551CE,
424 0xA3BC0074,
425 0xD4BB30E2,
426 0x4ADFA541,
427 0x3DD895D7,
428 0xA4D1C46D,
429 0xD3D6F4FB,
430 0x4369E96A,
431 0x346ED9FC,
432 0xAD678846,
433 0xDA60B8D0,
434 0x44042D73,
435 0x33031DE5,
436 0xAA0A4C5F,
437 0xDD0D7CC9,
438 0x5005713C,
439 0x270241AA,
440 0xBE0B1010,
441 0xC90C2086,
442 0x5768B525,
443 0x206F85B3,
444 0xB966D409,
445 0xCE61E49F,
446 0x5EDEF90E,
447 0x29D9C998,
448 0xB0D09822,
449 0xC7D7A8B4,
450 0x59B33D17,
451 0x2EB40D81,
452 0xB7BD5C3B,
453 0xC0BA6CAD,
454 0xEDB88320,
455 0x9ABFB3B6,
456 0x03B6E20C,
457 0x74B1D29A,
458 0xEAD54739,
459 0x9DD277AF,
460 0x04DB2615,
461 0x73DC1683,
462 0xE3630B12,
463 0x94643B84,
464 0x0D6D6A3E,
465 0x7A6A5AA8,
466 0xE40ECF0B,
467 0x9309FF9D,
468 0x0A00AE27,
469 0x7D079EB1,
470 0xF00F9344,
471 0x8708A3D2,
472 0x1E01F268,
473 0x6906C2FE,
474 0xF762575D,
475 0x806567CB,
476 0x196C3671,
477 0x6E6B06E7,
478 0xFED41B76,
479 0x89D32BE0,
480 0x10DA7A5A,
481 0x67DD4ACC,
482 0xF9B9DF6F,
483 0x8EBEEFF9,
484 0x17B7BE43,
485 0x60B08ED5,
486 0xD6D6A3E8,
487 0xA1D1937E,
488 0x38D8C2C4,
489 0x4FDFF252,
490 0xD1BB67F1,
491 0xA6BC5767,
492 0x3FB506DD,
493 0x48B2364B,
494 0xD80D2BDA,
495 0xAF0A1B4C,
496 0x36034AF6,
497 0x41047A60,
498 0xDF60EFC3,
499 0xA867DF55,
500 0x316E8EEF,
501 0x4669BE79,
502 0xCB61B38C,
503 0xBC66831A,
504 0x256FD2A0,
505 0x5268E236,
506 0xCC0C7795,
507 0xBB0B4703,
508 0x220216B9,
509 0x5505262F,
510 0xC5BA3BBE,
511 0xB2BD0B28,
512 0x2BB45A92,
513 0x5CB36A04,
514 0xC2D7FFA7,
515 0xB5D0CF31,
516 0x2CD99E8B,
517 0x5BDEAE1D,
518 0x9B64C2B0,
519 0xEC63F226,
520 0x756AA39C,
521 0x026D930A,
522 0x9C0906A9,
523 0xEB0E363F,
524 0x72076785,
525 0x05005713,
526 0x95BF4A82,
527 0xE2B87A14,
528 0x7BB12BAE,
529 0x0CB61B38,
530 0x92D28E9B,
531 0xE5D5BE0D,
532 0x7CDCEFB7,
533 0x0BDBDF21,
534 0x86D3D2D4,
535 0xF1D4E242,
536 0x68DDB3F8,
537 0x1FDA836E,
538 0x81BE16CD,
539 0xF6B9265B,
540 0x6FB077E1,
541 0x18B74777,
542 0x88085AE6,
543 0xFF0F6A70,
544 0x66063BCA,
545 0x11010B5C,
546 0x8F659EFF,
547 0xF862AE69,
548 0x616BFFD3,
549 0x166CCF45,
550 0xA00AE278,
551 0xD70DD2EE,
552 0x4E048354,
553 0x3903B3C2,
554 0xA7672661,
555 0xD06016F7,
556 0x4969474D,
557 0x3E6E77DB,
558 0xAED16A4A,
559 0xD9D65ADC,
560 0x40DF0B66,
561 0x37D83BF0,
562 0xA9BCAE53,
563 0xDEBB9EC5,
564 0x47B2CF7F,
565 0x30B5FFE9,
566 0xBDBDF21C,
567 0xCABAC28A,
568 0x53B39330,
569 0x24B4A3A6,
570 0xBAD03605,
571 0xCDD70693,
572 0x54DE5729,
573 0x23D967BF,
574 0xB3667A2E,
575 0xC4614AB8,
576 0x5D681B02,
577 0x2A6F2B94,
578 0xB40BBE37,
579 0xC30C8EA1,
580 0x5A05DF1B,
581 0x2D02EF8D
582 };
583
584 /**
585 Computes and returns a 32-bit CRC for a data buffer.
586 CRC32 value bases on ITU-T V.42.
587
588 If Buffer is NULL, then ASSERT().
589 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
590
591 @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is to be computed.
592 @param[in] Length The number of bytes in the buffer Data.
593
594 @retval Crc32 The 32-bit CRC was computed for the data buffer.
595
596 **/
597 UINT32
598 EFIAPI
599 CalculateCrc32 (
600 IN VOID *Buffer,
601 IN UINTN Length
602 )
603 {
604 UINTN Index;
605 UINT32 Crc;
606 UINT8 *Ptr;
607
608 ASSERT (Buffer != NULL);
609 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));
610
611 //
612 // Compute CRC
613 //
614 Crc = 0xffffffff;
615 for (Index = 0, Ptr = Buffer; Index < Length; Index++, Ptr++) {
616 Crc = (Crc >> 8) ^ mCrcTable[(UINT8)Crc ^ *Ptr];
617 }
618
619 return Crc ^ 0xffffffff;
620 }