summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPedro Falcato <pedro.falcato@gmail.com>2023-11-30 02:46:10 +0000
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-12-03 02:37:26 +0000
commite2d4f759137dea60a402a1810a4014a7cf00116b (patch)
tree728869fe1912373b271249ae3ff39c714acc91d9
parent7182621edc67260a322fa0fb8bb4c8e398d9323e (diff)
downloadedk2-e2d4f759137dea60a402a1810a4014a7cf00116b.tar.gz
edk2-e2d4f759137dea60a402a1810a4014a7cf00116b.tar.bz2
edk2-e2d4f759137dea60a402a1810a4014a7cf00116b.zip
MdePkg/BaseLib: Fix CRC16-ANSI calculation
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4609 The current CalculateCrc16Ansi implementation does the following: 1) Invert the passed checksum 2) Calculate the new checksum by going through data and using the lookup table 3) Invert it back again This emulated my design for CalculateCrc32c, where 0 is passed as the initial checksum, and it inverts in the end. However, CRC16 does not invert the checksum on input and output. So this is incorrect. Fix the problem by not inverting input checksums nor output checksums. Callers should now pass CRC16ANSI_INIT as the initial value instead of "0". This is a breaking change. This problem was found out-of-list when older ext4 filesystems (that use crc16 checksums) failed to mount with "corruption". Cc: Liming Gao <gaoliming@byosoft.com.cn> Cc: Michael D Kinney <michael.d.kinney@intel.com> Cc: Zhiguang Liu <zhiguang.liu@intel.com> Signed-off-by: Pedro Falcato <pedro.falcato@gmail.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
-rw-r--r--MdePkg/Include/Library/BaseLib.h5
-rw-r--r--MdePkg/Library/BaseLib/CheckSum.c4
2 files changed, 7 insertions, 2 deletions
diff --git a/MdePkg/Include/Library/BaseLib.h b/MdePkg/Include/Library/BaseLib.h
index 5d7067ee85..728e89d2bf 100644
--- a/MdePkg/Include/Library/BaseLib.h
+++ b/MdePkg/Include/Library/BaseLib.h
@@ -4599,6 +4599,11 @@ CalculateCrc16Ansi (
IN UINT16 InitialValue
);
+//
+// Initial value for the CRC16-ANSI algorithm, when no prior checksum has been calculated.
+//
+#define CRC16ANSI_INIT 0xffff
+
/**
Calculates the CRC32c checksum of the given buffer.
diff --git a/MdePkg/Library/BaseLib/CheckSum.c b/MdePkg/Library/BaseLib/CheckSum.c
index b6a0765731..57d324c82b 100644
--- a/MdePkg/Library/BaseLib/CheckSum.c
+++ b/MdePkg/Library/BaseLib/CheckSum.c
@@ -678,13 +678,13 @@ CalculateCrc16Ansi (
Buf = Buffer;
- Crc = ~InitialValue;
+ Crc = InitialValue;
while (Length-- != 0) {
Crc = mCrc16LookupTable[(Crc & 0xFF) ^ *(Buf++)] ^ (Crc >> 8);
}
- return ~Crc;
+ return Crc;
}
GLOBAL_REMOVE_IF_UNREFERENCED STATIC CONST UINT32 mCrc32cLookupTable[256] = {