1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 #include <zephyr/sys/crc.h>
9 #include "../../../lib/crc/crc8_sw.c"
10 #include "../../../lib/crc/crc16_sw.c"
11 #include "../../../lib/crc/crc32_sw.c"
12 #include "../../../lib/crc/crc32c_sw.c"
13 #include "../../../lib/crc/crc7_sw.c"
14 #include "../../../lib/crc/crc24_sw.c"
15 #include "../../../lib/crc/crc4_sw.c"
16 #include "../../../lib/crc/crc32k_4_2_sw.c"
17 
ZTEST(crc,test_crc32_k_4_2)18 ZTEST(crc, test_crc32_k_4_2)
19 {
20 	uint8_t test1[] = "A";
21 	uint8_t test2[] = "123456789";
22 	uint8_t test3[] = "Zephyr";
23 
24 	const uint32_t TEST2_CRC = 0x3ee83603;
25 
26 	zassert_equal(crc32_k_4_2_update(0xFFFFFFFF, test1, sizeof(test1) - 1), 0x2d098604);
27 	zassert_equal(crc32_k_4_2_update(0xFFFFFFFF, test2, sizeof(test2) - 1), TEST2_CRC);
28 	zassert_equal(crc32_k_4_2_update(0xFFFFFFFF, test3, sizeof(test3) - 1), 0xacf334b2);
29 
30 	/* test iteration */
31 	uint32_t crc = 0xFFFFFFFF;
32 
33 	for (size_t i = 0; i < sizeof(test2) - 1; i++) {
34 		crc = crc32_k_4_2_update(crc, &test2[i], 1);
35 	}
36 	zassert_equal(crc, TEST2_CRC);
37 }
38 
ZTEST(crc,test_crc32c)39 ZTEST(crc, test_crc32c)
40 {
41 	uint8_t test1[] = { 'A' };
42 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
43 	uint8_t test3[] = { 'Z', 'e', 'p', 'h', 'y', 'r' };
44 
45 	/* Single streams */
46 	zassert_equal(crc32_c(0, test1, sizeof(test1), true, true),
47 			0xE16DCDEE);
48 	zassert_equal(crc32_c(0, test2, sizeof(test2), true, true),
49 			0xE3069283);
50 	zassert_equal(crc32_c(0, test3, sizeof(test3), true, true),
51 			0xFCDEB58D);
52 
53 	/* Continuous streams - test1, test2 and test3 are considered part
54 	 * of one big stream whose CRC needs to be calculated. Note that the
55 	 * CRC of the first string is passed over to the second crc calculation,
56 	 * second to third and so on.
57 	 */
58 	zassert_equal(crc32_c(0, test1, sizeof(test1), true, false),
59 			0x1E923211);
60 	zassert_equal(crc32_c(0x1E923211, test2, sizeof(test2), false, false),
61 			0xB2983B83);
62 	zassert_equal(crc32_c(0xB2983B83, test3, sizeof(test3), false, true),
63 			0x7D4F9D21);
64 }
65 
ZTEST(crc,test_crc32_ieee)66 ZTEST(crc, test_crc32_ieee)
67 {
68 	uint8_t test1[] = { 'A' };
69 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
70 	uint8_t test3[] = { 'Z', 'e', 'p', 'h', 'y', 'r' };
71 
72 	zassert_equal(crc32_ieee(test1, sizeof(test1)), 0xD3D99E8B);
73 	zassert_equal(crc32_ieee(test2, sizeof(test2)), 0xCBF43926);
74 	zassert_equal(crc32_ieee(test3, sizeof(test3)), 0x20089AA4);
75 }
76 
ZTEST(crc,test_crc24_pgp)77 ZTEST(crc, test_crc24_pgp)
78 {
79 	uint8_t test1[] = { 'A' };
80 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
81 	uint8_t test3[] = { 'Z', 'e', 'p', 'h', 'y', 'r' };
82 
83 	zassert_equal(crc24_pgp(test1, sizeof(test1)), 0x00FE86FA);
84 	zassert_equal(crc24_pgp(test2, sizeof(test2)), 0x0021CF02);
85 	zassert_equal(crc24_pgp(test3, sizeof(test3)), 0x004662E9);
86 
87 	/* Compute a CRC in several steps */
88 	zassert_equal(crc24_pgp_update(CRC24_PGP_INITIAL_VALUE, test2, 3), 0x0009DF67);
89 	zassert_equal(crc24_pgp_update(0x0009DF67, test2 + 3, 2), 0x00BA353A);
90 	zassert_equal(crc24_pgp_update(0x00BA353A, test2 + 5, 4), 0x0021CF02);
91 }
92 
ZTEST(crc,test_crc24q_rtcm3)93 ZTEST(crc, test_crc24q_rtcm3)
94 {
95 	uint8_t test1[] = {0xD3, 0x00, 0x04, 0x4C, 0xE0, 0x00, 0x80};
96 	uint8_t test2[] = {0xD3, 0x00, 0x04, 0x4C, 0xE0, 0x00, 0x80, 0xED, 0xED, 0xD6};
97 
98 	zassert_equal(crc24q_rtcm3(test1, sizeof(test1)), 0xEDEDD6);
99 	zassert_equal(crc24q_rtcm3(test2, sizeof(test2)), 0x000000);
100 }
101 
ZTEST(crc,test_crc16)102 ZTEST(crc, test_crc16)
103 {
104 	uint8_t test[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
105 
106 	/* CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-16/KERMIT
107 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-kermit
108 	 * check=0x2189
109 	 * poly is 0x1021, reflected 0x8408
110 	 */
111 	zassert_equal(crc16_reflect(0x8408, 0x0, test, sizeof(test)), 0x2189);
112 
113 	/* CRC-16/DECT-X
114 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-dect-x
115 	 * check=0x007f
116 	 */
117 	zassert_equal(crc16(0x0589, 0x0, test, sizeof(test)), 0x007f);
118 }
119 
ZTEST(crc,test_crc16_ansi)120 ZTEST(crc, test_crc16_ansi)
121 {
122 	uint8_t test[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
123 
124 	uint16_t crc16_c = crc16_ansi(test, sizeof(test));
125 
126 	/* CRC-16/ANSI, CRC-16/MODBUS, CRC-16/USB, CRC-16/IBM
127 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-modbus
128 	 * check=0x4b37
129 	 * poly is 0x1021, reflected 0xA001
130 	 */
131 	zassert_equal(crc16_c, 0x4b37);
132 	zassert_equal(crc16_reflect(0xA001, 0xffff, test, sizeof(test)), crc16_c);
133 }
134 
ZTEST(crc,test_crc16_ccitt)135 ZTEST(crc, test_crc16_ccitt)
136 {
137 	uint8_t test0[] = { };
138 	uint8_t test1[] = { 'A' };
139 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
140 	uint8_t test3[] = { 'Z', 'e', 'p', 'h', 'y', 'r', 0, 0 };
141 	uint16_t crc;
142 
143 	zassert_equal(crc16_ccitt(0, test0, sizeof(test0)), 0x0);
144 	zassert_equal(crc16_ccitt(0, test1, sizeof(test1)), 0x538d);
145 	/* CRC-16/CCITT, CRC-16/CCITT-TRUE, CRC-16/KERMIT
146 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-kermit
147 	 * check=0x2189
148 	 */
149 	zassert_equal(crc16_ccitt(0, test2, sizeof(test2)), 0x2189);
150 	/* CRC-16/X-25, CRC-16/IBM-SDLC, CRC-16/ISO-HDLC
151 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-ibm-sdlc
152 	 * check=0x906e
153 	 */
154 	zassert_equal(crc16_ccitt(0xffff, test2, sizeof(test2)) ^ 0xffff,
155 		      0x906e);
156 
157 	/* Appending the CRC to a buffer and computing the CRC over
158 	 * the extended buffer leaves a residual of zero.
159 	 */
160 	crc = crc16_ccitt(0, test3, sizeof(test3) - sizeof(uint16_t));
161 	test3[sizeof(test3)-2] = (uint8_t)(crc >> 0);
162 	test3[sizeof(test3)-1] = (uint8_t)(crc >> 8);
163 
164 	zassert_equal(crc16_ccitt(0, test3, sizeof(test3)), 0);
165 }
166 
ZTEST(crc,test_crc16_ccitt_for_ppp)167 ZTEST(crc, test_crc16_ccitt_for_ppp)
168 {
169 	/* Example capture including FCS from
170 	 * https://www.horo.ch/techno/ppp-fcs/examples_en.html
171 	 */
172 	uint8_t test0[] = {
173 		0xff, 0x03, 0xc0, 0x21, 0x01, 0x01, 0x00, 0x17,
174 		0x02, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x05, 0x06,
175 		0x00, 0x2a, 0x2b, 0x78, 0x07, 0x02, 0x08, 0x02,
176 		0x0d, 0x03, 0x06, 0xa5, 0xf8
177 	};
178 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
179 
180 	zassert_equal(crc16_ccitt(0xffff, test0, sizeof(test0)),
181 		      0xf0b8);
182 	zassert_equal(crc16_ccitt(0xffff, test2, sizeof(test2)) ^ 0xFFFF,
183 		      0x906e);
184 }
185 
ZTEST(crc,test_crc16_itu_t)186 ZTEST(crc, test_crc16_itu_t)
187 {
188 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
189 
190 	/* CRC-16/XMODEM, CRC-16/ACORN, CRC-16/LTE
191 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-xmodem
192 	 * check=0x31c3
193 	 */
194 	zassert_equal(crc16_itu_t(0, test2, sizeof(test2)), 0x31c3);
195 	/* CRC16/CCITT-FALSE, CRC-16/IBM-3740, CRC-16/AUTOSAR
196 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-ibm-3740
197 	 * check=0x29b1
198 	 */
199 	zassert_equal(crc16_itu_t(0xffff, test2, sizeof(test2)), 0x29b1);
200 	/* CRC-16/GSM
201 	 * https://reveng.sourceforge.io/crc-catalogue/16.htm#crc.cat.crc-16-gsm
202 	 * check=0xce3c
203 	 */
204 	zassert_equal(crc16_itu_t(0, test2, sizeof(test2)) ^ 0xffff, 0xce3c);
205 
206 }
207 
ZTEST(crc,test_crc4)208 ZTEST(crc, test_crc4)
209 {
210 	uint8_t test1[] = {'A'};
211 	uint8_t test2[] = {'Z', 'e', 'p', 'h', 'y', 'r'};
212 
213 	zassert_equal(crc4(test1, sizeof(test1), 0x3, 0x0, true), 0x2);
214 	zassert_equal(crc4(test2, sizeof(test2), 0x3, 0x0, true), 0x0);
215 	zassert_equal(crc4(test1, sizeof(test1), 0x3, 0x0, false), 0x4);
216 	zassert_equal(crc4(test2, sizeof(test2), 0x3, 0x0, false), 0xE);
217 }
218 
ZTEST(crc,test_crc4_ti)219 ZTEST(crc, test_crc4_ti)
220 {
221 	uint8_t test1[] = {'Z', 'e', 'p'};
222 
223 	zassert_equal(crc4_ti(0x0, test1, sizeof(test1)), 0xF);
224 	zassert_equal(crc4_ti(0x5, test1, sizeof(test1)), 0xB);
225 }
226 
ZTEST(crc,test_crc8_ccitt)227 ZTEST(crc, test_crc8_ccitt)
228 {
229 	uint8_t test0[] = { 0 };
230 	uint8_t test1[] = { 'A' };
231 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
232 
233 	zassert_equal(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test0, sizeof(test0)), 0xF3);
234 	zassert_equal(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test1, sizeof(test1)), 0x33);
235 	zassert_equal(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test2, sizeof(test2)), 0xFB);
236 }
237 
ZTEST(crc,test_crc8_rohc)238 ZTEST(crc, test_crc8_rohc)
239 {
240 	uint8_t test0[] = { 0 };
241 	uint8_t test1[] = { 'A' };
242 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
243 	uint8_t test3[] = { 0x07, 0x3F };        /* GSM 07.10 example */
244 	uint8_t test4[] = { 0x07, 0x3F, 0x89 };  /* GSM 07.10 example */
245 	uint8_t test5[] = { 0x03, 0x3f, 0x01, 0x1c };  /* Our GSM 07.10 calc */
246 
247 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test0, sizeof(test0)), 0xcf);
248 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test1, sizeof(test1)), 0x2e);
249 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test2, sizeof(test2)), 0xd0);
250 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test3, sizeof(test3)), 0x76);
251 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test4, sizeof(test4)), 0xcf);
252 	zassert_equal(crc8_rohc(CRC8_ROHC_INITIAL_VALUE, test5, sizeof(test5)), 0xcf);
253 }
254 
ZTEST(crc,test_crc7_be)255 ZTEST(crc, test_crc7_be)
256 {
257 	uint8_t test0[] = { 0 };
258 	uint8_t test1[] = { 'A' };
259 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
260 
261 	zassert_equal(crc7_be(0, test0, sizeof(test0)), 0);
262 	zassert_equal(crc7_be(0, test1, sizeof(test1)), 0xDA);
263 	zassert_equal(crc7_be(0, test2, sizeof(test2)), 0xEA);
264 }
265 
ZTEST(crc,test_crc8)266 ZTEST(crc, test_crc8)
267 {
268 	uint8_t fcs, expected;
269 
270 	uint8_t test0[] = { 0x00 };
271 	uint8_t test1[] = { 0xBE, 0xEF };
272 	uint8_t test2[] = { 0x07, 0x3F };        /* GSM 07.10 example */
273 	uint8_t test3[] = { 0x07, 0x3F, 0x89 };  /* GSM 07.10 example */
274 	uint8_t test4[] = { 0x03, 0x02, 0x0A, 0x38, 0x17, 0x00 };
275 	uint8_t test5[] = { 0x03, 0x3f, 0x01, 0x1c };  /* Our GSM 07.10 calc */
276 
277 	fcs = crc8(test0, sizeof(test0), 0x00, 0x00, false);
278 	expected = 0x00;
279 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
280 
281 	fcs = crc8(test0, sizeof(test0), 0x31, 0x00, false);
282 	expected = 0x00;
283 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
284 
285 	fcs = crc8(test1, sizeof(test1), 0x07, 0x00, false);
286 	expected = 0x1a;
287 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
288 
289 	fcs = crc8(test1, sizeof(test1), 0x31, 0xff, false);
290 	expected = 0x92;
291 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
292 
293 	fcs = crc8(test1, sizeof(test1), 0x07, 0x00, false);
294 	expected = 0x1a;
295 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
296 
297 	fcs = crc8(test2, sizeof(test2), 0x31, 0x00, false);
298 	expected = 0x45;
299 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
300 
301 	fcs = crc8(test2, sizeof(test2), 0x31, 0xff, false);
302 	expected = 0xc4;
303 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
304 
305 	fcs = crc8(test2, sizeof(test2), 0x07, 0x00, false);
306 	expected = 0xd6;
307 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
308 
309 	fcs = crc8(test2, sizeof(test2), 0x07, 0xff, false);
310 	expected = 0x01;
311 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
312 
313 	fcs = crc8(test2, sizeof(test2), 0xe0, 0xff, true);
314 	expected = 0x76;
315 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
316 
317 	fcs = crc8(test3, sizeof(test3), 0xe0, 0xff, true);
318 	expected = 0xcf;
319 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
320 
321 	fcs = crc8(test3, sizeof(test3), 0x07, 0xff, false);
322 	expected = 0xb1;
323 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
324 
325 	fcs = crc8(test4, sizeof(test4), 0x31, 0x00, false);
326 	expected = 0x3a;
327 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
328 
329 	fcs = crc8(test4, sizeof(test4), 0x07, 0x00, false);
330 	expected = 0xaf;
331 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
332 
333 	fcs = crc8(test4, sizeof(test4), 0x9b, 0xff, false);
334 	expected = 0xf0;
335 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
336 
337 	fcs = crc8(test4, sizeof(test4), 0x1d, 0xfd, false);
338 	expected = 0x49;
339 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
340 
341 	fcs = crc8(test5, sizeof(test5), 0xe0, 0xff, true);
342 	expected = 0xcf;
343 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
344 }
345 
346 ZTEST_SUITE(crc, NULL, NULL, NULL, NULL, NULL);
347