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(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test0,
183 			   sizeof(test0)) == 0xF3, "pass", "fail");
184 	zassert(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test1,
185 			   sizeof(test1)) == 0x33, "pass", "fail");
186 	zassert(crc8_ccitt(CRC8_CCITT_INITIAL_VALUE, test2,
187 			   sizeof(test2)) == 0xFB, "pass", "fail");
188 }
189 
ZTEST(crc,test_crc7_be)190 ZTEST(crc, test_crc7_be)
191 {
192 	uint8_t test0[] = { 0 };
193 	uint8_t test1[] = { 'A' };
194 	uint8_t test2[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
195 
196 	zassert_equal(crc7_be(0, test0, sizeof(test0)), 0);
197 	zassert_equal(crc7_be(0, test1, sizeof(test1)), 0xDA);
198 	zassert_equal(crc7_be(0, test2, sizeof(test2)), 0xEA);
199 }
200 
ZTEST(crc,test_crc8)201 ZTEST(crc, test_crc8)
202 {
203 	uint8_t fcs, expected;
204 
205 	uint8_t test0[] = { 0x00 };
206 	uint8_t test1[] = { 0xBE, 0xEF };
207 	uint8_t test2[] = { 0x07, 0x3F };        /* GSM 07.10 example */
208 	uint8_t test3[] = { 0x07, 0x3F, 0x89 };  /* GSM 07.10 example */
209 	uint8_t test4[] = { 0x03, 0x02, 0x0A, 0x38, 0x17, 0x00 };
210 	uint8_t test5[] = { 0x03, 0x3f, 0x01, 0x1c };  /* Our GSM 07.10 calc */
211 
212 	fcs = crc8(test0, sizeof(test0), 0x00, 0x00, false);
213 	expected = 0x00;
214 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
215 
216 	fcs = crc8(test0, sizeof(test0), 0x31, 0x00, false);
217 	expected = 0x00;
218 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
219 
220 	fcs = crc8(test1, sizeof(test1), 0x07, 0x00, false);
221 	expected = 0x1a;
222 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
223 
224 	fcs = crc8(test1, sizeof(test1), 0x31, 0xff, false);
225 	expected = 0x92;
226 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
227 
228 	fcs = crc8(test1, sizeof(test1), 0x07, 0x00, false);
229 	expected = 0x1a;
230 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
231 
232 	fcs = crc8(test2, sizeof(test2), 0x31, 0x00, false);
233 	expected = 0x45;
234 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
235 
236 	fcs = crc8(test2, sizeof(test2), 0x31, 0xff, false);
237 	expected = 0xc4;
238 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
239 
240 	fcs = crc8(test2, sizeof(test2), 0x07, 0x00, false);
241 	expected = 0xd6;
242 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
243 
244 	fcs = crc8(test2, sizeof(test2), 0x07, 0xff, false);
245 	expected = 0x01;
246 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
247 
248 	fcs = crc8(test2, sizeof(test2), 0xe0, 0xff, true);
249 	expected = 0x76;
250 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
251 
252 	fcs = crc8(test3, sizeof(test3), 0xe0, 0xff, true);
253 	expected = 0xcf;
254 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
255 
256 	fcs = crc8(test3, sizeof(test3), 0x07, 0xff, false);
257 	expected = 0xb1;
258 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
259 
260 	fcs = crc8(test4, sizeof(test4), 0x31, 0x00, false);
261 	expected = 0x3a;
262 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
263 
264 	fcs = crc8(test4, sizeof(test4), 0x07, 0x00, false);
265 	expected = 0xaf;
266 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
267 
268 	fcs = crc8(test4, sizeof(test4), 0x9b, 0xff, false);
269 	expected = 0xf0;
270 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
271 
272 	fcs = crc8(test4, sizeof(test4), 0x1d, 0xfd, false);
273 	expected = 0x49;
274 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
275 
276 	fcs = crc8(test5, sizeof(test5), 0xe0, 0xff, true);
277 	expected = 0xcf;
278 	zassert_equal(fcs, expected, "0x%02x vs 0x%02x", fcs, expected);
279 }
280 
281 ZTEST_SUITE(crc, NULL, NULL, NULL, NULL, NULL);
282