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