CRC optional, replaced by magic on USB

This commit is contained in:
Philippe Teuwen 2019-04-18 21:39:35 +02:00
commit 9ff841efb2
7 changed files with 75 additions and 49 deletions

View file

@ -1452,11 +1452,7 @@ static void PacketReceived(PacketCommandNG *packet) {
if (packet->ng) { if (packet->ng) {
reply_ng(CMD_PING, PM3_SUCCESS, packet->data.asBytes, packet->length); reply_ng(CMD_PING, PM3_SUCCESS, packet->data.asBytes, packet->length);
} else { } else {
#ifdef WITH_FPC_HOST
reply_old(CMD_ACK, reply_via_fpc, 0, 0, 0, 0); reply_old(CMD_ACK, reply_via_fpc, 0, 0, 0, 0);
#else
reply_old(CMD_ACK, 0, 0, 0, 0, 0);
#endif
} }
break; break;
#ifdef WITH_LCD #ifdef WITH_LCD

View file

@ -222,7 +222,9 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
void iClass_ReadCheck(uint8_t blockno, uint8_t keytype); void iClass_ReadCheck(uint8_t blockno, uint8_t keytype);
// cmd.h // cmd.h
uint8_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); int16_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
int16_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
int16_t receive_ng(PacketCommandNG *rx);
// util.h // util.h
void HfSniff(int, int); void HfSniff(int, int);

View file

@ -18,6 +18,11 @@ static char *serial_port_name = NULL;
// If TRUE, then there is no active connection to the PM3, and we will drop commands sent. // If TRUE, then there is no active connection to the PM3, and we will drop commands sent.
static bool offline; static bool offline;
// Flags to tell where to add CRC on sent replies
bool send_with_crc_on_usb = false;
bool send_with_crc_on_fpc = true;
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
bool send_via_fpc = false;
static communication_arg_t conn; static communication_arg_t conn;
@ -120,9 +125,16 @@ void SendCommandNG(uint16_t cmd, uint8_t *data, size_t len) {
txBufferNG.pre.length = len; txBufferNG.pre.length = len;
txBufferNG.pre.cmd = cmd; txBufferNG.pre.cmd = cmd;
memcpy(&txBufferNG.data, data, len); memcpy(&txBufferNG.data, data, len);
uint8_t first, second;
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketCommandNGPreamble) + len, &first, &second); if ((send_via_fpc && send_with_crc_on_fpc) || ((!send_via_fpc) && send_with_crc_on_usb)) {
tx_post->crc = (first << 8) + second; uint8_t first, second;
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketCommandNGPreamble) + len, &first, &second);
tx_post->crc = (first << 8) + second;
} else {
tx_post->crc = USB_COMMANDNG_POSTAMBLE_MAGIC;
}
txBufferNGLen = sizeof(PacketCommandNGPreamble) + len + sizeof(PacketCommandNGPostamble); txBufferNGLen = sizeof(PacketCommandNGPreamble) + len + sizeof(PacketCommandNGPostamble);
txBuffer_pending = true; txBuffer_pending = true;
@ -316,13 +328,15 @@ __attribute__((force_align_arg_pointer))
error = true; error = true;
} }
} }
if (!error) { // Check CRC if (!error) { // Check CRC, accept MAGIC as placeholder
rx.crc = rx_raw.foopost.crc; rx.crc = rx_raw.foopost.crc;
uint8_t first, second; if (rx.crc != USB_REPLYNG_POSTAMBLE_MAGIC) {
compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + rx.length, &first, &second); uint8_t first, second;
if ((first << 8) + second != rx.crc) { compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketResponseNGPreamble) + rx.length, &first, &second);
PrintAndLogEx(WARNING, "Received packet frame CRC error %02X%02X <> %04X", first, second, rx.crc); if ((first << 8) + second != rx.crc) {
error = true; PrintAndLogEx(WARNING, "Received packet frame CRC error %02X%02X <> %04X", first, second, rx.crc);
error = true;
}
} }
} }
if (!error) { if (!error) {
@ -463,7 +477,8 @@ int TestProxmark(void) {
PacketCommandOLD c = {CMD_PING, {0, 0, 0}, {{0}}}; PacketCommandOLD c = {CMD_PING, {0, 0, 0}, {{0}}};
SendCommand(&c); SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK, &resp, 5000)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 5000)) {
PrintAndLogEx(INFO, "Communicating with PM3 over %s.", resp.oldarg[0] == 1 ? "FPC" : "USB"); send_via_fpc = resp.oldarg[0] == 1;
PrintAndLogEx(INFO, "Communicating with PM3 over %s.", send_via_fpc ? "FPC" : "USB");
return 1; return 1;
} else { } else {
return 0; return 0;

View file

@ -44,6 +44,11 @@ typedef struct {
bool block_after_ACK; // if true, block after receiving an ACK package bool block_after_ACK; // if true, block after receiving an ACK package
} communication_arg_t; } communication_arg_t;
// Flags to tell where to add CRC on sent replies
extern bool send_with_crc_on_usb;
extern bool send_with_crc_on_fpc;
// "Session" flag, to tell via which interface next msgs are sent: USB or FPC USART
extern bool send_via_fpc;
void SetOffline(bool value); void SetOffline(bool value);
bool IsOffline(void); bool IsOffline(void);

View file

@ -32,18 +32,22 @@
#include "cmd.h" #include "cmd.h"
#include "crc16.h" #include "crc16.h"
#ifdef WITH_FPC_HOST // Flags to tell where to add CRC on sent replies
bool reply_with_crc_on_usb = false;
bool reply_with_crc_on_fpc = true;
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART // "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
bool reply_via_fpc = false; bool reply_via_fpc = false;
#ifdef WITH_FPC_HOST
extern void Dbprintf(const char *fmt, ...); extern void Dbprintf(const char *fmt, ...);
#define Dbprintf_usb(...) {\ #define Dbprintf_usb(...) {\
bool tmp = reply_via_fpc;\
reply_via_fpc = false;\ reply_via_fpc = false;\
Dbprintf(__VA_ARGS__);\ Dbprintf(__VA_ARGS__);\
reply_via_fpc = true;} reply_via_fpc = tmp;}
#endif #endif
uint8_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) { int16_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len) {
PacketResponseOLD txcmd; PacketResponseOLD txcmd;
for (size_t i = 0; i < sizeof(PacketResponseOLD); i++) for (size_t i = 0; i < sizeof(PacketResponseOLD); i++)
@ -66,21 +70,21 @@ uint8_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, voi
uint32_t sendlen = 0; uint32_t sendlen = 0;
// Send frame and make sure all bytes are transmitted // Send frame and make sure all bytes are transmitted
#ifdef WITH_FPC_HOST
if (reply_via_fpc) { if (reply_via_fpc) {
#ifdef WITH_FPC_HOST
sendlen = usart_writebuffer((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); sendlen = usart_writebuffer((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
// Dbprintf_usb("Sent %i bytes over usart", len); // Dbprintf_usb("Sent %i bytes over usart", len);
#else
return PM3_EDEVNOTSUPP;
#endif
} else { } else {
sendlen = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD)); sendlen = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
} }
#else
sendlen = usb_write((uint8_t *)&txcmd, sizeof(PacketResponseOLD));
#endif
return sendlen; return sendlen;
} }
uint8_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) { int16_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) {
PacketResponseNGRaw txBufferNG; PacketResponseNGRaw txBufferNG;
size_t txBufferNGLen; size_t txBufferNGLen;
// for (size_t i = 0; i < sizeof(txBufferNG); i++) // for (size_t i = 0; i < sizeof(txBufferNG); i++)
@ -104,26 +108,29 @@ uint8_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len) {
} }
} }
uint8_t first, second;
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second);
PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len); PacketResponseNGPostamble *tx_post = (PacketResponseNGPostamble *)((uint8_t *)&txBufferNG + sizeof(PacketResponseNGPreamble) + len);
tx_post->crc = (first << 8) + second; if ((reply_via_fpc && reply_with_crc_on_fpc) || ((!reply_via_fpc) && reply_with_crc_on_usb)) {
uint8_t first, second;
compute_crc(CRC_14443_A, (uint8_t *)&txBufferNG, sizeof(PacketResponseNGPreamble) + len, &first, &second);
tx_post->crc = (first << 8) + second;
} else {
tx_post->crc = USB_REPLYNG_POSTAMBLE_MAGIC;
}
txBufferNGLen = sizeof(PacketResponseNGPreamble) + len + sizeof(PacketResponseNGPostamble); txBufferNGLen = sizeof(PacketResponseNGPreamble) + len + sizeof(PacketResponseNGPostamble);
uint32_t sendlen = 0; uint32_t sendlen = 0;
// Send frame and make sure all bytes are transmitted // Send frame and make sure all bytes are transmitted
#ifdef WITH_FPC_HOST
if (reply_via_fpc) { if (reply_via_fpc) {
#ifdef WITH_FPC_HOST
sendlen = usart_writebuffer((uint8_t *)&txBufferNG, txBufferNGLen); sendlen = usart_writebuffer((uint8_t *)&txBufferNG, txBufferNGLen);
// Dbprintf_usb("Sent %i bytes over usart", len); // Dbprintf_usb("Sent %i bytes over usart", len);
#else
return PM3_EDEVNOTSUPP;
#endif
} else { } else {
sendlen = usb_write((uint8_t *)&txBufferNG, txBufferNGLen); sendlen = usb_write((uint8_t *)&txBufferNG, txBufferNGLen);
} }
#else
sendlen = usb_write((uint8_t *)&txBufferNG, txBufferNGLen);
#endif
return sendlen; return sendlen;
} }
@ -148,15 +155,15 @@ int16_t receive_ng(PacketCommandNG *rx) {
bytes = usb_read_ng((uint8_t *)&rx_raw.foopost, sizeof(PacketCommandNGPostamble)); bytes = usb_read_ng((uint8_t *)&rx_raw.foopost, sizeof(PacketCommandNGPostamble));
if (bytes != sizeof(PacketCommandNGPostamble)) if (bytes != sizeof(PacketCommandNGPostamble))
return PM3_EIO; return PM3_EIO;
// Check CRC // Check CRC, accept MAGIC as placeholder
rx->crc = rx_raw.foopost.crc; rx->crc = rx_raw.foopost.crc;
uint8_t first, second; if (rx->crc != USB_COMMANDNG_POSTAMBLE_MAGIC) {
compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketCommandNGPreamble) + rx->length, &first, &second); uint8_t first, second;
if ((first << 8) + second != rx->crc) compute_crc(CRC_14443_A, (uint8_t *)&rx_raw, sizeof(PacketCommandNGPreamble) + rx->length, &first, &second);
return PM3_EIO; if ((first << 8) + second != rx->crc)
#ifdef WITH_FPC_HOST return PM3_EIO;
}
reply_via_fpc = false; reply_via_fpc = false;
#endif
rx->ng = true; rx->ng = true;
} else { // Old style command } else { // Old style command
PacketCommandOLD rx_old; PacketCommandOLD rx_old;
@ -164,9 +171,7 @@ int16_t receive_ng(PacketCommandNG *rx) {
bytes = usb_read_ng(((uint8_t *)&rx_old) + sizeof(PacketCommandNGPreamble), sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble)); bytes = usb_read_ng(((uint8_t *)&rx_old) + sizeof(PacketCommandNGPreamble), sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble));
if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble)) if (bytes != sizeof(PacketCommandOLD) - sizeof(PacketCommandNGPreamble))
return PM3_EIO; return PM3_EIO;
#ifdef WITH_FPC_HOST
reply_via_fpc = false; reply_via_fpc = false;
#endif
rx->ng = false; rx->ng = false;
rx->magic = 0; rx->magic = 0;
rx->crc = 0; rx->crc = 0;

View file

@ -39,9 +39,15 @@
#include "usart.h" #include "usart.h"
#include "proxmark3.h" #include "proxmark3.h"
uint8_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len); int16_t reply_old(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
uint8_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len); int16_t reply_ng(uint16_t cmd, int16_t status, uint8_t *data, size_t len);
int16_t receive_ng(PacketCommandNG *rx); int16_t receive_ng(PacketCommandNG *rx);
// Flags to tell where to add CRC on sent replies
extern bool reply_with_crc_on_usb;
extern bool reply_with_crc_on_fpc;
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
extern bool reply_via_fpc;
#endif // _PROXMARK_CMD_H_ #endif // _PROXMARK_CMD_H_

View file

@ -41,7 +41,8 @@ typedef struct {
uint16_t cmd; uint16_t cmd;
} PACKED PacketCommandNGPreamble; } PACKED PacketCommandNGPreamble;
#define USB_COMMANDNG_PREAMBLE_MAGIC 0x61334d50 // PM3a #define USB_COMMANDNG_PREAMBLE_MAGIC 0x61334d50 // PM3a
#define USB_COMMANDNG_POSTAMBLE_MAGIC 0x3361 // a3
typedef struct { typedef struct {
uint16_t crc; uint16_t crc;
@ -84,7 +85,8 @@ typedef struct {
uint16_t cmd; uint16_t cmd;
} PACKED PacketResponseNGPreamble; } PACKED PacketResponseNGPreamble;
#define USB_REPLYNG_PREAMBLE_MAGIC 0x62334d50 // PM3b #define USB_REPLYNG_PREAMBLE_MAGIC 0x62334d50 // PM3b
#define USB_REPLYNG_POSTAMBLE_MAGIC 0x3362 // b3
typedef struct { typedef struct {
uint16_t crc; uint16_t crc;
@ -112,11 +114,6 @@ typedef struct {
PacketResponseNGPostamble foopost; // Probably not at that offset! PacketResponseNGPostamble foopost; // Probably not at that offset!
} PACKED PacketResponseNGRaw; } PACKED PacketResponseNGRaw;
#ifdef WITH_FPC_HOST
// "Session" flag, to tell via which interface next msgs should be sent: USB or FPC USART
extern bool reply_via_fpc;
#endif
// A struct used to send sample-configs over USB // A struct used to send sample-configs over USB
typedef struct { typedef struct {
uint8_t decimation; uint8_t decimation;