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