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