|
@@ -0,0 +1,71 @@
|
|
|
+/** @file
|
|
|
+ Base implementation of the CRC library class.
|
|
|
+
|
|
|
+ @copyright
|
|
|
+ Copyright 2016 - 2018 Intel Corporation. <BR>
|
|
|
+
|
|
|
+ SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
+**/
|
|
|
+
|
|
|
+#include <Base.h>
|
|
|
+#include <Library/CrcLib.h>
|
|
|
+
|
|
|
+/**
|
|
|
+ Calculate a 16-bit CRC.
|
|
|
+
|
|
|
+ The algorithm used is MSB-first form of the ITU-T Recommendation V.41, which
|
|
|
+ uses an initial value of 0x0000 and a polynomial of 0x1021. It is the same
|
|
|
+ algorithm used by XMODEM.
|
|
|
+
|
|
|
+ The output CRC location is not updated until the calculation is finished, so
|
|
|
+ it is possible to pass a structure as the data, and the CRC field of the same
|
|
|
+ structure as the output location for the calculated CRC. The CRC field should
|
|
|
+ be set to zero before calling this function. Once the CRC field is updated by
|
|
|
+ this function, running it again over the structure produces a CRC of zero.
|
|
|
+
|
|
|
+ @param[in] Data A pointer to the target data.
|
|
|
+ @param[in] DataSize The target data size.
|
|
|
+ @param[out] CrcOut A pointer to the return location of the CRC.
|
|
|
+
|
|
|
+ @retval EFI_SUCCESS The CRC was calculated successfully.
|
|
|
+ @retval EFI_INVALID_PARAMETER A null pointer was provided.
|
|
|
+**/
|
|
|
+EFI_STATUS
|
|
|
+CalculateCrc16 (
|
|
|
+ IN VOID *Data,
|
|
|
+ IN UINTN DataSize,
|
|
|
+ OUT UINT16 *CrcOut
|
|
|
+ )
|
|
|
+{
|
|
|
+ UINT32 Crc;
|
|
|
+ UINTN Index;
|
|
|
+ UINT8 *Byte;
|
|
|
+
|
|
|
+ if (Data == NULL || CrcOut == NULL) {
|
|
|
+ return EFI_INVALID_PARAMETER;
|
|
|
+ }
|
|
|
+
|
|
|
+ Crc = 0x0000;
|
|
|
+ for (Byte = (UINT8 *) Data; Byte < (UINT8 *) Data + DataSize; Byte++) {
|
|
|
+ //
|
|
|
+ // XOR the next data byte into the CRC.
|
|
|
+ //
|
|
|
+ Crc ^= (UINT16) *Byte << 8;
|
|
|
+ //
|
|
|
+ // Shift out eight bits, feeding back based on the polynomial whenever a
|
|
|
+ // 1 is shifted out of bit 15.
|
|
|
+ //
|
|
|
+ for (Index = 0; Index < 8; Index++) {
|
|
|
+ Crc <<= 1;
|
|
|
+ if (Crc & BIT16) {
|
|
|
+ Crc ^= 0x1021;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //
|
|
|
+ // Mask and return the 16-bit CRC.
|
|
|
+ //
|
|
|
+ *CrcOut = (UINT16) (Crc & 0xFFFF);
|
|
|
+ return EFI_SUCCESS;
|
|
|
+}
|