1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
17 //-----------------------------------------------------------------------------
21 #include "commonutil.h"
23 static uint16_t crc_table
[256];
24 static bool crc_table_init
= false;
25 static CrcType_t current_crc_type
= CRC_NONE
;
27 void init_table(CrcType_t crctype
) {
29 // same crc algo, and initialised already
30 if (crctype
== current_crc_type
&& crc_table_init
)
33 // not the same crc algo. reset table.
34 if (crctype
!= current_crc_type
)
37 current_crc_type
= crctype
;
46 generate_table(CRC16_POLY_CCITT
, true);
53 generate_table(CRC16_POLY_CCITT
, false);
56 generate_table(CRC16_POLY_LEGIC
, true);
59 generate_table(CRC16_POLY_LEGIC_16
, true);
62 crc_table_init
= false;
63 current_crc_type
= CRC_NONE
;
68 void generate_table(uint16_t polynomial
, bool refin
) {
70 for (uint16_t i
= 0; i
< 256; i
++) {
77 for (uint16_t j
= 0; j
< 8; j
++) {
79 if ((crc
^ c
) & 0x8000)
80 crc
= (crc
<< 1) ^ polynomial
;
91 crc_table_init
= true;
94 void reset_table(void) {
95 memset(crc_table
, 0, sizeof(crc_table
));
96 crc_table_init
= false;
97 current_crc_type
= CRC_NONE
;
100 // table lookup LUT solution
101 uint16_t crc16_fast(uint8_t const *d
, size_t n
, uint16_t initval
, bool refin
, bool refout
) {
103 // fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
104 // only usable with polynom orders of 8, 16, 24 or 32.
108 uint16_t crc
= initval
;
111 crc
= reflect16(crc
);
114 while (n
--) crc
= (crc
<< 8) ^ crc_table
[((crc
>> 8) ^ *d
++) & 0xFF ];
116 while (n
--) crc
= (crc
>> 8) ^ crc_table
[(crc
& 0xFF) ^ *d
++];
119 crc
= reflect16(crc
);
124 // bit looped solution TODO REMOVED
125 uint16_t update_crc16_ex(uint16_t crc
, uint8_t c
, uint16_t polynomial
) {
127 uint16_t v
= (crc
^ c
) & 0xff;
129 for (uint16_t i
= 0; i
< 8; i
++) {
132 tmp
= (tmp
>> 1) ^ polynomial
;
138 return ((crc
>> 8) ^ tmp
) & 0xffff;
140 uint16_t update_crc16(uint16_t crc
, uint8_t c
) {
141 return update_crc16_ex(crc
, c
, CRC16_POLY_CCITT
);
144 // two ways. msb or lsb loop.
145 uint16_t Crc16(uint8_t const *d
, size_t length
, uint16_t remainder
, uint16_t polynomial
, bool refin
, bool refout
) {
149 for (uint32_t i
= 0; i
< length
; ++i
) {
151 if (refin
) c
= reflect8(c
);
154 remainder
^= (c
<< 8);
157 for (uint8_t j
= 8; j
; --j
) {
158 if (remainder
& 0x8000) {
159 remainder
= (remainder
<< 1) ^ polynomial
;
166 remainder
= reflect16(remainder
);
171 void compute_crc(CrcType_t ct
, const uint8_t *d
, size_t n
, uint8_t *first
, uint8_t *second
) {
173 // can't calc a crc on less than 1 byte
186 crc
= crc16_x25(d
, n
);
189 crc
= crc16_iclass(d
, n
);
193 crc
= crc16_xmodem(d
, n
);
196 crc
= crc16_ccitt(d
, n
);
199 crc
= crc16_kermit(d
, n
);
202 crc
= crc16_fdxb(d
, n
);
209 crc
= crc16_philips(d
, n
);
214 *first
= (crc
& 0xFF);
215 *second
= ((crc
>> 8) & 0xFF);
217 uint16_t Crc16ex(CrcType_t ct
, const uint8_t *d
, size_t n
) {
219 // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
225 return crc16_a(d
, n
);
229 return crc16_x25(d
, n
);
231 return crc16_iclass(d
, n
);
234 return crc16_xmodem(d
, n
);
236 return crc16_ccitt(d
, n
);
238 return crc16_kermit(d
, n
);
240 return crc16_fdxb(d
, n
);
246 return crc16_philips(d
, n
);
256 // d buffer with data
257 // n length (including crc)
259 // This function uses the message + crc bytes in order to compare the "residue" afterwards.
260 // crc16 algos like CRC-A become 0x0000
261 // while CRC-15693 become 0x0F47
262 // If calculated with crc bytes, the residue should be 0xF0B8
263 bool check_crc(CrcType_t ct
, const uint8_t *d
, size_t n
) {
265 // can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
266 if (n
< 3) return false;
272 return (crc16_a(d
, n
) == 0);
275 return (crc16_x25(d
, n
) == X25_CRC_CHECK
);
277 return (crc16_x25(d
, n
) == X25_CRC_CHECK
);
279 return (crc16_iclass(d
, n
) == 0);
282 return (crc16_xmodem(d
, n
) == 0);
284 return (crc16_ccitt(d
, n
) == 0);
286 return (crc16_kermit(d
, n
) == 0);
288 return (crc16_fdxb(d
, n
) == 0);
294 return (crc16_philips(d
, n
) == 0);
302 // poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
303 uint16_t crc16_ccitt(uint8_t const *d
, size_t n
) {
304 return crc16_fast(d
, n
, 0xffff, false, false);
307 // FDX-B ISO11784/85) uses KERMIT/CCITT
308 // poly 0x xx init=0x000 refin=false refout=true xorout=0x0000 ...
309 uint16_t crc16_fdxb(uint8_t const *d
, size_t n
) {
310 return crc16_fast(d
, n
, 0x0000, false, true);
313 // poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
314 uint16_t crc16_kermit(uint8_t const *d
, size_t n
) {
315 return crc16_fast(d
, n
, 0x0000, true, true);
318 // FeliCa uses XMODEM
319 // poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
320 uint16_t crc16_xmodem(uint8_t const *d
, size_t n
) {
321 return crc16_fast(d
, n
, 0x0000, false, false);
324 // Following standards uses X-25
327 // ISO/IEC 13239 (formerly ISO/IEC 3309)
328 // poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
329 uint16_t crc16_x25(uint8_t const *d
, size_t n
) {
330 uint16_t crc
= crc16_fast(d
, n
, 0xffff, true, true);
335 // poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
336 uint16_t crc16_a(uint8_t const *d
, size_t n
) {
337 return crc16_fast(d
, n
, 0xC6C6, true, true);
341 // initvalue 0x4807 reflected 0xE012
342 // poly 0x1021 reflected 0x8408
343 // poly=0x1021 init=0x4807 refin=true refout=true xorout=0x0BC3 check=0xF0B8 name="CRC-16/ICLASS"
344 uint16_t crc16_iclass(uint8_t const *d
, size_t n
) {
345 return crc16_fast(d
, n
, 0x4807, true, true);
348 // This CRC-16 is used in Legic Advant systems.
349 // poly=0xB400, init=depends refin=true refout=true xorout=0x0000 check= name="CRC-16/LEGIC"
350 uint16_t crc16_legic(uint8_t const *d
, size_t n
, uint8_t uidcrc
) {
351 uint16_t initial
= (uidcrc
<< 8 | uidcrc
);
352 return crc16_fast(d
, n
, initial
, true, false);
355 uint16_t crc16_philips(uint8_t const *d
, size_t n
) {
356 return crc16_fast(d
, n
, 0x49A3, false, false);