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