mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -07:00
CHG: refactor CRC16 algos. This is a big change, most likely some parts broke, hard to test it all.
This commit is contained in:
parent
d2e9f4a743
commit
52d69ed4ee
35 changed files with 512 additions and 674 deletions
103
common/crc16.c
103
common/crc16.c
|
@ -24,14 +24,14 @@ void init_table(CrcType_t ct) {
|
|||
crc_type = ct;
|
||||
|
||||
switch (ct) {
|
||||
case CRC_14A:
|
||||
case CRC_14B:
|
||||
case CRC_15:
|
||||
case CRC_15_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
|
||||
case CRC_14443_A:
|
||||
case CRC_14443_B:
|
||||
case CRC_15693:
|
||||
case CRC_ICLASS: generate_table(CRC16_POLY_CCITT, true); break;
|
||||
case CRC_FELICA: generate_table(CRC16_POLY_CCITT, false); break;
|
||||
case CRC_LEGIC: generate_table(CRC16_POLY_LEGIC, true); break;
|
||||
case CRC_DNP: generate_table(CRC16_POLY_DNP, true); break;
|
||||
case CRC_CCITT: generate_table(CRC16_POLY_CCITT, false); break;
|
||||
case CRC_KERMIT: generate_table(CRC16_POLY_CCITT, true); break;
|
||||
default:
|
||||
crc_table_init = false;
|
||||
crc_type = CRC_NONE;
|
||||
|
@ -97,7 +97,7 @@ uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bo
|
|||
return crc;
|
||||
}
|
||||
|
||||
// bit looped solution
|
||||
// bit looped solution TODO REMOVED
|
||||
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial ) {
|
||||
uint16_t i, v, tmp = 0;
|
||||
|
||||
|
@ -148,40 +148,88 @@ uint16_t crc16(uint8_t const *d, size_t length, uint16_t remainder, uint16_t pol
|
|||
|
||||
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second) {
|
||||
|
||||
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
||||
if ( n < 3 ) return;
|
||||
// can't calc a crc on less than 1 byte
|
||||
if ( n == 0 ) return;
|
||||
|
||||
init_table(ct);
|
||||
|
||||
uint16_t crc = 0;
|
||||
switch (ct) {
|
||||
case CRC_14A: crc = crc16_a(d, n); break;
|
||||
case CRC_14B:
|
||||
case CRC_15: crc = crc16_x25(d, n); break;
|
||||
case CRC_15_ICLASS: crc = crc16_iclass(d, n); break;
|
||||
case CRC_14443_A: crc = crc16_a(d, n); break;
|
||||
case CRC_14443_B:
|
||||
case CRC_15693: crc = crc16_x25(d, n); break;
|
||||
case CRC_ICLASS: crc = crc16_iclass(d, n); break;
|
||||
case CRC_FELICA:crc = crc16_xmodem(d, n); break;
|
||||
//case CRC_LEGIC:
|
||||
case CRC_DNP: crc = crc16_dnp(d, n); break;
|
||||
case CRC_CCITT: crc = crc16_ccitt(d, n); break;
|
||||
case CRC_KERMIT: crc = crc16_kermit(d, n); break;
|
||||
default: break;
|
||||
}
|
||||
*first = (crc & 0xFF);
|
||||
*second = ((crc >> 8) & 0xFF);
|
||||
}
|
||||
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
||||
|
||||
//poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
|
||||
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
||||
if ( n < 3 ) return 0;
|
||||
|
||||
init_table(ct);
|
||||
switch (ct) {
|
||||
case CRC_14443_A: return crc16_a(d, n);
|
||||
case CRC_14443_B:
|
||||
case CRC_15693: return crc16_x25(d, n);
|
||||
case CRC_ICLASS: return crc16_iclass(d, n);
|
||||
case CRC_FELICA: return crc16_xmodem(d, n);
|
||||
//case CRC_LEGIC:
|
||||
case CRC_CCITT: return crc16_ccitt(d, n);
|
||||
case CRC_KERMIT: return crc16_kermit(d, n);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check CRC
|
||||
// ct crc type
|
||||
// d buffer with data
|
||||
// n length (including crc)
|
||||
//
|
||||
// This function uses the message + crc bytes in order to compare the "residue" afterwards.
|
||||
// crc16 algos like CRC-A become 0x000
|
||||
// while CRC-15693 become 0x0F47
|
||||
// If calculated with crc bytes, the residue should be 0xF0B8
|
||||
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n) {
|
||||
|
||||
// can't calc a crc on less than 3 byte. (1byte + 2 crc bytes)
|
||||
if ( n < 3 ) return false;
|
||||
|
||||
init_table(ct);
|
||||
|
||||
switch (ct) {
|
||||
case CRC_14443_A: return (crc16_a(d, n) == 0);
|
||||
case CRC_14443_B: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
||||
case CRC_15693: return (crc16_x25(d, n) == X25_CRC_CHECK);
|
||||
case CRC_ICLASS: return (crc16_iclass(d, n) == 0);
|
||||
case CRC_FELICA: return (crc16_xmodem(d, n) == 0);
|
||||
//case CRC_LEGIC:
|
||||
case CRC_CCITT: return (crc16_ccitt(d, n) == 0);
|
||||
default: break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/CCITT-FALSE"
|
||||
uint16_t crc16_ccitt(uint8_t const *d, size_t n) {
|
||||
return crc16_fast(d, n, 0xffff, false, false);
|
||||
}
|
||||
|
||||
// FDX-B ISO11784/85) uses KERMIT
|
||||
//poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
|
||||
// poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 name="KERMIT"
|
||||
uint16_t crc16_kermit(uint8_t const *d, size_t n) {
|
||||
return crc16_fast(d, n, 0x0000, true, true);
|
||||
}
|
||||
|
||||
// FeliCa uses XMODEM
|
||||
//poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
|
||||
// poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 name="XMODEM"
|
||||
uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
|
||||
return crc16_fast(d, n, 0x0000, false, false);
|
||||
}
|
||||
|
@ -190,14 +238,14 @@ uint16_t crc16_xmodem(uint8_t const *d, size_t n) {
|
|||
// ISO 15693,
|
||||
// ISO 14443 CRC-B
|
||||
// ISO/IEC 13239 (formerly ISO/IEC 3309)
|
||||
//poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
|
||||
// poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff name="X-25"
|
||||
uint16_t crc16_x25(uint8_t const *d, size_t n) {
|
||||
uint16_t crc = crc16_fast(d, n, 0xffff, true, true);
|
||||
crc = ~crc;
|
||||
return crc;
|
||||
}
|
||||
// CRC-A (14443-3)
|
||||
//poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
|
||||
// CRC-A (14443-3)
|
||||
// poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 name="CRC-A"
|
||||
uint16_t crc16_a(uint8_t const *d, size_t n) {
|
||||
return crc16_fast(d, n, 0xC6C6, true, true);
|
||||
}
|
||||
|
@ -216,20 +264,3 @@ uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc) {
|
|||
uint16_t initial = uidcrc << 8 | uidcrc;
|
||||
return crc16_fast(d, n, initial, true, true);
|
||||
}
|
||||
|
||||
// poly=0x3d65 init=0x0000 refin=true refout=true xorout=0xffff check=0xea82 name="CRC-16/DNP"
|
||||
uint16_t crc16_dnp(uint8_t const *d, size_t n) {
|
||||
uint16_t crc = crc16_fast(d, n, 0, true, true);
|
||||
crc = ~crc;
|
||||
return crc;
|
||||
}
|
||||
|
||||
// -----------------CHECK functions.
|
||||
bool check_crc16_ccitt(uint8_t const *d, size_t n) {
|
||||
if (n < 3) return false;
|
||||
|
||||
uint16_t crc = crc16_ccitt(d, n - 2);
|
||||
if ((( crc & 0xff ) == d[n-2]) && (( crc >> 8 ) == d[n-1]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
|
@ -16,47 +16,47 @@
|
|||
#define CRC16_POLY_LEGIC 0xc6c6 //0x6363
|
||||
#define CRC16_POLY_DNP 0x3d65
|
||||
|
||||
#define X25_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
|
||||
|
||||
typedef enum {
|
||||
CRC_NONE,
|
||||
CRC_14A,
|
||||
CRC_14B,
|
||||
CRC_15,
|
||||
CRC_15_ICLASS,
|
||||
CRC_14443_A,
|
||||
CRC_14443_B,
|
||||
CRC_15693,
|
||||
CRC_ICLASS,
|
||||
CRC_FELICA,
|
||||
CRC_LEGIC,
|
||||
CRC_DNP,
|
||||
CRC_CCITT,
|
||||
CRC_KERMIT,
|
||||
} CrcType_t;
|
||||
|
||||
uint16_t update_crc16_ex( uint16_t crc, uint8_t c, uint16_t polynomial );
|
||||
uint16_t update_crc16(uint16_t crc, uint8_t c);
|
||||
uint16_t crc16(uint8_t const *message, size_t length, uint16_t remainder, uint16_t polynomial, bool refin, bool refout);
|
||||
|
||||
//
|
||||
uint16_t crc(CrcType_t ct, const uint8_t *d, size_t n);
|
||||
void compute_crc(CrcType_t ct, const uint8_t *d, size_t n, uint8_t *first, uint8_t *second);
|
||||
bool check_crc(CrcType_t ct, const uint8_t *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/CCITT-FALSE checksum
|
||||
// Calculate CRC-16/CCITT-FALSE
|
||||
uint16_t crc16_ccitt(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/KERMIT checksum
|
||||
// Calculate CRC-16/KERMIT (FDX-B ISO11784/85) LF
|
||||
uint16_t crc16_kermit(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/XMODEM (FeliCa) checksum
|
||||
// Calculate CRC-16/XMODEM (FeliCa)
|
||||
uint16_t crc16_xmodem(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/X25 (ISO15693, ISO14443 CRC-B,ISO/IEC 13239) checksum
|
||||
// Calculate CRC-16/X25 (ISO15693, ISO14443 CRC-B,ISO/IEC 13239)
|
||||
uint16_t crc16_x25(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/CRC-A (ISO14443 CRC-A) checksum
|
||||
// Calculate CRC-16/CRC-A (ISO14443 CRC-A)
|
||||
uint16_t crc16_a(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/iCLASS checksum
|
||||
// Calculate CRC-16/iCLASS
|
||||
uint16_t crc16_iclass(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/DNP checksum
|
||||
uint16_t crc16_dnp(uint8_t const *d, size_t n);
|
||||
|
||||
// Calculate CRC-16/Legic checksum
|
||||
// Calculate CRC-16/Legic
|
||||
// the initial_value is based on the previous legic_Crc8 of the UID.
|
||||
// ie: uidcrc = 0x78 then initial_value == 0x7878
|
||||
uint16_t crc16_legic(uint8_t const *d, size_t n, uint8_t uidcrc);
|
||||
|
@ -67,7 +67,4 @@ void reset_table(void);
|
|||
void generate_table(uint16_t polynomial, bool refin);
|
||||
uint16_t crc16_fast(uint8_t const *d, size_t n, uint16_t initval, bool refin, bool refout);
|
||||
|
||||
//checks
|
||||
bool check_crc16_ccitt(uint8_t const *d, size_t n);
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "iso14443crc.h"
|
||||
|
||||
|
||||
uint16_t UpdateCrc14443(uint8_t b, uint16_t *crc) {
|
||||
b = (b ^ (uint8_t)((*crc) & 0x00FF));
|
||||
b = (b ^ (b << 4));
|
||||
|
@ -41,4 +42,4 @@ bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length) {
|
|||
if ((b1 == data[length - 2]) && (b2 == data[length - 1]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,14 +13,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Routines to compute the CRCs (two different flavours, just for confusion)
|
||||
// required for ISO 14443, swiped directly from the spec.
|
||||
//-----------------------------------------------------------------------------
|
||||
#define CRC_14443_A 0x6363 /* ITU-V.41 */
|
||||
#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
|
||||
#define CRC_ICLASS 0xE012 /* ICLASS PREFIX */
|
||||
|
||||
uint16_t UpdateCrc14443(uint8_t b, uint16_t *crc);
|
||||
void ComputeCrc14443(uint16_t CrcType, const uint8_t *data, int length,
|
||||
uint8_t *TransmitFirst, uint8_t *TransmitSecond);
|
||||
bool CheckCrc14443(uint16_t CrcType, const uint8_t *data, int length);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,35 +3,10 @@
|
|||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO15693 CRC & other commons
|
||||
// ISO15693 other commons
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "iso15693tools.h"
|
||||
|
||||
// The CRC as described in ISO 15693-Part 3-Annex C
|
||||
uint16_t Iso15693Crc(uint8_t *d, size_t n){
|
||||
init_table(CRC_15);
|
||||
return crc16_x25(d, n);
|
||||
}
|
||||
|
||||
// adds a CRC to a dataframe
|
||||
// d[] iso15963 frame without crc
|
||||
// n length without crc
|
||||
// returns the new length of the dataframe.
|
||||
int Iso15693AddCrc(uint8_t *d, size_t n) {
|
||||
uint16_t crc = Iso15693Crc(d, n);
|
||||
d[n] = crc & 0xff;
|
||||
d[n+1] = crc >> 8;
|
||||
return n + 2;
|
||||
}
|
||||
|
||||
// check the CRC as described in ISO 15693-Part 3-Annex C
|
||||
// v buffer with data
|
||||
// n length (including crc)
|
||||
// If calculated with crc bytes, the residue should be 0xF0B8
|
||||
bool Iso15693CheckCrc(uint8_t *d, size_t n) {
|
||||
return (Iso15693Crc(d, n) == ISO15_CRC_CHECK );
|
||||
}
|
||||
|
||||
int sprintf(char *str, const char *format, ...);
|
||||
|
||||
// returns a string representation of the UID
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// ISO15693 commons
|
||||
// Adrian Dabrowski 2010 and others, GPLv2
|
||||
// Christian Herrmann 2018
|
||||
|
||||
#ifndef ISO15693_H__
|
||||
#define ISO15693_H__
|
||||
|
@ -9,11 +10,6 @@
|
|||
#include <stdlib.h>
|
||||
#include "crc16.h"
|
||||
|
||||
// ISO15693 CRC
|
||||
#define ISO15_CRC_PRESET (uint16_t)0xFFFF
|
||||
#define ISO15_CRC_POLY (uint16_t)0x8408
|
||||
#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
|
||||
|
||||
// REQUEST FLAGS
|
||||
|
||||
#define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
|
||||
|
@ -71,13 +67,8 @@
|
|||
#define ISO15_CMD_SYSINFO 0x2B
|
||||
#define ISO15_CMD_SECSTATUS 0x2C
|
||||
|
||||
|
||||
uint16_t Iso15693Crc(uint8_t *d, size_t n);
|
||||
int Iso15693AddCrc(uint8_t *d, size_t n);
|
||||
bool Iso15693CheckCrc(uint8_t *d, size_t n);
|
||||
char* Iso15693sprintUID(char *target, uint8_t *uid);
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Map a sequence of octets (~layer 2 command) into the set of bits to feed
|
||||
// to the FPGA, to transmit that command to the tag.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue