1 /*
2 * Copyright (c) 2018 Workaround GmbH.
3 * Copyright (c) 2017 Intel Corporation.
4 * Copyright (c) 2017 Nordic Semiconductor ASA
5 * Copyright (c) 2015 Runtime Inc
6 * Copyright (c) 2018 Google LLC.
7 *
8 * SPDX-License-Identifier: Apache-2.0
9 */
10 /** @file
11 * @brief CRC computation function
12 */
13
14 #ifndef ZEPHYR_INCLUDE_SYS_CRC_H_
15 #define ZEPHYR_INCLUDE_SYS_CRC_H_
16
17 #include <zephyr/types.h>
18 #include <stdbool.h>
19 #include <stddef.h>
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 /* Initial value expected to be used at the beginning of the crc8_ccitt
26 * computation.
27 */
28 #define CRC8_CCITT_INITIAL_VALUE 0xFF
29
30 /**
31 * @defgroup checksum Checksum
32 */
33
34 /**
35 * @defgroup crc CRC
36 * @ingroup checksum
37 * @{
38 */
39
40 /**
41 * @brief Generic function for computing CRC 16
42 *
43 * Compute CRC 16 by passing in the address of the input, the input length
44 * and polynomial used in addition to the initial value.
45 *
46 * @param src Input bytes for the computation
47 * @param len Length of the input in bytes
48 * @param polynomial The polynomial to use omitting the leading x^16
49 * coefficient
50 * @param initial_value Initial value for the CRC computation
51 * @param pad Adds padding with zeros at the end of input bytes
52 *
53 * @return The computed CRC16 value
54 */
55 uint16_t crc16(const uint8_t *src, size_t len, uint16_t polynomial,
56 uint16_t initial_value, bool pad);
57
58 /**
59 * @brief Generic function for computing CRC 8
60 *
61 * Compute CRC 8 by passing in the address of the input, the input length
62 * and polynomial used in addition to the initial value.
63 *
64 * @param src Input bytes for the computation
65 * @param len Length of the input in bytes
66 * @param polynomial The polynomial to use omitting the leading x^8
67 * coefficient
68 * @param initial_value Initial value for the CRC computation
69 * @param reversed Should we use reflected/reversed values or not
70 *
71 * @return The computed CRC8 value
72 */
73 uint8_t crc8(const uint8_t *src, size_t len, uint8_t polynomial, uint8_t initial_value,
74 bool reversed);
75
76 /**
77 * @brief Compute the CRC-16/CCITT checksum of a buffer.
78 *
79 * See ITU-T Recommendation V.41 (November 1988). Uses 0x1021 as the
80 * polynomial, reflects the input, and reflects the output.
81 *
82 * To calculate the CRC across non-contiguous blocks use the return
83 * value from block N-1 as the seed for block N.
84 *
85 * For CRC-16/CCITT, use 0 as the initial seed. Other checksums in
86 * the same family can be calculated by changing the seed and/or
87 * XORing the final value. Examples include:
88 *
89 * - X-25 (used in PPP): seed=0xffff, xor=0xffff, residual=0xf0b8
90 *
91 * @note API changed in Zephyr 1.11.
92 *
93 * @param seed Value to seed the CRC with
94 * @param src Input bytes for the computation
95 * @param len Length of the input in bytes
96 *
97 * @return The computed CRC16 value
98 */
99 uint16_t crc16_ccitt(uint16_t seed, const uint8_t *src, size_t len);
100
101 /**
102 * @brief Compute the CRC-16/XMODEM checksum of a buffer.
103 *
104 * The MSB first version of ITU-T Recommendation V.41 (November 1988).
105 * Uses 0x1021 as the polynomial with no reflection.
106 *
107 * To calculate the CRC across non-contiguous blocks use the return
108 * value from block N-1 as the seed for block N.
109 *
110 * For CRC-16/XMODEM, use 0 as the initial seed. Other checksums in
111 * the same family can be calculated by changing the seed and/or
112 * XORing the final value. Examples include:
113 *
114 * - CCIITT-FALSE: seed=0xffff
115 * - GSM: seed=0, xorout=0xffff, residue=0x1d0f
116 *
117 * @param seed Value to seed the CRC with
118 * @param src Input bytes for the computation
119 * @param len Length of the input in bytes
120 *
121 * @return The computed CRC16 value
122 */
123 uint16_t crc16_itu_t(uint16_t seed, const uint8_t *src, size_t len);
124
125 /**
126 * @brief Compute ANSI variant of CRC 16
127 *
128 * ANSI variant of CRC 16 is using 0x8005 as its polynomial with the initial
129 * value set to 0xffff.
130 *
131 * @param src Input bytes for the computation
132 * @param len Length of the input in bytes
133 *
134 * @return The computed CRC16 value
135 */
crc16_ansi(const uint8_t * src,size_t len)136 static inline uint16_t crc16_ansi(const uint8_t *src, size_t len)
137 {
138 return crc16(src, len, 0x8005, 0xffff, true);
139 }
140
141 /**
142 * @brief Generate IEEE conform CRC32 checksum.
143 *
144 * @param *data Pointer to data on which the CRC should be calculated.
145 * @param len Data length.
146 *
147 * @return CRC32 value.
148 *
149 */
150 uint32_t crc32_ieee(const uint8_t *data, size_t len);
151
152 /**
153 * @brief Update an IEEE conforming CRC32 checksum.
154 *
155 * @param crc CRC32 checksum that needs to be updated.
156 * @param *data Pointer to data on which the CRC should be calculated.
157 * @param len Data length.
158 *
159 * @return CRC32 value.
160 *
161 */
162 uint32_t crc32_ieee_update(uint32_t crc, const uint8_t *data, size_t len);
163
164 /**
165 * @brief Calculate CRC32C (Castagnoli) checksum.
166 *
167 * @param crc CRC32C checksum that needs to be updated.
168 * @param *data Pointer to data on which the CRC should be calculated.
169 * @param len Data length.
170 * @param first_pkt Whether this is the first packet in the stream.
171 * @param last_pkt Whether this is the last packet in the stream.
172 *
173 * @return CRC32 value.
174 *
175 */
176 uint32_t crc32_c(uint32_t crc, const uint8_t *data,
177 size_t len, bool first_pkt, bool last_pkt);
178
179 /**
180 * @brief Compute CCITT variant of CRC 8
181 *
182 * Normal CCITT variant of CRC 8 is using 0x07.
183 *
184 * @param initial_value Initial value for the CRC computation
185 * @param buf Input bytes for the computation
186 * @param len Length of the input in bytes
187 *
188 * @return The computed CRC8 value
189 */
190 uint8_t crc8_ccitt(uint8_t initial_value, const void *buf, size_t len);
191
192 /**
193 * @brief Compute the CRC-7 checksum of a buffer.
194 *
195 * See JESD84-A441. Used by the MMC protocol. Uses 0x09 as the
196 * polynomial with no reflection. The CRC is left
197 * justified, so bit 7 of the result is bit 6 of the CRC.
198 *
199 * @param seed Value to seed the CRC with
200 * @param src Input bytes for the computation
201 * @param len Length of the input in bytes
202 *
203 * @return The computed CRC7 value
204 */
205 uint8_t crc7_be(uint8_t seed, const uint8_t *src, size_t len);
206
207 /**
208 * @}
209 */
210
211 #ifdef __cplusplus
212 }
213 #endif
214
215 #endif
216