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