aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/crc32.h40
-rw-r--r--lib/crc32.c81
2 files changed, 121 insertions, 0 deletions
diff --git a/include/linux/crc32.h b/include/linux/crc32.h
index 68267b64bb98..7d275c4fc011 100644
--- a/include/linux/crc32.h
+++ b/include/linux/crc32.h
@@ -11,8 +11,48 @@
11extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len); 11extern u32 crc32_le(u32 crc, unsigned char const *p, size_t len);
12extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len); 12extern u32 crc32_be(u32 crc, unsigned char const *p, size_t len);
13 13
14/**
15 * crc32_le_combine - Combine two crc32 check values into one. For two
16 * sequences of bytes, seq1 and seq2 with lengths len1
17 * and len2, crc32_le() check values were calculated
18 * for each, crc1 and crc2.
19 *
20 * @crc1: crc32 of the first block
21 * @crc2: crc32 of the second block
22 * @len2: length of the second block
23 *
24 * Return: The crc32_le() check value of seq1 and seq2 concatenated,
25 * requiring only crc1, crc2, and len2. Note: If seq_full denotes
26 * the concatenated memory area of seq1 with seq2, and crc_full
27 * the crc32_le() value of seq_full, then crc_full ==
28 * crc32_le_combine(crc1, crc2, len2) when crc_full was seeded
29 * with the same initializer as crc1, and crc2 seed was 0. See
30 * also crc32_combine_test().
31 */
32extern u32 crc32_le_combine(u32 crc1, u32 crc2, size_t len2);
33
14extern u32 __crc32c_le(u32 crc, unsigned char const *p, size_t len); 34extern u32 __crc32c_le(u32 crc, unsigned char const *p, size_t len);
15 35
36/**
37 * __crc32c_le_combine - Combine two crc32c check values into one. For two
38 * sequences of bytes, seq1 and seq2 with lengths len1
39 * and len2, __crc32c_le() check values were calculated
40 * for each, crc1 and crc2.
41 *
42 * @crc1: crc32c of the first block
43 * @crc2: crc32c of the second block
44 * @len2: length of the second block
45 *
46 * Return: The __crc32c_le() check value of seq1 and seq2 concatenated,
47 * requiring only crc1, crc2, and len2. Note: If seq_full denotes
48 * the concatenated memory area of seq1 with seq2, and crc_full
49 * the __crc32c_le() value of seq_full, then crc_full ==
50 * __crc32c_le_combine(crc1, crc2, len2) when crc_full was
51 * seeded with the same initializer as crc1, and crc2 seed
52 * was 0. See also crc32c_combine_test().
53 */
54extern u32 __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2);
55
16#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)(data), length) 56#define crc32(seed, data, length) crc32_le(seed, (unsigned char const *)(data), length)
17 57
18/* 58/*
diff --git a/lib/crc32.c b/lib/crc32.c
index 429d61ce6aa0..595205cddc30 100644
--- a/lib/crc32.c
+++ b/lib/crc32.c
@@ -49,6 +49,30 @@ MODULE_AUTHOR("Matt Domsch <Matt_Domsch@dell.com>");
49MODULE_DESCRIPTION("Various CRC32 calculations"); 49MODULE_DESCRIPTION("Various CRC32 calculations");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51 51
52#define GF2_DIM 32
53
54static u32 gf2_matrix_times(u32 *mat, u32 vec)
55{
56 u32 sum = 0;
57
58 while (vec) {
59 if (vec & 1)
60 sum ^= *mat;
61 vec >>= 1;
62 mat++;
63 }
64
65 return sum;
66}
67
68static void gf2_matrix_square(u32 *square, u32 *mat)
69{
70 int i;
71
72 for (i = 0; i < GF2_DIM; i++)
73 square[i] = gf2_matrix_times(mat, mat[i]);
74}
75
52#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8 76#if CRC_LE_BITS > 8 || CRC_BE_BITS > 8
53 77
54/* implements slicing-by-4 or slicing-by-8 algorithm */ 78/* implements slicing-by-4 or slicing-by-8 algorithm */
@@ -130,6 +154,52 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 (*tab)[256])
130} 154}
131#endif 155#endif
132 156
157/* For conditions of distribution and use, see copyright notice in zlib.h */
158static u32 crc32_generic_combine(u32 crc1, u32 crc2, size_t len2,
159 u32 polynomial)
160{
161 u32 even[GF2_DIM]; /* Even-power-of-two zeros operator */
162 u32 odd[GF2_DIM]; /* Odd-power-of-two zeros operator */
163 u32 row;
164 int i;
165
166 if (len2 <= 0)
167 return crc1;
168
169 /* Put operator for one zero bit in odd */
170 odd[0] = polynomial;
171 row = 1;
172 for (i = 1; i < GF2_DIM; i++) {
173 odd[i] = row;
174 row <<= 1;
175 }
176
177 gf2_matrix_square(even, odd); /* Put operator for two zero bits in even */
178 gf2_matrix_square(odd, even); /* Put operator for four zero bits in odd */
179
180 /* Apply len2 zeros to crc1 (first square will put the operator for one
181 * zero byte, eight zero bits, in even).
182 */
183 do {
184 /* Apply zeros operator for this bit of len2 */
185 gf2_matrix_square(even, odd);
186 if (len2 & 1)
187 crc1 = gf2_matrix_times(even, crc1);
188 len2 >>= 1;
189 /* If no more bits set, then done */
190 if (len2 == 0)
191 break;
192 /* Another iteration of the loop with odd and even swapped */
193 gf2_matrix_square(odd, even);
194 if (len2 & 1)
195 crc1 = gf2_matrix_times(odd, crc1);
196 len2 >>= 1;
197 } while (len2 != 0);
198
199 crc1 ^= crc2;
200 return crc1;
201}
202
133/** 203/**
134 * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II 204 * crc32_le_generic() - Calculate bitwise little-endian Ethernet AUTODIN II
135 * CRC32/CRC32C 205 * CRC32/CRC32C
@@ -200,8 +270,19 @@ u32 __pure __crc32c_le(u32 crc, unsigned char const *p, size_t len)
200 (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE); 270 (const u32 (*)[256])crc32ctable_le, CRC32C_POLY_LE);
201} 271}
202#endif 272#endif
273u32 __pure crc32_le_combine(u32 crc1, u32 crc2, size_t len2)
274{
275 return crc32_generic_combine(crc1, crc2, len2, CRCPOLY_LE);
276}
277
278u32 __pure __crc32c_le_combine(u32 crc1, u32 crc2, size_t len2)
279{
280 return crc32_generic_combine(crc1, crc2, len2, CRC32C_POLY_LE);
281}
203EXPORT_SYMBOL(crc32_le); 282EXPORT_SYMBOL(crc32_le);
283EXPORT_SYMBOL(crc32_le_combine);
204EXPORT_SYMBOL(__crc32c_le); 284EXPORT_SYMBOL(__crc32c_le);
285EXPORT_SYMBOL(__crc32c_le_combine);
205 286
206/** 287/**
207 * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32 288 * crc32_be_generic() - Calculate bitwise big-endian Ethernet AUTODIN II CRC32