1 /* crc.c
2  * crc checksum generation and calculation functions: crc.c
3  *
4  * Copyright (c) 2007 by Intel Corporation.
5  *
6  * Author: Mike Harvey <michael.harvey@intel.com>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1999 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14 
15 #include "crc.h"
16 
17 #define WMAX_MAC_CRC32_POLYNOMIAL 0x04c11db7U /* polynomial used in calculating the CRC-32 checksum */
18 #define CCITT_X25_CRC16_POLYNOMIAL 0x1021     /* polynomial used in calculating the CRC-16 checksum */
19 #define WMAX_MAC_CRC8_POLYNOMIAL  0x07        /* polynomial used in calculating the CRC-8 checksum */
20 #define CRC32_INITIAL_VALUE       0xFFFFFFFF
21 #define CRC16_INITIAL_VALUE       0xFFFF
22 
23 #ifndef STATIC_DATA
24 static guint8  crc8_table[256];
25 static guint32 crc32_table[256];
26 
27 extern guint16 crc16_table[256];
28 
29 /*
30   void wimax_mac_gen_crc32_table(void)
31 
32   REQUIRES: The functions must be called only once to initialze CRC table
33 
34   DESCRIPTION:  Generate the table of CRC remainders
35                 for all possible bytes
36 
37   ARGS:
38 
39   RETURNS:
40 
41   SIDE EFFECTS:
42 
43 */
wimax_mac_gen_crc32_table(void)44 void wimax_mac_gen_crc32_table(void)
45 {
46   guint32 i, bit;
47   guint32 crc;
48 
49   /* little-endian (reflected) algorithm */
50   for ( i = 0;  i < G_N_ELEMENTS(crc32_table);  i++ )
51   {
52     crc = ( i << 24 );
53     for ( bit = 0;  bit < 8;  bit++ )
54     {
55       if ( crc & 0x80000000U )
56         crc = ( crc << 1 ) ^ WMAX_MAC_CRC32_POLYNOMIAL;
57       else
58         crc = ( crc << 1 );
59     }
60     crc32_table[i] = crc;
61   }
62 }
63 
64 /*
65   void wimax_mac_gen_crc8_table(void)
66 
67   REQUIRES: The functions must be called only once to initialze CRC table
68 
69   DESCRIPTION:  Generate the table of CRC remainders
70                 for all possible bytes
71 
72   ARGS:
73 
74   RETURNS:
75 
76   SIDE EFFECTS:
77 
78 */
wimax_mac_gen_crc8_table(void)79 void wimax_mac_gen_crc8_table(void)
80 {
81   guint  i, bit;
82   guint8 crc;
83 
84   for ( i = 0;  i < G_N_ELEMENTS(crc8_table);  i++ )
85   {
86     crc = i;
87     for ( bit = 0;  bit < 8;  bit++ )
88     {
89       if ( crc & 0x80 )
90         crc = ( crc << 1 ) ^ WMAX_MAC_CRC8_POLYNOMIAL;
91       else
92         crc = ( crc << 1 );
93     }
94     crc8_table[i] = crc;
95   }
96 }
97 #endif
98 
99 /*
100 
101   guint32 wimax_mac_calc_crc32(guint8 *data, guint data_len)
102 
103   REQUIRES: wimax_mac_gen_crc32_table() must be called before
104 
105   DESCRIPTION: Calculate the 32-bit CRC from a given data block
106 
107   ARGS:  data - pointer to data
108          data_len - length of data (in bytes)
109 
110   RETURNS:  calculated crc32
111 
112   SIDE EFFECTS:
113 
114 */
wimax_mac_calc_crc32(const guint8 * data,guint data_len)115 guint32 wimax_mac_calc_crc32(const guint8 *data, guint data_len)
116 {
117   guint32 crc=CRC32_INITIAL_VALUE;
118   guint i, j;
119 
120   for ( j = 0;  j < data_len;  j++ )
121   {
122     i = ( (guint8)(crc>>24) ^ data[j] ) & 0xff;
123     crc = ( crc<<8 ) ^ crc32_table[i];
124   }
125   return ~crc;
126 }
127 
128 /*
129 
130   guint16 wimax_mac_calc_crc16(guint8 *data, guint data_len)
131 
132   REQUIRES: crc16_table[] in crc_data.c
133 
134   DESCRIPTION: Calculate the 16-bit CRC from a given data block
135 
136   ARGS:  data - pointer to data
137          data_len - length of data (in bytes)
138 
139   RETURNS:  calculated crc16
140 
141   SIDE EFFECTS:
142 
143 */
wimax_mac_calc_crc16(const guint8 * data,guint data_len)144 guint16 wimax_mac_calc_crc16(const guint8 *data, guint data_len)
145 {
146   guint32 crc=CRC16_INITIAL_VALUE;
147   guint j;
148 
149   for ( j = 0;  j < data_len;  j++ )
150   {
151     crc ^= data[j] << 8;
152     crc = (crc << 8) ^ crc16_table[(crc & 0xff00) >> 8];
153   }
154   crc ^= 0xFFFF;        /* Invert the output. */
155   crc &= 0xFFFF;
156   return crc;
157 }
158 
159 /*
160 
161   guint8 wimax_mac_calc_crc8(guint8 *data, guint data_len)
162 
163   REQUIRES: wimax_mac_gen_crc8_table() must be called before
164 
165   DESCRIPTION: Calculate the 8-bit CRC from a given data block
166 
167   ARGS:  data - pointer to data
168          data_len - length of data (in bytes)
169 
170   RETURNS:  calculated crc8
171 
172   SIDE EFFECTS:
173 
174 */
wimax_mac_calc_crc8(const guint8 * data,guint data_len)175 guint8 wimax_mac_calc_crc8(const guint8 *data, guint data_len)
176 {
177   guint8 crc=0;
178   guint i;
179 
180   for(i = 0; i < data_len; i++)
181   {
182     crc = crc8_table[data[i]^crc];
183   }
184   return crc;
185 }
186 
187 /*
188  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
189  *
190  * Local Variables:
191  * c-basic-offset: 2
192  * tab-width: 8
193  * indent-tabs-mode: nil
194  * End:
195  *
196  * ex: set shiftwidth=2 tabstop=8 expandtab:
197  * :indentSize=2:tabSize=8:noTabs=true:
198  */
199