]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/CheckSum.c
MdePkg/BaseLib: Add CRC16-ANSI and CRC32c implementations
[mirror_edk2.git] / MdePkg / Library / BaseLib / CheckSum.c
CommitLineData
e1f414b6 1/** @file\r
2 Utility functions to generate checksum based on 2's complement\r
3 algorithm.\r
4\r
9095d37b 5 Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
92288f43 6 Copyright (c) 2022, Pedro Falcato. All rights reserved.<BR>\r
9344f092 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
e1f414b6 8\r
e1f414b6 9**/\r
10\r
47fc17d8 11#include "BaseLibInternals.h"\r
f734a10a 12\r
e1f414b6 13/**\r
9aa049d9 14 Returns the sum of all elements in a buffer in unit of UINT8.\r
e1f414b6 15 During calculation, the carry bits are dropped.\r
16\r
9aa049d9 17 This function calculates the sum of all elements in a buffer\r
18 in unit of UINT8. The carry bits in result of addition are dropped.\r
19 The result is returned as UINT8. If Length is Zero, then Zero is\r
e1f414b6 20 returned.\r
9aa049d9 21\r
e1f414b6 22 If Buffer is NULL, then ASSERT().\r
9aa049d9 23 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
e1f414b6 24\r
127010dd 25 @param Buffer The pointer to the buffer to carry out the sum operation.\r
9aa049d9 26 @param Length The size, in bytes, of Buffer.\r
e1f414b6 27\r
9aa049d9 28 @return Sum The sum of Buffer with carry bits dropped during additions.\r
e1f414b6 29\r
30**/\r
31UINT8\r
32EFIAPI\r
33CalculateSum8 (\r
2f88bd3a
MK
34 IN CONST UINT8 *Buffer,\r
35 IN UINTN Length\r
e1f414b6 36 )\r
37{\r
2f88bd3a
MK
38 UINT8 Sum;\r
39 UINTN Count;\r
e1f414b6 40\r
41 ASSERT (Buffer != NULL);\r
2f88bd3a 42 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));\r
e1f414b6 43\r
44 for (Sum = 0, Count = 0; Count < Length; Count++) {\r
2f88bd3a 45 Sum = (UINT8)(Sum + *(Buffer + Count));\r
e1f414b6 46 }\r
9095d37b 47\r
e1f414b6 48 return Sum;\r
49}\r
50\r
e1f414b6 51/**\r
9aa049d9 52 Returns the two's complement checksum of all elements in a buffer\r
e1f414b6 53 of 8-bit values.\r
54\r
9aa049d9 55 This function first calculates the sum of the 8-bit values in the\r
56 buffer specified by Buffer and Length. The carry bits in the result\r
57 of addition are dropped. Then, the two's complement of the sum is\r
e1f414b6 58 returned. If Length is 0, then 0 is returned.\r
9aa049d9 59\r
e1f414b6 60 If Buffer is NULL, then ASSERT().\r
61 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
62\r
127010dd 63 @param Buffer The pointer to the buffer to carry out the checksum operation.\r
1106ffe1 64 @param Length The size, in bytes, of Buffer.\r
e1f414b6 65\r
9aa049d9 66 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 67\r
68**/\r
69UINT8\r
70EFIAPI\r
71CalculateCheckSum8 (\r
2f88bd3a
MK
72 IN CONST UINT8 *Buffer,\r
73 IN UINTN Length\r
e1f414b6 74 )\r
75{\r
2f88bd3a 76 UINT8 CheckSum;\r
e1f414b6 77\r
78 CheckSum = CalculateSum8 (Buffer, Length);\r
79\r
80 //\r
81 // Return the checksum based on 2's complement.\r
82 //\r
2f88bd3a 83 return (UINT8)(0x100 - CheckSum);\r
e1f414b6 84}\r
85\r
86/**\r
9aa049d9 87 Returns the sum of all elements in a buffer of 16-bit values. During\r
e1f414b6 88 calculation, the carry bits are dropped.\r
89\r
9aa049d9 90 This function calculates the sum of the 16-bit values in the buffer\r
91 specified by Buffer and Length. The carry bits in result of addition are dropped.\r
92 The 16-bit result is returned. If Length is 0, then 0 is returned.\r
93\r
e1f414b6 94 If Buffer is NULL, then ASSERT().\r
95 If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
96 If Length is not aligned on a 16-bit boundary, then ASSERT().\r
97 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
98\r
127010dd 99 @param Buffer The pointer to the buffer to carry out the sum operation.\r
1106ffe1 100 @param Length The size, in bytes, of Buffer.\r
e1f414b6 101\r
9aa049d9 102 @return Sum The sum of Buffer with carry bits dropped during additions.\r
e1f414b6 103\r
104**/\r
105UINT16\r
106EFIAPI\r
107CalculateSum16 (\r
2f88bd3a
MK
108 IN CONST UINT16 *Buffer,\r
109 IN UINTN Length\r
e1f414b6 110 )\r
111{\r
2f88bd3a
MK
112 UINT16 Sum;\r
113 UINTN Count;\r
114 UINTN Total;\r
e1f414b6 115\r
116 ASSERT (Buffer != NULL);\r
2f88bd3a 117 ASSERT (((UINTN)Buffer & 0x1) == 0);\r
e1f414b6 118 ASSERT ((Length & 0x1) == 0);\r
2f88bd3a 119 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));\r
e1f414b6 120\r
f9cea76b 121 Total = Length / sizeof (*Buffer);\r
122 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
2f88bd3a 123 Sum = (UINT16)(Sum + *(Buffer + Count));\r
e1f414b6 124 }\r
9095d37b 125\r
e1f414b6 126 return Sum;\r
127}\r
128\r
e1f414b6 129/**\r
9aa049d9 130 Returns the two's complement checksum of all elements in a buffer of\r
e1f414b6 131 16-bit values.\r
132\r
9aa049d9 133 This function first calculates the sum of the 16-bit values in the buffer\r
134 specified by Buffer and Length. The carry bits in the result of addition\r
135 are dropped. Then, the two's complement of the sum is returned. If Length\r
e1f414b6 136 is 0, then 0 is returned.\r
9aa049d9 137\r
e1f414b6 138 If Buffer is NULL, then ASSERT().\r
139 If Buffer is not aligned on a 16-bit boundary, then ASSERT().\r
140 If Length is not aligned on a 16-bit boundary, then ASSERT().\r
9aa049d9 141 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
e1f414b6 142\r
127010dd 143 @param Buffer The pointer to the buffer to carry out the checksum operation.\r
1106ffe1 144 @param Length The size, in bytes, of Buffer.\r
e1f414b6 145\r
9aa049d9 146 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 147\r
148**/\r
149UINT16\r
150EFIAPI\r
151CalculateCheckSum16 (\r
2f88bd3a
MK
152 IN CONST UINT16 *Buffer,\r
153 IN UINTN Length\r
e1f414b6 154 )\r
155{\r
2f88bd3a 156 UINT16 CheckSum;\r
e1f414b6 157\r
158 CheckSum = CalculateSum16 (Buffer, Length);\r
159\r
160 //\r
161 // Return the checksum based on 2's complement.\r
162 //\r
2f88bd3a 163 return (UINT16)(0x10000 - CheckSum);\r
e1f414b6 164}\r
165\r
e1f414b6 166/**\r
9aa049d9 167 Returns the sum of all elements in a buffer of 32-bit values. During\r
e1f414b6 168 calculation, the carry bits are dropped.\r
169\r
9aa049d9 170 This function calculates the sum of the 32-bit values in the buffer\r
171 specified by Buffer and Length. The carry bits in result of addition are dropped.\r
172 The 32-bit result is returned. If Length is 0, then 0 is returned.\r
173\r
e1f414b6 174 If Buffer is NULL, then ASSERT().\r
175 If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
176 If Length is not aligned on a 32-bit boundary, then ASSERT().\r
177 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
178\r
127010dd 179 @param Buffer The pointer to the buffer to carry out the sum operation.\r
1106ffe1 180 @param Length The size, in bytes, of Buffer.\r
e1f414b6 181\r
9aa049d9 182 @return Sum The sum of Buffer with carry bits dropped during additions.\r
e1f414b6 183\r
184**/\r
185UINT32\r
186EFIAPI\r
187CalculateSum32 (\r
2f88bd3a
MK
188 IN CONST UINT32 *Buffer,\r
189 IN UINTN Length\r
e1f414b6 190 )\r
191{\r
2f88bd3a
MK
192 UINT32 Sum;\r
193 UINTN Count;\r
194 UINTN Total;\r
e1f414b6 195\r
196 ASSERT (Buffer != NULL);\r
2f88bd3a 197 ASSERT (((UINTN)Buffer & 0x3) == 0);\r
e1f414b6 198 ASSERT ((Length & 0x3) == 0);\r
2f88bd3a 199 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));\r
e1f414b6 200\r
f9cea76b 201 Total = Length / sizeof (*Buffer);\r
202 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
e1f414b6 203 Sum = Sum + *(Buffer + Count);\r
204 }\r
9095d37b 205\r
e1f414b6 206 return Sum;\r
207}\r
208\r
e1f414b6 209/**\r
9aa049d9 210 Returns the two's complement checksum of all elements in a buffer of\r
e1f414b6 211 32-bit values.\r
212\r
9aa049d9 213 This function first calculates the sum of the 32-bit values in the buffer\r
214 specified by Buffer and Length. The carry bits in the result of addition\r
215 are dropped. Then, the two's complement of the sum is returned. If Length\r
e1f414b6 216 is 0, then 0 is returned.\r
9aa049d9 217\r
e1f414b6 218 If Buffer is NULL, then ASSERT().\r
219 If Buffer is not aligned on a 32-bit boundary, then ASSERT().\r
220 If Length is not aligned on a 32-bit boundary, then ASSERT().\r
9aa049d9 221 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
e1f414b6 222\r
127010dd 223 @param Buffer The pointer to the buffer to carry out the checksum operation.\r
1106ffe1 224 @param Length The size, in bytes, of Buffer.\r
e1f414b6 225\r
9aa049d9 226 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 227\r
228**/\r
229UINT32\r
230EFIAPI\r
231CalculateCheckSum32 (\r
2f88bd3a
MK
232 IN CONST UINT32 *Buffer,\r
233 IN UINTN Length\r
e1f414b6 234 )\r
235{\r
2f88bd3a 236 UINT32 CheckSum;\r
e1f414b6 237\r
238 CheckSum = CalculateSum32 (Buffer, Length);\r
239\r
240 //\r
241 // Return the checksum based on 2's complement.\r
242 //\r
2f88bd3a 243 return (UINT32)((UINT32)(-1) - CheckSum + 1);\r
e1f414b6 244}\r
245\r
e1f414b6 246/**\r
9aa049d9 247 Returns the sum of all elements in a buffer of 64-bit values. During\r
e1f414b6 248 calculation, the carry bits are dropped.\r
249\r
9aa049d9 250 This function calculates the sum of the 64-bit values in the buffer\r
251 specified by Buffer and Length. The carry bits in result of addition are dropped.\r
252 The 64-bit result is returned. If Length is 0, then 0 is returned.\r
253\r
e1f414b6 254 If Buffer is NULL, then ASSERT().\r
255 If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
256 If Length is not aligned on a 64-bit boundary, then ASSERT().\r
257 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
258\r
127010dd 259 @param Buffer The pointer to the buffer to carry out the sum operation.\r
1106ffe1 260 @param Length The size, in bytes, of Buffer.\r
e1f414b6 261\r
9aa049d9 262 @return Sum The sum of Buffer with carry bits dropped during additions.\r
e1f414b6 263\r
264**/\r
265UINT64\r
266EFIAPI\r
267CalculateSum64 (\r
2f88bd3a
MK
268 IN CONST UINT64 *Buffer,\r
269 IN UINTN Length\r
e1f414b6 270 )\r
271{\r
2f88bd3a
MK
272 UINT64 Sum;\r
273 UINTN Count;\r
274 UINTN Total;\r
e1f414b6 275\r
276 ASSERT (Buffer != NULL);\r
2f88bd3a 277 ASSERT (((UINTN)Buffer & 0x7) == 0);\r
e1f414b6 278 ASSERT ((Length & 0x7) == 0);\r
2f88bd3a 279 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));\r
e1f414b6 280\r
f9cea76b 281 Total = Length / sizeof (*Buffer);\r
282 for (Sum = 0, Count = 0; Count < Total; Count++) {\r
e1f414b6 283 Sum = Sum + *(Buffer + Count);\r
284 }\r
9095d37b 285\r
e1f414b6 286 return Sum;\r
287}\r
288\r
e1f414b6 289/**\r
9aa049d9 290 Returns the two's complement checksum of all elements in a buffer of\r
e1f414b6 291 64-bit values.\r
292\r
9aa049d9 293 This function first calculates the sum of the 64-bit values in the buffer\r
294 specified by Buffer and Length. The carry bits in the result of addition\r
295 are dropped. Then, the two's complement of the sum is returned. If Length\r
e1f414b6 296 is 0, then 0 is returned.\r
9aa049d9 297\r
e1f414b6 298 If Buffer is NULL, then ASSERT().\r
299 If Buffer is not aligned on a 64-bit boundary, then ASSERT().\r
300 If Length is not aligned on a 64-bit boundary, then ASSERT().\r
9aa049d9 301 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
e1f414b6 302\r
127010dd 303 @param Buffer The pointer to the buffer to carry out the checksum operation.\r
1106ffe1 304 @param Length The size, in bytes, of Buffer.\r
e1f414b6 305\r
9aa049d9 306 @return Checksum The 2's complement checksum of Buffer.\r
e1f414b6 307\r
308**/\r
309UINT64\r
310EFIAPI\r
311CalculateCheckSum64 (\r
2f88bd3a
MK
312 IN CONST UINT64 *Buffer,\r
313 IN UINTN Length\r
e1f414b6 314 )\r
315{\r
2f88bd3a 316 UINT64 CheckSum;\r
e1f414b6 317\r
318 CheckSum = CalculateSum64 (Buffer, Length);\r
319\r
320 //\r
321 // Return the checksum based on 2's complement.\r
322 //\r
2f88bd3a 323 return (UINT64)((UINT64)(-1) - CheckSum + 1);\r
e1f414b6 324}\r
325\r
0a8e6f79
LG
326GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 mCrcTable[256] = {\r
327 0x00000000,\r
328 0x77073096,\r
329 0xEE0E612C,\r
330 0x990951BA,\r
331 0x076DC419,\r
332 0x706AF48F,\r
333 0xE963A535,\r
334 0x9E6495A3,\r
335 0x0EDB8832,\r
336 0x79DCB8A4,\r
337 0xE0D5E91E,\r
338 0x97D2D988,\r
339 0x09B64C2B,\r
340 0x7EB17CBD,\r
341 0xE7B82D07,\r
342 0x90BF1D91,\r
343 0x1DB71064,\r
344 0x6AB020F2,\r
345 0xF3B97148,\r
346 0x84BE41DE,\r
347 0x1ADAD47D,\r
348 0x6DDDE4EB,\r
349 0xF4D4B551,\r
350 0x83D385C7,\r
351 0x136C9856,\r
352 0x646BA8C0,\r
353 0xFD62F97A,\r
354 0x8A65C9EC,\r
355 0x14015C4F,\r
356 0x63066CD9,\r
357 0xFA0F3D63,\r
358 0x8D080DF5,\r
359 0x3B6E20C8,\r
360 0x4C69105E,\r
361 0xD56041E4,\r
362 0xA2677172,\r
363 0x3C03E4D1,\r
364 0x4B04D447,\r
365 0xD20D85FD,\r
366 0xA50AB56B,\r
367 0x35B5A8FA,\r
368 0x42B2986C,\r
369 0xDBBBC9D6,\r
370 0xACBCF940,\r
371 0x32D86CE3,\r
372 0x45DF5C75,\r
373 0xDCD60DCF,\r
374 0xABD13D59,\r
375 0x26D930AC,\r
376 0x51DE003A,\r
377 0xC8D75180,\r
378 0xBFD06116,\r
379 0x21B4F4B5,\r
380 0x56B3C423,\r
381 0xCFBA9599,\r
382 0xB8BDA50F,\r
383 0x2802B89E,\r
384 0x5F058808,\r
385 0xC60CD9B2,\r
386 0xB10BE924,\r
387 0x2F6F7C87,\r
388 0x58684C11,\r
389 0xC1611DAB,\r
390 0xB6662D3D,\r
391 0x76DC4190,\r
392 0x01DB7106,\r
393 0x98D220BC,\r
394 0xEFD5102A,\r
395 0x71B18589,\r
396 0x06B6B51F,\r
397 0x9FBFE4A5,\r
398 0xE8B8D433,\r
399 0x7807C9A2,\r
400 0x0F00F934,\r
401 0x9609A88E,\r
402 0xE10E9818,\r
403 0x7F6A0DBB,\r
404 0x086D3D2D,\r
405 0x91646C97,\r
406 0xE6635C01,\r
407 0x6B6B51F4,\r
408 0x1C6C6162,\r
409 0x856530D8,\r
410 0xF262004E,\r
411 0x6C0695ED,\r
412 0x1B01A57B,\r
413 0x8208F4C1,\r
414 0xF50FC457,\r
415 0x65B0D9C6,\r
416 0x12B7E950,\r
417 0x8BBEB8EA,\r
418 0xFCB9887C,\r
419 0x62DD1DDF,\r
420 0x15DA2D49,\r
421 0x8CD37CF3,\r
422 0xFBD44C65,\r
423 0x4DB26158,\r
424 0x3AB551CE,\r
425 0xA3BC0074,\r
426 0xD4BB30E2,\r
427 0x4ADFA541,\r
428 0x3DD895D7,\r
429 0xA4D1C46D,\r
430 0xD3D6F4FB,\r
431 0x4369E96A,\r
432 0x346ED9FC,\r
433 0xAD678846,\r
434 0xDA60B8D0,\r
435 0x44042D73,\r
436 0x33031DE5,\r
437 0xAA0A4C5F,\r
438 0xDD0D7CC9,\r
439 0x5005713C,\r
440 0x270241AA,\r
441 0xBE0B1010,\r
442 0xC90C2086,\r
443 0x5768B525,\r
444 0x206F85B3,\r
445 0xB966D409,\r
446 0xCE61E49F,\r
447 0x5EDEF90E,\r
448 0x29D9C998,\r
449 0xB0D09822,\r
450 0xC7D7A8B4,\r
451 0x59B33D17,\r
452 0x2EB40D81,\r
453 0xB7BD5C3B,\r
454 0xC0BA6CAD,\r
455 0xEDB88320,\r
456 0x9ABFB3B6,\r
457 0x03B6E20C,\r
458 0x74B1D29A,\r
459 0xEAD54739,\r
460 0x9DD277AF,\r
461 0x04DB2615,\r
462 0x73DC1683,\r
463 0xE3630B12,\r
464 0x94643B84,\r
465 0x0D6D6A3E,\r
466 0x7A6A5AA8,\r
467 0xE40ECF0B,\r
468 0x9309FF9D,\r
469 0x0A00AE27,\r
470 0x7D079EB1,\r
471 0xF00F9344,\r
472 0x8708A3D2,\r
473 0x1E01F268,\r
474 0x6906C2FE,\r
475 0xF762575D,\r
476 0x806567CB,\r
477 0x196C3671,\r
478 0x6E6B06E7,\r
479 0xFED41B76,\r
480 0x89D32BE0,\r
481 0x10DA7A5A,\r
482 0x67DD4ACC,\r
483 0xF9B9DF6F,\r
484 0x8EBEEFF9,\r
485 0x17B7BE43,\r
486 0x60B08ED5,\r
487 0xD6D6A3E8,\r
488 0xA1D1937E,\r
489 0x38D8C2C4,\r
490 0x4FDFF252,\r
491 0xD1BB67F1,\r
492 0xA6BC5767,\r
493 0x3FB506DD,\r
494 0x48B2364B,\r
495 0xD80D2BDA,\r
496 0xAF0A1B4C,\r
497 0x36034AF6,\r
498 0x41047A60,\r
499 0xDF60EFC3,\r
500 0xA867DF55,\r
501 0x316E8EEF,\r
502 0x4669BE79,\r
503 0xCB61B38C,\r
504 0xBC66831A,\r
505 0x256FD2A0,\r
506 0x5268E236,\r
507 0xCC0C7795,\r
508 0xBB0B4703,\r
509 0x220216B9,\r
510 0x5505262F,\r
511 0xC5BA3BBE,\r
512 0xB2BD0B28,\r
513 0x2BB45A92,\r
514 0x5CB36A04,\r
515 0xC2D7FFA7,\r
516 0xB5D0CF31,\r
517 0x2CD99E8B,\r
518 0x5BDEAE1D,\r
519 0x9B64C2B0,\r
520 0xEC63F226,\r
521 0x756AA39C,\r
522 0x026D930A,\r
523 0x9C0906A9,\r
524 0xEB0E363F,\r
525 0x72076785,\r
526 0x05005713,\r
527 0x95BF4A82,\r
528 0xE2B87A14,\r
529 0x7BB12BAE,\r
530 0x0CB61B38,\r
531 0x92D28E9B,\r
532 0xE5D5BE0D,\r
533 0x7CDCEFB7,\r
534 0x0BDBDF21,\r
535 0x86D3D2D4,\r
536 0xF1D4E242,\r
537 0x68DDB3F8,\r
538 0x1FDA836E,\r
539 0x81BE16CD,\r
540 0xF6B9265B,\r
541 0x6FB077E1,\r
542 0x18B74777,\r
543 0x88085AE6,\r
544 0xFF0F6A70,\r
545 0x66063BCA,\r
546 0x11010B5C,\r
547 0x8F659EFF,\r
548 0xF862AE69,\r
549 0x616BFFD3,\r
550 0x166CCF45,\r
551 0xA00AE278,\r
552 0xD70DD2EE,\r
553 0x4E048354,\r
554 0x3903B3C2,\r
555 0xA7672661,\r
556 0xD06016F7,\r
557 0x4969474D,\r
558 0x3E6E77DB,\r
559 0xAED16A4A,\r
560 0xD9D65ADC,\r
561 0x40DF0B66,\r
562 0x37D83BF0,\r
563 0xA9BCAE53,\r
564 0xDEBB9EC5,\r
565 0x47B2CF7F,\r
566 0x30B5FFE9,\r
567 0xBDBDF21C,\r
568 0xCABAC28A,\r
569 0x53B39330,\r
570 0x24B4A3A6,\r
571 0xBAD03605,\r
572 0xCDD70693,\r
573 0x54DE5729,\r
574 0x23D967BF,\r
575 0xB3667A2E,\r
576 0xC4614AB8,\r
577 0x5D681B02,\r
578 0x2A6F2B94,\r
579 0xB40BBE37,\r
580 0xC30C8EA1,\r
581 0x5A05DF1B,\r
582 0x2D02EF8D\r
583};\r
e1f414b6 584\r
0a8e6f79
LG
585/**\r
586 Computes and returns a 32-bit CRC for a data buffer.\r
587 CRC32 value bases on ITU-T V.42.\r
588\r
589 If Buffer is NULL, then ASSERT().\r
590 If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
591\r
592 @param[in] Buffer A pointer to the buffer on which the 32-bit CRC is to be computed.\r
593 @param[in] Length The number of bytes in the buffer Data.\r
594\r
595 @retval Crc32 The 32-bit CRC was computed for the data buffer.\r
596\r
597**/\r
598UINT32\r
599EFIAPI\r
2f88bd3a
MK
600CalculateCrc32 (\r
601 IN VOID *Buffer,\r
602 IN UINTN Length\r
0a8e6f79
LG
603 )\r
604{\r
605 UINTN Index;\r
606 UINT32 Crc;\r
607 UINT8 *Ptr;\r
608\r
609 ASSERT (Buffer != NULL);\r
2f88bd3a 610 ASSERT (Length <= (MAX_ADDRESS - ((UINTN)Buffer) + 1));\r
0a8e6f79
LG
611\r
612 //\r
613 // Compute CRC\r
614 //\r
615 Crc = 0xffffffff;\r
616 for (Index = 0, Ptr = Buffer; Index < Length; Index++, Ptr++) {\r
2f88bd3a 617 Crc = (Crc >> 8) ^ mCrcTable[(UINT8)Crc ^ *Ptr];\r
0a8e6f79
LG
618 }\r
619\r
620 return Crc ^ 0xffffffff;\r
621}\r
92288f43
PF
622\r
623GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT16 mCrc16LookupTable[256] =\r
624{\r
625 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,\r
626 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,\r
627 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,\r
628 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,\r
629 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,\r
630 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,\r
631 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,\r
632 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,\r
633 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,\r
634 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,\r
635 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,\r
636 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,\r
637 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,\r
638 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,\r
639 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,\r
640 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,\r
641 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,\r
642 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,\r
643 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,\r
644 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,\r
645 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,\r
646 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,\r
647 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,\r
648 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,\r
649 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,\r
650 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,\r
651 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,\r
652 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,\r
653 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,\r
654 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,\r
655 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,\r
656 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040\r
657};\r
658\r
659/**\r
660 Calculates the CRC16-ANSI checksum of the given buffer.\r
661\r
662 @param[in] Buffer Pointer to the buffer.\r
663 @param[in] Length Length of the buffer, in bytes.\r
664 @param[in] InitialValue Initial value of the CRC.\r
665\r
666 @return The CRC16-ANSI checksum.\r
667**/\r
668UINT16\r
669EFIAPI\r
670CalculateCrc16Ansi (\r
671 IN CONST VOID *Buffer,\r
672 IN UINTN Length,\r
673 IN UINT16 InitialValue\r
674 )\r
675{\r
676 CONST UINT8 *Buf;\r
677 UINT16 Crc;\r
678\r
679 Buf = Buffer;\r
680\r
681 Crc = ~InitialValue;\r
682\r
683 while (Length-- != 0) {\r
684 Crc = mCrc16LookupTable[(Crc & 0xFF) ^ *(Buf++)] ^ (Crc >> 8);\r
685 }\r
686\r
687 return ~Crc;\r
688}\r
689\r
690GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT32 mCrc32cLookupTable[256] = {\r
691 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c,\r
692 0x26a1e7e8, 0xd4ca64eb, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,\r
693 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, 0x105ec76f, 0xe235446c,\r
694 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,\r
695 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc,\r
696 0xbc267848, 0x4e4dfb4b, 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,\r
697 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, 0xaa64d611, 0x580f5512,\r
698 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,\r
699 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad,\r
700 0x1642ae59, 0xe4292d5a, 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,\r
701 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, 0x417b1dbc, 0xb3109ebf,\r
702 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,\r
703 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f,\r
704 0xed03a29b, 0x1f682198, 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,\r
705 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, 0xdbfc821c, 0x2997011f,\r
706 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,\r
707 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e,\r
708 0x4767748a, 0xb50cf789, 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,\r
709 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, 0x7198540d, 0x83f3d70e,\r
710 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,\r
711 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de,\r
712 0xdde0eb2a, 0x2f8b6829, 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,\r
713 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, 0x082f63b7, 0xfa44e0b4,\r
714 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,\r
715 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b,\r
716 0xb4091bff, 0x466298fc, 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,\r
717 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, 0xa24bb5a6, 0x502036a5,\r
718 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,\r
719 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975,\r
720 0x0e330a81, 0xfc588982, 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,\r
721 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, 0x38cc2a06, 0xcaa7a905,\r
722 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,\r
723 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8,\r
724 0xe52cc12c, 0x1747422f, 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,\r
725 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, 0xd3d3e1ab, 0x21b862a8,\r
726 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,\r
727 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78,\r
728 0x7fab5e8c, 0x8dc0dd8f, 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,\r
729 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, 0x69e9f0d5, 0x9b8273d6,\r
730 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,\r
731 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69,\r
732 0xd5cf889d, 0x27a40b9e, 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,\r
733 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351\r
734};\r
735\r
736/**\r
737 Calculates the CRC32c checksum of the given buffer.\r
738\r
739 @param[in] Buffer Pointer to the buffer.\r
740 @param[in] Length Length of the buffer, in bytes.\r
741 @param[in] InitialValue Initial value of the CRC.\r
742\r
743 @return The CRC32c checksum.\r
744**/\r
745UINT32\r
746EFIAPI\r
747CalculateCrc32c (\r
748 IN CONST VOID *Buffer,\r
749 IN UINTN Length,\r
750 IN UINT32 InitialValue\r
751 )\r
752{\r
753 CONST UINT8 *Buf;\r
754 UINT32 Crc;\r
755\r
756 Buf = Buffer;\r
757 Crc = ~InitialValue;\r
758\r
759 while (Length-- != 0) {\r
760 Crc = mCrc32cLookupTable[(Crc & 0xFF) ^ *(Buf++)] ^ (Crc >> 8);\r
761 }\r
762\r
763 return ~Crc;\r
764}\r