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