summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/842/842.h2
-rw-r--r--lib/842/842_compress.c13
-rw-r--r--lib/842/842_decompress.c17
3 files changed, 32 insertions, 0 deletions
diff --git a/lib/842/842.h b/lib/842/842.h
index 7c200030acf7..e0a122bc1cdb 100644
--- a/lib/842/842.h
+++ b/lib/842/842.h
@@ -76,6 +76,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/bitops.h>
+#include <linux/crc32.h>
#include <asm/unaligned.h>
#include <linux/sw842.h>
@@ -98,6 +99,7 @@
#define I2_BITS (8)
#define I4_BITS (9)
#define I8_BITS (8)
+#define CRC_BITS (32)
#define REPEAT_BITS_MAX (0x3f)
#define SHORT_DATA_BITS_MAX (0x7)
diff --git a/lib/842/842_compress.c b/lib/842/842_compress.c
index 7ce68948e68c..4051339bdfbd 100644
--- a/lib/842/842_compress.c
+++ b/lib/842/842_compress.c
@@ -490,6 +490,7 @@ int sw842_compress(const u8 *in, unsigned int ilen,
int ret;
u64 last, next, pad, total;
u8 repeat_count = 0;
+ u32 crc;
BUILD_BUG_ON(sizeof(*p) > SW842_MEM_COMPRESS);
@@ -580,6 +581,18 @@ skip_comp:
if (ret)
return ret;
+ /*
+ * crc(0:31) is appended to target data starting with the next
+ * bit after End of stream template.
+ * nx842 calculates CRC for data in big-endian format. So doing
+ * same here so that sw842 decompression can be used for both
+ * compressed data.
+ */
+ crc = crc32_be(0, in, ilen);
+ ret = add_bits(p, crc, CRC_BITS);
+ if (ret)
+ return ret;
+
if (p->bit) {
p->out++;
p->olen--;
diff --git a/lib/842/842_decompress.c b/lib/842/842_decompress.c
index 5446ff0c9ba0..8881dad2a6a0 100644
--- a/lib/842/842_decompress.c
+++ b/lib/842/842_decompress.c
@@ -285,6 +285,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
struct sw842_param p;
int ret;
u64 op, rep, tmp, bytes, total;
+ u64 crc;
p.in = (u8 *)in;
p.bit = 0;
@@ -375,6 +376,22 @@ int sw842_decompress(const u8 *in, unsigned int ilen,
}
} while (op != OP_END);
+ /*
+ * crc(0:31) is saved in compressed data starting with the
+ * next bit after End of stream template.
+ */
+ ret = next_bits(&p, &crc, CRC_BITS);
+ if (ret)
+ return ret;
+
+ /*
+ * Validate CRC saved in compressed data.
+ */
+ if (crc != (u64)crc32_be(0, out, total - p.olen)) {
+ pr_debug("CRC mismatch for decompression\n");
+ return -EINVAL;
+ }
+
if (unlikely((total - p.olen) > UINT_MAX))
return -ENOSPC;