mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-12 08:16:09 -07:00
Merged with master
This commit is contained in:
commit
0644d5e3a3
77 changed files with 441269 additions and 1214 deletions
97
armsrc/BigBuf.c
Normal file
97
armsrc/BigBuf.c
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Jonathan Westhues, Aug 2005
|
||||||
|
// Gerhard de Koning Gans, April 2008, May 2011
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// BigBuf and functions to allocate/free parts of it.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "proxmark3.h"
|
||||||
|
#include "apps.h"
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
||||||
|
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
||||||
|
|
||||||
|
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
||||||
|
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
|
||||||
|
|
||||||
|
// High memory mark
|
||||||
|
static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
||||||
|
|
||||||
|
// pointer to the emulator memory.
|
||||||
|
static uint8_t *emulator_memory = NULL;
|
||||||
|
|
||||||
|
// trace related global variables
|
||||||
|
// (only one left). ToDo: make this static as well?
|
||||||
|
uint16_t traceLen = 0;
|
||||||
|
|
||||||
|
|
||||||
|
// get the address of BigBuf
|
||||||
|
uint8_t *BigBuf_get_addr(void)
|
||||||
|
{
|
||||||
|
return (uint8_t *)BigBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||||
|
uint8_t *BigBuf_get_EM_addr(void)
|
||||||
|
{
|
||||||
|
if (emulator_memory == NULL) { // not yet allocated
|
||||||
|
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return emulator_memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// clear ALL of BigBuf
|
||||||
|
void BigBuf_Clear(void)
|
||||||
|
{
|
||||||
|
memset(BigBuf,0,BIGBUF_SIZE);
|
||||||
|
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||||
|
// at the beginning of BigBuf is always for traces/samples
|
||||||
|
uint8_t *BigBuf_malloc(uint16_t chunksize)
|
||||||
|
{
|
||||||
|
if (BigBuf_hi - chunksize < 0) {
|
||||||
|
return NULL; // no memory left
|
||||||
|
} else {
|
||||||
|
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||||
|
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||||
|
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||||
|
void BigBuf_free(void)
|
||||||
|
{
|
||||||
|
BigBuf_hi = BIGBUF_SIZE;
|
||||||
|
emulator_memory = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// free allocated chunks EXCEPT the emulator memory
|
||||||
|
void BigBuf_free_keep_EM(void)
|
||||||
|
{
|
||||||
|
if (emulator_memory != NULL) {
|
||||||
|
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||||
|
} else {
|
||||||
|
BigBuf_hi = BIGBUF_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||||
|
uint16_t BigBuf_max_traceLen(void)
|
||||||
|
{
|
||||||
|
return BigBuf_hi;
|
||||||
|
}
|
34
armsrc/BigBuf.h
Normal file
34
armsrc/BigBuf.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Jonathan Westhues, Aug 2005
|
||||||
|
// Gerhard de Koning Gans, April 2008, May 2011
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// BigBuf and functions to allocate/free parts of it.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __BIGBUF_H
|
||||||
|
#define __BIGBUF_H
|
||||||
|
|
||||||
|
|
||||||
|
#define BIGBUF_SIZE 40000
|
||||||
|
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||||
|
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||||
|
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||||
|
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||||
|
#define CARD_MEMORY_SIZE 4096
|
||||||
|
#define DMA_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
extern uint8_t *BigBuf_get_addr(void);
|
||||||
|
extern uint8_t *BigBuf_get_EM_addr(void);
|
||||||
|
extern uint16_t BigBuf_max_traceLen(void);
|
||||||
|
void BigBuf_Clear(void);
|
||||||
|
extern uint8_t *BigBuf_malloc(uint16_t);
|
||||||
|
extern void BigBuf_free(void);
|
||||||
|
extern void BigBuf_free_keep_EM(void);
|
||||||
|
|
||||||
|
extern uint16_t traceLen;
|
||||||
|
|
||||||
|
#endif /* __BIGBUF_H */
|
|
@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
|
||||||
|
|
||||||
#remove one of the following defines and comment out the relevant line
|
#remove one of the following defines and comment out the relevant line
|
||||||
#in the next section to remove that particular feature from compilation
|
#in the next section to remove that particular feature from compilation
|
||||||
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -fno-strict-aliasing
|
APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -fno-strict-aliasing
|
||||||
#-DWITH_LCD
|
#-DWITH_LCD
|
||||||
|
|
||||||
#SRC_LCD = fonts.c LCD.c
|
#SRC_LCD = fonts.c LCD.c
|
||||||
|
@ -18,7 +18,8 @@ SRC_LF = lfops.c hitag2.c lfsampling.c
|
||||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||||
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||||
SRC_ISO14443b = iso14443.c
|
SRC_ISO14443b = iso14443.c
|
||||||
SRC_CRAPTO1 = crapto1.c crypto1.c
|
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
|
||||||
|
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
|
||||||
|
|
||||||
THUMBSRC = start.c \
|
THUMBSRC = start.c \
|
||||||
$(SRC_LCD) \
|
$(SRC_LCD) \
|
||||||
|
@ -34,15 +35,14 @@ THUMBSRC = start.c \
|
||||||
# These are to be compiled in ARM mode
|
# These are to be compiled in ARM mode
|
||||||
ARMSRC = fpgaloader.c \
|
ARMSRC = fpgaloader.c \
|
||||||
legicrf.c \
|
legicrf.c \
|
||||||
iso14443crc.c \
|
|
||||||
crc16.c \
|
|
||||||
lfdemod.c \
|
lfdemod.c \
|
||||||
$(SRC_ISO14443a) \
|
$(SRC_ISO14443a) \
|
||||||
$(SRC_ISO14443b) \
|
$(SRC_ISO14443b) \
|
||||||
$(SRC_CRAPTO1) \
|
$(SRC_CRAPTO1) \
|
||||||
|
$(SRC_CRC) \
|
||||||
legic_prng.c \
|
legic_prng.c \
|
||||||
iclass.c \
|
iclass.c \
|
||||||
crc.c
|
BigBuf.c \
|
||||||
|
|
||||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
||||||
APP_CFLAGS += -I.
|
APP_CFLAGS += -I.
|
||||||
|
|
1168
armsrc/aes.c
Normal file
1168
armsrc/aes.c
Normal file
File diff suppressed because it is too large
Load diff
30
armsrc/aes.h
Normal file
30
armsrc/aes.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* AES Cryptographic Algorithm Header File. Include this header file in
|
||||||
|
* your source which uses these given APIs. (This source is kept under
|
||||||
|
* public domain)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// AES context structure
|
||||||
|
typedef struct {
|
||||||
|
unsigned int Ek[60];
|
||||||
|
unsigned int Dk[60];
|
||||||
|
unsigned int Iv[4];
|
||||||
|
unsigned char Nr;
|
||||||
|
unsigned char Mode;
|
||||||
|
} AesCtx;
|
||||||
|
|
||||||
|
// key length in bytes
|
||||||
|
#define KEY128 16
|
||||||
|
#define KEY192 24
|
||||||
|
#define KEY256 32
|
||||||
|
// block size in bytes
|
||||||
|
#define BLOCKSZ 16
|
||||||
|
// mode
|
||||||
|
#define EBC 0
|
||||||
|
#define CBC 1
|
||||||
|
|
||||||
|
// AES API function prototype
|
||||||
|
|
||||||
|
int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned int KeyLen, unsigned char Mode);
|
||||||
|
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen);
|
||||||
|
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen);
|
|
@ -42,12 +42,6 @@ int ToSendMax;
|
||||||
static int ToSendBit;
|
static int ToSendBit;
|
||||||
struct common_area common_area __attribute__((section(".commonarea")));
|
struct common_area common_area __attribute__((section(".commonarea")));
|
||||||
|
|
||||||
void BufferClear(void)
|
|
||||||
{
|
|
||||||
memset(BigBuf,0,sizeof(BigBuf));
|
|
||||||
Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ToSendReset(void)
|
void ToSendReset(void)
|
||||||
{
|
{
|
||||||
ToSendMax = -1;
|
ToSendMax = -1;
|
||||||
|
@ -246,7 +240,10 @@ void MeasureAntennaTuningHf(void)
|
||||||
|
|
||||||
void SimulateTagHfListen(void)
|
void SimulateTagHfListen(void)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
|
// ToDo: historically this used the free buffer, which was 2744 Bytes long.
|
||||||
|
// There might be a better size to be defined:
|
||||||
|
#define HF_14B_SNOOP_BUFFER_SIZE 2744
|
||||||
|
uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE);
|
||||||
uint8_t v = 0;
|
uint8_t v = 0;
|
||||||
int i;
|
int i;
|
||||||
int p = 0;
|
int p = 0;
|
||||||
|
@ -281,7 +278,7 @@ void SimulateTagHfListen(void)
|
||||||
p = 0;
|
p = 0;
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i >= FREE_BUFFER_SIZE) {
|
if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -802,9 +799,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_MIFAREU_READBL:
|
case CMD_MIFAREU_READBL:
|
||||||
MifareUReadBlock(c->arg[0],c->d.asBytes);
|
MifareUReadBlock(c->arg[0],c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
case CMD_MIFAREUC_AUTH1:
|
||||||
|
MifareUC_Auth1(c->arg[0],c->d.asBytes);
|
||||||
|
break;
|
||||||
|
case CMD_MIFAREUC_AUTH2:
|
||||||
|
MifareUC_Auth2(c->arg[0],c->d.asBytes);
|
||||||
|
break;
|
||||||
case CMD_MIFAREU_READCARD:
|
case CMD_MIFAREU_READCARD:
|
||||||
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
case CMD_MIFAREUC_READCARD:
|
||||||
|
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
|
break;
|
||||||
case CMD_MIFARE_READSC:
|
case CMD_MIFARE_READSC:
|
||||||
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
@ -859,6 +865,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_MIFARE_SNIFFER:
|
case CMD_MIFARE_SNIFFER:
|
||||||
SniffMifare(c->arg[0]);
|
SniffMifare(c->arg[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ICLASS
|
#ifdef WITH_ICLASS
|
||||||
|
@ -882,7 +889,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_BUFF_CLEAR:
|
case CMD_BUFF_CLEAR:
|
||||||
BufferClear();
|
BigBuf_Clear();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_MEASURE_ANTENNA_TUNING:
|
case CMD_MEASURE_ANTENNA_TUNING:
|
||||||
|
@ -906,18 +913,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
|
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
|
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
|
||||||
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
|
size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
|
||||||
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
|
cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
// We put a 1 in arg[0] to alert the host we're also sending sample_config
|
cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config));
|
||||||
cmd_send(CMD_ACK,1,0,0,getSamplingConfig(),sizeof(sample_config));
|
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
|
||||||
uint8_t *b = (uint8_t *)BigBuf;
|
uint8_t *b = BigBuf_get_addr();
|
||||||
memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
|
memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -17,48 +17,10 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
|
#include "../common/crc32.h"
|
||||||
// The large multi-purpose buffer, typically used to hold A/D samples,
|
#include "BigBuf.h"
|
||||||
// maybe processed in some way.
|
|
||||||
#define BIGBUF_SIZE 40000
|
|
||||||
uint32_t BigBuf[BIGBUF_SIZE / sizeof(uint32_t)];
|
|
||||||
#define TRACE_OFFSET 0
|
|
||||||
#define TRACE_SIZE 3000
|
|
||||||
#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE)
|
|
||||||
#define MAX_FRAME_SIZE 256
|
|
||||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8)
|
|
||||||
#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE)
|
|
||||||
#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE)
|
|
||||||
#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE)
|
|
||||||
#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE)
|
|
||||||
#define CARD_MEMORY_SIZE 4096
|
|
||||||
#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET
|
|
||||||
#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE
|
|
||||||
#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE)
|
|
||||||
#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1)
|
|
||||||
|
|
||||||
/*
|
|
||||||
The statements above translates into this :
|
|
||||||
BIGBUF_SIZE = 40000
|
|
||||||
TRACE_OFFSET = 0
|
|
||||||
TRACE_SIZE = 3000
|
|
||||||
RECV_CMD_OFFSET = 3000
|
|
||||||
MAX_FRAME_SIZE = 256
|
|
||||||
MAX_PARITY_SIZE = 32
|
|
||||||
RECV_CMD_PAR_OFFSET = 3256
|
|
||||||
RECV_RESP_OFFSET = 3288
|
|
||||||
RECV_RESP_PAR_OFFSET= 3544
|
|
||||||
CARD_MEMORY_OFFSET = 3576
|
|
||||||
CARD_MEMORY_SIZE = 4096
|
|
||||||
DMA_BUFFER_OFFSET = 3576
|
|
||||||
DMA_BUFFER_SIZE = 4096
|
|
||||||
FREE_BUFFER_OFFSET = 7672
|
|
||||||
FREE_BUFFER_SIZE = 32327
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern const uint8_t OddByteParity[256];
|
extern const uint8_t OddByteParity[256];
|
||||||
extern uint8_t *trace; // = (uint8_t *) BigBuf;
|
|
||||||
extern int traceLen; // = 0;
|
|
||||||
extern int rsamples; // = 0;
|
extern int rsamples; // = 0;
|
||||||
extern int tracing; // = TRUE;
|
extern int tracing; // = TRUE;
|
||||||
extern uint8_t trigger;
|
extern uint8_t trigger;
|
||||||
|
@ -83,7 +45,6 @@ void ToSendReset(void);
|
||||||
void ListenReaderField(int limit);
|
void ListenReaderField(int limit);
|
||||||
extern int ToSendMax;
|
extern int ToSendMax;
|
||||||
extern uint8_t ToSend[];
|
extern uint8_t ToSend[];
|
||||||
extern uint32_t BigBuf[];
|
|
||||||
|
|
||||||
/// fpga.h
|
/// fpga.h
|
||||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||||
|
@ -199,7 +160,9 @@ void ReaderMifare(bool first_try);
|
||||||
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
|
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
|
||||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
|
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
|
||||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
|
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
|
||||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain);
|
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain);
|
||||||
|
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain);
|
||||||
|
void MifareUReadCard(uint8_t arg0, int Pages, uint8_t *datain);
|
||||||
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||||
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||||
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
|
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
|
||||||
|
@ -216,6 +179,25 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void MifareCIdent(); // is "magic chinese" card?
|
void MifareCIdent(); // is "magic chinese" card?
|
||||||
|
|
||||||
|
//desfire
|
||||||
|
void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);
|
||||||
|
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
|
||||||
|
|
||||||
|
// mifaredesfire.h
|
||||||
|
bool InitDesfireCard();
|
||||||
|
void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain);
|
||||||
|
void MifareDesfireGetInformation();
|
||||||
|
void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
|
||||||
|
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
|
||||||
|
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
|
||||||
|
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
|
||||||
|
void OnSuccess();
|
||||||
|
void OnError(uint8_t reason);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// iso15693.h
|
/// iso15693.h
|
||||||
void RecordRawAdcSamplesIso15693(void);
|
void RecordRawAdcSamplesIso15693(void);
|
||||||
void AcquireRawAdcSamplesIso15693(void);
|
void AcquireRawAdcSamplesIso15693(void);
|
||||||
|
|
383
armsrc/des.c
Normal file
383
armsrc/des.c
Normal file
|
@ -0,0 +1,383 @@
|
||||||
|
/* des.c */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file des.c
|
||||||
|
* \author Daniel Otte
|
||||||
|
* \email daniel.otte@rub.de
|
||||||
|
* \date 2007-06-16
|
||||||
|
* \brief DES and EDE-DES implementation
|
||||||
|
* \license GPLv3 or later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
const uint8_t sbox[256] = {
|
||||||
|
/* S-box 1 */
|
||||||
|
0xE4, 0xD1, 0x2F, 0xB8, 0x3A, 0x6C, 0x59, 0x07,
|
||||||
|
0x0F, 0x74, 0xE2, 0xD1, 0xA6, 0xCB, 0x95, 0x38,
|
||||||
|
0x41, 0xE8, 0xD6, 0x2B, 0xFC, 0x97, 0x3A, 0x50,
|
||||||
|
0xFC, 0x82, 0x49, 0x17, 0x5B, 0x3E, 0xA0, 0x6D,
|
||||||
|
/* S-box 2 */
|
||||||
|
0xF1, 0x8E, 0x6B, 0x34, 0x97, 0x2D, 0xC0, 0x5A,
|
||||||
|
0x3D, 0x47, 0xF2, 0x8E, 0xC0, 0x1A, 0x69, 0xB5,
|
||||||
|
0x0E, 0x7B, 0xA4, 0xD1, 0x58, 0xC6, 0x93, 0x2F,
|
||||||
|
0xD8, 0xA1, 0x3F, 0x42, 0xB6, 0x7C, 0x05, 0xE9,
|
||||||
|
/* S-box 3 */
|
||||||
|
0xA0, 0x9E, 0x63, 0xF5, 0x1D, 0xC7, 0xB4, 0x28,
|
||||||
|
0xD7, 0x09, 0x34, 0x6A, 0x28, 0x5E, 0xCB, 0xF1,
|
||||||
|
0xD6, 0x49, 0x8F, 0x30, 0xB1, 0x2C, 0x5A, 0xE7,
|
||||||
|
0x1A, 0xD0, 0x69, 0x87, 0x4F, 0xE3, 0xB5, 0x2C,
|
||||||
|
/* S-box 4 */
|
||||||
|
0x7D, 0xE3, 0x06, 0x9A, 0x12, 0x85, 0xBC, 0x4F,
|
||||||
|
0xD8, 0xB5, 0x6F, 0x03, 0x47, 0x2C, 0x1A, 0xE9,
|
||||||
|
0xA6, 0x90, 0xCB, 0x7D, 0xF1, 0x3E, 0x52, 0x84,
|
||||||
|
0x3F, 0x06, 0xA1, 0xD8, 0x94, 0x5B, 0xC7, 0x2E,
|
||||||
|
/* S-box 5 */
|
||||||
|
0x2C, 0x41, 0x7A, 0xB6, 0x85, 0x3F, 0xD0, 0xE9,
|
||||||
|
0xEB, 0x2C, 0x47, 0xD1, 0x50, 0xFA, 0x39, 0x86,
|
||||||
|
0x42, 0x1B, 0xAD, 0x78, 0xF9, 0xC5, 0x63, 0x0E,
|
||||||
|
0xB8, 0xC7, 0x1E, 0x2D, 0x6F, 0x09, 0xA4, 0x53,
|
||||||
|
/* S-box 6 */
|
||||||
|
0xC1, 0xAF, 0x92, 0x68, 0x0D, 0x34, 0xE7, 0x5B,
|
||||||
|
0xAF, 0x42, 0x7C, 0x95, 0x61, 0xDE, 0x0B, 0x38,
|
||||||
|
0x9E, 0xF5, 0x28, 0xC3, 0x70, 0x4A, 0x1D, 0xB6,
|
||||||
|
0x43, 0x2C, 0x95, 0xFA, 0xBE, 0x17, 0x60, 0x8D,
|
||||||
|
/* S-box 7 */
|
||||||
|
0x4B, 0x2E, 0xF0, 0x8D, 0x3C, 0x97, 0x5A, 0x61,
|
||||||
|
0xD0, 0xB7, 0x49, 0x1A, 0xE3, 0x5C, 0x2F, 0x86,
|
||||||
|
0x14, 0xBD, 0xC3, 0x7E, 0xAF, 0x68, 0x05, 0x92,
|
||||||
|
0x6B, 0xD8, 0x14, 0xA7, 0x95, 0x0F, 0xE2, 0x3C,
|
||||||
|
/* S-box 8 */
|
||||||
|
0xD2, 0x84, 0x6F, 0xB1, 0xA9, 0x3E, 0x50, 0xC7,
|
||||||
|
0x1F, 0xD8, 0xA3, 0x74, 0xC5, 0x6B, 0x0E, 0x92,
|
||||||
|
0x7B, 0x41, 0x9C, 0xE2, 0x06, 0xAD, 0xF3, 0x58,
|
||||||
|
0x21, 0xE7, 0x4A, 0x8D, 0xFC, 0x90, 0x35, 0x6B
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t e_permtab[] ={
|
||||||
|
4, 6, /* 4 bytes in 6 bytes out*/
|
||||||
|
32, 1, 2, 3, 4, 5,
|
||||||
|
4, 5, 6, 7, 8, 9,
|
||||||
|
8, 9, 10, 11, 12, 13,
|
||||||
|
12, 13, 14, 15, 16, 17,
|
||||||
|
16, 17, 18, 19, 20, 21,
|
||||||
|
20, 21, 22, 23, 24, 25,
|
||||||
|
24, 25, 26, 27, 28, 29,
|
||||||
|
28, 29, 30, 31, 32, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t p_permtab[] ={
|
||||||
|
4, 4, /* 32 bit -> 32 bit */
|
||||||
|
16, 7, 20, 21,
|
||||||
|
29, 12, 28, 17,
|
||||||
|
1, 15, 23, 26,
|
||||||
|
5, 18, 31, 10,
|
||||||
|
2, 8, 24, 14,
|
||||||
|
32, 27, 3, 9,
|
||||||
|
19, 13, 30, 6,
|
||||||
|
22, 11, 4, 25
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t ip_permtab[] ={
|
||||||
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
|
58, 50, 42, 34, 26, 18, 10, 2,
|
||||||
|
60, 52, 44, 36, 28, 20, 12, 4,
|
||||||
|
62, 54, 46, 38, 30, 22, 14, 6,
|
||||||
|
64, 56, 48, 40, 32, 24, 16, 8,
|
||||||
|
57, 49, 41, 33, 25, 17, 9, 1,
|
||||||
|
59, 51, 43, 35, 27, 19, 11, 3,
|
||||||
|
61, 53, 45, 37, 29, 21, 13, 5,
|
||||||
|
63, 55, 47, 39, 31, 23, 15, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t inv_ip_permtab[] ={
|
||||||
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
|
40, 8, 48, 16, 56, 24, 64, 32,
|
||||||
|
39, 7, 47, 15, 55, 23, 63, 31,
|
||||||
|
38, 6, 46, 14, 54, 22, 62, 30,
|
||||||
|
37, 5, 45, 13, 53, 21, 61, 29,
|
||||||
|
36, 4, 44, 12, 52, 20, 60, 28,
|
||||||
|
35, 3, 43, 11, 51, 19, 59, 27,
|
||||||
|
34, 2, 42, 10, 50, 18, 58, 26,
|
||||||
|
33, 1, 41, 9, 49, 17, 57, 25
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t pc1_permtab[] ={
|
||||||
|
8, 7, /* 64 bit -> 56 bit*/
|
||||||
|
57, 49, 41, 33, 25, 17, 9,
|
||||||
|
1, 58, 50, 42, 34, 26, 18,
|
||||||
|
10, 2, 59, 51, 43, 35, 27,
|
||||||
|
19, 11, 3, 60, 52, 44, 36,
|
||||||
|
63, 55, 47, 39, 31, 23, 15,
|
||||||
|
7, 62, 54, 46, 38, 30, 22,
|
||||||
|
14, 6, 61, 53, 45, 37, 29,
|
||||||
|
21, 13, 5, 28, 20, 12, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t pc2_permtab[] ={
|
||||||
|
7, 6, /* 56 bit -> 48 bit */
|
||||||
|
14, 17, 11, 24, 1, 5,
|
||||||
|
3, 28, 15, 6, 21, 10,
|
||||||
|
23, 19, 12, 4, 26, 8,
|
||||||
|
16, 7, 27, 20, 13, 2,
|
||||||
|
41, 52, 31, 37, 47, 55,
|
||||||
|
30, 40, 51, 45, 33, 48,
|
||||||
|
44, 49, 39, 56, 34, 53,
|
||||||
|
46, 42, 50, 36, 29, 32
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t splitin6bitword_permtab[] = {
|
||||||
|
8, 8, /* 64 bit -> 64 bit */
|
||||||
|
64, 64, 1, 6, 2, 3, 4, 5,
|
||||||
|
64, 64, 7, 12, 8, 9, 10, 11,
|
||||||
|
64, 64, 13, 18, 14, 15, 16, 17,
|
||||||
|
64, 64, 19, 24, 20, 21, 22, 23,
|
||||||
|
64, 64, 25, 30, 26, 27, 28, 29,
|
||||||
|
64, 64, 31, 36, 32, 33, 34, 35,
|
||||||
|
64, 64, 37, 42, 38, 39, 40, 41,
|
||||||
|
64, 64, 43, 48, 44, 45, 46, 47
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t shiftkey_permtab[] = {
|
||||||
|
7, 7, /* 56 bit -> 56 bit */
|
||||||
|
2, 3, 4, 5, 6, 7, 8, 9,
|
||||||
|
10, 11, 12, 13, 14, 15, 16, 17,
|
||||||
|
18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
|
26, 27, 28, 1,
|
||||||
|
30, 31, 32, 33, 34, 35, 36, 37,
|
||||||
|
38, 39, 40, 41, 42, 43, 44, 45,
|
||||||
|
46, 47, 48, 49, 50, 51, 52, 53,
|
||||||
|
54, 55, 56, 29
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t shiftkeyinv_permtab[] = {
|
||||||
|
7, 7,
|
||||||
|
28, 1, 2, 3, 4, 5, 6, 7,
|
||||||
|
8, 9, 10, 11, 12, 13, 14, 15,
|
||||||
|
16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
|
24, 25, 26, 27,
|
||||||
|
56, 29, 30, 31, 32, 33, 34, 35,
|
||||||
|
36, 37, 38, 39, 40, 41, 42, 43,
|
||||||
|
44, 45, 46, 47, 48, 49, 50, 51,
|
||||||
|
52, 53, 54, 55
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
1 0
|
||||||
|
1 0
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
----
|
||||||
|
1 0
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
2 1
|
||||||
|
1 0
|
||||||
|
*/
|
||||||
|
#define ROTTABLE 0x7EFC
|
||||||
|
#define ROTTABLE_INV 0x3F7E
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
|
||||||
|
uint8_t ob; /* in-bytes and out-bytes */
|
||||||
|
uint8_t byte, bit; /* counter for bit and byte */
|
||||||
|
ob = ptable[1];
|
||||||
|
ptable = &(ptable[2]);
|
||||||
|
for(byte=0; byte<ob; ++byte){
|
||||||
|
uint8_t x,t=0;
|
||||||
|
for(bit=0; bit<8; ++bit){
|
||||||
|
x=*ptable++ -1 ;
|
||||||
|
t<<=1;
|
||||||
|
if((in[x/8]) & (0x80>>(x%8)) ){
|
||||||
|
t|=0x01;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out[byte]=t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void changeendian32(uint32_t * a){
|
||||||
|
*a = (*a & 0x000000FF) << 24 |
|
||||||
|
(*a & 0x0000FF00) << 8 |
|
||||||
|
(*a & 0x00FF0000) >> 8 |
|
||||||
|
(*a & 0xFF000000) >> 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
static inline
|
||||||
|
void shiftkey(uint8_t *key){
|
||||||
|
uint8_t k[7];
|
||||||
|
memcpy(k, key, 7);
|
||||||
|
permute((uint8_t*)shiftkey_permtab, k, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
static inline
|
||||||
|
void shiftkey_inv(uint8_t *key){
|
||||||
|
uint8_t k[7];
|
||||||
|
memcpy(k, key, 7);
|
||||||
|
permute((uint8_t*)shiftkeyinv_permtab, k, key);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
static inline
|
||||||
|
uint64_t splitin6bitwords(uint64_t a){
|
||||||
|
uint64_t ret=0;
|
||||||
|
a &= 0x0000ffffffffffffLL;
|
||||||
|
permute((uint8_t*)splitin6bitword_permtab, (uint8_t*)&a, (uint8_t*)&ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uint8_t substitute(uint8_t a, uint8_t * sbp){
|
||||||
|
uint8_t x;
|
||||||
|
x = sbp[a>>1];
|
||||||
|
x = (a&1)?x&0x0F:x>>4;
|
||||||
|
return x;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
uint32_t des_f(uint32_t r, uint8_t* kr){
|
||||||
|
uint8_t i;
|
||||||
|
uint32_t t=0,ret;
|
||||||
|
uint64_t data;
|
||||||
|
uint8_t *sbp; /* sboxpointer */
|
||||||
|
permute((uint8_t*)e_permtab, (uint8_t*)&r, (uint8_t*)&data);
|
||||||
|
for(i=0; i<7; ++i)
|
||||||
|
((uint8_t*)&data)[i] ^= kr[i];
|
||||||
|
|
||||||
|
/* Sbox substitution */
|
||||||
|
data = splitin6bitwords(data);
|
||||||
|
sbp=(uint8_t*)sbox;
|
||||||
|
for(i=0; i<8; ++i){
|
||||||
|
uint8_t x;
|
||||||
|
x = substitute(((uint8_t*)&data)[i], sbp);
|
||||||
|
t<<=4;
|
||||||
|
t |= x;
|
||||||
|
sbp += 32;
|
||||||
|
}
|
||||||
|
changeendian32(&t);
|
||||||
|
|
||||||
|
permute((uint8_t*)p_permtab,(uint8_t*)&t, (uint8_t*)&ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void des_enc(void* out, const void* in, const void* key){
|
||||||
|
#define R *((uint32_t*)&(data[4]))
|
||||||
|
#define L *((uint32_t*)&(data[0]))
|
||||||
|
|
||||||
|
uint8_t data[8],kr[6],k[7];
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
|
||||||
|
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||||
|
for(i=0; i<8; ++i){
|
||||||
|
shiftkey(k);
|
||||||
|
if(ROTTABLE&((1<<((i<<1)+0))) )
|
||||||
|
shiftkey(k);
|
||||||
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
|
L ^= des_f(R, kr);
|
||||||
|
|
||||||
|
shiftkey(k);
|
||||||
|
if(ROTTABLE&((1<<((i<<1)+1))) )
|
||||||
|
shiftkey(k);
|
||||||
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
|
R ^= des_f(L, kr);
|
||||||
|
|
||||||
|
}
|
||||||
|
/* L <-> R*/
|
||||||
|
R ^= L;
|
||||||
|
L ^= R;
|
||||||
|
R ^= L;
|
||||||
|
|
||||||
|
permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void des_dec(void* out, const void* in, const uint8_t* key){
|
||||||
|
#define R *((uint32_t*)&(data[4]))
|
||||||
|
#define L *((uint32_t*)&(data[0]))
|
||||||
|
|
||||||
|
uint8_t data[8],kr[6],k[7];
|
||||||
|
int8_t i;
|
||||||
|
permute((uint8_t*)ip_permtab, (uint8_t*)in, data);
|
||||||
|
permute((uint8_t*)pc1_permtab, (const uint8_t*)key, k);
|
||||||
|
for(i=7; i>=0; --i){
|
||||||
|
|
||||||
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
|
L ^= des_f(R, kr);
|
||||||
|
shiftkey_inv(k);
|
||||||
|
if(ROTTABLE&((1<<((i<<1)+1))) ){
|
||||||
|
shiftkey_inv(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
permute((uint8_t*)pc2_permtab, k, kr);
|
||||||
|
R ^= des_f(L, kr);
|
||||||
|
shiftkey_inv(k);
|
||||||
|
if(ROTTABLE&((1<<((i<<1)+0))) ){
|
||||||
|
shiftkey_inv(k);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/* L <-> R*/
|
||||||
|
R ^= L;
|
||||||
|
L ^= R;
|
||||||
|
R ^= L;
|
||||||
|
|
||||||
|
permute((uint8_t*)inv_ip_permtab, data, (uint8_t*)out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void tdes_enc(void* out, void* in, const void* key){
|
||||||
|
des_enc(out, in, (uint8_t*)key + 0);
|
||||||
|
des_dec(out, out, (uint8_t*)key + 8);
|
||||||
|
des_enc(out, out, (uint8_t*)key +16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
void tdes_dec(void* out, void* in, const uint8_t* key){
|
||||||
|
des_dec(out, in, (uint8_t*)key +16);
|
||||||
|
des_enc(out, out, (uint8_t*)key + 8);
|
||||||
|
des_dec(out, out, (uint8_t*)key + 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
|
107
armsrc/des.h
Normal file
107
armsrc/des.h
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/* des.h */
|
||||||
|
/*
|
||||||
|
This file is part of the ARM-Crypto-Lib.
|
||||||
|
Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* \file des.h
|
||||||
|
* \author Daniel Otte
|
||||||
|
* \date 2007-06-16
|
||||||
|
* \brief des and tdes declarations
|
||||||
|
* \license GPLv3 or later
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef DES_H_
|
||||||
|
#define DES_H_
|
||||||
|
|
||||||
|
/* the FIPS 46-3 (1999-10-25) name for triple DES is triple data encryption algorithm so TDEA.
|
||||||
|
* Also we only implement the three key mode */
|
||||||
|
|
||||||
|
/** \def tdea_enc
|
||||||
|
* \brief defining an alias for void tdes_enc(void* out, const void* in, const void* key)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \def tdea_dec
|
||||||
|
* \brief defining an alias for void tdes_dec(void* out, const void* in, const void* key)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define tdea_enc tdes_enc
|
||||||
|
#define tdea_dec tdes_dec
|
||||||
|
|
||||||
|
/** \fn void des_enc(void* out, const void* in, const void* key)
|
||||||
|
* \brief encrypt a block with DES
|
||||||
|
*
|
||||||
|
* This function encrypts a block of 64 bits (8 bytes) with the DES algorithm.
|
||||||
|
* Key expansion is done automatically. The key is 64 bits long, but note that
|
||||||
|
* only 56 bits are used (the LSB of each byte is dropped). The input and output
|
||||||
|
* blocks may overlap.
|
||||||
|
*
|
||||||
|
* \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
|
||||||
|
* \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from
|
||||||
|
* \param key pointer to the key (64 bit = 8 byte)
|
||||||
|
*/
|
||||||
|
void des_enc(void* out, const void* in, const void* key);
|
||||||
|
|
||||||
|
/** \fn void des_dec(void* out, const void* in, const void* key)
|
||||||
|
* \brief decrypt a block with DES
|
||||||
|
*
|
||||||
|
* This function decrypts a block of 64 bits (8 bytes) with the DES algorithm.
|
||||||
|
* Key expansion is done automatically. The key is 64 bits long, but note that
|
||||||
|
* only 56 bits are used (the LSB of each byte is dropped). The input and output
|
||||||
|
* blocks may overlap.
|
||||||
|
*
|
||||||
|
* \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
|
||||||
|
* \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from
|
||||||
|
* \param key pointer to the key (64 bit = 8 byte)
|
||||||
|
*/
|
||||||
|
void des_dec(void* out, const void* in, const void* key);
|
||||||
|
|
||||||
|
/** \fn void tdes_enc(void* out, const void* in, const void* key)
|
||||||
|
* \brief encrypt a block with Tripple-DES
|
||||||
|
*
|
||||||
|
* This function encrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
|
||||||
|
* algorithm. Key expansion is done automatically. The key is 192 bits long, but
|
||||||
|
* note that only 178 bits are used (the LSB of each byte is dropped). The input
|
||||||
|
* and output blocks may overlap.
|
||||||
|
*
|
||||||
|
* \param out pointer to the block (64 bit = 8 byte) where the ciphertext is written to
|
||||||
|
* \param in pointer to the block (64 bit = 8 byte) where the plaintext is read from
|
||||||
|
* \param key pointer to the key (192 bit = 24 byte)
|
||||||
|
*/
|
||||||
|
void tdes_enc(void* out, const void* in, const void* key);
|
||||||
|
|
||||||
|
/** \fn void tdes_dec(void* out, const void* in, const void* key)
|
||||||
|
* \brief decrypt a block with Tripple-DES
|
||||||
|
*
|
||||||
|
* This function decrypts a block of 64 bits (8 bytes) with the Tripple-DES (EDE)
|
||||||
|
* algorithm. Key expansion is done automatically. The key is 192 bits long, but
|
||||||
|
* note that only 178 bits are used (the LSB of each byte is dropped). The input
|
||||||
|
* and output blocks may overlap.
|
||||||
|
*
|
||||||
|
* \param out pointer to the block (64 bit = 8 byte) where the plaintext is written to
|
||||||
|
* \param in pointer to the block (64 bit = 8 byte) where the ciphertext is read from
|
||||||
|
* \param key pointer to the key (192 bit = 24 byte)
|
||||||
|
*/
|
||||||
|
void tdes_dec(void* out, const void* in, const void* key);
|
||||||
|
|
||||||
|
#endif /*DES_H_*/
|
||||||
|
|
||||||
|
// Copied from des.h in desfire imp.
|
||||||
|
typedef unsigned long DES_KS[16][2]; /* Single-key DES key schedule */
|
||||||
|
typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */
|
||||||
|
|
||||||
|
|
||||||
|
extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */
|
|
@ -24,15 +24,19 @@
|
||||||
|
|
||||||
static bool bQuiet;
|
static bool bQuiet;
|
||||||
|
|
||||||
bool bCrypto;
|
static bool bCrypto;
|
||||||
bool bAuthenticating;
|
static bool bAuthenticating;
|
||||||
bool bPwd;
|
static bool bPwd;
|
||||||
bool bSuccessful;
|
static bool bSuccessful;
|
||||||
|
|
||||||
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
|
|
||||||
|
static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader)
|
||||||
{
|
{
|
||||||
|
static uint16_t traceLen = 0;
|
||||||
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen >= TRACE_SIZE) return FALSE;
|
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE;
|
||||||
|
|
||||||
// Trace the random, i'm curious
|
// Trace the random, i'm curious
|
||||||
rsamples += iSamples;
|
rsamples += iSamples;
|
||||||
|
@ -85,21 +89,17 @@ static struct hitag2_tag tag = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
//#define TRACE_LENGTH 3000
|
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||||
//uint8_t *trace = (uint8_t *) BigBuf;
|
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||||
//int traceLen = 0;
|
#define AUTH_TABLE_LENGTH 2744
|
||||||
//int rsamples = 0;
|
static byte_t* auth_table;
|
||||||
|
static size_t auth_table_pos = 0;
|
||||||
|
static size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||||
|
|
||||||
#define AUTH_TABLE_OFFSET FREE_BUFFER_OFFSET
|
static byte_t password[4];
|
||||||
#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE
|
static byte_t NrAr[8];
|
||||||
byte_t* auth_table = (byte_t *)BigBuf+AUTH_TABLE_OFFSET;
|
static byte_t key[8];
|
||||||
size_t auth_table_pos = 0;
|
static uint64_t cipher_state;
|
||||||
size_t auth_table_len = AUTH_TABLE_LENGTH;
|
|
||||||
|
|
||||||
byte_t password[4];
|
|
||||||
byte_t NrAr[8];
|
|
||||||
byte_t key[8];
|
|
||||||
uint64_t cipher_state;
|
|
||||||
|
|
||||||
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */
|
||||||
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
|
// Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007.
|
||||||
|
@ -177,14 +177,14 @@ static u32 _hitag2_byte (u64 * x)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hitag2_reset(void)
|
static int hitag2_reset(void)
|
||||||
{
|
{
|
||||||
tag.state = TAG_STATE_RESET;
|
tag.state = TAG_STATE_RESET;
|
||||||
tag.crypto_active = 0;
|
tag.crypto_active = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hitag2_init(void)
|
static int hitag2_init(void)
|
||||||
{
|
{
|
||||||
// memcpy(&tag, &resetdata, sizeof(tag));
|
// memcpy(&tag, &resetdata, sizeof(tag));
|
||||||
hitag2_reset();
|
hitag2_reset();
|
||||||
|
@ -300,7 +300,8 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
|
||||||
|
static void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||||
{
|
{
|
||||||
byte_t rx_air[HITAG_FRAME_LEN];
|
byte_t rx_air[HITAG_FRAME_LEN];
|
||||||
|
|
||||||
|
@ -457,6 +458,7 @@ static void hitag_reader_send_bit(int bit) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||||
{
|
{
|
||||||
// Send the content of the frame
|
// Send the content of the frame
|
||||||
|
@ -475,7 +477,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||||
|
|
||||||
size_t blocknr;
|
size_t blocknr;
|
||||||
|
|
||||||
bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||||
// Reset the transmission frame length
|
// Reset the transmission frame length
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
|
@ -530,7 +532,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||||
// Reset the transmission frame length
|
// Reset the transmission frame length
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
|
@ -623,7 +625,7 @@ bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||||
// Reset the transmission frame length
|
// Reset the transmission frame length
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
|
@ -663,7 +665,9 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
|
||||||
|
static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
|
||||||
|
|
||||||
// Reset the transmission frame length
|
// Reset the transmission frame length
|
||||||
*txlen = 0;
|
*txlen = 0;
|
||||||
|
|
||||||
|
@ -679,7 +683,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
||||||
auth_table_len -= 8;
|
auth_table_len -= 8;
|
||||||
|
|
||||||
// Return if we reached the end of the authentiactions table
|
// Return if we reached the end of the authentications table
|
||||||
bCrypto = false;
|
bCrypto = false;
|
||||||
if (auth_table_pos == auth_table_len) {
|
if (auth_table_pos == auth_table_len) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -718,6 +722,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SnoopHitag(uint32_t type) {
|
void SnoopHitag(uint32_t type) {
|
||||||
int frame_count;
|
int frame_count;
|
||||||
int response;
|
int response;
|
||||||
|
@ -730,14 +735,16 @@ void SnoopHitag(uint32_t type) {
|
||||||
byte_t rx[HITAG_FRAME_LEN];
|
byte_t rx[HITAG_FRAME_LEN];
|
||||||
size_t rxlen=0;
|
size_t rxlen=0;
|
||||||
|
|
||||||
|
auth_table_len = 0;
|
||||||
|
auth_table_pos = 0;
|
||||||
|
BigBuf_free();
|
||||||
|
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||||
|
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||||
|
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
|
|
||||||
auth_table_len = 0;
|
|
||||||
auth_table_pos = 0;
|
|
||||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
|
||||||
|
|
||||||
DbpString("Starting Hitag2 snoop");
|
DbpString("Starting Hitag2 snoop");
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
|
||||||
|
@ -940,12 +947,16 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||||
bool bQuitTraceFull = false;
|
bool bQuitTraceFull = false;
|
||||||
bQuiet = false;
|
bQuiet = false;
|
||||||
|
|
||||||
|
auth_table_len = 0;
|
||||||
|
auth_table_pos = 0;
|
||||||
|
byte_t* auth_table;
|
||||||
|
BigBuf_free();
|
||||||
|
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||||
|
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||||
|
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
auth_table_len = 0;
|
|
||||||
auth_table_pos = 0;
|
|
||||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
|
||||||
|
|
||||||
DbpString("Starting Hitag2 simulation");
|
DbpString("Starting Hitag2 simulation");
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
@ -1133,6 +1144,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
// Clean up trace and prepare it for storing frames
|
// Clean up trace and prepare it for storing frames
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
|
|
||||||
DbpString("Starting Hitag reader family");
|
DbpString("Starting Hitag reader family");
|
||||||
|
|
||||||
// Check configuration
|
// Check configuration
|
||||||
|
@ -1170,7 +1182,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||||
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
||||||
Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
|
Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
|
||||||
auth_table_pos = 0;
|
auth_table_pos = 0;
|
||||||
memcpy(NrAr,auth_table,8);
|
memcpy(NrAr, auth_table, 8);
|
||||||
bQuitTraceFull = false;
|
bQuitTraceFull = false;
|
||||||
bQuiet = false;
|
bQuiet = false;
|
||||||
bCrypto = false;
|
bCrypto = false;
|
||||||
|
|
|
@ -640,21 +640,25 @@ void RAMFUNC SnoopIClass(void)
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
// The length of a received command will in most cases be no more than 18 bytes.
|
// The length of a received command will in most cases be no more than 18 bytes.
|
||||||
// So 32 should be enough!
|
// So 32 should be enough!
|
||||||
uint8_t *readerToTagCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
#define ICLASS_BUFFER_SIZE 32
|
||||||
|
uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE];
|
||||||
// The response (tag -> reader) that we're receiving.
|
// The response (tag -> reader) that we're receiving.
|
||||||
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE];
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
|
||||||
|
// free all BigBuf memory
|
||||||
|
BigBuf_free();
|
||||||
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// reset traceLen to 0
|
// reset traceLen to 0
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
iso14a_set_trigger(FALSE);
|
iso14a_set_trigger(FALSE);
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
|
||||||
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
|
||||||
int lastRxCounter;
|
int lastRxCounter;
|
||||||
int8_t *upTo;
|
uint8_t *upTo;
|
||||||
int smpl;
|
int smpl;
|
||||||
int maxBehindBy = 0;
|
int maxBehindBy = 0;
|
||||||
|
|
||||||
|
@ -703,7 +707,7 @@ void RAMFUNC SnoopIClass(void)
|
||||||
(DMA_BUFFER_SIZE-1);
|
(DMA_BUFFER_SIZE-1);
|
||||||
if(behindBy > maxBehindBy) {
|
if(behindBy > maxBehindBy) {
|
||||||
maxBehindBy = behindBy;
|
maxBehindBy = behindBy;
|
||||||
if(behindBy > 400) {
|
if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1064,27 +1068,28 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||||
int trace_data_size = 0;
|
int trace_data_size = 0;
|
||||||
//uint8_t sof = 0x0f;
|
//uint8_t sof = 0x0f;
|
||||||
|
|
||||||
|
// free eventually allocated BigBuf memory
|
||||||
|
BigBuf_free();
|
||||||
// Respond SOF -- takes 1 bytes
|
// Respond SOF -- takes 1 bytes
|
||||||
uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
uint8_t *resp1 = BigBuf_malloc(2);
|
||||||
int resp1Len;
|
int resp1Len;
|
||||||
|
|
||||||
// Anticollision CSN (rotated CSN)
|
// Anticollision CSN (rotated CSN)
|
||||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||||
uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 2);
|
uint8_t *resp2 = BigBuf_malloc(28);
|
||||||
int resp2Len;
|
int resp2Len;
|
||||||
|
|
||||||
// CSN
|
// CSN
|
||||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||||
uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 30);
|
uint8_t *resp3 = BigBuf_malloc(30);
|
||||||
int resp3Len;
|
int resp3Len;
|
||||||
|
|
||||||
// e-Purse
|
// e-Purse
|
||||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/byte)
|
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
||||||
uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 60);
|
uint8_t *resp4 = BigBuf_malloc(20);
|
||||||
int resp4Len;
|
int resp4Len;
|
||||||
|
|
||||||
// + 1720..
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
|
||||||
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
|
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
|
@ -1529,7 +1534,7 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||||
static uint8_t identify[] = { 0x0c };
|
static uint8_t identify[] = { 0x0c };
|
||||||
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
static uint8_t readcheck_cc[]= { 0x88, 0x02 };
|
||||||
uint8_t *resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||||
|
|
||||||
uint8_t read_status = 0;
|
uint8_t read_status = 0;
|
||||||
|
|
||||||
|
@ -1587,7 +1592,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
while(!BUTTON_PRESS())
|
while(!BUTTON_PRESS())
|
||||||
{
|
{
|
||||||
|
|
||||||
if(traceLen > TRACE_SIZE) {
|
if(traceLen > BigBuf_max_traceLen()) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1650,7 +1655,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||||
int keyaccess;
|
int keyaccess;
|
||||||
} memory;
|
} memory;
|
||||||
|
|
||||||
uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||||
|
|
||||||
setupIclassReader();
|
setupIclassReader();
|
||||||
|
|
||||||
|
@ -1659,7 +1664,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if(traceLen > TRACE_SIZE) {
|
if(traceLen > BigBuf_max_traceLen()) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,10 +339,10 @@ void SimulateIso14443Tag(void)
|
||||||
uint8_t *resp;
|
uint8_t *resp;
|
||||||
int respLen;
|
int respLen;
|
||||||
|
|
||||||
uint8_t *resp1 = (((uint8_t *)BigBuf) + 800);
|
uint8_t *resp1 = BigBuf_get_addr() + 800;
|
||||||
int resp1Len;
|
int resp1Len;
|
||||||
|
|
||||||
uint8_t *receivedCmd = (uint8_t *)BigBuf;
|
uint8_t *receivedCmd = BigBuf_get_addr();
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
@ -629,31 +629,32 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
|
||||||
int gotFrame = FALSE;
|
int gotFrame = FALSE;
|
||||||
|
|
||||||
//# define DMA_BUFFER_SIZE 8
|
//# define DMA_BUFFER_SIZE 8
|
||||||
int8_t *dmaBuf;
|
uint8_t *dmaBuf;
|
||||||
|
|
||||||
int lastRxCounter;
|
int lastRxCounter;
|
||||||
int8_t *upTo;
|
uint8_t *upTo;
|
||||||
|
|
||||||
int ci, cq;
|
int ci, cq;
|
||||||
|
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
|
||||||
// Clear out the state of the "UART" that receives from the tag.
|
// Clear out the state of the "UART" that receives from the tag.
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
memset(BigBuf, 0x00, 400);
|
memset(BigBuf, 0x00, 400);
|
||||||
Demod.output = (uint8_t *)BigBuf;
|
Demod.output = BigBuf;
|
||||||
Demod.len = 0;
|
Demod.len = 0;
|
||||||
Demod.state = DEMOD_UNSYNCD;
|
Demod.state = DEMOD_UNSYNCD;
|
||||||
|
|
||||||
// And the UART that receives from the reader
|
// And the UART that receives from the reader
|
||||||
Uart.output = (((uint8_t *)BigBuf) + 1024);
|
Uart.output = BigBuf + 1024;
|
||||||
Uart.byteCntMax = 100;
|
Uart.byteCntMax = 100;
|
||||||
Uart.state = STATE_UNSYNCD;
|
Uart.state = STATE_UNSYNCD;
|
||||||
|
|
||||||
// Setup for the DMA.
|
// Setup for the DMA.
|
||||||
dmaBuf = (int8_t *)(BigBuf + 32);
|
dmaBuf = BigBuf + 32;
|
||||||
upTo = dmaBuf;
|
upTo = dmaBuf;
|
||||||
lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
|
lastRxCounter = DEMOD_DMA_BUFFER_SIZE;
|
||||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE);
|
FpgaSetupSscDma(dmaBuf, DEMOD_DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
// Signal field is ON with the appropriate LED:
|
// Signal field is ON with the appropriate LED:
|
||||||
if (weTx) LED_D_ON(); else LED_D_OFF();
|
if (weTx) LED_D_ON(); else LED_D_OFF();
|
||||||
|
@ -1012,20 +1013,21 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
int triggered = TRUE;
|
int triggered = TRUE;
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
BigBuf_free();
|
||||||
// The command (reader -> tag) that we're working on receiving.
|
// The command (reader -> tag) that we're working on receiving.
|
||||||
uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE;
|
uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE);
|
||||||
// The response (tag -> reader) that we're working on receiving.
|
// The response (tag -> reader) that we're working on receiving.
|
||||||
uint8_t *receivedResponse = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE;
|
uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE);
|
||||||
|
|
||||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
||||||
// into trace, along with its length and other annotations.
|
// into trace, along with its length and other annotations.
|
||||||
uint8_t *trace = (uint8_t *)BigBuf;
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
int traceLen = 0;
|
traceLen = 0;
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA.
|
// The DMA buffer, used to stream samples from the FPGA.
|
||||||
int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE;
|
uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE);
|
||||||
int lastRxCounter;
|
int lastRxCounter;
|
||||||
int8_t *upTo;
|
uint8_t *upTo;
|
||||||
int ci, cq;
|
int ci, cq;
|
||||||
int maxBehindBy = 0;
|
int maxBehindBy = 0;
|
||||||
|
|
||||||
|
@ -1034,7 +1036,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
|
||||||
// Initialize the trace buffer
|
// Initialize the trace buffer
|
||||||
memset(trace, 0x44, DEMOD_TRACE_SIZE);
|
memset(trace, 0x44, BigBuf_max_traceLen());
|
||||||
|
|
||||||
// Set up the demodulator for tag -> reader responses.
|
// Set up the demodulator for tag -> reader responses.
|
||||||
Demod.output = receivedResponse;
|
Demod.output = receivedResponse;
|
||||||
|
@ -1049,7 +1051,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
|
|
||||||
// Print some debug information about the buffer sizes
|
// Print some debug information about the buffer sizes
|
||||||
Dbprintf("Snooping buffers initialized:");
|
Dbprintf("Snooping buffers initialized:");
|
||||||
Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE);
|
Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen());
|
||||||
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
|
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
|
||||||
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
|
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
|
||||||
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
|
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
|
||||||
|
@ -1076,7 +1078,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
(DEMOD_DMA_BUFFER_SIZE-1);
|
(DEMOD_DMA_BUFFER_SIZE-1);
|
||||||
if(behindBy > maxBehindBy) {
|
if(behindBy > maxBehindBy) {
|
||||||
maxBehindBy = behindBy;
|
maxBehindBy = behindBy;
|
||||||
if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not?
|
if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not?
|
||||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1149,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||||
trace[traceLen++] = Demod.len;
|
trace[traceLen++] = Demod.len;
|
||||||
memcpy(trace+traceLen, receivedResponse, Demod.len);
|
memcpy(trace+traceLen, receivedResponse, Demod.len);
|
||||||
traceLen += Demod.len;
|
traceLen += Demod.len;
|
||||||
if(traceLen > DEMOD_TRACE_SIZE) {
|
if(traceLen > BigBuf_max_traceLen()) {
|
||||||
DbpString("Reached trace limit");
|
DbpString("Reached trace limit");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,7 @@
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
|
||||||
static uint32_t iso14a_timeout;
|
static uint32_t iso14a_timeout;
|
||||||
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
|
|
||||||
int rsamples = 0;
|
int rsamples = 0;
|
||||||
int traceLen = 0;
|
|
||||||
int tracing = TRUE;
|
int tracing = TRUE;
|
||||||
uint8_t trigger = 0;
|
uint8_t trigger = 0;
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
|
@ -149,7 +147,9 @@ void iso14a_set_trigger(bool enable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_clear_trace() {
|
void iso14a_clear_trace() {
|
||||||
memset(trace, 0x44, TRACE_SIZE);
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
memset(trace, 0x44, max_traceLen);
|
||||||
traceLen = 0;
|
traceLen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,11 +204,13 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
{
|
{
|
||||||
if (!tracing) return FALSE;
|
if (!tracing) return FALSE;
|
||||||
|
|
||||||
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||||
uint16_t duration = timestamp_end - timestamp_start;
|
uint16_t duration = timestamp_end - timestamp_start;
|
||||||
|
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) {
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) {
|
||||||
tracing = FALSE; // don't trace any more
|
tracing = FALSE; // don't trace any more
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -591,9 +593,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
// bit 1 - trigger from first reader 7-bit request
|
// bit 1 - trigger from first reader 7-bit request
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
// init trace buffer
|
|
||||||
iso14a_clear_trace();
|
|
||||||
iso14a_set_tracing(TRUE);
|
|
||||||
|
|
||||||
// We won't start recording the frames that we acquire until we trigger;
|
// We won't start recording the frames that we acquire until we trigger;
|
||||||
// a good trigger condition to get started is probably when we see a
|
// a good trigger condition to get started is probably when we see a
|
||||||
|
@ -601,22 +600,25 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
// triggered == FALSE -- to wait first for card
|
// triggered == FALSE -- to wait first for card
|
||||||
bool triggered = !(param & 0x03);
|
bool triggered = !(param & 0x03);
|
||||||
|
|
||||||
|
// Allocate memory from BigBuf for some buffers
|
||||||
|
// free all previous allocations first
|
||||||
|
BigBuf_free();
|
||||||
|
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
// The length of a received command will in most cases be no more than 18 bytes.
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
// So 32 should be enough!
|
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
|
|
||||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
|
||||||
|
|
||||||
// The response (tag -> reader) that we're receiving.
|
// The response (tag -> reader) that we're receiving.
|
||||||
uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
|
|
||||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
|
||||||
// into trace, along with its length and other annotations.
|
|
||||||
//uint8_t *trace = (uint8_t *)BigBuf;
|
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
// The DMA buffer, used to stream samples from the FPGA
|
||||||
uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// init trace buffer
|
||||||
|
iso14a_clear_trace();
|
||||||
|
iso14a_set_tracing(TRUE);
|
||||||
|
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
int maxDataLen = 0;
|
int maxDataLen = 0;
|
||||||
|
@ -656,7 +658,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
// test for length of buffer
|
// test for length of buffer
|
||||||
if(dataLen > maxDataLen) {
|
if(dataLen > maxDataLen) {
|
||||||
maxDataLen = dataLen;
|
maxDataLen = dataLen;
|
||||||
if(dataLen > 400) {
|
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||||
Dbprintf("blew circular buffer! dataLen=%d", dataLen);
|
Dbprintf("blew circular buffer! dataLen=%d", dataLen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -885,7 +887,7 @@ int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par);
|
||||||
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_StartTime, uint32_t reader_EndTime, uint8_t *reader_Parity,
|
||||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity);
|
||||||
|
|
||||||
static uint8_t* free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
static uint8_t* free_buffer_pointer;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t* response;
|
uint8_t* response;
|
||||||
|
@ -895,10 +897,6 @@ typedef struct {
|
||||||
uint32_t ProxToAirDuration;
|
uint32_t ProxToAirDuration;
|
||||||
} tag_response_info_t;
|
} tag_response_info_t;
|
||||||
|
|
||||||
void reset_free_buffer() {
|
|
||||||
free_buffer_pointer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) {
|
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) {
|
||||||
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
|
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
|
||||||
// This will need the following byte array for a modulation sequence
|
// This will need the following byte array for a modulation sequence
|
||||||
|
@ -911,6 +909,7 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||||
// 166 bytes, since every bit that needs to be send costs us a byte
|
// 166 bytes, since every bit that needs to be send costs us a byte
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// Prepare the tag modulation bits from the message
|
// Prepare the tag modulation bits from the message
|
||||||
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
||||||
|
|
||||||
|
@ -931,15 +930,22 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit.
|
||||||
|
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||||
|
// 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits
|
||||||
|
// -> need 273 bytes buffer
|
||||||
|
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273
|
||||||
|
|
||||||
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
||||||
// Retrieve and store the current buffer index
|
// Retrieve and store the current buffer index
|
||||||
response_info->modulation = free_buffer_pointer;
|
response_info->modulation = free_buffer_pointer;
|
||||||
|
|
||||||
// Determine the maximum size we can use from our buffer
|
// Determine the maximum size we can use from our buffer
|
||||||
size_t max_buffer_size = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE) - free_buffer_pointer;
|
size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||||
|
|
||||||
// Forward the prepare tag modulation function to the inner function
|
// Forward the prepare tag modulation function to the inner function
|
||||||
if (prepare_tag_modulation(response_info,max_buffer_size)) {
|
if (prepare_tag_modulation(response_info, max_buffer_size)) {
|
||||||
// Update the free buffer offset
|
// Update the free buffer offset
|
||||||
free_buffer_pointer += ToSendMax;
|
free_buffer_pointer += ToSendMax;
|
||||||
return true;
|
return true;
|
||||||
|
@ -954,10 +960,6 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
{
|
{
|
||||||
// Enable and clear the trace
|
|
||||||
iso14a_clear_trace();
|
|
||||||
iso14a_set_tracing(TRUE);
|
|
||||||
|
|
||||||
uint8_t sak;
|
uint8_t sak;
|
||||||
|
|
||||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||||
|
@ -1001,10 +1003,11 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The second response contains the (mandatory) first 24 bits of the UID
|
// The second response contains the (mandatory) first 24 bits of the UID
|
||||||
uint8_t response2[5];
|
uint8_t response2[5] = {0x00};
|
||||||
|
|
||||||
// Check if the uid uses the (optional) part
|
// Check if the uid uses the (optional) part
|
||||||
uint8_t response2a[5];
|
uint8_t response2a[5] = {0x00};
|
||||||
|
|
||||||
if (uid_2nd) {
|
if (uid_2nd) {
|
||||||
response2[0] = 0x88;
|
response2[0] = 0x88;
|
||||||
num_to_bytes(uid_1st,3,response2+1);
|
num_to_bytes(uid_1st,3,response2+1);
|
||||||
|
@ -1025,12 +1028,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
|
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
|
||||||
|
|
||||||
// Prepare the mandatory SAK (for 4 and 7 byte UID)
|
// Prepare the mandatory SAK (for 4 and 7 byte UID)
|
||||||
uint8_t response3[3];
|
uint8_t response3[3] = {0x00};
|
||||||
response3[0] = sak;
|
response3[0] = sak;
|
||||||
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
|
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
|
||||||
|
|
||||||
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
|
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
|
||||||
uint8_t response3a[3];
|
uint8_t response3a[3] = {0x00};
|
||||||
response3a[0] = sak & 0xFB;
|
response3a[0] = sak & 0xFB;
|
||||||
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
|
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
|
||||||
|
|
||||||
|
@ -1066,8 +1069,16 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
.modulation_n = 0
|
.modulation_n = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Reset the offset pointer of the free buffer
|
BigBuf_free_keep_EM();
|
||||||
reset_free_buffer();
|
|
||||||
|
// allocate buffers:
|
||||||
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
|
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
|
free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||||
|
|
||||||
|
// clear trace
|
||||||
|
iso14a_clear_trace();
|
||||||
|
iso14a_set_tracing(TRUE);
|
||||||
|
|
||||||
// Prepare the responses of the anticollision phase
|
// Prepare the responses of the anticollision phase
|
||||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||||
|
@ -1089,10 +1100,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
// We need to listen to the high-frequency, peak-detected path.
|
// We need to listen to the high-frequency, peak-detected path.
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||||
|
|
||||||
// buffers used on software Uart:
|
|
||||||
uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
|
|
||||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
|
||||||
|
|
||||||
cmdsRecvd = 0;
|
cmdsRecvd = 0;
|
||||||
tag_response_info_t* p_response;
|
tag_response_info_t* p_response;
|
||||||
|
|
||||||
|
@ -1253,6 +1260,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
|
|
||||||
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
|
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1726,8 +1734,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
uint8_t sel_all[] = { 0x93,0x20 };
|
uint8_t sel_all[] = { 0x93,0x20 };
|
||||||
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
|
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
|
||||||
uint8_t *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
|
||||||
uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
uint8_t resp_par[MAX_PARITY_SIZE];
|
||||||
byte_t uid_resp[4];
|
byte_t uid_resp[4];
|
||||||
size_t uid_resp_len;
|
size_t uid_resp_len;
|
||||||
|
|
||||||
|
@ -2019,8 +2027,11 @@ void ReaderMifare(bool first_try)
|
||||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||||
static uint8_t mf_nr_ar3;
|
static uint8_t mf_nr_ar3;
|
||||||
|
|
||||||
uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET);
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
// free eventually allocated BigBuf memory. We want all for tracing.
|
||||||
|
BigBuf_free();
|
||||||
|
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
|
@ -2231,10 +2242,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
uint32_t numReads = 0;//Counts numer of times reader read a block
|
uint32_t numReads = 0;//Counts numer of times reader read a block
|
||||||
uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf();
|
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE;
|
uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE];
|
||||||
uint8_t* response = get_bigbufptr_recvrespbuf();
|
uint8_t response[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* response_par = response + MAX_FRAME_SIZE;
|
uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
|
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
|
||||||
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
|
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
|
||||||
|
@ -2251,6 +2262,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
|
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
|
||||||
uint8_t ar_nr_collected = 0;
|
uint8_t ar_nr_collected = 0;
|
||||||
|
|
||||||
|
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(TRUE);
|
iso14a_set_tracing(TRUE);
|
||||||
|
@ -2721,18 +2734,20 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
// The length of a received command will in most cases be no more than 18 bytes.
|
// The length of a received command will in most cases be no more than 18 bytes.
|
||||||
// So 32 should be enough!
|
// So 32 should be enough!
|
||||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
// The response (tag -> reader) that we're receiving.
|
// The response (tag -> reader) that we're receiving.
|
||||||
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
||||||
// into trace, along with its length and other annotations.
|
// into trace, along with its length and other annotations.
|
||||||
//uint8_t *trace = (uint8_t *)BigBuf;
|
//uint8_t *trace = (uint8_t *)BigBuf;
|
||||||
|
|
||||||
// The DMA buffer, used to stream samples from the FPGA
|
// free eventually allocated BigBuf memory
|
||||||
uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
BigBuf_free();
|
||||||
|
// allocate the DMA buffer, used to stream samples from the FPGA
|
||||||
|
uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
int maxDataLen = 0;
|
int maxDataLen = 0;
|
||||||
|
@ -2791,7 +2806,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// test for length of buffer
|
// test for length of buffer
|
||||||
if(dataLen > maxDataLen) { // we are more behind than ever...
|
if(dataLen > maxDataLen) { // we are more behind than ever...
|
||||||
maxDataLen = dataLen;
|
maxDataLen = dataLen;
|
||||||
if(dataLen > 400) {
|
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||||
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
|
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,7 @@ static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int
|
||||||
static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int getNext = 0;
|
int getNext = 0;
|
||||||
|
|
||||||
int8_t prev = 0;
|
int8_t prev = 0;
|
||||||
|
@ -446,7 +446,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
|
||||||
static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int getNext = 0;
|
int getNext = 0;
|
||||||
|
|
||||||
int8_t prev = 0;
|
int8_t prev = 0;
|
||||||
|
@ -596,7 +596,7 @@ static void BuildIdentifyRequest(void);
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void AcquireRawAdcSamplesIso15693(void)
|
void AcquireRawAdcSamplesIso15693(void)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
int getNext = 0;
|
int getNext = 0;
|
||||||
|
@ -678,7 +678,7 @@ void AcquireRawAdcSamplesIso15693(void)
|
||||||
|
|
||||||
void RecordRawAdcSamplesIso15693(void)
|
void RecordRawAdcSamplesIso15693(void)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
int c = 0;
|
int c = 0;
|
||||||
int getNext = 0;
|
int getNext = 0;
|
||||||
|
@ -878,8 +878,8 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv)
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
int answerLen=0;
|
int answerLen=0;
|
||||||
uint8_t *answer = (((uint8_t *)BigBuf) + 3660);
|
uint8_t *answer = BigBuf_get_addr() + 3660;
|
||||||
if (recv!=NULL) memset(BigBuf + 3660, 0, 100);
|
if (recv != NULL) memset(answer, 0, 100);
|
||||||
|
|
||||||
if (init) Iso15693InitReader();
|
if (init) Iso15693InitReader();
|
||||||
|
|
||||||
|
@ -999,9 +999,9 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
uint8_t *answer1 = (((uint8_t *)BigBuf) + 3660); //
|
uint8_t *answer1 = BigBuf_get_addr() + 3660;
|
||||||
uint8_t *answer2 = (((uint8_t *)BigBuf) + 3760);
|
uint8_t *answer2 = BigBuf_get_addr() + 3760;
|
||||||
uint8_t *answer3 = (((uint8_t *)BigBuf) + 3860);
|
uint8_t *answer3 = BigBuf_get_addr() + 3860;
|
||||||
|
|
||||||
int answerLen1 = 0;
|
int answerLen1 = 0;
|
||||||
int answerLen2 = 0;
|
int answerLen2 = 0;
|
||||||
|
@ -1015,7 +1015,7 @@ void ReaderIso15693(uint32_t parameter)
|
||||||
|
|
||||||
|
|
||||||
// Blank arrays
|
// Blank arrays
|
||||||
memset(BigBuf + 3660, 0x00, 300);
|
memset(answer1, 0x00, 300);
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
|
|
||||||
|
@ -1111,7 +1111,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
|
|
||||||
uint8_t *buf = (((uint8_t *)BigBuf) + 3660); //
|
uint8_t *buf = BigBuf_get_addr() + 3660;
|
||||||
|
|
||||||
int answerLen1 = 0;
|
int answerLen1 = 0;
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
@ -1213,7 +1213,7 @@ void BruteforceIso15693Afi(uint32_t speed)
|
||||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
|
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
|
||||||
|
|
||||||
int recvlen=0;
|
int recvlen=0;
|
||||||
uint8_t *recvbuf=(uint8_t *)BigBuf;
|
uint8_t *recvbuf = BigBuf_get_addr();
|
||||||
// UsbCommand n;
|
// UsbCommand n;
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
|
|
|
@ -98,13 +98,14 @@ static uint32_t get_key_stream(int skip, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write Time Data into LOG */
|
/* Write Time Data into LOG */
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
if(count == 6) { i = -1; } else { i = legic_read_count; }
|
if(count == 6) { i = -1; } else { i = legic_read_count; }
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i] = legic_prng_count();
|
BigBuf[OFFSET_LOG+128+i] = legic_prng_count();
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
|
BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
|
BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
|
BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
|
BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i] = count;
|
BigBuf[OFFSET_LOG+384+i] = count;
|
||||||
|
|
||||||
/* Generate KeyStream */
|
/* Generate KeyStream */
|
||||||
for(i=0; i<count; i++) {
|
for(i=0; i<count; i++) {
|
||||||
|
@ -426,6 +427,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||||
|
|
||||||
LegicCommonInit();
|
LegicCommonInit();
|
||||||
|
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
memset(BigBuf, 0, 1024);
|
memset(BigBuf, 0, 1024);
|
||||||
|
|
||||||
DbpString("setting up legic card");
|
DbpString("setting up legic card");
|
||||||
|
@ -465,7 +467,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
((uint8_t*)BigBuf)[byte_index] = r;
|
BigBuf[byte_index] = r;
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
byte_index++;
|
byte_index++;
|
||||||
if(byte_index & 0x10) LED_C_ON(); else LED_C_OFF();
|
if(byte_index & 0x10) LED_C_ON(); else LED_C_OFF();
|
||||||
|
@ -480,6 +482,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||||
|
|
||||||
void LegicRfWriter(int bytes, int offset) {
|
void LegicRfWriter(int bytes, int offset) {
|
||||||
int byte_index=0, addr_sz=0;
|
int byte_index=0, addr_sz=0;
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
|
|
||||||
LegicCommonInit();
|
LegicCommonInit();
|
||||||
|
|
||||||
|
@ -512,7 +515,7 @@ void LegicRfWriter(int bytes, int offset) {
|
||||||
perform_setup_phase_rwd(SESSION_IV);
|
perform_setup_phase_rwd(SESSION_IV);
|
||||||
legic_prng_forward(2);
|
legic_prng_forward(2);
|
||||||
while(byte_index < bytes) {
|
while(byte_index < bytes) {
|
||||||
int r = legic_write_byte(((uint8_t*)BigBuf)[byte_index+offset], byte_index+offset, addr_sz);
|
int r = legic_write_byte(BigBuf[byte_index+offset], byte_index+offset, addr_sz);
|
||||||
if((r != 0) || BUTTON_PRESS()) {
|
if((r != 0) || BUTTON_PRESS()) {
|
||||||
Dbprintf("operation aborted @ 0x%03.3x", byte_index);
|
Dbprintf("operation aborted @ 0x%03.3x", byte_index);
|
||||||
switch_off_tag_rwd();
|
switch_off_tag_rwd();
|
||||||
|
@ -534,6 +537,8 @@ int timestamp;
|
||||||
/* Handle (whether to respond) a frame in tag mode */
|
/* Handle (whether to respond) a frame in tag mode */
|
||||||
static void frame_handle_tag(struct legic_frame const * const f)
|
static void frame_handle_tag(struct legic_frame const * const f)
|
||||||
{
|
{
|
||||||
|
uint8_t *BigBuf = BigBuf_get_addr();
|
||||||
|
|
||||||
/* First Part of Handshake (IV) */
|
/* First Part of Handshake (IV) */
|
||||||
if(f->bits == 7) {
|
if(f->bits == 7) {
|
||||||
if(f->data == SESSION_IV) {
|
if(f->data == SESSION_IV) {
|
||||||
|
@ -582,9 +587,9 @@ static void frame_handle_tag(struct legic_frame const * const f)
|
||||||
if(legic_state == STATE_CON) {
|
if(legic_state == STATE_CON) {
|
||||||
int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
|
int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
|
||||||
int addr = f->data ^ key; addr = addr >> 1;
|
int addr = f->data ^ key; addr = addr >> 1;
|
||||||
int data = ((uint8_t*)BigBuf)[addr];
|
int data = BigBuf[addr];
|
||||||
int hash = LegicCRC(addr, data, 11) << 8;
|
int hash = LegicCRC(addr, data, 11) << 8;
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
BigBuf[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
||||||
legic_read_count++;
|
legic_read_count++;
|
||||||
|
|
||||||
//Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c);
|
//Dbprintf("Data:%03.3x, key:%03.3x, addr: %03.3x, read_c:%u", f->data, key, addr, read_c);
|
||||||
|
@ -619,19 +624,19 @@ static void frame_handle_tag(struct legic_frame const * const f)
|
||||||
int i;
|
int i;
|
||||||
Dbprintf("IV: %03.3x", legic_prng_iv);
|
Dbprintf("IV: %03.3x", legic_prng_iv);
|
||||||
for(i = 0; i<legic_read_count; i++) {
|
for(i = 0; i<legic_read_count; i++) {
|
||||||
Dbprintf("Read Nb: %u, Addr: %u", i, ((uint8_t*)BigBuf)[OFFSET_LOG+i]);
|
Dbprintf("Read Nb: %u, Addr: %u", i, BigBuf[OFFSET_LOG+i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = -1; i<legic_read_count; i++) {
|
for(i = -1; i<legic_read_count; i++) {
|
||||||
uint32_t t;
|
uint32_t t;
|
||||||
t = ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4];
|
t = BigBuf[OFFSET_LOG+256+i*4];
|
||||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] << 8;
|
t |= BigBuf[OFFSET_LOG+256+i*4+1] << 8;
|
||||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+2] <<16;
|
t |= BigBuf[OFFSET_LOG+256+i*4+2] <<16;
|
||||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+3] <<24;
|
t |= BigBuf[OFFSET_LOG+256+i*4+3] <<24;
|
||||||
|
|
||||||
Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
|
Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i],
|
BigBuf[OFFSET_LOG+128+i],
|
||||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i],
|
BigBuf[OFFSET_LOG+384+i],
|
||||||
t);
|
t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,8 @@ void ReadTItag(void)
|
||||||
#define FREQLO 123200
|
#define FREQLO 123200
|
||||||
#define FREQHI 134200
|
#define FREQHI 134200
|
||||||
|
|
||||||
signed char *dest = (signed char *)BigBuf;
|
signed char *dest = (signed char *)BigBuf_get_addr();
|
||||||
int n = sizeof(BigBuf);
|
uint16_t n = BigBuf_max_traceLen();
|
||||||
// 128 bit shift register [shift3:shift2:shift1:shift0]
|
// 128 bit shift register [shift3:shift2:shift1:shift0]
|
||||||
uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
|
uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
|
||||||
|
|
||||||
|
@ -246,7 +246,8 @@ void AcquireTiType(void)
|
||||||
#define TIBUFLEN 1250
|
#define TIBUFLEN 1250
|
||||||
|
|
||||||
// clear buffer
|
// clear buffer
|
||||||
memset(BigBuf,0,sizeof(BigBuf));
|
uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr();
|
||||||
|
memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t));
|
||||||
|
|
||||||
// Set up the synchronous serial port
|
// Set up the synchronous serial port
|
||||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
|
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
|
||||||
|
@ -294,7 +295,7 @@ void AcquireTiType(void)
|
||||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
||||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
|
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
|
||||||
|
|
||||||
char *dest = (char *)BigBuf;
|
char *dest = (char *)BigBuf_get_addr();
|
||||||
n = TIBUFLEN*32;
|
n = TIBUFLEN*32;
|
||||||
// unpack buffer
|
// unpack buffer
|
||||||
for (i=TIBUFLEN-1; i>=0; i--) {
|
for (i=TIBUFLEN-1; i>=0; i--) {
|
||||||
|
@ -383,7 +384,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
|
||||||
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
uint8_t *tab = (uint8_t *)BigBuf;
|
uint8_t *tab = BigBuf_get_addr();
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||||
|
@ -443,7 +444,7 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
||||||
|
|
||||||
// compose fc/8 fc/10 waveform
|
// compose fc/8 fc/10 waveform
|
||||||
static void fc(int c, int *n) {
|
static void fc(int c, int *n) {
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
// for when we want an fc8 pattern every 4 logical bits
|
// for when we want an fc8 pattern every 4 logical bits
|
||||||
|
@ -547,11 +548,11 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
|
||||||
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
||||||
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
const size_t sizeOfBigBuff = BigBuf_max_traceLen();
|
||||||
size_t size=0; //, found=0;
|
size_t size = 0;
|
||||||
uint32_t hi2=0, hi=0, lo=0;
|
uint32_t hi2=0, hi=0, lo=0;
|
||||||
|
int idx=0;
|
||||||
// Configure to go in 125Khz listen mode
|
// Configure to go in 125Khz listen mode
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(95, true);
|
||||||
|
|
||||||
|
@ -562,11 +563,10 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
|
|
||||||
DoAcquisition_default(-1,true);
|
DoAcquisition_default(-1,true);
|
||||||
// FSK demodulator
|
// FSK demodulator
|
||||||
size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
|
size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
|
||||||
|
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
|
||||||
|
|
||||||
WDT_HIT();
|
if (idx>0 && lo>0){
|
||||||
|
|
||||||
if (size>0 && lo>0){
|
|
||||||
// final loop, go over previously decoded manchester data and decode into usable tag ID
|
// final loop, go over previously decoded manchester data and decode into usable tag ID
|
||||||
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
|
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
|
||||||
if (hi2 != 0){ //extra large HID tags
|
if (hi2 != 0){ //extra large HID tags
|
||||||
|
@ -622,6 +622,8 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
}
|
}
|
||||||
if (findone){
|
if (findone){
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
|
*high = hi;
|
||||||
|
*low = lo;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// reset
|
// reset
|
||||||
|
@ -635,9 +637,9 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
|
|
||||||
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
size_t size=0;
|
size_t size=0, idx=0;
|
||||||
int clk=0, invert=0, errCnt=0;
|
int clk=0, invert=0, errCnt=0;
|
||||||
uint64_t lo=0;
|
uint64_t lo=0;
|
||||||
// Configure to go in 125Khz listen mode
|
// Configure to go in 125Khz listen mode
|
||||||
|
@ -649,7 +651,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||||
if (ledcontrol) LED_A_ON();
|
if (ledcontrol) LED_A_ON();
|
||||||
|
|
||||||
DoAcquisition_default(-1,true);
|
DoAcquisition_default(-1,true);
|
||||||
size = sizeof(BigBuf);
|
size = BigBuf_max_traceLen();
|
||||||
//Dbprintf("DEBUG: Buffer got");
|
//Dbprintf("DEBUG: Buffer got");
|
||||||
//askdemod and manchester decode
|
//askdemod and manchester decode
|
||||||
errCnt = askmandemod(dest, &size, &clk, &invert);
|
errCnt = askmandemod(dest, &size, &clk, &invert);
|
||||||
|
@ -657,7 +659,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if (errCnt>=0){
|
if (errCnt>=0){
|
||||||
lo = Em410xDecode(dest,size);
|
lo = Em410xDecode(dest, &size, &idx);
|
||||||
//Dbprintf("DEBUG: EM GOT");
|
//Dbprintf("DEBUG: EM GOT");
|
||||||
if (lo>0){
|
if (lo>0){
|
||||||
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
|
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
|
||||||
|
@ -669,6 +671,8 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||||
}
|
}
|
||||||
if (findone){
|
if (findone){
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
|
*high=lo>>32;
|
||||||
|
*low=lo & 0xFFFFFFFF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else{
|
} else{
|
||||||
|
@ -687,7 +691,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||||
|
|
||||||
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int idx=0;
|
int idx=0;
|
||||||
uint32_t code=0, code2=0;
|
uint32_t code=0, code2=0;
|
||||||
uint8_t version=0;
|
uint8_t version=0;
|
||||||
|
@ -702,7 +706,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
DoAcquisition_default(-1,true);
|
DoAcquisition_default(-1,true);
|
||||||
//fskdemod and get start index
|
//fskdemod and get start index
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
idx = IOdemodFSK(dest,sizeof(BigBuf));
|
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
|
||||||
if (idx>0){
|
if (idx>0){
|
||||||
//valid tag found
|
//valid tag found
|
||||||
|
|
||||||
|
@ -735,6 +739,8 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
if (findone){
|
if (findone){
|
||||||
if (ledcontrol) LED_A_OFF();
|
if (ledcontrol) LED_A_OFF();
|
||||||
//LED_A_OFF();
|
//LED_A_OFF();
|
||||||
|
*high=code;
|
||||||
|
*low=code2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
code=code2=0;
|
code=code2=0;
|
||||||
|
@ -874,11 +880,11 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
||||||
// Read one card block in page 0
|
// Read one card block in page 0
|
||||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||||
{
|
{
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
//int m=0, i=0; //enio adjustment 12/10/14
|
//int m=0, i=0; //enio adjustment 12/10/14
|
||||||
uint32_t m=0, i=0;
|
uint32_t m=0, i=0;
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
m = sizeof(BigBuf);
|
m = BigBuf_max_traceLen();
|
||||||
// Clear destination buffer before sending the command
|
// Clear destination buffer before sending the command
|
||||||
memset(dest, 128, m);
|
memset(dest, 128, m);
|
||||||
// Connect the A/D to the peak-detected low-frequency path.
|
// Connect the A/D to the peak-detected low-frequency path.
|
||||||
|
@ -939,11 +945,11 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||||
|
|
||||||
// Read card traceability data (page 1)
|
// Read card traceability data (page 1)
|
||||||
void T55xxReadTrace(void){
|
void T55xxReadTrace(void){
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int m=0, i=0;
|
int m=0, i=0;
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
m = sizeof(BigBuf);
|
m = BigBuf_max_traceLen();
|
||||||
// Clear destination buffer before sending the command
|
// Clear destination buffer before sending the command
|
||||||
memset(dest, 128, m);
|
memset(dest, 128, m);
|
||||||
// Connect the A/D to the peak-detected low-frequency path.
|
// Connect the A/D to the peak-detected low-frequency path.
|
||||||
|
@ -1293,8 +1299,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
|
||||||
int DemodPCF7931(uint8_t **outBlocks) {
|
int DemodPCF7931(uint8_t **outBlocks) {
|
||||||
uint8_t BitStream[256];
|
uint8_t BitStream[256];
|
||||||
uint8_t Blocks[8][16];
|
uint8_t Blocks[8][16];
|
||||||
uint8_t *GraphBuffer = (uint8_t *)BigBuf;
|
uint8_t *GraphBuffer = BigBuf_get_addr();
|
||||||
int GraphTraceLen = sizeof(BigBuf);
|
int GraphTraceLen = BigBuf_max_traceLen();
|
||||||
int i, j, lastval, bitidx, half_switch;
|
int i, j, lastval, bitidx, half_switch;
|
||||||
int clock = 64;
|
int clock = 64;
|
||||||
int tolerance = clock / 8;
|
int tolerance = clock / 8;
|
||||||
|
@ -1713,7 +1719,7 @@ void EM4xLogin(uint32_t Password) {
|
||||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||||
|
|
||||||
uint8_t fwd_bit_count;
|
uint8_t fwd_bit_count;
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int m=0, i=0;
|
int m=0, i=0;
|
||||||
|
|
||||||
//If password mode do login
|
//If password mode do login
|
||||||
|
@ -1723,7 +1729,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||||
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
|
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
|
||||||
fwd_bit_count += Prepare_Addr( Address );
|
fwd_bit_count += Prepare_Addr( Address );
|
||||||
|
|
||||||
m = sizeof(BigBuf);
|
m = BigBuf_max_traceLen();
|
||||||
// Clear destination buffer before sending the command
|
// Clear destination buffer before sending the command
|
||||||
memset(dest, 128, m);
|
memset(dest, 128, m);
|
||||||
// Connect the A/D to the peak-detected low-frequency path.
|
// Connect the A/D to the peak-detected low-frequency path.
|
||||||
|
|
|
@ -124,8 +124,9 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
|
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold,bool silent)
|
||||||
{
|
{
|
||||||
//.
|
//.
|
||||||
uint8_t *dest = (uint8_t *)BigBuf;
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
int bufsize = BIGBUF_SIZE;
|
int bufsize = BigBuf_max_traceLen();
|
||||||
|
|
||||||
memset(dest, 0, bufsize);
|
memset(dest, 0, bufsize);
|
||||||
|
|
||||||
if(bits_per_sample < 1) bits_per_sample = 1;
|
if(bits_per_sample < 1) bits_per_sample = 1;
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "crc.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Select, Authenticate, Read a MIFARE tag.
|
// Select, Authenticate, Read a MIFARE tag.
|
||||||
// read block
|
// read block
|
||||||
|
@ -80,7 +82,71 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
// Thats it...
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
|
byte_t isOK = 0;
|
||||||
|
byte_t dataoutbuf[16] = {0x00};
|
||||||
|
uint8_t uid[10] = {0x00};
|
||||||
|
uint32_t cuid;
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
LED_B_OFF();
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
iso14a_clear_trace();
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Can't select card");
|
||||||
|
//OnError(0);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(mifare_ultra_auth1(cuid, dataoutbuf)){
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Authentication part1: Fail.");
|
||||||
|
//OnError(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOK = 1;
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||||
|
DbpString("AUTH 1 FINISHED");
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
|
uint32_t cuid = arg0;
|
||||||
|
uint8_t key[16] = {0x00};
|
||||||
|
byte_t isOK = 0;
|
||||||
|
byte_t dataoutbuf[16] = {0x00};
|
||||||
|
|
||||||
|
memcpy(key, datain, 16);
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
LED_B_OFF();
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Authentication part2: Fail...");
|
||||||
|
//OnError(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isOK = 1;
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||||
|
DbpString("AUTH 2 FINISHED");
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
@ -463,11 +529,13 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
struct Crypto1State mpcs = {0, 0};
|
struct Crypto1State mpcs = {0, 0};
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
pcs = &mpcs;
|
pcs = &mpcs;
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
|
||||||
uint32_t auth1_time, auth2_time;
|
uint32_t auth1_time, auth2_time;
|
||||||
static uint16_t delta_time;
|
static uint16_t delta_time;
|
||||||
|
|
||||||
|
// free eventually allocated BigBuf memory
|
||||||
|
BigBuf_free();
|
||||||
// clear trace
|
// clear trace
|
||||||
iso14a_clear_trace();
|
iso14a_clear_trace();
|
||||||
iso14a_set_tracing(false);
|
iso14a_set_tracing(false);
|
||||||
|
@ -854,8 +922,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
uint8_t d_block[18] = {0x00};
|
uint8_t d_block[18] = {0x00};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// reset FPGA and LED
|
// reset FPGA and LED
|
||||||
if (workFlags & 0x08) {
|
if (workFlags & 0x08) {
|
||||||
|
@ -973,8 +1041,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
uint8_t data[18] = {0x00};
|
uint8_t data[18] = {0x00};
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
|
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
if (workFlags & 0x08) {
|
if (workFlags & 0x08) {
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
@ -1038,8 +1106,8 @@ void MifareCIdent(){
|
||||||
// variables
|
// variables
|
||||||
byte_t isOK = 1;
|
byte_t isOK = 1;
|
||||||
|
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
@ -1061,3 +1129,58 @@ void MifareCIdent(){
|
||||||
//
|
//
|
||||||
// DESFIRE
|
// DESFIRE
|
||||||
//
|
//
|
||||||
|
|
||||||
|
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
|
byte_t dataout[11] = {0x00};
|
||||||
|
uint8_t uid[10] = {0x00};
|
||||||
|
uint32_t cuid;
|
||||||
|
|
||||||
|
iso14a_clear_trace();
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
|
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||||
|
if(!len) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Can't select card");
|
||||||
|
//OnError(1);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if(mifare_desfire_des_auth1(cuid, dataout)){
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Authentication part1: Fail.");
|
||||||
|
//OnError(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
|
uint32_t cuid = arg0;
|
||||||
|
uint8_t key[16] = {0x00};
|
||||||
|
byte_t isOK = 0;
|
||||||
|
byte_t dataout[12] = {0x00};
|
||||||
|
|
||||||
|
memcpy(key, datain, 16);
|
||||||
|
|
||||||
|
isOK = mifare_desfire_des_auth2(cuid, key, dataout);
|
||||||
|
|
||||||
|
if( isOK) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||||
|
Dbprintf("Authentication part2: Failed");
|
||||||
|
//OnError(4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||||
|
DbpString("AUTH 2 FINISHED");
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
|
|
||||||
static int sniffState = SNF_INIT;
|
static int sniffState = SNF_INIT;
|
||||||
static uint8_t sniffUIDType;
|
static uint8_t sniffUIDType;
|
||||||
static uint8_t sniffUID[8];
|
static uint8_t sniffUID[8] = {0x00};
|
||||||
static uint8_t sniffATQA[2];
|
static uint8_t sniffATQA[2] = {0x00};
|
||||||
static uint8_t sniffSAK;
|
static uint8_t sniffSAK;
|
||||||
static uint8_t sniffBuf[16];
|
static uint8_t sniffBuf[16] = {0x00};
|
||||||
static uint32_t timerData = 0;
|
static uint32_t timerData = 0;
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,12 +151,13 @@ bool intMfSniffSend() {
|
||||||
int pckSize = 0;
|
int pckSize = 0;
|
||||||
int pckLen = traceLen;
|
int pckLen = traceLen;
|
||||||
int pckNum = 0;
|
int pckNum = 0;
|
||||||
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
while (pckLen > 0) {
|
while (pckLen > 0) {
|
||||||
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK, 1, pckSize, pckNum, trace + traceLen - pckLen, pckSize);
|
cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
pckLen -= pckSize;
|
pckLen -= pckSize;
|
||||||
|
|
|
@ -21,17 +21,6 @@
|
||||||
|
|
||||||
int MF_DBGLEVEL = MF_DBG_ALL;
|
int MF_DBGLEVEL = MF_DBG_ALL;
|
||||||
|
|
||||||
// memory management
|
|
||||||
uint8_t* get_bigbufptr_recvrespbuf(void) {
|
|
||||||
return (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
|
||||||
}
|
|
||||||
uint8_t* get_bigbufptr_recvcmdbuf(void) {
|
|
||||||
return (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
|
||||||
}
|
|
||||||
uint8_t* get_bigbufptr_emlcardmem(void) {
|
|
||||||
return (((uint8_t *)BigBuf) + CARD_MEMORY_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// crypto1 helpers
|
// crypto1 helpers
|
||||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
|
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
|
||||||
uint8_t bt = 0;
|
uint8_t bt = 0;
|
||||||
|
@ -93,14 +82,34 @@ int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint
|
||||||
AppendCrc14443a(dcmd, 6);
|
AppendCrc14443a(dcmd, 6);
|
||||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||||
int len = ReaderReceive(answer, answer_parity);
|
int len = ReaderReceive(answer, answer_parity);
|
||||||
if(!len)
|
if(!len) {
|
||||||
{
|
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
|
||||||
|
{
|
||||||
|
uint8_t dcmd[19];
|
||||||
|
int len;
|
||||||
|
dcmd[0] = cmd;
|
||||||
|
memcpy(dcmd+1,data,16);
|
||||||
|
AppendCrc14443a(dcmd, 17);
|
||||||
|
|
||||||
|
ReaderTransmit(dcmd, sizeof(dcmd), timing);
|
||||||
|
len = ReaderReceive(answer, answer_parity);
|
||||||
|
if(!len) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed. Card timeout.");
|
||||||
|
len = ReaderReceive(answer,answer_parity);
|
||||||
|
}
|
||||||
|
if(len==1) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("NAK - Authentication failed.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
|
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
|
||||||
{
|
{
|
||||||
uint8_t dcmd[4], ecmd[4];
|
uint8_t dcmd[4], ecmd[4];
|
||||||
|
@ -166,8 +175,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
|
||||||
uint32_t nt, ntpp; // Supplied tag nonce
|
uint32_t nt, ntpp; // Supplied tag nonce
|
||||||
|
|
||||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// Transmit MIFARE_CLASSIC_AUTH
|
// Transmit MIFARE_CLASSIC_AUTH
|
||||||
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
|
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
|
||||||
|
@ -253,8 +262,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||||
int len;
|
int len;
|
||||||
uint8_t bt[2];
|
uint8_t bt[2];
|
||||||
|
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// command MIFARE_CLASSIC_READBLOCK
|
// command MIFARE_CLASSIC_READBLOCK
|
||||||
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
|
@ -278,12 +287,63 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mifare ultralight commands
|
||||||
|
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
|
||||||
|
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
|
||||||
|
if (len == 1) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (len != 11)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||||
|
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||||
|
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||||
|
receivedAnswer[10]);
|
||||||
|
}
|
||||||
|
memcpy(blockData, receivedAnswer, 11);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||||
|
|
||||||
|
uint16_t len;
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
|
if (len == 1) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (len != 11)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||||
|
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||||
|
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||||
|
receivedAnswer[10]);
|
||||||
|
}
|
||||||
|
memcpy(blockData, receivedAnswer, 11);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||||
{
|
{
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t bt[2];
|
uint8_t bt[2];
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
|
||||||
// command MIFARE_CLASSIC_READBLOCK
|
// command MIFARE_CLASSIC_READBLOCK
|
||||||
|
@ -321,8 +381,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
||||||
byte_t res;
|
byte_t res;
|
||||||
|
|
||||||
uint8_t d_block[18], d_block_enc[18];
|
uint8_t d_block[18], d_block_enc[18];
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||||
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
|
@ -364,8 +424,8 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t par[3] = {0}; // enough for 18 parity bits
|
uint8_t par[3] = {0}; // enough for 18 parity bits
|
||||||
uint8_t d_block[18] = {0x00};
|
uint8_t d_block[18] = {0x00};
|
||||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||||
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
|
@ -395,8 +455,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
||||||
{
|
{
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t d_block[8] = {0x00};
|
uint8_t d_block[8] = {0x00};
|
||||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||||
d_block[0]= blockNo;
|
d_block[0]= blockNo;
|
||||||
|
@ -416,8 +476,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
||||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||||
{
|
{
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
|
@ -432,8 +492,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||||
int mifare_ultra_halt(uint32_t uid)
|
int mifare_ultra_halt(uint32_t uid)
|
||||||
{
|
{
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
|
@ -467,22 +527,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
|
||||||
|
|
||||||
// work with emulator memory
|
// work with emulator memory
|
||||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
|
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
|
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
|
memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
|
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
memcpy(data, emCARD + bytePtr, byteCount);
|
memcpy(data, emCARD + bytePtr, byteCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
int emlCheckValBl(int blockNum) {
|
int emlCheckValBl(int blockNum) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
uint8_t* data = emCARD + blockNum * 16;
|
uint8_t* data = emCARD + blockNum * 16;
|
||||||
|
|
||||||
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
|
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
|
||||||
|
@ -497,7 +557,7 @@ int emlCheckValBl(int blockNum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
uint8_t* data = emCARD + blockNum * 16;
|
uint8_t* data = emCARD + blockNum * 16;
|
||||||
|
|
||||||
if (emlCheckValBl(blockNum)) {
|
if (emlCheckValBl(blockNum)) {
|
||||||
|
@ -510,7 +570,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
uint8_t* data = emCARD + blockNum * 16;
|
uint8_t* data = emCARD + blockNum * 16;
|
||||||
|
|
||||||
memcpy(data + 0, &blReg, 4);
|
memcpy(data + 0, &blReg, 4);
|
||||||
|
@ -528,7 +588,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||||
|
|
||||||
uint64_t emlGetKey(int sectorNum, int keyType) {
|
uint64_t emlGetKey(int sectorNum, int keyType) {
|
||||||
uint8_t key[6];
|
uint8_t key[6];
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
|
|
||||||
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
||||||
return bytes_to_num(key, 6);
|
return bytes_to_num(key, 6);
|
||||||
|
@ -539,7 +599,7 @@ void emlClearMem(void) {
|
||||||
|
|
||||||
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
|
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
|
||||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||||
|
|
||||||
memset(emCARD, 0, CARD_MEMORY_SIZE);
|
memset(emCARD, 0, CARD_MEMORY_SIZE);
|
||||||
|
|
||||||
|
@ -552,3 +612,98 @@ void emlClearMem(void) {
|
||||||
emlSetMem((uint8_t *)uid, 0, 1);
|
emlSetMem((uint8_t *)uid, 0, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mifare desfire commands
|
||||||
|
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing)
|
||||||
|
{
|
||||||
|
uint8_t dcmd[5] = {0x00};
|
||||||
|
dcmd[0] = cmd;
|
||||||
|
memcpy(dcmd+1,data,2);
|
||||||
|
AppendCrc14443a(dcmd, 3);
|
||||||
|
|
||||||
|
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||||
|
int len = ReaderReceive(answer, answer_parity);
|
||||||
|
if(!len) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Authentication failed. Card timeout.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing)
|
||||||
|
{
|
||||||
|
uint8_t dcmd[20] = {0x00};
|
||||||
|
dcmd[0] = cmd;
|
||||||
|
memcpy(dcmd+1,data,17);
|
||||||
|
AppendCrc14443a(dcmd, 18);
|
||||||
|
|
||||||
|
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||||
|
int len = ReaderReceive(answer, answer_parity);
|
||||||
|
if(!len){
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Authentication failed. Card timeout.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
|
||||||
|
|
||||||
|
int len;
|
||||||
|
// load key, keynumber
|
||||||
|
uint8_t data[2]={0x0a, 0x00};
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);
|
||||||
|
if (len == 1) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 12) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||||
|
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||||
|
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||||
|
receivedAnswer[10],receivedAnswer[11]);
|
||||||
|
}
|
||||||
|
memcpy(blockData, receivedAnswer, 12);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||||
|
|
||||||
|
int len;
|
||||||
|
uint8_t data[17] = {0x00};
|
||||||
|
data[0] = 0xAF;
|
||||||
|
memcpy(data+1,key,16);
|
||||||
|
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
|
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL);
|
||||||
|
|
||||||
|
if ((receivedAnswer[0] == 0x03) && (receivedAnswer[1] == 0xae)) {
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||||
|
Dbprintf("Auth Error: %02x %02x", receivedAnswer[0], receivedAnswer[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 12){
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||||
|
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
|
||||||
|
receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4],
|
||||||
|
receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9],
|
||||||
|
receivedAnswer[10],receivedAnswer[11]);
|
||||||
|
}
|
||||||
|
memcpy(blockData, receivedAnswer, 12);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -53,14 +53,17 @@ extern int MF_DBGLEVEL;
|
||||||
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
|
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
|
||||||
|
|
||||||
//functions
|
//functions
|
||||||
uint8_t* mifare_get_bigbufptr(void);
|
|
||||||
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||||
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||||
|
|
||||||
|
int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing);
|
||||||
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||||
|
|
||||||
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
|
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
|
||||||
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
|
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
|
||||||
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
|
int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData);
|
||||||
|
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);
|
||||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
|
@ -68,16 +71,17 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
||||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
|
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
|
||||||
int mifare_ultra_halt(uint32_t uid);
|
int mifare_ultra_halt(uint32_t uid);
|
||||||
|
|
||||||
|
// desfire
|
||||||
|
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);
|
||||||
|
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing);
|
||||||
|
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData);
|
||||||
|
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData);
|
||||||
|
|
||||||
// crypto functions
|
// crypto functions
|
||||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
|
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len);
|
||||||
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
|
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par);
|
||||||
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
|
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data);
|
||||||
|
|
||||||
// memory management
|
|
||||||
uint8_t* get_bigbufptr_recvrespbuf(void);
|
|
||||||
uint8_t* get_bigbufptr_recvcmdbuf(void);
|
|
||||||
uint8_t* get_bigbufptr_emlcardmem(void);
|
|
||||||
|
|
||||||
// Mifare memory structure
|
// Mifare memory structure
|
||||||
uint8_t NumBlocksPerSector(uint8_t sectorNo);
|
uint8_t NumBlocksPerSector(uint8_t sectorNo);
|
||||||
uint8_t FirstBlockOfSector(uint8_t sectorNo);
|
uint8_t FirstBlockOfSector(uint8_t sectorNo);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <common.h>
|
#include "common.h"
|
||||||
|
|
||||||
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
|
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ include ../common/Makefile.common
|
||||||
CC=gcc
|
CC=gcc
|
||||||
CXX=g++
|
CXX=g++
|
||||||
#COMMON_FLAGS = -m32
|
#COMMON_FLAGS = -m32
|
||||||
|
|
||||||
VPATH = ../common
|
VPATH = ../common
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
|
||||||
|
@ -17,7 +16,6 @@ LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthre
|
||||||
LDFLAGS = $(COMMON_FLAGS)
|
LDFLAGS = $(COMMON_FLAGS)
|
||||||
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
|
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
||||||
|
@ -79,6 +77,7 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||||
cmdhflegic.c \
|
cmdhflegic.c \
|
||||||
cmdhficlass.c \
|
cmdhficlass.c \
|
||||||
cmdhfmf.c \
|
cmdhfmf.c \
|
||||||
|
cmdhfmfu.c \
|
||||||
cmdhw.c \
|
cmdhw.c \
|
||||||
cmdlf.c \
|
cmdlf.c \
|
||||||
cmdlfio.c \
|
cmdlfio.c \
|
||||||
|
|
650
client/cmddata.c
650
client/cmddata.c
|
@ -24,21 +24,30 @@
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
|
|
||||||
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
|
uint8_t g_debugMode;
|
||||||
int DemodBufferLen;
|
int DemodBufferLen;
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
//set the demod buffer with given array of binary (one bit per byte)
|
//set the demod buffer with given array of binary (one bit per byte)
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
void setDemodBuf(uint8_t *buff,int size)
|
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
|
||||||
{
|
{
|
||||||
int i=0;
|
size_t i = 0;
|
||||||
for (; i < size; ++i){
|
for (; i < size; i++){
|
||||||
DemodBuffer[i]=buff[i];
|
DemodBuffer[i]=buff[startIdx++];
|
||||||
}
|
}
|
||||||
DemodBufferLen=size;
|
DemodBufferLen=size;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdSetDebugMode(const char *Cmd)
|
||||||
|
{
|
||||||
|
int demod=0;
|
||||||
|
sscanf(Cmd, "%i", &demod);
|
||||||
|
g_debugMode=(uint8_t)demod;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
void printDemodBuff()
|
void printDemodBuff()
|
||||||
{
|
{
|
||||||
|
@ -208,7 +217,7 @@ void printEM410x(uint64_t id)
|
||||||
{
|
{
|
||||||
if (id !=0){
|
if (id !=0){
|
||||||
uint64_t iii=1;
|
uint64_t iii=1;
|
||||||
uint64_t id2lo=0; //id2hi=0,
|
uint64_t id2lo=0;
|
||||||
uint32_t ii=0;
|
uint32_t ii=0;
|
||||||
uint32_t i=0;
|
uint32_t i=0;
|
||||||
for (ii=5; ii>0;ii--){
|
for (ii=5; ii>0;ii--){
|
||||||
|
@ -218,7 +227,7 @@ void printEM410x(uint64_t id)
|
||||||
}
|
}
|
||||||
//output em id
|
//output em id
|
||||||
PrintAndLog("EM TAG ID : %010llx", id);
|
PrintAndLog("EM TAG ID : %010llx", id);
|
||||||
PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
|
PrintAndLog("Unique TAG ID: %010llx", id2lo);
|
||||||
PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
|
PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
|
||||||
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
|
PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
|
||||||
PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
|
PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
|
||||||
|
@ -235,12 +244,17 @@ void printEM410x(uint64_t id)
|
||||||
int CmdEm410xDecode(const char *Cmd)
|
int CmdEm410xDecode(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint64_t id=0;
|
uint64_t id=0;
|
||||||
// uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
size_t size = DemodBufferLen, idx=0;
|
||||||
// uint32_t i=0;
|
id = Em410xDecode(DemodBuffer, &size, &idx);
|
||||||
// i=getFromGraphBuf(BitStream);
|
if (id>0){
|
||||||
id = Em410xDecode(DemodBuffer,DemodBufferLen);
|
setDemodBuf(DemodBuffer, size, idx);
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: Printing demod buffer:");
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
printEM410x(id);
|
printEM410x(id);
|
||||||
if (id>0) return 1;
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,11 +275,11 @@ int Cmdaskmandemod(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t BitLen = getFromGraphBuf(BitStream);
|
size_t BitLen = getFromGraphBuf(BitStream);
|
||||||
// PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
|
if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
|
||||||
int errCnt=0;
|
int errCnt=0;
|
||||||
errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
|
errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
|
||||||
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
|
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
|
||||||
// PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
|
if (g_debugMode==1) PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
|
PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
|
||||||
|
@ -276,17 +290,22 @@ int Cmdaskmandemod(const char *Cmd)
|
||||||
}
|
}
|
||||||
PrintAndLog("ASK/Manchester decoded bitstream:");
|
PrintAndLog("ASK/Manchester decoded bitstream:");
|
||||||
// Now output the bitstream to the scrollback by line of 16 bits
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
setDemodBuf(BitStream,BitLen);
|
setDemodBuf(BitStream,BitLen,0);
|
||||||
printDemodBuff();
|
printDemodBuff();
|
||||||
uint64_t lo =0;
|
uint64_t lo =0;
|
||||||
lo = Em410xDecode(BitStream,BitLen);
|
size_t idx=0;
|
||||||
|
lo = Em410xDecode(BitStream, &BitLen, &idx);
|
||||||
if (lo>0){
|
if (lo>0){
|
||||||
//set GraphBuffer for clone or sim command
|
//set GraphBuffer for clone or sim command
|
||||||
|
setDemodBuf(BitStream, BitLen, idx);
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
PrintAndLog("EM410x pattern found: ");
|
PrintAndLog("EM410x pattern found: ");
|
||||||
printEM410x(lo);
|
printEM410x(lo);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//if (BitLen>16) return 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,17 +338,23 @@ int Cmdmandecoderaw(const char *Cmd)
|
||||||
printBitStream(BitStream, size);
|
printBitStream(BitStream, size);
|
||||||
if (errCnt==0){
|
if (errCnt==0){
|
||||||
uint64_t id = 0;
|
uint64_t id = 0;
|
||||||
id = Em410xDecode(BitStream, size);
|
size_t idx=0;
|
||||||
if (id>0) setDemodBuf(BitStream, size);
|
id = Em410xDecode(BitStream, &size, &idx);
|
||||||
|
if (id>0){
|
||||||
|
//need to adjust to set bitstream back to manchester encoded data
|
||||||
|
//setDemodBuf(BitStream, size, idx);
|
||||||
|
|
||||||
printEM410x(id);
|
printEM410x(id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//biphase decode
|
//biphase decode
|
||||||
//take 01 or 10 = 0 and 11 or 00 = 1
|
//take 01 or 10 = 0 and 11 or 00 = 1
|
||||||
//takes 1 argument "offset" default = 0 if 1 it will shift the decode by one bit
|
//takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit
|
||||||
|
// and "invert" default = 0 if 1 it will invert output
|
||||||
// since it is not like manchester and doesn't have an incorrect bit pattern we
|
// since it is not like manchester and doesn't have an incorrect bit pattern we
|
||||||
// cannot determine if our decode is correct or if it should be shifted by one bit
|
// cannot determine if our decode is correct or if it should be shifted by one bit
|
||||||
// the argument offset allows us to manually shift if the output is incorrect
|
// the argument offset allows us to manually shift if the output is incorrect
|
||||||
|
@ -341,8 +366,9 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
|
||||||
int errCnt=0;
|
int errCnt=0;
|
||||||
size_t size=0;
|
size_t size=0;
|
||||||
int offset=0;
|
int offset=0;
|
||||||
|
int invert=0;
|
||||||
int high=0, low=0;
|
int high=0, low=0;
|
||||||
sscanf(Cmd, "%i", &offset);
|
sscanf(Cmd, "%i %i", &offset, &invert);
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
//get graphbuffer & high and low
|
//get graphbuffer & high and low
|
||||||
for (;i<DemodBufferLen;++i){
|
for (;i<DemodBufferLen;++i){
|
||||||
|
@ -355,7 +381,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
size=i;
|
size=i;
|
||||||
errCnt=BiphaseRawDecode(BitStream, &size, offset);
|
errCnt=BiphaseRawDecode(BitStream, &size, offset, invert);
|
||||||
if (errCnt>=20){
|
if (errCnt>=20){
|
||||||
PrintAndLog("Too many errors attempting to decode: %d",errCnt);
|
PrintAndLog("Too many errors attempting to decode: %d",errCnt);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -366,7 +392,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//takes 2 arguments - clock and invert both as integers
|
//takes 2 arguments - clock and invert both as integers
|
||||||
//attempts to demodulate ask only
|
//attempts to demodulate ask only
|
||||||
|
@ -386,12 +411,13 @@ int Cmdaskrawdemod(const char *Cmd)
|
||||||
errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
|
errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
|
||||||
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
|
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
|
||||||
PrintAndLog("no data found");
|
PrintAndLog("no data found");
|
||||||
|
if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
||||||
//PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
|
|
||||||
//move BitStream back to DemodBuffer
|
//move BitStream back to DemodBuffer
|
||||||
setDemodBuf(BitStream,BitLen);
|
setDemodBuf(BitStream,BitLen,0);
|
||||||
|
|
||||||
//output
|
//output
|
||||||
if (errCnt>0){
|
if (errCnt>0){
|
||||||
|
@ -513,10 +539,6 @@ int CmdBitstream(const char *Cmd)
|
||||||
bit ^= 1;
|
bit ^= 1;
|
||||||
|
|
||||||
AppendGraph(0, clock, bit);
|
AppendGraph(0, clock, bit);
|
||||||
// for (j = 0; j < (int)(clock/2); j++)
|
|
||||||
// GraphBuffer[(i * clock) + j] = bit ^ 1;
|
|
||||||
// for (j = (int)(clock/2); j < clock; j++)
|
|
||||||
// GraphBuffer[(i * clock) + j] = bit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
|
@ -578,6 +600,27 @@ int CmdUndec(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//shift graph zero up or down based on input + or -
|
||||||
|
int CmdGraphShiftZero(const char *Cmd)
|
||||||
|
{
|
||||||
|
|
||||||
|
int shift=0;
|
||||||
|
//set options from parameters entered with the command
|
||||||
|
sscanf(Cmd, "%i", &shift);
|
||||||
|
int shiftedVal=0;
|
||||||
|
for(int i = 0; i<GraphTraceLen; i++){
|
||||||
|
shiftedVal=GraphBuffer[i]+shift;
|
||||||
|
if (shiftedVal>127)
|
||||||
|
shiftedVal=127;
|
||||||
|
else if (shiftedVal<-127)
|
||||||
|
shiftedVal=-127;
|
||||||
|
GraphBuffer[i]= shiftedVal;
|
||||||
|
}
|
||||||
|
CmdNorm("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print our clock rate */
|
/* Print our clock rate */
|
||||||
// uses data from graphbuffer
|
// uses data from graphbuffer
|
||||||
int CmdDetectClockRate(const char *Cmd)
|
int CmdDetectClockRate(const char *Cmd)
|
||||||
|
@ -596,27 +639,44 @@ int CmdFSKrawdemod(const char *Cmd)
|
||||||
{
|
{
|
||||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
//set defaults
|
//set defaults
|
||||||
int rfLen = 50;
|
int rfLen = 0;
|
||||||
int invert=0;
|
int invert=0;
|
||||||
int fchigh=10;
|
int fchigh=0;
|
||||||
int fclow=8;
|
int fclow=0;
|
||||||
//set options from parameters entered with the command
|
//set options from parameters entered with the command
|
||||||
sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
|
sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
|
||||||
|
|
||||||
if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
|
if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
|
||||||
//rfLen=param_get8(Cmd, 0); //if rfLen option only is used
|
|
||||||
if (rfLen==1){
|
if (rfLen==1){
|
||||||
invert=1; //if invert option only is used
|
invert=1; //if invert option only is used
|
||||||
rfLen = 50;
|
rfLen = 0;
|
||||||
} else if(rfLen==0) rfLen=50;
|
|
||||||
}
|
}
|
||||||
PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
|
}
|
||||||
|
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
size_t BitLen = getFromGraphBuf(BitStream);
|
size_t BitLen = getFromGraphBuf(BitStream);
|
||||||
|
//get field clock lengths
|
||||||
|
uint16_t fcs=0;
|
||||||
|
if (fchigh==0 || fclow == 0){
|
||||||
|
fcs=countFC(BitStream, BitLen);
|
||||||
|
if (fcs==0){
|
||||||
|
fchigh=10;
|
||||||
|
fclow=8;
|
||||||
|
}else{
|
||||||
|
fchigh = (fcs >> 8) & 0xFF;
|
||||||
|
fclow = fcs & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//get bit clock length
|
||||||
|
if (rfLen==0){
|
||||||
|
rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow);
|
||||||
|
if (rfLen == 0) rfLen = 50;
|
||||||
|
}
|
||||||
|
PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
|
||||||
int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
|
int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
|
||||||
if (size>0){
|
if (size>0){
|
||||||
PrintAndLog("FSK decoded bitstream:");
|
PrintAndLog("FSK decoded bitstream:");
|
||||||
setDemodBuf(BitStream,size);
|
setDemodBuf(BitStream,size,0);
|
||||||
|
|
||||||
// Now output the bitstream to the scrollback by line of 16 bits
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
|
if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
|
||||||
|
@ -638,20 +698,32 @@ int CmdFSKdemodHID(const char *Cmd)
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
size_t BitLen = getFromGraphBuf(BitStream);
|
size_t BitLen = getFromGraphBuf(BitStream);
|
||||||
//get binary from fsk wave
|
//get binary from fsk wave
|
||||||
size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
|
int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
|
||||||
if (size<0){
|
if (idx<0){
|
||||||
PrintAndLog("Error demoding fsk");
|
if (g_debugMode){
|
||||||
|
if (idx==-1){
|
||||||
|
PrintAndLog("DEBUG: Just Noise Detected");
|
||||||
|
} else if (idx == -2) {
|
||||||
|
PrintAndLog("DEBUG: Error demoding fsk");
|
||||||
|
} else if (idx == -3) {
|
||||||
|
PrintAndLog("DEBUG: Preamble not found");
|
||||||
|
} else if (idx == -4) {
|
||||||
|
PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("DEBUG: Error demoding fsk %d", idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (hi2==0 && hi==0 && lo==0) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Error - no values found");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (hi2==0 && hi==0 && lo==0) return 0;
|
|
||||||
if (hi2 != 0){ //extra large HID tags
|
if (hi2 != 0){ //extra large HID tags
|
||||||
PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)",
|
PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)",
|
||||||
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
|
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
|
||||||
setDemodBuf(BitStream,BitLen);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
else { //standard HID tags <38 bits
|
else { //standard HID tags <38 bits
|
||||||
//Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
|
|
||||||
uint8_t fmtLen = 0;
|
uint8_t fmtLen = 0;
|
||||||
uint32_t fc = 0;
|
uint32_t fc = 0;
|
||||||
uint32_t cardnum = 0;
|
uint32_t cardnum = 0;
|
||||||
|
@ -691,12 +763,61 @@ int CmdFSKdemodHID(const char *Cmd)
|
||||||
PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
|
PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
|
||||||
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
|
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
|
||||||
(unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
|
(unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
|
||||||
setDemodBuf(BitStream,BitLen);
|
}
|
||||||
|
setDemodBuf(BitStream,BitLen,idx);
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded)
|
||||||
|
//print full Paradox Prox ID and some bit format details if found
|
||||||
|
int CmdFSKdemodParadox(const char *Cmd)
|
||||||
|
{
|
||||||
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
|
uint32_t hi2=0, hi=0, lo=0;
|
||||||
|
|
||||||
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
|
size_t BitLen = getFromGraphBuf(BitStream);
|
||||||
|
//get binary from fsk wave
|
||||||
|
int idx = ParadoxdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
|
||||||
|
if (idx<0){
|
||||||
|
if (g_debugMode){
|
||||||
|
if (idx==-1){
|
||||||
|
PrintAndLog("DEBUG: Just Noise Detected");
|
||||||
|
} else if (idx == -2) {
|
||||||
|
PrintAndLog("DEBUG: Error demoding fsk");
|
||||||
|
} else if (idx == -3) {
|
||||||
|
PrintAndLog("DEBUG: Preamble not found");
|
||||||
|
} else if (idx == -4) {
|
||||||
|
PrintAndLog("DEBUG: Error in Manchester data");
|
||||||
|
} else {
|
||||||
|
PrintAndLog("DEBUG: Error demoding fsk %d", idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
if (hi2==0 && hi==0 && lo==0){
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Error - no value found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint32_t fc = ((hi & 0x3)<<6) | (lo>>26);
|
||||||
|
uint32_t cardnum = (lo>>10)&0xFFFF;
|
||||||
|
|
||||||
|
PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x",
|
||||||
|
hi>>10, (hi & 0x3)<<26 | (lo>>10), fc, cardnum, (lo>>2) & 0xFF );
|
||||||
|
setDemodBuf(BitStream,BitLen,idx);
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen);
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//by marshmellow
|
//by marshmellow
|
||||||
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
//IO-Prox demod - FSK RF/64 with preamble of 000000001
|
||||||
//print ioprox ID and some format details
|
//print ioprox ID and some format details
|
||||||
|
@ -705,21 +826,39 @@ int CmdFSKdemodIO(const char *Cmd)
|
||||||
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
//set defaults
|
//set defaults
|
||||||
int idx=0;
|
int idx=0;
|
||||||
//something in graphbuffer
|
//something in graphbuffer?
|
||||||
if (GraphTraceLen < 65) return 0;
|
if (GraphTraceLen < 65) {
|
||||||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer");
|
||||||
size_t BitLen = getFromGraphBuf(BitStream);
|
return 0;
|
||||||
//get binary from fsk wave
|
}
|
||||||
// PrintAndLog("DEBUG: got buff");
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
idx = IOdemodFSK(BitStream,BitLen);
|
size_t BitLen = getFromGraphBuf(BitStream);
|
||||||
if (idx<0){
|
|
||||||
//PrintAndLog("Error demoding fsk");
|
//get binary from fsk wave
|
||||||
|
idx = IOdemodFSK(BitStream,BitLen);
|
||||||
|
if (idx<0){
|
||||||
|
if (g_debugMode){
|
||||||
|
if (idx==-1){
|
||||||
|
PrintAndLog("DEBUG: Just Noise Detected");
|
||||||
|
} else if (idx == -2) {
|
||||||
|
PrintAndLog("DEBUG: not enough samples");
|
||||||
|
} else if (idx == -3) {
|
||||||
|
PrintAndLog("DEBUG: error during fskdemod");
|
||||||
|
} else if (idx == -4) {
|
||||||
|
PrintAndLog("DEBUG: Preamble not found");
|
||||||
|
} else if (idx == -5) {
|
||||||
|
PrintAndLog("DEBUG: Separator bits not found");
|
||||||
|
} else {
|
||||||
|
PrintAndLog("DEBUG: Error demoding fsk %d", idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// PrintAndLog("DEBUG: Got IOdemodFSK");
|
|
||||||
if (idx==0){
|
if (idx==0){
|
||||||
//PrintAndLog("IO Prox Data not found - FSK Data:");
|
if (g_debugMode==1){
|
||||||
//if (BitLen > 92) printBitStream(BitStream,92);
|
PrintAndLog("DEBUG: IO Prox Data not found - FSK Bits: %d",BitLen);
|
||||||
|
if (BitLen > 92) printBitStream(BitStream,92);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
//Index map
|
//Index map
|
||||||
|
@ -731,7 +870,10 @@ int CmdFSKdemodIO(const char *Cmd)
|
||||||
//
|
//
|
||||||
//XSF(version)facility:codeone+codetwo (raw)
|
//XSF(version)facility:codeone+codetwo (raw)
|
||||||
//Handle the data
|
//Handle the data
|
||||||
if (idx+64>BitLen) return 0;
|
if (idx+64>BitLen) {
|
||||||
|
if (g_debugMode==1) PrintAndLog("not enough bits found - bitlen: %d",BitLen);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
|
PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
|
||||||
PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
|
PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
|
||||||
PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
|
PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
|
||||||
|
@ -746,13 +888,241 @@ int CmdFSKdemodIO(const char *Cmd)
|
||||||
uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
|
uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
|
||||||
uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
|
uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
|
||||||
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
|
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
|
||||||
int i;
|
setDemodBuf(BitStream,64,idx);
|
||||||
for (i=0;i<64;++i)
|
if (g_debugMode){
|
||||||
DemodBuffer[i]=BitStream[idx++];
|
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
|
||||||
|
printDemodBuff();
|
||||||
DemodBufferLen=64;
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//AWID Prox demod - FSK RF/50 with preamble of 00000001 (always a 96 bit data stream)
|
||||||
|
//print full AWID Prox ID and some bit format details if found
|
||||||
|
int CmdFSKdemodAWID(const char *Cmd)
|
||||||
|
{
|
||||||
|
|
||||||
|
//int verbose=1;
|
||||||
|
//sscanf(Cmd, "%i", &verbose);
|
||||||
|
|
||||||
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
|
size_t size = getFromGraphBuf(BitStream);
|
||||||
|
|
||||||
|
//get binary from fsk wave
|
||||||
|
int idx = AWIDdemodFSK(BitStream, &size);
|
||||||
|
if (idx<=0){
|
||||||
|
if (g_debugMode==1){
|
||||||
|
if (idx == -1)
|
||||||
|
PrintAndLog("DEBUG: Error - not enough samples");
|
||||||
|
else if (idx == -2)
|
||||||
|
PrintAndLog("DEBUG: Error - only noise found");
|
||||||
|
else if (idx == -3)
|
||||||
|
PrintAndLog("DEBUG: Error - problem during FSK demod");
|
||||||
|
// else if (idx == -3)
|
||||||
|
// PrintAndLog("Error: thought we had a tag but the parity failed");
|
||||||
|
else if (idx == -4)
|
||||||
|
PrintAndLog("DEBUG: Error - AWID preamble not found");
|
||||||
|
else if (idx == -5)
|
||||||
|
PrintAndLog("DEBUG: Error - Size not correct: %d", size);
|
||||||
|
else
|
||||||
|
PrintAndLog("DEBUG: Error %d",idx);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Index map
|
||||||
|
// 0 10 20 30 40 50 60
|
||||||
|
// | | | | | | |
|
||||||
|
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
|
||||||
|
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
|
||||||
|
// |---26 bit---| |-----117----||-------------142-------------|
|
||||||
|
// b = format bit len, o = odd parity of last 3 bits
|
||||||
|
// f = facility code, c = card number
|
||||||
|
// w = wiegand parity
|
||||||
|
// (26 bit format shown)
|
||||||
|
|
||||||
|
//get raw ID before removing parities
|
||||||
|
uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
|
||||||
|
uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
|
||||||
|
uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
|
||||||
|
setDemodBuf(BitStream,96,idx);
|
||||||
|
|
||||||
|
size = removeParity(BitStream, idx+8, 4, 1, 88);
|
||||||
|
if (size != 66){
|
||||||
|
if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ok valid card found!
|
||||||
|
|
||||||
|
// Index map
|
||||||
|
// 0 10 20 30 40 50 60
|
||||||
|
// | | | | | | |
|
||||||
|
// 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
|
||||||
|
// bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
// |26 bit| |-117--| |-----142------|
|
||||||
|
// b = format bit len, o = odd parity of last 3 bits
|
||||||
|
// f = facility code, c = card number
|
||||||
|
// w = wiegand parity
|
||||||
|
// (26 bit format shown)
|
||||||
|
|
||||||
|
uint32_t fc = 0;
|
||||||
|
uint32_t cardnum = 0;
|
||||||
|
uint32_t code1 = 0;
|
||||||
|
uint32_t code2 = 0;
|
||||||
|
uint8_t fmtLen = bytebits_to_byte(BitStream,8);
|
||||||
|
if (fmtLen==26){
|
||||||
|
fc = bytebits_to_byte(BitStream+9, 8);
|
||||||
|
cardnum = bytebits_to_byte(BitStream+17, 16);
|
||||||
|
code1 = bytebits_to_byte(BitStream+8,fmtLen);
|
||||||
|
PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||||
|
} else {
|
||||||
|
cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16);
|
||||||
|
if (fmtLen>32){
|
||||||
|
code1 = bytebits_to_byte(BitStream+8,fmtLen-32);
|
||||||
|
code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32);
|
||||||
|
PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
|
||||||
|
} else{
|
||||||
|
code1 = bytebits_to_byte(BitStream+8,fmtLen);
|
||||||
|
PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: idx: %d, Len: %d Printing Demod Buffer:", idx, 96);
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
|
//todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
|
||||||
|
//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
|
||||||
|
int CmdFSKdemodPyramid(const char *Cmd)
|
||||||
|
{
|
||||||
|
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
|
||||||
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
|
size_t size = getFromGraphBuf(BitStream);
|
||||||
|
|
||||||
|
//get binary from fsk wave
|
||||||
|
int idx = PyramiddemodFSK(BitStream, &size);
|
||||||
|
if (idx < 0){
|
||||||
|
if (g_debugMode==1){
|
||||||
|
if (idx == -5)
|
||||||
|
PrintAndLog("DEBUG: Error - not enough samples");
|
||||||
|
else if (idx == -1)
|
||||||
|
PrintAndLog("DEBUG: Error - only noise found");
|
||||||
|
else if (idx == -2)
|
||||||
|
PrintAndLog("DEBUG: Error - problem during FSK demod");
|
||||||
|
else if (idx == -3)
|
||||||
|
PrintAndLog("DEBUG: Error - Size not correct: %d", size);
|
||||||
|
else if (idx == -4)
|
||||||
|
PrintAndLog("DEBUG: Error - Pyramid preamble not found");
|
||||||
|
else
|
||||||
|
PrintAndLog("DEBUG: Error - idx: %d",idx);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Index map
|
||||||
|
// 0 10 20 30 40 50 60
|
||||||
|
// | | | | | | |
|
||||||
|
// 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
|
||||||
|
// premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
|
||||||
|
|
||||||
|
// 64 70 80 90 100 110 120
|
||||||
|
// | | | | | | |
|
||||||
|
// 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
|
||||||
|
// xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
|
||||||
|
// |---115---||---------71---------|
|
||||||
|
// s = format start bit, o = odd parity of last 7 bits
|
||||||
|
// f = facility code, c = card number
|
||||||
|
// w = wiegand parity, x = extra space for other formats
|
||||||
|
// p = unknown checksum
|
||||||
|
// (26 bit format shown)
|
||||||
|
|
||||||
|
//get raw ID before removing parities
|
||||||
|
uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
|
||||||
|
uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
|
||||||
|
uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32);
|
||||||
|
uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32);
|
||||||
|
setDemodBuf(BitStream,128,idx);
|
||||||
|
|
||||||
|
size = removeParity(BitStream, idx+8, 8, 1, 120);
|
||||||
|
if (size != 105){
|
||||||
|
if (g_debugMode==1) PrintAndLog("DEBUG: Error at parity check-tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ok valid card found!
|
||||||
|
|
||||||
|
// Index map
|
||||||
|
// 0 10 20 30 40 50 60 70
|
||||||
|
// | | | | | | | |
|
||||||
|
// 01234567890123456789012345678901234567890123456789012345678901234567890
|
||||||
|
// -----------------------------------------------------------------------
|
||||||
|
// 00000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
|
||||||
|
// 71 80 90 100
|
||||||
|
// | | | |
|
||||||
|
// 1 2 34567890 1234567890123456 7 8901234
|
||||||
|
// ---------------------------------------
|
||||||
|
// 1 1 01110011 0000000001000110 0 1001010
|
||||||
|
// s w ffffffff cccccccccccccccc w ppppppp
|
||||||
|
// |--115-| |------71------|
|
||||||
|
// s = format start bit, o = odd parity of last 7 bits
|
||||||
|
// f = facility code, c = card number
|
||||||
|
// w = wiegand parity, x = extra space for other formats
|
||||||
|
// p = unknown checksum
|
||||||
|
// (26 bit format shown)
|
||||||
|
|
||||||
|
//find start bit to get fmtLen
|
||||||
|
int j;
|
||||||
|
for (j=0; j<size; j++){
|
||||||
|
if(BitStream[j]) break;
|
||||||
|
}
|
||||||
|
uint8_t fmtLen = size-j-8;
|
||||||
|
uint32_t fc = 0;
|
||||||
|
uint32_t cardnum = 0;
|
||||||
|
uint32_t code1 = 0;
|
||||||
|
//uint32_t code2 = 0;
|
||||||
|
if (fmtLen==26){
|
||||||
|
fc = bytebits_to_byte(BitStream+73, 8);
|
||||||
|
cardnum = bytebits_to_byte(BitStream+81, 16);
|
||||||
|
code1 = bytebits_to_byte(BitStream+72,fmtLen);
|
||||||
|
PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
|
||||||
|
} else if (fmtLen==45){
|
||||||
|
fmtLen=42; //end = 10 bits not 7 like 26 bit fmt
|
||||||
|
fc = bytebits_to_byte(BitStream+53, 10);
|
||||||
|
cardnum = bytebits_to_byte(BitStream+63, 32);
|
||||||
|
PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
|
||||||
|
} else {
|
||||||
|
cardnum = bytebits_to_byte(BitStream+81, 16);
|
||||||
|
if (fmtLen>32){
|
||||||
|
//code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
|
||||||
|
//code2 = bytebits_to_byte(BitStream+(size-32),32);
|
||||||
|
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
|
||||||
|
} else{
|
||||||
|
//code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
|
||||||
|
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
|
int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
|
||||||
{
|
{
|
||||||
static const int LowTone[] = {
|
static const int LowTone[] = {
|
||||||
|
@ -839,8 +1209,7 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
|
||||||
PrintAndLog("actual data bits start at sample %d", maxPos);
|
PrintAndLog("actual data bits start at sample %d", maxPos);
|
||||||
PrintAndLog("length %d/%d", highLen, lowLen);
|
PrintAndLog("length %d/%d", highLen, lowLen);
|
||||||
|
|
||||||
uint8_t bits[46];
|
uint8_t bits[46] = {0x00};
|
||||||
bits[sizeof(bits)-1] = '\0';
|
|
||||||
|
|
||||||
// find bit pairs and manchester decode them
|
// find bit pairs and manchester decode them
|
||||||
for (i = 0; i < arraylen(bits) - 1; ++i) {
|
for (i = 0; i < arraylen(bits) - 1; ++i) {
|
||||||
|
@ -872,13 +1241,44 @@ int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//attempt to detect the field clock and bit clock for FSK
|
||||||
|
int CmdFSKfcDetect(const char *Cmd)
|
||||||
|
{
|
||||||
|
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
|
size_t size = getFromGraphBuf(BitStream);
|
||||||
|
|
||||||
|
uint16_t ans = countFC(BitStream, size);
|
||||||
|
if (ans==0) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: No data found");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uint8_t fc1, fc2;
|
||||||
|
fc1 = (ans >> 8) & 0xFF;
|
||||||
|
fc2 = ans & 0xFF;
|
||||||
|
|
||||||
|
uint8_t rf1 = detectFSKClk(BitStream, size, fc1, fc2);
|
||||||
|
if (rf1==0) {
|
||||||
|
if (g_debugMode) PrintAndLog("DEBUG: Clock detect error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//attempt to detect the bit clock for PSK or NRZ modulations
|
||||||
int CmdDetectNRZpskClockRate(const char *Cmd)
|
int CmdDetectNRZpskClockRate(const char *Cmd)
|
||||||
{
|
{
|
||||||
GetNRZpskClock("",0,0);
|
GetNRZpskClock("",0,0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PSKnrzDemod(const char *Cmd){
|
//by marshmellow
|
||||||
|
//attempt to psk1 or nrz demod graph buffer
|
||||||
|
//NOTE CURRENTLY RELIES ON PEAKS :(
|
||||||
|
int PSKnrzDemod(const char *Cmd, uint8_t verbose)
|
||||||
|
{
|
||||||
int invert=0;
|
int invert=0;
|
||||||
int clk=0;
|
int clk=0;
|
||||||
sscanf(Cmd, "%i %i", &clk, &invert);
|
sscanf(Cmd, "%i %i", &clk, &invert);
|
||||||
|
@ -891,13 +1291,13 @@ int PSKnrzDemod(const char *Cmd){
|
||||||
int errCnt=0;
|
int errCnt=0;
|
||||||
errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert);
|
errCnt = pskNRZrawDemod(BitStream, &BitLen,&clk,&invert);
|
||||||
if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
|
if (errCnt<0|| BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
|
||||||
//PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
if (g_debugMode==1) PrintAndLog("no data found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
if (verbose) PrintAndLog("Tried PSK/NRZ Demod using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
|
||||||
|
|
||||||
//prime demod buffer for output
|
//prime demod buffer for output
|
||||||
setDemodBuf(BitStream,BitLen);
|
setDemodBuf(BitStream,BitLen,0);
|
||||||
return errCnt;
|
return errCnt;
|
||||||
}
|
}
|
||||||
// Indala 26 bit decode
|
// Indala 26 bit decode
|
||||||
|
@ -905,35 +1305,30 @@ int PSKnrzDemod(const char *Cmd){
|
||||||
// optional arguments - same as CmdpskNRZrawDemod (clock & invert)
|
// optional arguments - same as CmdpskNRZrawDemod (clock & invert)
|
||||||
int CmdIndalaDecode(const char *Cmd)
|
int CmdIndalaDecode(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t verbose = 1;
|
|
||||||
int ans;
|
int ans;
|
||||||
if (strlen(Cmd)>0){
|
if (strlen(Cmd)>0){
|
||||||
if (Cmd[0]=='0'){
|
ans = PSKnrzDemod(Cmd, 0);
|
||||||
verbose=0;
|
|
||||||
ans = PSKnrzDemod("32");
|
|
||||||
}else{
|
|
||||||
ans = PSKnrzDemod(Cmd);
|
|
||||||
}
|
|
||||||
} else{ //default to RF/32
|
} else{ //default to RF/32
|
||||||
ans = PSKnrzDemod("32");
|
ans = PSKnrzDemod("32", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ans < 0){
|
if (ans < 0){
|
||||||
if (verbose)
|
if (g_debugMode==1)
|
||||||
PrintAndLog("Error1: %d",ans);
|
PrintAndLog("Error1: %d",ans);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
uint8_t invert=0;
|
uint8_t invert=0;
|
||||||
ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert);
|
ans = indala26decode(DemodBuffer,(size_t *) &DemodBufferLen, &invert);
|
||||||
if (ans < 1) {
|
if (ans < 1) {
|
||||||
if (verbose)
|
if (g_debugMode==1)
|
||||||
PrintAndLog("Error2: %d",ans);
|
PrintAndLog("Error2: %d",ans);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char showbits[251];
|
char showbits[251]={0x00};
|
||||||
if (invert)
|
if (invert)
|
||||||
if (verbose)
|
if (g_debugMode==1)
|
||||||
PrintAndLog("Had to invert bits");
|
PrintAndLog("Had to invert bits");
|
||||||
|
|
||||||
//convert UID to HEX
|
//convert UID to HEX
|
||||||
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
|
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
|
||||||
int idx;
|
int idx;
|
||||||
|
@ -979,9 +1374,16 @@ int CmdIndalaDecode(const char *Cmd)
|
||||||
showbits[idx]='\0';
|
showbits[idx]='\0';
|
||||||
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
|
PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
|
||||||
}
|
}
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("DEBUG: printing demodbuffer:");
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//by marshmellow
|
||||||
|
//attempt to clean psk wave noise after a peak
|
||||||
|
//NOTE RELIES ON PEAKS :(
|
||||||
int CmdPskClean(const char *Cmd)
|
int CmdPskClean(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t bitStream[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t bitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
|
@ -991,30 +1393,59 @@ int CmdPskClean(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//by marshmellow
|
// by marshmellow
|
||||||
//takes 2 arguments - clock and invert both as integers
|
// takes 2 arguments - clock and invert both as integers
|
||||||
//attempts to demodulate ask only
|
// attempts to demodulate psk only
|
||||||
//prints binary found and saves in graphbuffer for further commands
|
// prints binary found and saves in demodbuffer for further commands
|
||||||
int CmdpskNRZrawDemod(const char *Cmd)
|
int CmdpskNRZrawDemod(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t verbose = 1;
|
|
||||||
int errCnt;
|
int errCnt;
|
||||||
if (strlen(Cmd)>0){
|
|
||||||
if (Cmd[0]=='0')
|
|
||||||
verbose=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
errCnt = PSKnrzDemod(Cmd);
|
errCnt = PSKnrzDemod(Cmd, 1);
|
||||||
//output
|
//output
|
||||||
if (errCnt<0) return 0;
|
if (errCnt<0){
|
||||||
if (errCnt>0){
|
if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
|
||||||
if (verbose)
|
return 0;
|
||||||
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
|
|
||||||
}
|
}
|
||||||
|
if (errCnt>0){
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
|
||||||
PrintAndLog("PSK or NRZ demoded bitstream:");
|
PrintAndLog("PSK or NRZ demoded bitstream:");
|
||||||
// Now output the bitstream to the scrollback by line of 16 bits
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
printDemodBuff();
|
printDemodBuff();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
PrintAndLog("PSK or NRZ demoded bitstream:");
|
||||||
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
|
printDemodBuff();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// by marshmellow
|
||||||
|
// takes same args as cmdpsknrzrawdemod
|
||||||
|
int CmdPSK2rawDemod(const char *Cmd)
|
||||||
|
{
|
||||||
|
int errCnt=0;
|
||||||
|
errCnt=PSKnrzDemod(Cmd, 1);
|
||||||
|
if (errCnt<0){
|
||||||
|
if (g_debugMode) PrintAndLog("Error demoding: %d",errCnt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||||
|
if (errCnt>0){
|
||||||
|
if (g_debugMode){
|
||||||
|
PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
|
||||||
|
PrintAndLog("PSK2 demoded bitstream:");
|
||||||
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
PrintAndLog("PSK2 demoded bitstream:");
|
||||||
|
// Now output the bitstream to the scrollback by line of 16 bits
|
||||||
|
printDemodBuff();
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,7 +1465,7 @@ int CmdHexsamples(const char *Cmd)
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
char string_buf[25];
|
char string_buf[25];
|
||||||
char* string_ptr = string_buf;
|
char* string_ptr = string_buf;
|
||||||
uint8_t got[40000];
|
uint8_t got[BIGBUF_SIZE];
|
||||||
|
|
||||||
sscanf(Cmd, "%i %i", &requested, &offset);
|
sscanf(Cmd, "%i %i", &requested, &offset);
|
||||||
|
|
||||||
|
@ -1043,7 +1474,7 @@ int CmdHexsamples(const char *Cmd)
|
||||||
requested = 8;
|
requested = 8;
|
||||||
}
|
}
|
||||||
if (offset + requested > sizeof(got)) {
|
if (offset + requested > sizeof(got)) {
|
||||||
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
|
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > %d", BIGBUF_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1551,7 @@ int CmdSamples(const char *Cmd)
|
||||||
// we don't have to worry about remaining trash
|
// we don't have to worry about remaining trash
|
||||||
// in the last byte in case the bits-per-sample
|
// in the last byte in case the bits-per-sample
|
||||||
// does not line up on byte boundaries
|
// does not line up on byte boundaries
|
||||||
uint8_t got[40000-1];
|
uint8_t got[BIGBUF_SIZE-1] = { 0 };
|
||||||
|
|
||||||
int n = strtol(Cmd, NULL, 0);
|
int n = strtol(Cmd, NULL, 0);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
@ -1257,6 +1688,8 @@ int CmdLtrim(const char *Cmd)
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// trim graph to input argument length
|
||||||
int CmdRtrim(const char *Cmd)
|
int CmdRtrim(const char *Cmd)
|
||||||
{
|
{
|
||||||
int ds = atoi(Cmd);
|
int ds = atoi(Cmd);
|
||||||
|
@ -1653,19 +2086,23 @@ static command_t CommandTable[] =
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"amp", CmdAmp, 1, "Amplify peaks"},
|
{"amp", CmdAmp, 1, "Amplify peaks"},
|
||||||
{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
|
{"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
|
||||||
{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
|
{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
|
||||||
{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
|
{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
|
||||||
{"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
|
{"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
|
||||||
{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
|
{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] Biphase decode bin stream in demod buffer (offset = 0|1 bits to shift the decode start)"},
|
||||||
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
|
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
|
||||||
{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
|
{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
|
||||||
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
|
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
|
||||||
{"dec", CmdDec, 1, "Decimate samples"},
|
{"dec", CmdDec, 1, "Decimate samples"},
|
||||||
{"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"},
|
{"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"},
|
||||||
{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
|
{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
|
||||||
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
|
{"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate graph window as an AWID FSK tag using raw"},
|
||||||
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
|
{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
|
||||||
{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
|
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK tag using raw"},
|
||||||
|
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox tag FSK using raw"},
|
||||||
|
{"fskpyramiddemod",CmdFSKdemodPyramid,1, "Demodulate graph window as a Pyramid FSK tag using raw"},
|
||||||
|
{"fskparadoxdemod",CmdFSKdemodParadox,1, "Demodulate graph window as a Paradox FSK tag using raw"},
|
||||||
|
{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to bin (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
|
||||||
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
|
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
|
||||||
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
|
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
|
||||||
{"hide", CmdHide, 1, "Hide graph window"},
|
{"hide", CmdHide, 1, "Hide graph window"},
|
||||||
|
@ -1680,11 +2117,14 @@ static command_t CommandTable[] =
|
||||||
{"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
|
{"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
|
||||||
{"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"},
|
{"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"},
|
||||||
{"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
|
{"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
|
||||||
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"},
|
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 indala tags and output ID binary & hex (args optional)"},
|
||||||
{"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"},
|
{"psk1nrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk1 or nrz tags and output binary (args optional)"},
|
||||||
|
{"psk2rawdemod", CmdPSK2rawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk2 tags and output binary (args optional)"},
|
||||||
{"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
|
{"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
|
||||||
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
|
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
|
||||||
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
|
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
|
||||||
|
{"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"},
|
||||||
|
{"shiftgraphzero",CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
|
||||||
{"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
|
{"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
|
||||||
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
|
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
|
||||||
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
|
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
|
||||||
|
|
|
@ -26,9 +26,12 @@ int CmdBitstream(const char *Cmd);
|
||||||
int CmdBuffClear(const char *Cmd);
|
int CmdBuffClear(const char *Cmd);
|
||||||
int CmdDec(const char *Cmd);
|
int CmdDec(const char *Cmd);
|
||||||
int CmdDetectClockRate(const char *Cmd);
|
int CmdDetectClockRate(const char *Cmd);
|
||||||
|
int CmdFSKdemodAWID(const char *Cmd);
|
||||||
int CmdFSKdemod(const char *Cmd);
|
int CmdFSKdemod(const char *Cmd);
|
||||||
int CmdFSKdemodHID(const char *Cmd);
|
int CmdFSKdemodHID(const char *Cmd);
|
||||||
int CmdFSKdemodIO(const char *Cmd);
|
int CmdFSKdemodIO(const char *Cmd);
|
||||||
|
int CmdFSKdemodParadox(const char *Cmd);
|
||||||
|
int CmdFSKdemodPyramid(const char *Cmd);
|
||||||
int CmdFSKrawdemod(const char *Cmd);
|
int CmdFSKrawdemod(const char *Cmd);
|
||||||
int CmdDetectNRZpskClockRate(const char *Cmd);
|
int CmdDetectNRZpskClockRate(const char *Cmd);
|
||||||
int CmdpskNRZrawDemod(const char *Cmd);
|
int CmdpskNRZrawDemod(const char *Cmd);
|
||||||
|
@ -57,4 +60,6 @@ int CmdIndalaDecode(const char *Cmd);
|
||||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||||
extern int DemodBufferLen;
|
extern int DemodBufferLen;
|
||||||
|
|
||||||
|
#define BIGBUF_SIZE 40000
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "cmdhflegic.h"
|
#include "cmdhflegic.h"
|
||||||
#include "cmdhficlass.h"
|
#include "cmdhficlass.h"
|
||||||
#include "cmdhfmf.h"
|
#include "cmdhfmf.h"
|
||||||
|
#include "cmdhfmfu.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -31,8 +32,6 @@ int CmdHFTune(const char *Cmd)
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// for the time being. Need better Bigbuf handling.
|
|
||||||
#define TRACE_SIZE 3000
|
|
||||||
|
|
||||||
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
|
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
|
||||||
/*
|
/*
|
||||||
|
@ -193,7 +192,7 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||||
case ISO14443A_CMD_ANTICOLL_OR_SELECT:{
|
case ISO14443A_CMD_ANTICOLL_OR_SELECT:{
|
||||||
// 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
|
// 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
|
||||||
// 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
|
// 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
|
||||||
if(cmd[2] == 0x70)
|
if(cmd[1] == 0x70)
|
||||||
{
|
{
|
||||||
snprintf(exp,size,"SELECT_UID"); break;
|
snprintf(exp,size,"SELECT_UID"); break;
|
||||||
}else
|
}else
|
||||||
|
@ -221,8 +220,8 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||||
case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break;
|
case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break;
|
||||||
case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
|
case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
|
||||||
case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
|
case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
|
||||||
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A"); break;
|
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break;
|
||||||
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B"); break;
|
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
|
||||||
case MIFARE_MAGICMODE: snprintf(exp,size,"MAGIC"); break;
|
case MIFARE_MAGICMODE: snprintf(exp,size,"MAGIC"); break;
|
||||||
default: snprintf(exp,size,"?"); break;
|
default: snprintf(exp,size,"?"); break;
|
||||||
}
|
}
|
||||||
|
@ -383,18 +382,18 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, bool showWaitCycles)
|
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
|
||||||
{
|
{
|
||||||
bool isResponse;
|
bool isResponse;
|
||||||
uint16_t duration, data_len,parity_len;
|
uint16_t duration, data_len, parity_len;
|
||||||
|
|
||||||
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
|
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
|
||||||
char explanation[30] = {0};
|
char explanation[30] = {0};
|
||||||
|
|
||||||
|
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
|
||||||
|
|
||||||
first_timestamp = *((uint32_t *)(trace));
|
first_timestamp = *((uint32_t *)(trace));
|
||||||
timestamp = *((uint32_t *)(trace + tracepos));
|
timestamp = *((uint32_t *)(trace + tracepos));
|
||||||
// Break and stick with current result if buffer was not completely full
|
|
||||||
if (timestamp == 0x44444444) return TRACE_SIZE;
|
|
||||||
|
|
||||||
tracepos += 4;
|
tracepos += 4;
|
||||||
duration = *((uint16_t *)(trace + tracepos));
|
duration = *((uint16_t *)(trace + tracepos));
|
||||||
|
@ -410,8 +409,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
|
||||||
}
|
}
|
||||||
parity_len = (data_len-1)/8 + 1;
|
parity_len = (data_len-1)/8 + 1;
|
||||||
|
|
||||||
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
|
if (tracepos + data_len + parity_len > traceLen) {
|
||||||
return TRACE_SIZE;
|
return traceLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *frame = trace + tracepos;
|
uint8_t *frame = trace + tracepos;
|
||||||
|
@ -497,6 +496,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
|
||||||
|
|
||||||
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||||
|
|
||||||
if (showWaitCycles && !isResponse && next_isResponse) {
|
if (showWaitCycles && !isResponse && next_isResponse) {
|
||||||
|
@ -509,9 +510,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
|
||||||
(next_timestamp - EndOfTransmissionTimestamp));
|
(next_timestamp - EndOfTransmissionTimestamp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return tracepos;
|
return tracepos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CmdHFList(const char *Cmd)
|
int CmdHFList(const char *Cmd)
|
||||||
{
|
{
|
||||||
bool showWaitCycles = false;
|
bool showWaitCycles = false;
|
||||||
|
@ -551,12 +554,13 @@ int CmdHFList(const char *Cmd)
|
||||||
|
|
||||||
if (errors) {
|
if (errors) {
|
||||||
PrintAndLog("List protocol data in trace buffer.");
|
PrintAndLog("List protocol data in trace buffer.");
|
||||||
PrintAndLog("Usage: hf list [14a|14b|iclass] [f]");
|
PrintAndLog("Usage: hf list <protocol> [f]");
|
||||||
|
PrintAndLog(" f - show frame delay times as well");
|
||||||
|
PrintAndLog("Supported <protocol> values:");
|
||||||
|
PrintAndLog(" raw - just show raw data without annotations");
|
||||||
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
||||||
PrintAndLog(" 14b - interpret data as iso14443b communications");
|
PrintAndLog(" 14b - interpret data as iso14443b communications");
|
||||||
PrintAndLog(" iclass - interpret data as iclass communications");
|
PrintAndLog(" iclass - interpret data as iclass communications");
|
||||||
PrintAndLog(" raw - just show raw data");
|
|
||||||
PrintAndLog(" f - show frame delay times as well");
|
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("example: hf list 14a f");
|
PrintAndLog("example: hf list 14a f");
|
||||||
PrintAndLog("example: hf list iclass");
|
PrintAndLog("example: hf list iclass");
|
||||||
|
@ -569,12 +573,28 @@ int CmdHFList(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t trace[TRACE_SIZE];
|
uint8_t *trace;
|
||||||
uint16_t tracepos = 0;
|
uint16_t tracepos = 0;
|
||||||
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
trace = malloc(USB_CMD_DATA_SIZE);
|
||||||
WaitForResponse(CMD_ACK, NULL);
|
|
||||||
|
|
||||||
PrintAndLog("Recorded Activity");
|
// Query for the size of the trace
|
||||||
|
UsbCommand response;
|
||||||
|
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
|
||||||
|
WaitForResponse(CMD_ACK, &response);
|
||||||
|
uint16_t traceLen = response.arg[2];
|
||||||
|
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||||
|
uint8_t *p = realloc(trace, traceLen);
|
||||||
|
if (p == NULL) {
|
||||||
|
PrintAndLog("Cannot allocate memory for trace");
|
||||||
|
free(trace);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
trace = p;
|
||||||
|
GetFromBigBuf(trace, traceLen, 0);
|
||||||
|
WaitForResponse(CMD_ACK, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||||
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
|
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
|
||||||
|
@ -583,10 +603,12 @@ int CmdHFList(const char *Cmd)
|
||||||
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
|
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
|
||||||
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
|
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
|
||||||
|
|
||||||
while(tracepos < TRACE_SIZE)
|
while(tracepos < traceLen)
|
||||||
{
|
{
|
||||||
tracepos = printTraceLine(tracepos, trace, protocol, showWaitCycles);
|
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(trace);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -601,6 +623,7 @@ static command_t CommandTable[] =
|
||||||
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
|
{"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
|
||||||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||||
|
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||||
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
|
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
|
|
|
@ -412,9 +412,9 @@ int CmdHF14ASim(const char *Cmd)
|
||||||
PrintAndLog(" syntax: hf 14a sim <type> <uid>");
|
PrintAndLog(" syntax: hf 14a sim <type> <uid>");
|
||||||
PrintAndLog(" types: 1 = MIFARE Classic");
|
PrintAndLog(" types: 1 = MIFARE Classic");
|
||||||
PrintAndLog(" 2 = MIFARE Ultralight");
|
PrintAndLog(" 2 = MIFARE Ultralight");
|
||||||
PrintAndLog(" 3 = MIFARE DESFIRE");
|
PrintAndLog(" 3 = MIFARE Desfire");
|
||||||
PrintAndLog(" 4 = ISO/IEC 14443-4");
|
PrintAndLog(" 4 = ISO/IEC 14443-4");
|
||||||
PrintAndLog(" 5 = MIFARE TNP3XXX");
|
PrintAndLog(" 5 = MIFARE Tnp3xxx");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,8 @@ int CmdHF14ASim(const char *Cmd)
|
||||||
int CmdHF14ASnoop(const char *Cmd) {
|
int CmdHF14ASnoop(const char *Cmd) {
|
||||||
int param = 0;
|
int param = 0;
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h') {
|
uint8_t ctmp = param_getchar(Cmd, 0) ;
|
||||||
|
if (ctmp == 'h' || ctmp == 'H') {
|
||||||
PrintAndLog("It get data from the field and saves it into command buffer.");
|
PrintAndLog("It get data from the field and saves it into command buffer.");
|
||||||
PrintAndLog("Buffer accessible from command hf list 14a.");
|
PrintAndLog("Buffer accessible from command hf list 14a.");
|
||||||
PrintAndLog("Usage: hf 14a snoop [c][r]");
|
PrintAndLog("Usage: hf 14a snoop [c][r]");
|
||||||
|
@ -491,7 +492,7 @@ int CmdHF14ASnoop(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
char ctmp = param_getchar(Cmd, i);
|
ctmp = param_getchar(Cmd, i);
|
||||||
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
|
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
|
||||||
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
|
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
|
||||||
}
|
}
|
||||||
|
@ -670,7 +671,7 @@ static command_t CommandTable[] =
|
||||||
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"},
|
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"},
|
||||||
{"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
|
{"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
|
||||||
{"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
|
{"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
|
||||||
{"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
|
{"sim", CmdHF14ASim, 0, "<UID> -- Simulate ISO 14443a tag"},
|
||||||
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
|
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
|
||||||
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
|
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
|
|
|
@ -145,11 +145,25 @@ demodError:
|
||||||
|
|
||||||
int CmdHF14BList(const char *Cmd)
|
int CmdHF14BList(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t got[TRACE_BUFFER_SIZE];
|
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
|
||||||
|
|
||||||
PrintAndLog("recorded activity:");
|
// Query for the actual size of the trace
|
||||||
|
UsbCommand response;
|
||||||
|
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
||||||
|
WaitForResponse(CMD_ACK, &response);
|
||||||
|
uint16_t traceLen = response.arg[2];
|
||||||
|
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||||
|
uint8_t *p = realloc(got, traceLen);
|
||||||
|
if (p == NULL) {
|
||||||
|
PrintAndLog("Cannot allocate memory for trace");
|
||||||
|
free(got);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
got = p;
|
||||||
|
GetFromBigBuf(got, traceLen, 0);
|
||||||
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
|
}
|
||||||
|
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
|
||||||
PrintAndLog(" time :rssi: who bytes");
|
PrintAndLog(" time :rssi: who bytes");
|
||||||
PrintAndLog("---------+----+----+-----------");
|
PrintAndLog("---------+----+----+-----------");
|
||||||
|
|
||||||
|
@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd)
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
if(i >= TRACE_BUFFER_SIZE) { break; }
|
if(i >= traceLen) { break; }
|
||||||
|
|
||||||
bool isResponse;
|
bool isResponse;
|
||||||
int timestamp = *((uint32_t *)(got+i));
|
int timestamp = *((uint32_t *)(got+i));
|
||||||
|
@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd)
|
||||||
if(len > 100) {
|
if(len > 100) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(i + len >= TRACE_BUFFER_SIZE) {
|
if(i + len >= traceLen) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd)
|
||||||
prev = timestamp;
|
prev = timestamp;
|
||||||
i += (len + 9);
|
i += (len + 9);
|
||||||
}
|
}
|
||||||
|
free(got);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +295,7 @@ int CmdHF14BCmdRaw (const char *cmd) {
|
||||||
uint8_t power=0;
|
uint8_t power=0;
|
||||||
char buf[5]="";
|
char buf[5]="";
|
||||||
int i=0;
|
int i=0;
|
||||||
uint8_t data[100];
|
uint8_t data[100] = {0x00};
|
||||||
unsigned int datalen=0, temp;
|
unsigned int datalen=0, temp;
|
||||||
char *hexout;
|
char *hexout;
|
||||||
|
|
||||||
|
@ -334,7 +349,7 @@ int CmdHF14BCmdRaw (const char *cmd) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PrintAndLog("Invalid char on input");
|
PrintAndLog("Invalid char on input");
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
if (datalen == 0)
|
if (datalen == 0)
|
||||||
{
|
{
|
||||||
|
@ -448,7 +463,7 @@ int CmdHF14BWrite( const char *Cmd){
|
||||||
else
|
else
|
||||||
PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
|
PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
|
||||||
|
|
||||||
sprintf(str, "-c -p 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
|
sprintf(str, "-c 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
|
||||||
|
|
||||||
CmdHF14BCmdRaw(str);
|
CmdHF14BCmdRaw(str);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
292
client/cmdhfmf.c
292
client/cmdhfmf.c
|
@ -140,117 +140,6 @@ int CmdHF14AMfWrBl(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfUWrBl(const char *Cmd)
|
|
||||||
{
|
|
||||||
uint8_t blockNo = 0;
|
|
||||||
bool chinese_card=0;
|
|
||||||
uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
UsbCommand resp;
|
|
||||||
|
|
||||||
if (strlen(Cmd)<3) {
|
|
||||||
PrintAndLog("Usage: hf mf uwrbl <block number> <block data (8 hex symbols)> <w>");
|
|
||||||
PrintAndLog(" sample: hf mf uwrbl 0 01020304");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
|
||||||
if (param_gethex(Cmd, 1, bldata, 8)) {
|
|
||||||
PrintAndLog("Block data must include 8 HEX symbols");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strchr(Cmd,'w') != 0) {
|
|
||||||
chinese_card=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(blockNo){
|
|
||||||
case 0:
|
|
||||||
if (!chinese_card){
|
|
||||||
PrintAndLog("Access Denied");
|
|
||||||
}else{
|
|
||||||
PrintAndLog("--specialblock no:%d", blockNo);
|
|
||||||
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
|
||||||
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
|
||||||
memcpy(d.d.asBytes,bldata, 4);
|
|
||||||
SendCommand(&d);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (!chinese_card){
|
|
||||||
PrintAndLog("Access Denied");
|
|
||||||
}else{
|
|
||||||
PrintAndLog("--specialblock no:%d", blockNo);
|
|
||||||
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
|
||||||
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
|
||||||
memcpy(d.d.asBytes,bldata, 4);
|
|
||||||
SendCommand(&d);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (!chinese_card){
|
|
||||||
PrintAndLog("Access Denied");
|
|
||||||
}else{
|
|
||||||
PrintAndLog("--specialblock no:%d", blockNo);
|
|
||||||
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
|
||||||
UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
|
||||||
memcpy(c.d.asBytes, bldata, 4);
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
PrintAndLog("--specialblock no:%d", blockNo);
|
|
||||||
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
|
||||||
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
|
||||||
memcpy(d.d.asBytes,bldata, 4);
|
|
||||||
SendCommand(&d);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
PrintAndLog("--block no:%d", blockNo);
|
|
||||||
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
|
||||||
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
|
||||||
memcpy(e.d.asBytes,bldata, 4);
|
|
||||||
SendCommand(&e);
|
|
||||||
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfRdBl(const char *Cmd)
|
int CmdHF14AMfRdBl(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
|
@ -299,87 +188,6 @@ int CmdHF14AMfRdBl(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfURdBl(const char *Cmd)
|
|
||||||
{
|
|
||||||
uint8_t blockNo = 0;
|
|
||||||
|
|
||||||
if (strlen(Cmd)<1) {
|
|
||||||
PrintAndLog("Usage: hf mf urdbl <block number>");
|
|
||||||
PrintAndLog(" sample: hf mf urdbl 0");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
blockNo = param_get8(Cmd, 0);
|
|
||||||
PrintAndLog("--block no:%d", blockNo);
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
|
||||||
uint8_t *data = resp.d.asBytes;
|
|
||||||
|
|
||||||
if (isOK)
|
|
||||||
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 4));
|
|
||||||
else
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfURdCard(const char *Cmd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uint8_t sectorNo = 0;
|
|
||||||
uint8_t *lockbytes_t=NULL;
|
|
||||||
uint8_t lockbytes[2]={0,0};
|
|
||||||
bool bit[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
||||||
|
|
||||||
uint8_t isOK = 0;
|
|
||||||
uint8_t * data = NULL;
|
|
||||||
|
|
||||||
PrintAndLog("Attempting to Read Ultralight... ");
|
|
||||||
|
|
||||||
UsbCommand c = {CMD_MIFAREU_READCARD, {sectorNo}};
|
|
||||||
SendCommand(&c);
|
|
||||||
|
|
||||||
UsbCommand resp;
|
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
|
||||||
isOK = resp.arg[0] & 0xff;
|
|
||||||
data = resp.d.asBytes;
|
|
||||||
|
|
||||||
PrintAndLog("isOk:%02x", isOK);
|
|
||||||
if (isOK)
|
|
||||||
{ // bit 0 and 1
|
|
||||||
PrintAndLog("Block %3d:%s ", 0,sprint_hex(data + 0 * 4, 4));
|
|
||||||
PrintAndLog("Block %3d:%s ", 1,sprint_hex(data + 1 * 4, 4));
|
|
||||||
// bit 2
|
|
||||||
//process lock bytes
|
|
||||||
lockbytes_t=data+(2*4);
|
|
||||||
lockbytes[0]=lockbytes_t[2];
|
|
||||||
lockbytes[1]=lockbytes_t[3];
|
|
||||||
for(int j=0; j<16; j++){
|
|
||||||
bit[j]=lockbytes[j/8] & ( 1 <<(7-j%8));
|
|
||||||
}
|
|
||||||
//remaining
|
|
||||||
for (i = 3; i < 16; i++) {
|
|
||||||
int bitnum = (23-i) % 16;
|
|
||||||
PrintAndLog("Block %3d:%s [%d]", i,sprint_hex(data + i * 4, 4),bit[bitnum]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
PrintAndLog("Command execute timeout");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfRdSc(const char *Cmd)
|
int CmdHF14AMfRdSc(const char *Cmd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -970,12 +778,14 @@ int CmdHF14AMfNested(const char *Cmd)
|
||||||
int CmdHF14AMfChk(const char *Cmd)
|
int CmdHF14AMfChk(const char *Cmd)
|
||||||
{
|
{
|
||||||
if (strlen(Cmd)<3) {
|
if (strlen(Cmd)<3) {
|
||||||
PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t] [<key (12 hex symbols)>] [<dic (*.dic)>]");
|
PrintAndLog("Usage: hf mf chk <block number>|<*card memory> <key type (A/B/?)> [t|d] [<key (12 hex symbols)>] [<dic (*.dic)>]");
|
||||||
PrintAndLog(" * - all sectors");
|
PrintAndLog(" * - all sectors");
|
||||||
PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
|
PrintAndLog("card memory - 0 - MINI(320 bytes), 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
|
||||||
PrintAndLog("d - write keys to binary file\n");
|
PrintAndLog("d - write keys to binary file\n");
|
||||||
|
PrintAndLog("t - write keys to emulator memory");
|
||||||
PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic");
|
PrintAndLog(" sample: hf mf chk 0 A 1234567890ab keys.dic");
|
||||||
PrintAndLog(" hf mf chk *1 ? t");
|
PrintAndLog(" hf mf chk *1 ? t");
|
||||||
|
PrintAndLog(" hf mf chk *1 ? d");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1202,12 +1012,16 @@ int CmdHF14AMf1kSim(const char *Cmd)
|
||||||
uint8_t exitAfterNReads = 0;
|
uint8_t exitAfterNReads = 0;
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h') {
|
uint8_t cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') {
|
||||||
PrintAndLog("Usage: hf mf sim u <uid (8 hex symbols)> n <numreads> i x");
|
PrintAndLog("Usage: hf mf sim u <uid (8 hex symbols)> n <numreads> i x");
|
||||||
|
PrintAndLog(" h this help");
|
||||||
PrintAndLog(" u (Optional) UID. If not specified, the UID from emulator memory will be used");
|
PrintAndLog(" u (Optional) UID. If not specified, the UID from emulator memory will be used");
|
||||||
PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
|
PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
|
||||||
PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
|
PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
|
||||||
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");
|
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");
|
||||||
|
PrintAndLog("");
|
||||||
PrintAndLog(" sample: hf mf sim u 0a0a0a0a ");
|
PrintAndLog(" sample: hf mf sim u 0a0a0a0a ");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1288,7 +1102,7 @@ int CmdHF14AMfDbg(const char *Cmd)
|
||||||
int CmdHF14AMfEGet(const char *Cmd)
|
int CmdHF14AMfEGet(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
uint8_t data[16];
|
uint8_t data[16] = {0x00};
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("Usage: hf mf eget <block number>");
|
PrintAndLog("Usage: hf mf eget <block number>");
|
||||||
|
@ -1355,14 +1169,11 @@ int CmdHF14AMfELoad(const char *Cmd)
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char filename[FILE_PATH_SIZE];
|
char filename[FILE_PATH_SIZE];
|
||||||
char *fnameptr = filename;
|
char *fnameptr = filename;
|
||||||
char buf[64];
|
char buf[64] = {0x00};
|
||||||
uint8_t buf8[64];
|
uint8_t buf8[64] = {0x00};
|
||||||
int i, len, blockNum, numBlocks;
|
int i, len, blockNum, numBlocks;
|
||||||
int nameParamNo = 1;
|
int nameParamNo = 1;
|
||||||
|
|
||||||
memset(filename, 0, sizeof(filename));
|
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if ( ctmp == 'h' || ctmp == 0x00) {
|
if ( ctmp == 'h' || ctmp == 0x00) {
|
||||||
|
@ -1432,11 +1243,13 @@ int CmdHF14AMfELoad(const char *Cmd)
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
printf(".");
|
||||||
blockNum++;
|
blockNum++;
|
||||||
|
|
||||||
if (blockNum >= numBlocks) break;
|
if (blockNum >= numBlocks) break;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
if ((blockNum != numBlocks)) {
|
if ((blockNum != numBlocks)) {
|
||||||
PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
|
PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
|
||||||
|
@ -1638,7 +1451,7 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
||||||
char ctmp = param_getchar(Cmd, 1);
|
char ctmp = param_getchar(Cmd, 1);
|
||||||
if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
|
if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
|
||||||
|
|
||||||
PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
|
PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
|
||||||
|
|
||||||
res = mfCSetUID(uid, oldUid, wipeCard);
|
res = mfCSetUID(uid, oldUid, wipeCard);
|
||||||
if (res) {
|
if (res) {
|
||||||
|
@ -1653,11 +1466,10 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
||||||
|
|
||||||
int CmdHF14AMfCSetBlk(const char *Cmd)
|
int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t uid[8];
|
uint8_t uid[8] = {0x00};
|
||||||
uint8_t memBlock[16];
|
uint8_t memBlock[16] = {0x00};
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
int res;
|
int res;
|
||||||
memset(memBlock, 0x00, sizeof(memBlock));
|
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
|
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
|
||||||
|
@ -1682,7 +1494,6 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("UID:%s", sprint_hex(uid, 4));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1697,11 +1508,8 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
int i, len, blockNum, flags;
|
int i, len, blockNum, flags;
|
||||||
|
|
||||||
// memset(filename, 0, sizeof(filename));
|
|
||||||
// memset(buf, 0, sizeof(buf));
|
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
||||||
PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");
|
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
|
||||||
PrintAndLog("or from emulator memory (option `e`)");
|
PrintAndLog("or from emulator memory (option `e`)");
|
||||||
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
|
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
|
||||||
PrintAndLog(" or: hf mf cload e ");
|
PrintAndLog(" or: hf mf cload e ");
|
||||||
|
@ -1748,7 +1556,9 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
blockNum = 0;
|
blockNum = 0;
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||||
while(!feof(f)){
|
while(!feof(f)){
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||||
PrintAndLog("File reading error.");
|
PrintAndLog("File reading error.");
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -1783,6 +1593,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
PrintAndLog("Loaded from file: %s", filename);
|
PrintAndLog("Loaded from file: %s", filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
|
@ -1814,10 +1625,9 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
|
|
||||||
|
|
||||||
int CmdHF14AMfCGetSc(const char *Cmd) {
|
int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
uint8_t memBlock[16];
|
uint8_t memBlock[16] = {0x00};
|
||||||
uint8_t sectorNo = 0;
|
uint8_t sectorNo = 0;
|
||||||
int i, res, flags;
|
int i, res, flags;
|
||||||
memset(memBlock, 0x00, sizeof(memBlock));
|
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
||||||
|
@ -1955,18 +1765,19 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int blockLen = 0;
|
int blockLen = 0;
|
||||||
int num = 0;
|
|
||||||
int pckNum = 0;
|
int pckNum = 0;
|
||||||
|
int num = 0;
|
||||||
uint8_t uid[7];
|
uint8_t uid[7];
|
||||||
uint8_t uid_len;
|
uint8_t uid_len;
|
||||||
uint8_t atqa[2];
|
uint8_t atqa[2] = {0x00};
|
||||||
uint8_t sak;
|
uint8_t sak;
|
||||||
bool isTag;
|
bool isTag;
|
||||||
uint8_t buf[3000];
|
uint8_t *buf = NULL;
|
||||||
uint8_t * bufPtr = buf;
|
uint16_t bufsize = 0;
|
||||||
memset(buf, 0x00, 3000);
|
uint8_t *bufPtr = NULL;
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h') {
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
if ( ctmp == 'h' || ctmp == 'H' ) {
|
||||||
PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
|
PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
|
||||||
PrintAndLog("You can specify:");
|
PrintAndLog("You can specify:");
|
||||||
PrintAndLog(" l - save encrypted sequence to logfile `uid.log`");
|
PrintAndLog(" l - save encrypted sequence to logfile `uid.log`");
|
||||||
|
@ -1979,7 +1790,7 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
char ctmp = param_getchar(Cmd, i);
|
ctmp = param_getchar(Cmd, i);
|
||||||
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
|
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
|
||||||
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
|
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
|
||||||
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
|
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
|
||||||
|
@ -2009,29 +1820,44 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
|
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
|
||||||
res = resp.arg[0] & 0xff;
|
res = resp.arg[0] & 0xff;
|
||||||
len = resp.arg[1];
|
uint16_t traceLen = resp.arg[1];
|
||||||
num = resp.arg[2];
|
len = resp.arg[2];
|
||||||
|
|
||||||
if (res == 0) return 0;
|
if (res == 0) return 0; // we are done
|
||||||
if (res == 1) {
|
|
||||||
if (num ==0) {
|
if (res == 1) { // there is (more) data to be transferred
|
||||||
|
if (pckNum == 0) { // first packet, (re)allocate necessary buffer
|
||||||
|
if (traceLen > bufsize) {
|
||||||
|
uint8_t *p;
|
||||||
|
if (buf == NULL) { // not yet allocated
|
||||||
|
p = malloc(traceLen);
|
||||||
|
} else { // need more memory
|
||||||
|
p = realloc(buf, traceLen);
|
||||||
|
}
|
||||||
|
if (p == NULL) {
|
||||||
|
PrintAndLog("Cannot allocate memory for trace");
|
||||||
|
free(buf);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
buf = p;
|
||||||
|
}
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
memset(buf, 0x00, 3000);
|
bufsize = traceLen;
|
||||||
|
memset(buf, 0x00, traceLen);
|
||||||
}
|
}
|
||||||
memcpy(bufPtr, resp.d.asBytes, len);
|
memcpy(bufPtr, resp.d.asBytes, len);
|
||||||
bufPtr += len;
|
bufPtr += len;
|
||||||
pckNum++;
|
pckNum++;
|
||||||
}
|
}
|
||||||
if (res == 2) {
|
|
||||||
|
if (res == 2) { // received all data, start displaying
|
||||||
blockLen = bufPtr - buf;
|
blockLen = bufPtr - buf;
|
||||||
bufPtr = buf;
|
bufPtr = buf;
|
||||||
printf(">\n");
|
printf(">\n");
|
||||||
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
|
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
|
||||||
num = 0;
|
|
||||||
while (bufPtr - buf < blockLen) {
|
while (bufPtr - buf < blockLen) {
|
||||||
bufPtr += 6;
|
bufPtr += 6; // skip (void) timing information
|
||||||
len = *((uint16_t *)bufPtr);
|
len = *((uint16_t *)bufPtr);
|
||||||
|
|
||||||
if(len & 0x8000) {
|
if(len & 0x8000) {
|
||||||
isTag = true;
|
isTag = true;
|
||||||
len &= 0x7fff;
|
len &= 0x7fff;
|
||||||
|
@ -2040,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
}
|
}
|
||||||
bufPtr += 2;
|
bufPtr += 2;
|
||||||
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
|
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
|
||||||
|
|
||||||
memcpy(uid, bufPtr + 2, 7);
|
memcpy(uid, bufPtr + 2, 7);
|
||||||
memcpy(atqa, bufPtr + 2 + 7, 2);
|
memcpy(atqa, bufPtr + 2 + 7, 2);
|
||||||
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
|
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
|
||||||
sak = bufPtr[11];
|
sak = bufPtr[11];
|
||||||
|
|
||||||
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
|
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
|
||||||
sprint_hex(uid + (7 - uid_len), uid_len),
|
sprint_hex(uid + (7 - uid_len), uid_len),
|
||||||
atqa[1],
|
atqa[1],
|
||||||
|
@ -2063,26 +1887,26 @@ int CmdHF14AMfSniff(const char *Cmd){
|
||||||
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
|
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
|
||||||
if (wantDecrypt)
|
if (wantDecrypt)
|
||||||
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
|
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
|
||||||
|
num++;
|
||||||
}
|
}
|
||||||
bufPtr += len;
|
bufPtr += len;
|
||||||
bufPtr += ((len-1)/8+1); // ignore parity
|
bufPtr += ((len-1)/8+1); // ignore parity
|
||||||
num++;
|
|
||||||
}
|
}
|
||||||
|
pckNum = 0;
|
||||||
}
|
}
|
||||||
} // resp not NULL
|
} // resp not NULL
|
||||||
} // while (true)
|
} // while (true)
|
||||||
|
|
||||||
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
|
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
|
||||||
{"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
|
{"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},
|
||||||
{"urdbl", CmdHF14AMfURdBl, 0, "Read MIFARE Ultralight block"},
|
|
||||||
{"urdcard", CmdHF14AMfURdCard, 0,"Read MIFARE Ultralight Card"},
|
|
||||||
{"uwrbl", CmdHF14AMfUWrBl, 0,"Write MIFARE Ultralight block"},
|
|
||||||
{"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
|
{"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},
|
||||||
{"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
|
{"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},
|
||||||
{"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},
|
{"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},
|
||||||
|
|
741
client/cmdhfmfu.c
Normal file
741
client/cmdhfmfu.c
Normal file
|
@ -0,0 +1,741 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// High frequency MIFARE ULTRALIGHT (C) commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//#include <openssl/des.h>
|
||||||
|
#include "loclass/des.h"
|
||||||
|
#include "cmdhfmfu.h"
|
||||||
|
#include "cmdhfmf.h"
|
||||||
|
#include "cmdhf14a.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_ULTRA_BLOCKS 0x0f
|
||||||
|
#define MAX_ULTRAC_BLOCKS 0x2f
|
||||||
|
//#define MAX_ULTRAC_BLOCKS 0x2c
|
||||||
|
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
int CmdHF14AMfUInfo(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t datatemp[7] = {0x00};
|
||||||
|
uint8_t isOK = 0;
|
||||||
|
uint8_t *data = NULL;
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_MIFAREU_READCARD, {0, 4}};
|
||||||
|
SendCommand(&c);
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
|
isOK = resp.arg[0] & 0xff;
|
||||||
|
data = resp.d.asBytes;
|
||||||
|
|
||||||
|
if (!isOK) {
|
||||||
|
PrintAndLog("Error reading from tag");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timed out");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("-- Mifare Ultralight / Ultralight-C Tag Information ---------");
|
||||||
|
PrintAndLog("-------------------------------------------------------------");
|
||||||
|
|
||||||
|
// UID
|
||||||
|
memcpy( datatemp, data, 3);
|
||||||
|
memcpy( datatemp+3, data+4, 4);
|
||||||
|
|
||||||
|
PrintAndLog("MANUFACTURER : %s", getTagInfo(datatemp[0]));
|
||||||
|
PrintAndLog(" UID : %s ", sprint_hex(datatemp, 7));
|
||||||
|
// BBC
|
||||||
|
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
|
||||||
|
int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
|
||||||
|
if ( data[3] == crc0 )
|
||||||
|
PrintAndLog(" BCC0 : %02x - Ok", data[3]);
|
||||||
|
else
|
||||||
|
PrintAndLog(" BCC0 : %02x - crc should be %02x", data[3], crc0);
|
||||||
|
|
||||||
|
int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
|
||||||
|
if ( data[8] == crc1 )
|
||||||
|
PrintAndLog(" BCC1 : %02x - Ok", data[8]);
|
||||||
|
else
|
||||||
|
PrintAndLog(" BCC1 : %02x - crc should be %02x", data[8], crc1 );
|
||||||
|
|
||||||
|
PrintAndLog(" Internal : %s ", sprint_hex(data + 9, 1));
|
||||||
|
|
||||||
|
memcpy(datatemp, data+10, 2);
|
||||||
|
PrintAndLog(" Lock : %s - %s", sprint_hex(datatemp, 2),printBits( 2, &datatemp) );
|
||||||
|
PrintAndLog(" OneTimePad : %s ", sprint_hex(data + 3*4, 4));
|
||||||
|
PrintAndLog("");
|
||||||
|
|
||||||
|
int len = CmdHF14AMfucAuth("K 0");
|
||||||
|
// PrintAndLog("CODE: %d",len);
|
||||||
|
|
||||||
|
PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mifare Ultralight Write Single Block
|
||||||
|
//
|
||||||
|
int CmdHF14AMfUWrBl(const char *Cmd){
|
||||||
|
uint8_t blockNo = -1;
|
||||||
|
bool chinese_card = FALSE;
|
||||||
|
uint8_t bldata[16] = {0x00};
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
|
||||||
|
PrintAndLog("Usage: hf mfu wrbl <block number> <block data (8 hex symbols)> [w]");
|
||||||
|
PrintAndLog(" [block number]");
|
||||||
|
PrintAndLog(" [block data] - (8 hex symbols)");
|
||||||
|
PrintAndLog(" [w] - Chinese magic ultralight tag");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog(" sample: hf mfu wrbl 0 01020304");
|
||||||
|
PrintAndLog("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
|
if (blockNo > MAX_ULTRA_BLOCKS){
|
||||||
|
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param_gethex(Cmd, 1, bldata, 8)) {
|
||||||
|
PrintAndLog("Block data must include 8 HEX symbols");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
|
||||||
|
chinese_card = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( blockNo <= 3) {
|
||||||
|
if (!chinese_card){
|
||||||
|
PrintAndLog("Access Denied");
|
||||||
|
} else {
|
||||||
|
PrintAndLog("--specialblock no:%02x", blockNo);
|
||||||
|
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
||||||
|
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
||||||
|
memcpy(d.d.asBytes,bldata, 4);
|
||||||
|
SendCommand(&d);
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
PrintAndLog("isOk:%02x", isOK);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("--block no:%02x", blockNo);
|
||||||
|
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
|
||||||
|
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
||||||
|
memcpy(e.d.asBytes,bldata, 4);
|
||||||
|
SendCommand(&e);
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
PrintAndLog("isOk:%02x", isOK);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mifare Ultralight Read Single Block
|
||||||
|
//
|
||||||
|
int CmdHF14AMfURdBl(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t blockNo = -1;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
||||||
|
PrintAndLog("Usage: hf mfu rdbl <block number>");
|
||||||
|
PrintAndLog(" sample: hfu mfu rdbl 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
|
||||||
|
if (blockNo > MAX_ULTRA_BLOCKS){
|
||||||
|
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("--block no:0x%02X (%d)", (int)blockNo, blockNo);
|
||||||
|
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
|
||||||
|
SendCommand(&c);
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
uint8_t * data = resp.d.asBytes;
|
||||||
|
|
||||||
|
PrintAndLog("isOk: %02x", isOK);
|
||||||
|
|
||||||
|
if (isOK)
|
||||||
|
PrintAndLog("Data: %s", sprint_hex(data, 4));
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mifare Ultralight / Ultralight-C; Read and Dump Card Contents
|
||||||
|
//
|
||||||
|
int CmdHF14AMfUDump(const char *Cmd){
|
||||||
|
|
||||||
|
FILE *fout;
|
||||||
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
|
char * fnameptr = filename;
|
||||||
|
|
||||||
|
uint8_t *lockbytes_t = NULL;
|
||||||
|
uint8_t lockbytes[2] = {0x00};
|
||||||
|
|
||||||
|
uint8_t *lockbytes_t2 = NULL;
|
||||||
|
uint8_t lockbytes2[2] = {0x00};
|
||||||
|
|
||||||
|
bool bit[16] = {0x00};
|
||||||
|
bool bit2[16] = {0x00};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
uint8_t BlockNo = 0;
|
||||||
|
int Pages = 16;
|
||||||
|
|
||||||
|
bool tmplockbit = false;
|
||||||
|
uint8_t isOK = 0;
|
||||||
|
uint8_t *data = NULL;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') {
|
||||||
|
PrintAndLog("Reads all pages from Mifare Ultralight or Ultralight-C tag.");
|
||||||
|
PrintAndLog("It saves binary dump into the file `filename.bin` or `cardUID.bin`");
|
||||||
|
PrintAndLog("Usage: hf mfu dump <c> <filename w/o .bin>");
|
||||||
|
PrintAndLog(" <c> optional cardtype c == Ultralight-C, if not defaults to Ultralight");
|
||||||
|
PrintAndLog(" sample: hf mfu dump");
|
||||||
|
PrintAndLog(" : hf mfu dump myfile");
|
||||||
|
PrintAndLog(" : hf mfu dump c myfile");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// UL or UL-C?
|
||||||
|
Pages = (cmdp == 'c' || cmdp == 'C') ? 44 : 16;
|
||||||
|
|
||||||
|
PrintAndLog("Dumping Ultralight%s Card Data...", (Pages ==16)?"":"-C");
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_MIFAREU_READCARD, {BlockNo,Pages}};
|
||||||
|
SendCommand(&c);
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
isOK = resp.arg[0] & 0xff;
|
||||||
|
if (!isOK) {
|
||||||
|
PrintAndLog("Command error");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
data = resp.d.asBytes;
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load lock bytes.
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
lockbytes_t = data + 8;
|
||||||
|
lockbytes[0] = lockbytes_t[2];
|
||||||
|
lockbytes[1] = lockbytes_t[3];
|
||||||
|
for(j = 0; j < 16; j++){
|
||||||
|
bit[j] = lockbytes[j/8] & ( 1 <<(7-j%8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load bottom lockbytes if available
|
||||||
|
if ( Pages == 44 ) {
|
||||||
|
|
||||||
|
lockbytes_t2 = data + (40*4);
|
||||||
|
lockbytes2[0] = lockbytes_t2[2];
|
||||||
|
lockbytes2[1] = lockbytes_t2[3];
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
bit2[j] = lockbytes2[j/8] & ( 1 <<(7-j%8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < Pages; ++i) {
|
||||||
|
|
||||||
|
if ( i < 3 ) {
|
||||||
|
PrintAndLog("Block %02x:%s ", i,sprint_hex(data + i * 4, 4));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(i){
|
||||||
|
case 3: tmplockbit = bit[4]; break;
|
||||||
|
case 4: tmplockbit = bit[3]; break;
|
||||||
|
case 5: tmplockbit = bit[2]; break;
|
||||||
|
case 6: tmplockbit = bit[1]; break;
|
||||||
|
case 7: tmplockbit = bit[0]; break;
|
||||||
|
case 8: tmplockbit = bit[15]; break;
|
||||||
|
case 9: tmplockbit = bit[14]; break;
|
||||||
|
case 10: tmplockbit = bit[13]; break;
|
||||||
|
case 11: tmplockbit = bit[12]; break;
|
||||||
|
case 12: tmplockbit = bit[11]; break;
|
||||||
|
case 13: tmplockbit = bit[10]; break;
|
||||||
|
case 14: tmplockbit = bit[9]; break;
|
||||||
|
case 15: tmplockbit = bit[8]; break;
|
||||||
|
case 16:
|
||||||
|
case 17:
|
||||||
|
case 18:
|
||||||
|
case 19: tmplockbit = bit2[6]; break;
|
||||||
|
case 20:
|
||||||
|
case 21:
|
||||||
|
case 22:
|
||||||
|
case 23: tmplockbit = bit2[5]; break;
|
||||||
|
case 24:
|
||||||
|
case 25:
|
||||||
|
case 26:
|
||||||
|
case 27: tmplockbit = bit2[4]; break;
|
||||||
|
case 28:
|
||||||
|
case 29:
|
||||||
|
case 30:
|
||||||
|
case 31: tmplockbit = bit2[2]; break;
|
||||||
|
case 32:
|
||||||
|
case 33:
|
||||||
|
case 34:
|
||||||
|
case 35: tmplockbit = bit2[1]; break;
|
||||||
|
case 36:
|
||||||
|
case 37:
|
||||||
|
case 38:
|
||||||
|
case 39: tmplockbit = bit2[0]; break;
|
||||||
|
case 40: tmplockbit = bit2[12]; break;
|
||||||
|
case 41: tmplockbit = bit2[11]; break;
|
||||||
|
case 42: tmplockbit = bit2[10]; break; //auth0
|
||||||
|
case 43: tmplockbit = bit2[9]; break; //auth1
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
PrintAndLog("Block %02x:%s [%d]", i,sprint_hex(data + i * 4, 4),tmplockbit);
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = 0;
|
||||||
|
if ( Pages == 16 )
|
||||||
|
len = param_getstr(Cmd,0,filename);
|
||||||
|
else
|
||||||
|
len = param_getstr(Cmd,1,filename);
|
||||||
|
|
||||||
|
if (len > FILE_PATH_SIZE-5) len = FILE_PATH_SIZE-5;
|
||||||
|
|
||||||
|
// user supplied filename?
|
||||||
|
if (len < 1) {
|
||||||
|
|
||||||
|
// UID = data 0-1-2 4-5-6-7 (skips a beat)
|
||||||
|
sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin",
|
||||||
|
data[0],data[1], data[2], data[4],data[5],data[6], data[7]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sprintf(fnameptr + len," .bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((fout = fopen(filename,"wb")) == NULL) {
|
||||||
|
PrintAndLog("Could not create file name %s", filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fwrite( data, 1, Pages*4, fout );
|
||||||
|
fclose(fout);
|
||||||
|
|
||||||
|
PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages, Pages*4, filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needed to Authenticate to Ultralight C tags
|
||||||
|
void rol (uint8_t *data, const size_t len){
|
||||||
|
uint8_t first = data[0];
|
||||||
|
for (size_t i = 0; i < len-1; i++) {
|
||||||
|
data[i] = data[i+1];
|
||||||
|
}
|
||||||
|
data[len-1] = first;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
// Ultralight C Methods
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//
|
||||||
|
// Ultralight C Authentication Demo {currently uses hard-coded key}
|
||||||
|
//
|
||||||
|
int CmdHF14AMfucAuth(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t default_keys[5][16] = {
|
||||||
|
{ 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
|
||||||
|
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
|
||||||
|
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
|
||||||
|
{ 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
|
||||||
|
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } // all ones
|
||||||
|
};
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
uint8_t keyNo = 0;
|
||||||
|
bool errors = false;
|
||||||
|
//Change key to user defined one
|
||||||
|
if (cmdp == 'k' || cmdp == 'K'){
|
||||||
|
keyNo = param_get8(Cmd, 1);
|
||||||
|
if(keyNo >= 4) errors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmdp == 'h' || cmdp == 'H') {
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors) {
|
||||||
|
PrintAndLog("Usage: hf mfu cauth k <key number>");
|
||||||
|
PrintAndLog(" 0 (default): 3DES standard key");
|
||||||
|
PrintAndLog(" 1 : all zeros key");
|
||||||
|
PrintAndLog(" 2 : 0x00-0x0F key");
|
||||||
|
PrintAndLog(" 3 : nfc key");
|
||||||
|
PrintAndLog(" 4 : all ones key");
|
||||||
|
PrintAndLog(" sample : hf mfu cauth k");
|
||||||
|
PrintAndLog(" : hf mfu cauth k 3");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
|
||||||
|
//uint8_t enc_random_a[8] = { 0 };
|
||||||
|
uint8_t random_b[8] = { 0 };
|
||||||
|
uint8_t enc_random_b[8] = { 0 };
|
||||||
|
uint8_t random_a_and_b[16] = { 0 };
|
||||||
|
des3_context ctx = { 0 };
|
||||||
|
uint8_t *key = default_keys[keyNo];
|
||||||
|
uint8_t blockNo = 0;
|
||||||
|
uint32_t cuid = 0;
|
||||||
|
|
||||||
|
//Auth1
|
||||||
|
UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
|
||||||
|
SendCommand(&c);
|
||||||
|
UsbCommand resp;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
cuid = resp.arg[1];
|
||||||
|
uint8_t * data= resp.d.asBytes;
|
||||||
|
|
||||||
|
if (isOK){
|
||||||
|
PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
|
||||||
|
memcpy(enc_random_b,data+1,8);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Auth failed");
|
||||||
|
return 2; // auth failed.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t iv[8] = { 0 };
|
||||||
|
// Do we need random ? Right now we use all ones, is that random enough ?
|
||||||
|
// DES_random_key(&RndA);
|
||||||
|
|
||||||
|
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
|
||||||
|
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
|
||||||
|
|
||||||
|
des3_set2key_dec(&ctx, key);
|
||||||
|
|
||||||
|
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||||
|
, DES_DECRYPT // int mode
|
||||||
|
, sizeof(random_b) // size_t length
|
||||||
|
, iv // unsigned char iv[8]
|
||||||
|
, enc_random_b // const unsigned char *input
|
||||||
|
, random_b // unsigned char *output
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
|
||||||
|
|
||||||
|
rol(random_b,8);
|
||||||
|
memcpy(random_a_and_b ,random_a,8);
|
||||||
|
memcpy(random_a_and_b+8,random_b,8);
|
||||||
|
|
||||||
|
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
|
||||||
|
|
||||||
|
des3_set2key_enc(&ctx, key);
|
||||||
|
|
||||||
|
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||||
|
, DES_ENCRYPT // int mode
|
||||||
|
, sizeof(random_a_and_b) // size_t length
|
||||||
|
, enc_random_b // unsigned char iv[8]
|
||||||
|
, random_a_and_b // const unsigned char *input
|
||||||
|
, random_a_and_b // unsigned char *output
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
|
||||||
|
|
||||||
|
//Auth2
|
||||||
|
UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
|
||||||
|
memcpy(d.d.asBytes,random_a_and_b, 16);
|
||||||
|
SendCommand(&d);
|
||||||
|
|
||||||
|
UsbCommand respb;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&respb,1500)) {
|
||||||
|
uint8_t isOK = respb.arg[0] & 0xff;
|
||||||
|
uint8_t * data2= respb.d.asBytes;
|
||||||
|
|
||||||
|
if (isOK){
|
||||||
|
PrintAndLog("enc(RndA'):%s", sprint_hex(data2+1, 8));
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
A test function to validate that the polarssl-function works the same
|
||||||
|
was as the openssl-implementation.
|
||||||
|
Commented out, since it requires openssl
|
||||||
|
|
||||||
|
int CmdTestDES(const char * cmd)
|
||||||
|
{
|
||||||
|
uint8_t key[16] = {0x00};
|
||||||
|
|
||||||
|
memcpy(key,key3_3des_data,16);
|
||||||
|
DES_cblock RndA, RndB;
|
||||||
|
|
||||||
|
PrintAndLog("----------OpenSSL DES implementation----------");
|
||||||
|
{
|
||||||
|
uint8_t e_RndB[8] = {0x00};
|
||||||
|
unsigned char RndARndB[16] = {0x00};
|
||||||
|
|
||||||
|
DES_cblock iv = { 0 };
|
||||||
|
DES_key_schedule ks1,ks2;
|
||||||
|
DES_cblock key1,key2;
|
||||||
|
|
||||||
|
memcpy(key,key3_3des_data,16);
|
||||||
|
memcpy(key1,key,8);
|
||||||
|
memcpy(key2,key+8,8);
|
||||||
|
|
||||||
|
|
||||||
|
DES_set_key((DES_cblock *)key1,&ks1);
|
||||||
|
DES_set_key((DES_cblock *)key2,&ks2);
|
||||||
|
|
||||||
|
DES_random_key(&RndA);
|
||||||
|
PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
|
||||||
|
PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
|
||||||
|
//void DES_ede2_cbc_encrypt(const unsigned char *input,
|
||||||
|
// unsigned char *output, long length, DES_key_schedule *ks1,
|
||||||
|
// DES_key_schedule *ks2, DES_cblock *ivec, int enc);
|
||||||
|
DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
|
||||||
|
|
||||||
|
PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
|
||||||
|
rol(RndB,8);
|
||||||
|
memcpy(RndARndB,RndA,8);
|
||||||
|
memcpy(RndARndB+8,RndB,8);
|
||||||
|
PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
|
||||||
|
DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
|
||||||
|
PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
|
||||||
|
|
||||||
|
}
|
||||||
|
PrintAndLog("----------PolarSSL implementation----------");
|
||||||
|
{
|
||||||
|
uint8_t random_a[8] = { 0 };
|
||||||
|
uint8_t enc_random_a[8] = { 0 };
|
||||||
|
uint8_t random_b[8] = { 0 };
|
||||||
|
uint8_t enc_random_b[8] = { 0 };
|
||||||
|
uint8_t random_a_and_b[16] = { 0 };
|
||||||
|
des3_context ctx = { 0 };
|
||||||
|
|
||||||
|
memcpy(random_a, RndA,8);
|
||||||
|
|
||||||
|
uint8_t output[8] = { 0 };
|
||||||
|
uint8_t iv[8] = { 0 };
|
||||||
|
|
||||||
|
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
|
||||||
|
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
|
||||||
|
|
||||||
|
des3_set2key_dec(&ctx, key);
|
||||||
|
|
||||||
|
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||||
|
, DES_DECRYPT // int mode
|
||||||
|
, sizeof(random_b) // size_t length
|
||||||
|
, iv // unsigned char iv[8]
|
||||||
|
, enc_random_b // const unsigned char *input
|
||||||
|
, random_b // unsigned char *output
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
|
||||||
|
|
||||||
|
rol(random_b,8);
|
||||||
|
memcpy(random_a_and_b ,random_a,8);
|
||||||
|
memcpy(random_a_and_b+8,random_b,8);
|
||||||
|
|
||||||
|
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
|
||||||
|
|
||||||
|
des3_set2key_enc(&ctx, key);
|
||||||
|
|
||||||
|
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||||
|
, DES_ENCRYPT // int mode
|
||||||
|
, sizeof(random_a_and_b) // size_t length
|
||||||
|
, enc_random_b // unsigned char iv[8]
|
||||||
|
, random_a_and_b // const unsigned char *input
|
||||||
|
, random_a_and_b // unsigned char *output
|
||||||
|
);
|
||||||
|
|
||||||
|
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
**/
|
||||||
|
//
|
||||||
|
// Ultralight C Read Single Block
|
||||||
|
//
|
||||||
|
int CmdHF14AMfUCRdBl(const char *Cmd)
|
||||||
|
{
|
||||||
|
uint8_t blockNo = -1;
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
||||||
|
PrintAndLog("Usage: hf mfu crdbl <block number>");
|
||||||
|
PrintAndLog(" sample: hf mfu crdbl 0");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
if (blockNo < 0) {
|
||||||
|
PrintAndLog("Wrong block number");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blockNo > MAX_ULTRAC_BLOCKS ){
|
||||||
|
PrintAndLog("Error: Maximum number of readable blocks is 47 for Ultralight-C Cards!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("--block no: 0x%02X (%d)", (int)blockNo, blockNo);
|
||||||
|
|
||||||
|
//Read Block
|
||||||
|
UsbCommand e = {CMD_MIFAREU_READBL, {blockNo}};
|
||||||
|
SendCommand(&e);
|
||||||
|
UsbCommand resp_c;
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp_c,1500)) {
|
||||||
|
uint8_t isOK = resp_c.arg[0] & 0xff;
|
||||||
|
uint8_t *data = resp_c.d.asBytes;
|
||||||
|
|
||||||
|
PrintAndLog("isOk: %02x", isOK);
|
||||||
|
if (isOK)
|
||||||
|
PrintAndLog("Data: %s", sprint_hex(data, 4));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mifare Ultralight C Write Single Block
|
||||||
|
//
|
||||||
|
int CmdHF14AMfUCWrBl(const char *Cmd){
|
||||||
|
|
||||||
|
uint8_t blockNo = -1;
|
||||||
|
bool chinese_card = FALSE;
|
||||||
|
uint8_t bldata[16] = {0x00};
|
||||||
|
UsbCommand resp;
|
||||||
|
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
|
||||||
|
PrintAndLog("Usage: hf mfu cwrbl <block number> <block data (8 hex symbols)> [w]");
|
||||||
|
PrintAndLog(" [block number]");
|
||||||
|
PrintAndLog(" [block data] - (8 hex symbols)");
|
||||||
|
PrintAndLog(" [w] - Chinese magic ultralight tag");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog(" sample: hf mfu cwrbl 0 01020304");
|
||||||
|
PrintAndLog("");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockNo = param_get8(Cmd, 0);
|
||||||
|
if (blockNo > MAX_ULTRAC_BLOCKS ){
|
||||||
|
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param_gethex(Cmd, 1, bldata, 8)) {
|
||||||
|
PrintAndLog("Block data must include 8 HEX symbols");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
|
||||||
|
chinese_card = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( blockNo <= 3 ) {
|
||||||
|
if (!chinese_card){
|
||||||
|
PrintAndLog("Access Denied");
|
||||||
|
} else {
|
||||||
|
PrintAndLog("--Special block no: 0x%02x", blockNo);
|
||||||
|
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
|
||||||
|
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
||||||
|
memcpy(d.d.asBytes,bldata, 4);
|
||||||
|
SendCommand(&d);
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
PrintAndLog("isOk:%02x", isOK);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("--Block no : 0x%02x", blockNo);
|
||||||
|
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
|
||||||
|
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
|
||||||
|
memcpy(e.d.asBytes,bldata, 4);
|
||||||
|
SendCommand(&e);
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
|
uint8_t isOK = resp.arg[0] & 0xff;
|
||||||
|
PrintAndLog("isOk : %02x", isOK);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Command execute timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------
|
||||||
|
// Menu Stuff
|
||||||
|
//------------------------------------
|
||||||
|
static command_t CommandTable[] =
|
||||||
|
{
|
||||||
|
{"help", CmdHelp, 1,"This help"},
|
||||||
|
{"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
|
||||||
|
{"info", CmdHF14AMfUInfo, 0,"Taginfo"},
|
||||||
|
{"dump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight / Ultralight-C tag to binary file"},
|
||||||
|
{"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
|
||||||
|
{"wrbl", CmdHF14AMfUWrBl, 0,"Write block - MIFARE Ultralight"},
|
||||||
|
{"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
|
||||||
|
{"cwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
|
||||||
|
{"cauth", CmdHF14AMfucAuth, 0,"try a Ultralight C Authentication"},
|
||||||
|
//{"testdes", CmdTestDES , 1, "Test DES"},
|
||||||
|
{NULL, NULL, 0, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
int CmdHFMFUltra(const char *Cmd){
|
||||||
|
WaitForResponseTimeout(CMD_ACK,NULL,100);
|
||||||
|
CmdsParse(CommandTable, Cmd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdHelp(const char *Cmd){
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return 0;
|
||||||
|
}
|
19
client/cmdhfmfu.h
Normal file
19
client/cmdhfmfu.h
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "cmdhfmf.h"
|
||||||
|
#include "cmdhf14a.h"
|
||||||
|
|
||||||
|
//standard ultralight
|
||||||
|
int CmdHF14AMfUWrBl(const char *Cmd);
|
||||||
|
int CmdHF14AMfURdBl(const char *Cmd);
|
||||||
|
|
||||||
|
//Crypto Cards
|
||||||
|
int CmdHF14AMfUCRdBl(const char *Cmd);
|
||||||
|
int CmdHF14AMfUCRdCard(const char *Cmd);
|
||||||
|
int CmdHF14AMfucAuth(const char *Cmd);
|
||||||
|
|
||||||
|
//general stuff
|
||||||
|
int CmdHF14AMfUDump(const char *Cmd);
|
||||||
|
void rol (uint8_t *data, const size_t len);
|
||||||
|
|
||||||
|
|
||||||
|
int CmdHFMFUltra(const char *Cmd);
|
||||||
|
int CmdHF14AMfUInfo(const char *Cmd);
|
|
@ -519,7 +519,7 @@ static void ChkBitstream(const char *str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//appears to attempt to simulate manchester
|
||||||
int CmdLFSim(const char *Cmd)
|
int CmdLFSim(const char *Cmd)
|
||||||
{
|
{
|
||||||
int i,j;
|
int i,j;
|
||||||
|
@ -682,26 +682,41 @@ int CmdLFfind(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
|
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
|
||||||
PrintAndLog("Checking for known tags:");
|
PrintAndLog("\nChecking for known tags:\n");
|
||||||
ans=CmdFSKdemodIO("");
|
ans=CmdFSKdemodIO("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("Valid IO Prox ID Found!");
|
PrintAndLog("\nValid IO Prox ID Found!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ans=CmdFSKdemodPyramid("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid Pyramid ID Found!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ans=CmdFSKdemodParadox("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid Paradox ID Found!");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
ans=CmdFSKdemodAWID("");
|
||||||
|
if (ans>0) {
|
||||||
|
PrintAndLog("\nValid AWID ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ans=CmdFSKdemodHID("");
|
ans=CmdFSKdemodHID("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("Valid HID Prox ID Found!");
|
PrintAndLog("\nValid HID Prox ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
//add psk and indala
|
//add psk and indala
|
||||||
ans=CmdIndalaDecode("0");
|
ans=CmdIndalaDecode("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("Valid Indala ID Found!");
|
PrintAndLog("\nValid Indala ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ans=Cmdaskmandemod("");
|
ans=Cmdaskmandemod("");
|
||||||
if (ans>0) {
|
if (ans>0) {
|
||||||
PrintAndLog("Valid EM410x ID Found!");
|
PrintAndLog("\nValid EM410x ID Found!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
PrintAndLog("No Known Tags Found!\n");
|
PrintAndLog("No Known Tags Found!\n");
|
||||||
|
|
|
@ -29,11 +29,26 @@ size_t nbytes(size_t nbits) {
|
||||||
|
|
||||||
int CmdLFHitagList(const char *Cmd)
|
int CmdLFHitagList(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t got[TRACE_BUFFER_SIZE];
|
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
|
||||||
|
|
||||||
PrintAndLog("recorded activity:");
|
// Query for the actual size of the trace
|
||||||
|
UsbCommand response;
|
||||||
|
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
||||||
|
WaitForResponse(CMD_ACK, &response);
|
||||||
|
uint16_t traceLen = response.arg[2];
|
||||||
|
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||||
|
uint8_t *p = realloc(got, traceLen);
|
||||||
|
if (p == NULL) {
|
||||||
|
PrintAndLog("Cannot allocate memory for trace");
|
||||||
|
free(got);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
got = p;
|
||||||
|
GetFromBigBuf(got, traceLen, 0);
|
||||||
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("recorded activity (TraceLen = %d bytes):");
|
||||||
PrintAndLog(" ETU :nbits: who bytes");
|
PrintAndLog(" ETU :nbits: who bytes");
|
||||||
PrintAndLog("---------+-----+----+-----------");
|
PrintAndLog("---------+-----+----+-----------");
|
||||||
|
|
||||||
|
@ -57,7 +72,7 @@ int CmdLFHitagList(const char *Cmd)
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if(i >= TRACE_BUFFER_SIZE) { break; }
|
if(i > traceLen) { break; }
|
||||||
|
|
||||||
bool isResponse;
|
bool isResponse;
|
||||||
int timestamp = *((uint32_t *)(got+i));
|
int timestamp = *((uint32_t *)(got+i));
|
||||||
|
@ -82,7 +97,7 @@ int CmdLFHitagList(const char *Cmd)
|
||||||
if (len > 100) {
|
if (len > 100) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i + len >= TRACE_BUFFER_SIZE) { break;}
|
if (i + len > traceLen) { break;}
|
||||||
|
|
||||||
uint8_t *frame = (got+i+9);
|
uint8_t *frame = (got+i+9);
|
||||||
|
|
||||||
|
@ -114,7 +129,6 @@ int CmdLFHitagList(const char *Cmd)
|
||||||
(isResponse ? "TAG" : " "),
|
(isResponse ? "TAG" : " "),
|
||||||
line);
|
line);
|
||||||
|
|
||||||
|
|
||||||
if (pf) {
|
if (pf) {
|
||||||
fprintf(pf," +%7d: %3d: %s %s\n",
|
fprintf(pf," +%7d: %3d: %s %s\n",
|
||||||
(prev < 0 ? 0 : (timestamp - prev)),
|
(prev < 0 ? 0 : (timestamp - prev)),
|
||||||
|
@ -132,6 +146,7 @@ int CmdLFHitagList(const char *Cmd)
|
||||||
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
|
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(got);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC)
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
|
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
|
||||||
sample_buf_len += UC->arg[1];
|
|
||||||
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
|
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,9 @@
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
|
|
||||||
uint8_t* sample_buf;
|
uint8_t* sample_buf;
|
||||||
size_t sample_buf_len;
|
|
||||||
|
|
||||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
|
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
|
||||||
{
|
{
|
||||||
sample_buf_len = 0;
|
|
||||||
sample_buf = dest;
|
sample_buf = dest;
|
||||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
|
@ -13,13 +13,9 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
|
|
||||||
#define TRACE_BUFFER_SIZE 4096
|
|
||||||
#define FILE_PATH_SIZE 1000
|
#define FILE_PATH_SIZE 1000
|
||||||
#define SAMPLE_BUFFER_SIZE 64
|
|
||||||
|
|
||||||
extern uint8_t* sample_buf;
|
extern uint8_t* sample_buf;
|
||||||
extern size_t sample_buf_len;
|
|
||||||
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
|
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
|
||||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
|
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "graph.h"
|
#include "graph.h"
|
||||||
|
@ -50,7 +51,11 @@ int ClearGraph(int redraw)
|
||||||
|
|
||||||
void setGraphBuf(uint8_t *buff, size_t size)
|
void setGraphBuf(uint8_t *buff, size_t size)
|
||||||
{
|
{
|
||||||
int i=0;
|
if ( buff == NULL ) return;
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
if ( size > MAX_GRAPH_TRACE_LEN )
|
||||||
|
size = MAX_GRAPH_TRACE_LEN;
|
||||||
ClearGraph(0);
|
ClearGraph(0);
|
||||||
for (; i < size; ++i){
|
for (; i < size; ++i){
|
||||||
GraphBuffer[i]=buff[i]-128;
|
GraphBuffer[i]=buff[i]-128;
|
||||||
|
@ -61,6 +66,8 @@ void setGraphBuf(uint8_t *buff, size_t size)
|
||||||
}
|
}
|
||||||
size_t getFromGraphBuf(uint8_t *buff)
|
size_t getFromGraphBuf(uint8_t *buff)
|
||||||
{
|
{
|
||||||
|
if ( buff == NULL ) return 0;
|
||||||
|
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
for (i=0;i<GraphTraceLen;++i){
|
for (i=0;i<GraphTraceLen;++i){
|
||||||
if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
|
if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
|
||||||
|
@ -69,6 +76,8 @@ size_t getFromGraphBuf(uint8_t *buff)
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get or auto-detect clock rate
|
// Get or auto-detect clock rate
|
||||||
int GetClock(const char *str, int peak, int verbose)
|
int GetClock(const char *str, int peak, int verbose)
|
||||||
{
|
{
|
||||||
|
@ -82,16 +91,51 @@ int GetClock(const char *str, int peak, int verbose)
|
||||||
{
|
{
|
||||||
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
size_t size = getFromGraphBuf(grph);
|
size_t size = getFromGraphBuf(grph);
|
||||||
|
if ( size == 0 ) {
|
||||||
|
PrintAndLog("Failed to copy from graphbuffer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
clock = DetectASKClock(grph,size,0);
|
clock = DetectASKClock(grph,size,0);
|
||||||
// Only print this message if we're not looping something
|
// Only print this message if we're not looping something
|
||||||
if (!verbose){
|
if (!verbose){
|
||||||
PrintAndLog("Auto-detected clock rate: %d", clock);
|
PrintAndLog("Auto-detected clock rate: %d", clock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clock;
|
return clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A simple test to see if there is any data inside Graphbuffer.
|
||||||
|
bool HasGraphData(){
|
||||||
|
|
||||||
|
if ( GraphTraceLen <= 0) {
|
||||||
|
PrintAndLog("No data available, try reading something first");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect high and lows in Grapbuffer.
|
||||||
|
// Only loops the first 256 values.
|
||||||
|
void DetectHighLowInGraph(int *high, int *low, bool addFuzz) {
|
||||||
|
|
||||||
|
uint8_t loopMax = 255;
|
||||||
|
if ( loopMax > GraphTraceLen)
|
||||||
|
loopMax = GraphTraceLen;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < loopMax; ++i) {
|
||||||
|
if (GraphBuffer[i] > *high)
|
||||||
|
*high = GraphBuffer[i];
|
||||||
|
else if (GraphBuffer[i] < *low)
|
||||||
|
*low = GraphBuffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
//12% fuzz in case highs and lows aren't clipped
|
||||||
|
if (addFuzz) {
|
||||||
|
*high = (int)(*high * .88);
|
||||||
|
*low = (int)(*low * .88);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int GetNRZpskClock(const char *str, int peak, int verbose)
|
int GetNRZpskClock(const char *str, int peak, int verbose)
|
||||||
{
|
{
|
||||||
int clock;
|
int clock;
|
||||||
|
@ -104,6 +148,10 @@ int GetNRZpskClock(const char *str, int peak, int verbose)
|
||||||
{
|
{
|
||||||
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
||||||
size_t size = getFromGraphBuf(grph);
|
size_t size = getFromGraphBuf(grph);
|
||||||
|
if ( size == 0 ) {
|
||||||
|
PrintAndLog("Failed to copy from graphbuffer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
clock = DetectpskNRZClock(grph,size,0);
|
clock = DetectpskNRZClock(grph,size,0);
|
||||||
// Only print this message if we're not looping something
|
// Only print this message if we're not looping something
|
||||||
if (!verbose){
|
if (!verbose){
|
||||||
|
|
|
@ -20,9 +20,12 @@ int GetClock(const char *str, int peak, int verbose);
|
||||||
int GetNRZpskClock(const char *str, int peak, int verbose);
|
int GetNRZpskClock(const char *str, int peak, int verbose);
|
||||||
void setGraphBuf(uint8_t *buff, size_t size);
|
void setGraphBuf(uint8_t *buff, size_t size);
|
||||||
|
|
||||||
|
bool HasGraphData();
|
||||||
|
void DetectHighLowInGraph(int *high, int *low, bool addFuzz);
|
||||||
|
|
||||||
// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample)
|
// Max graph trace len: 40000 (bigbuf) * 8 (at 1 bit per sample)
|
||||||
#define MAX_GRAPH_TRACE_LEN (40000 * 8 )
|
#define MAX_GRAPH_TRACE_LEN (40000 * 8 )
|
||||||
|
|
||||||
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
|
||||||
extern int GraphTraceLen;
|
extern int GraphTraceLen;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
#define POLARSSL_DES_H
|
#define POLARSSL_DES_H
|
||||||
|
|
||||||
//#include "config.h"
|
//#include "config.h"
|
||||||
|
/**
|
||||||
|
* \def POLARSSL_CIPHER_MODE_CBC
|
||||||
|
*
|
||||||
|
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
|
||||||
|
*/
|
||||||
|
#define POLARSSL_CIPHER_MODE_CBC
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ local _commands = {
|
||||||
CMD_EM4X_WRITE_WORD = 0x0219,
|
CMD_EM4X_WRITE_WORD = 0x0219,
|
||||||
CMD_IO_DEMOD_FSK = 0x021A,
|
CMD_IO_DEMOD_FSK = 0x021A,
|
||||||
CMD_IO_CLONE_TAG = 0x021B,
|
CMD_IO_CLONE_TAG = 0x021B,
|
||||||
CMD_EM410X_DEMOD = 0x021C,
|
CMD_EM410X_DEMOD = 0x021c,
|
||||||
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||||
|
|
||||||
--// For the 13.56 MHz tags
|
--// For the 13.56 MHz tags
|
||||||
|
|
|
@ -108,6 +108,24 @@ local Utils =
|
||||||
return retval
|
return retval
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-- input parameter is a string
|
||||||
|
-- Swaps the endianess and returns a string,
|
||||||
|
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
||||||
|
SwapEndiannessStr = function(s, len)
|
||||||
|
if s == nil then return nil end
|
||||||
|
if #s == 0 then return '' end
|
||||||
|
if type(s) ~= 'string' then return nil end
|
||||||
|
|
||||||
|
local retval
|
||||||
|
if len == 16 then
|
||||||
|
retval = s:sub(3,4)..s:sub(1,2)
|
||||||
|
elseif len == 24 then
|
||||||
|
retval = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
|
elseif len == 32 then
|
||||||
|
retval = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||||
|
end
|
||||||
|
return retval
|
||||||
|
end,
|
||||||
------------ CONVERSIONS
|
------------ CONVERSIONS
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -116,7 +134,7 @@ local Utils =
|
||||||
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
|
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
|
||||||
while IN>0 do
|
while IN>0 do
|
||||||
I=I+1
|
I=I+1
|
||||||
IN,D=math.floor(IN/B),math.mod(IN,B)+1
|
IN , D = math.floor(IN/B), math.modf(IN,B)+1
|
||||||
OUT=string.sub(K,D,D)..OUT
|
OUT=string.sub(K,D,D)..OUT
|
||||||
end
|
end
|
||||||
return OUT
|
return OUT
|
||||||
|
|
|
@ -232,14 +232,27 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||||
// "MAGIC" CARD
|
// "MAGIC" CARD
|
||||||
|
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
|
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
|
||||||
|
|
||||||
|
uint8_t oldblock0[16] = {0x00};
|
||||||
uint8_t block0[16] = {0x00};
|
uint8_t block0[16] = {0x00};
|
||||||
memcpy(block0, uid, 4);
|
memcpy(block0, uid, 4);
|
||||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
|
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
|
||||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7)
|
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7)
|
||||||
block0[5] = 0x08;
|
//block0[5] = 0x08;
|
||||||
block0[6] = 0x04;
|
//block0[6] = 0x04;
|
||||||
block0[7] = 0x00;
|
//block0[7] = 0x00;
|
||||||
|
|
||||||
|
block0[5] = 0x01; //sak
|
||||||
|
block0[6] = 0x01;
|
||||||
|
block0[7] = 0x0f;
|
||||||
|
|
||||||
|
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
|
||||||
|
if ( old == 0) {
|
||||||
|
memcpy(block0+8, oldblock0+8, 8);
|
||||||
|
PrintAndLog("block 0: %s", sprint_hex(block0,16));
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0.");
|
||||||
|
}
|
||||||
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +266,10 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||||
isOK = resp.arg[0] & 0xff;
|
isOK = resp.arg[0] & 0xff;
|
||||||
if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);
|
if (uid != NULL)
|
||||||
if (!isOK) return 2;
|
memcpy(uid, resp.d.asBytes, 4);
|
||||||
|
if (!isOK)
|
||||||
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
PrintAndLog("Command execute timeout");
|
PrintAndLog("Command execute timeout");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -286,9 +301,9 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
||||||
static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};
|
static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
char logHexFileName[200] = {0x00};
|
char logHexFileName[FILE_PATH_SIZE] = {0x00};
|
||||||
static uint8_t traceCard[4096] = {0x00};
|
static uint8_t traceCard[4096] = {0x00};
|
||||||
static char traceFileName[200] = {0x00};
|
static char traceFileName[FILE_PATH_SIZE] = {0x00};
|
||||||
static int traceState = TRACE_IDLE;
|
static int traceState = TRACE_IDLE;
|
||||||
static uint8_t traceCurBlock = 0;
|
static uint8_t traceCurBlock = 0;
|
||||||
static uint8_t traceCurKey = 0;
|
static uint8_t traceCurKey = 0;
|
||||||
|
@ -323,20 +338,28 @@ int isBlockTrailer(int blockN) {
|
||||||
|
|
||||||
int loadTraceCard(uint8_t *tuid) {
|
int loadTraceCard(uint8_t *tuid) {
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char buf[64];
|
char buf[64] = {0x00};
|
||||||
uint8_t buf8[64];
|
uint8_t buf8[64] = {0x00};
|
||||||
int i, blockNum;
|
int i, blockNum;
|
||||||
|
|
||||||
if (!isTraceCardEmpty()) saveTraceCard();
|
if (!isTraceCardEmpty())
|
||||||
|
saveTraceCard();
|
||||||
|
|
||||||
memset(traceCard, 0x00, 4096);
|
memset(traceCard, 0x00, 4096);
|
||||||
memcpy(traceCard, tuid + 3, 4);
|
memcpy(traceCard, tuid + 3, 4);
|
||||||
|
|
||||||
FillFileNameByUID(traceFileName, tuid, ".eml", 7);
|
FillFileNameByUID(traceFileName, tuid, ".eml", 7);
|
||||||
|
|
||||||
f = fopen(traceFileName, "r");
|
f = fopen(traceFileName, "r");
|
||||||
if (!f) return 1;
|
if (!f) {
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
blockNum = 0;
|
blockNum = 0;
|
||||||
|
|
||||||
while(!feof(f)){
|
while(!feof(f)){
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||||
PrintAndLog("File reading error.");
|
PrintAndLog("File reading error.");
|
||||||
|
@ -368,22 +391,30 @@ int saveTraceCard(void) {
|
||||||
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;
|
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;
|
||||||
|
|
||||||
f = fopen(traceFileName, "w+");
|
f = fopen(traceFileName, "w+");
|
||||||
|
if ( !f ) {
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 64; i++) { // blocks
|
for (int i = 0; i < 64; i++) { // blocks
|
||||||
for (int j = 0; j < 16; j++) // bytes
|
for (int j = 0; j < 16; j++) // bytes
|
||||||
fprintf(f, "%02x", *(traceCard + i * 16 + j));
|
fprintf(f, "%02x", *(traceCard + i * 16 + j));
|
||||||
fprintf(f,"\n");
|
fprintf(f,"\n");
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {
|
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {
|
||||||
|
|
||||||
if (traceCrypto1) crypto1_destroy(traceCrypto1);
|
if (traceCrypto1)
|
||||||
|
crypto1_destroy(traceCrypto1);
|
||||||
|
|
||||||
traceCrypto1 = NULL;
|
traceCrypto1 = NULL;
|
||||||
|
|
||||||
if (wantSaveToEmlFile) loadTraceCard(tuid);
|
if (wantSaveToEmlFile)
|
||||||
|
loadTraceCard(tuid);
|
||||||
|
|
||||||
traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];
|
traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];
|
||||||
traceCard[5] = sak;
|
traceCard[5] = sak;
|
||||||
memcpy(&traceCard[6], atqa, 2);
|
memcpy(&traceCard[6], atqa, 2);
|
||||||
|
|
|
@ -47,7 +47,7 @@ typedef struct {
|
||||||
int foundKey[2];
|
int foundKey[2];
|
||||||
} sector;
|
} sector;
|
||||||
|
|
||||||
extern char logHexFileName[200];
|
extern char logHexFileName[FILE_PATH_SIZE];
|
||||||
|
|
||||||
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
|
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
|
||||||
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
|
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
|
||||||
|
|
63
client/scripts/remagic.lua
Normal file
63
client/scripts/remagic.lua
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
local getopt = require('getopt')
|
||||||
|
|
||||||
|
example = "script run remagic"
|
||||||
|
author = "Iceman"
|
||||||
|
|
||||||
|
desc =
|
||||||
|
[[
|
||||||
|
This is a script that tries to bring back a chinese magic card (1k generation1)
|
||||||
|
from the dead when it's block 0 has been written with bad values.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
-h this help
|
||||||
|
]]
|
||||||
|
---
|
||||||
|
-- A debug printout-function
|
||||||
|
function dbg(args)
|
||||||
|
if DEBUG then
|
||||||
|
print("###", args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- This is only meant to be used when errors occur
|
||||||
|
function oops(err)
|
||||||
|
print("ERROR: ",err)
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- Usage help
|
||||||
|
function help()
|
||||||
|
print(desc)
|
||||||
|
print("Example usage")
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- The main entry point
|
||||||
|
function main(args)
|
||||||
|
|
||||||
|
|
||||||
|
-- Read the parameters
|
||||||
|
for o, a in getopt.getopt(args, 'h') do
|
||||||
|
if o == "h" then help() return end
|
||||||
|
end
|
||||||
|
|
||||||
|
local _cmds = {
|
||||||
|
--[[
|
||||||
|
--]]
|
||||||
|
[0] = "hf 14a raw -p -a -b 7 40",
|
||||||
|
[1] = "hf 14a raw -p -a 43",
|
||||||
|
[2] = "hf 14a raw -c -p -a A000",
|
||||||
|
[3] = "hf 14a raw -c -p -a 01 02 03 04 04 98 02 00 00 00 00 00 00 00 10 01",
|
||||||
|
}
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
|
local i
|
||||||
|
--for _,c in pairs(_cmds) do
|
||||||
|
for i = 0, 3 do
|
||||||
|
print ( _cmds[i] )
|
||||||
|
core.console( _cmds[i] )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
main(args)
|
173
client/scripts/test_t55x7_psk.lua
Normal file
173
client/scripts/test_t55x7_psk.lua
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
local cmds = require('commands')
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local bin = require('bin')
|
||||||
|
local utils = require('utils')
|
||||||
|
local dumplib = require('html_dumplib')
|
||||||
|
|
||||||
|
example =[[
|
||||||
|
1. script run tracetest
|
||||||
|
2. script run tracetest -o
|
||||||
|
|
||||||
|
]]
|
||||||
|
author = "Iceman"
|
||||||
|
usage = "script run test_t55x7_psk -o <filename>"
|
||||||
|
desc =[[
|
||||||
|
This script will program a T55x7 TAG with the configuration: block 0x00 data 0x00088040
|
||||||
|
The outlined procedure is as following:
|
||||||
|
|
||||||
|
"lf t55xx write 0 00088040"
|
||||||
|
"lf read"
|
||||||
|
"data samples"
|
||||||
|
"data pskdet"
|
||||||
|
"data psknrz"
|
||||||
|
"data pskindala"
|
||||||
|
"data psknrzraw"
|
||||||
|
|
||||||
|
Loop OUTER:
|
||||||
|
change the configuretion block 0 with:
|
||||||
|
-xxxx8xxx = PSK RF/2 with Manchester modulation
|
||||||
|
-xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes)
|
||||||
|
-xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high)
|
||||||
|
-xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input)
|
||||||
|
Loop INNER
|
||||||
|
for each outer configuration, also do
|
||||||
|
XXXXX0XX = PSK RF/2
|
||||||
|
XXXXX4XX = PSK RF/4
|
||||||
|
XXXXX8XX = PSK RF/8
|
||||||
|
|
||||||
|
In all 12 individual test for the PSK demod
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
-h : this help
|
||||||
|
-o : logfile name
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||||
|
local DEBUG = true -- the debug flag
|
||||||
|
|
||||||
|
--BLOCK 0 = 00088040
|
||||||
|
local config1 = '0008'
|
||||||
|
local config2 = '40'
|
||||||
|
|
||||||
|
local procedurecmds = {
|
||||||
|
[1] = '%s%s%s%s',
|
||||||
|
[2] = 'lf read',
|
||||||
|
--[3] = '',
|
||||||
|
[3] = 'data samples',
|
||||||
|
[4] = 'data pskdetectclock',
|
||||||
|
[5] = 'data psknrzrawdemod',
|
||||||
|
[6] = 'data pskindalademod',
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
-- A debug printout-function
|
||||||
|
function dbg(args)
|
||||||
|
if not DEBUG then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(args) == "table" then
|
||||||
|
local i = 1
|
||||||
|
while args[i] do
|
||||||
|
dbg(args[i])
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("###", args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- This is only meant to be used when errors occur
|
||||||
|
function oops(err)
|
||||||
|
print("ERROR: ",err)
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- Usage help
|
||||||
|
function help()
|
||||||
|
print(desc)
|
||||||
|
print("Example usage")
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
--
|
||||||
|
-- Exit message
|
||||||
|
function ExitMsg(msg)
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print(msg)
|
||||||
|
print()
|
||||||
|
end
|
||||||
|
|
||||||
|
function pskTest(modulation)
|
||||||
|
local y
|
||||||
|
for y = 0, 8, 4 do
|
||||||
|
for _ = 1, #procedurecmds do
|
||||||
|
local cmd = procedurecmds[_]
|
||||||
|
|
||||||
|
if #cmd == 0 then
|
||||||
|
|
||||||
|
elseif _ == 1 then
|
||||||
|
|
||||||
|
dbg("Writing to T55x7 TAG")
|
||||||
|
|
||||||
|
local configdata = cmd:format( config1, modulation , y, config2)
|
||||||
|
|
||||||
|
dbg( configdata)
|
||||||
|
|
||||||
|
local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = configdata ,arg2 = 0, arg3 = 0}
|
||||||
|
local err = core.SendCommand(writecommand:getBytes())
|
||||||
|
if err then return oops(err) end
|
||||||
|
local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
|
||||||
|
|
||||||
|
if response then
|
||||||
|
local count,cmd,arg0 = bin.unpack('LL',response)
|
||||||
|
if(arg0==1) then
|
||||||
|
dbg("Writing success")
|
||||||
|
else
|
||||||
|
return nil, "Couldn't read block.."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
dbg(cmd)
|
||||||
|
core.console( cmd )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
end
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function main(args)
|
||||||
|
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
|
local outputTemplate = os.date("testpsk_%Y-%m-%d_%H%M%S")
|
||||||
|
|
||||||
|
-- Arguments for the script
|
||||||
|
for o, arg in getopt.getopt(args, 'ho:') do
|
||||||
|
if o == "h" then return help() end
|
||||||
|
if o == "o" then outputTemplate = arg end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
|
pskTest(1)
|
||||||
|
pskTest(2)
|
||||||
|
pskTest(3)
|
||||||
|
pskTest(8)
|
||||||
|
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
end
|
||||||
|
main(args)
|
||||||
|
|
||||||
|
-- Where it iterates over
|
||||||
|
-- xxxx8xxx = PSK RF/2 with Manchester modulation
|
||||||
|
-- xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes)
|
||||||
|
-- xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high)
|
||||||
|
-- xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input)
|
||||||
|
|
||||||
|
-- XXXXX0XX = PSK RF/2
|
||||||
|
-- XXXXX4XX = PSK RF/4
|
||||||
|
-- XXXXX8XX = PSK RF/8
|
|
@ -249,18 +249,19 @@ local function main(args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Write dump to files
|
|
||||||
if not DEBUG then
|
|
||||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
|
|
||||||
print(("Wrote a BIN dump to the file %s"):format(foo))
|
|
||||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
|
|
||||||
print(("Wrote a EML dump to the file %s"):format(bar))
|
|
||||||
end
|
|
||||||
|
|
||||||
local uid = block0:sub(1,8)
|
local uid = block0:sub(1,8)
|
||||||
local itemtype = block1:sub(1,4)
|
local itemtype = block1:sub(1,4)
|
||||||
local cardid = block1:sub(9,24)
|
local cardid = block1:sub(9,24)
|
||||||
|
|
||||||
|
-- Write dump to files
|
||||||
|
if not DEBUG then
|
||||||
|
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin')
|
||||||
|
print(("Wrote a BIN dump to the file %s"):format(foo))
|
||||||
|
local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml')
|
||||||
|
print(("Wrote a EML dump to the file %s"):format(bar))
|
||||||
|
end
|
||||||
|
|
||||||
-- Show info
|
-- Show info
|
||||||
print( string.rep('--',20) )
|
print( string.rep('--',20) )
|
||||||
print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
|
print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
|
||||||
|
|
|
@ -241,18 +241,20 @@ local function main(args)
|
||||||
local cmdSetDbgOff = "hf mf dbg 0"
|
local cmdSetDbgOff = "hf mf dbg 0"
|
||||||
core.console( cmdSetDbgOff)
|
core.console( cmdSetDbgOff)
|
||||||
|
|
||||||
-- Look for tag present on reader,
|
-- if not loadFromDump then
|
||||||
result, err = lib14a.read1443a(false)
|
-- -- Look for tag present on reader,
|
||||||
if not result then return oops(err) end
|
-- result, err = lib14a.read1443a(false)
|
||||||
|
-- if not result then return oops(err) end
|
||||||
|
|
||||||
core.clearCommandBuffer()
|
-- core.clearCommandBuffer()
|
||||||
|
|
||||||
if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
|
-- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
|
||||||
return oops('This is not a TNP3xxx tag. aborting.')
|
-- return oops('This is not a TNP3xxx tag. aborting.')
|
||||||
end
|
-- end
|
||||||
|
|
||||||
-- Show tag info
|
-- -- Show tag info
|
||||||
print((' Found tag : %s'):format(result.name))
|
-- print((' Found tag : %s'):format(result.name))
|
||||||
|
-- end
|
||||||
|
|
||||||
-- Load dump.bin file
|
-- Load dump.bin file
|
||||||
print( (' Load data from %s'):format(inputTemplate))
|
print( (' Load data from %s'):format(inputTemplate))
|
||||||
|
@ -349,7 +351,7 @@ local function main(args)
|
||||||
err = LoadEmulator(blocks)
|
err = LoadEmulator(blocks)
|
||||||
if err then return oops(err) end
|
if err then return oops(err) end
|
||||||
core.clearCommandBuffer()
|
core.clearCommandBuffer()
|
||||||
print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
|
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..' x\" <--')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
main(args)
|
main(args)
|
132
client/scripts/tracetest.lua
Normal file
132
client/scripts/tracetest.lua
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
local cmds = require('commands')
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local bin = require('bin')
|
||||||
|
local utils = require('utils')
|
||||||
|
local dumplib = require('html_dumplib')
|
||||||
|
|
||||||
|
example =[[
|
||||||
|
1. script run tracetest
|
||||||
|
2. script run tracetest -o
|
||||||
|
|
||||||
|
]]
|
||||||
|
author = "Iceman"
|
||||||
|
usage = "script run tracetest -o <filename>"
|
||||||
|
desc =[[
|
||||||
|
This script will load several traces files in ../traces/ folder and do
|
||||||
|
"data load"
|
||||||
|
"lf search"
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
-h : this help
|
||||||
|
-o : logfile name
|
||||||
|
]]
|
||||||
|
|
||||||
|
local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
|
||||||
|
local DEBUG = true -- the debug flag
|
||||||
|
---
|
||||||
|
-- A debug printout-function
|
||||||
|
function dbg(args)
|
||||||
|
if not DEBUG then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(args) == "table" then
|
||||||
|
local i = 1
|
||||||
|
while result[i] do
|
||||||
|
dbg(result[i])
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("###", args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- This is only meant to be used when errors occur
|
||||||
|
function oops(err)
|
||||||
|
print("ERROR: ",err)
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- Usage help
|
||||||
|
function help()
|
||||||
|
print(desc)
|
||||||
|
print("Example usage")
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
--
|
||||||
|
-- Exit message
|
||||||
|
function ExitMsg(msg)
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print(msg)
|
||||||
|
print()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function main(args)
|
||||||
|
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
|
local cmdDataLoad = 'data load %s';
|
||||||
|
local tracesEM = "find '../traces/' -iname 'em*.pm3' -type f"
|
||||||
|
local tracesMOD = "find '../traces/' -iname 'm*.pm3' -type f"
|
||||||
|
|
||||||
|
local outputTemplate = os.date("testtest_%Y-%m-%d_%H%M%S")
|
||||||
|
|
||||||
|
-- Arguments for the script
|
||||||
|
for o, arg in getopt.getopt(args, 'ho:') do
|
||||||
|
if o == "h" then return help() end
|
||||||
|
if o == "o" then outputTemplate = arg end
|
||||||
|
end
|
||||||
|
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
|
local files = {}
|
||||||
|
|
||||||
|
-- Find a set of traces staring with EM
|
||||||
|
local p = assert( io.popen(tracesEM))
|
||||||
|
for file in p:lines() do
|
||||||
|
table.insert(files, file)
|
||||||
|
end
|
||||||
|
p.close();
|
||||||
|
|
||||||
|
-- Find a set of traces staring with MOD
|
||||||
|
p = assert( io.popen(tracesMOD) )
|
||||||
|
for file in p:lines() do
|
||||||
|
table.insert(files, file)
|
||||||
|
end
|
||||||
|
p.close();
|
||||||
|
|
||||||
|
local cmdLFSEARCH = "lf search 1"
|
||||||
|
|
||||||
|
-- main loop
|
||||||
|
io.write('Starting to test traces > ')
|
||||||
|
for _,file in pairs(files) do
|
||||||
|
|
||||||
|
local x = "data load "..file
|
||||||
|
dbg(x)
|
||||||
|
core.console(x)
|
||||||
|
|
||||||
|
dbg(cmdLFSEARCH)
|
||||||
|
core.console(cmdLFSEARCH)
|
||||||
|
|
||||||
|
core.clearCommandBuffer()
|
||||||
|
|
||||||
|
if core.ukbhit() then
|
||||||
|
print("aborted by user")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
io.write('\n')
|
||||||
|
|
||||||
|
-- Write dump to files
|
||||||
|
if not DEBUG then
|
||||||
|
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.txt')
|
||||||
|
print(("Wrote output to: %s"):format(bar))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Show info
|
||||||
|
print( string.rep('--',20) )
|
||||||
|
|
||||||
|
end
|
||||||
|
main(args)
|
|
@ -33,8 +33,8 @@
|
||||||
#ifndef _PROXMARK_CMD_H_
|
#ifndef _PROXMARK_CMD_H_
|
||||||
#define _PROXMARK_CMD_H_
|
#define _PROXMARK_CMD_H_
|
||||||
|
|
||||||
#include <common.h>
|
#include "common.h"
|
||||||
#include <usb_cmd.h>
|
#include "usb_cmd.h"
|
||||||
#include "usb_cdc.h"
|
#include "usb_cdc.h"
|
||||||
|
|
||||||
bool cmd_receive(UsbCommand* cmd);
|
bool cmd_receive(UsbCommand* cmd);
|
||||||
|
|
809
common/lfdemod.c
809
common/lfdemod.c
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,11 @@
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
// the license.
|
// the license.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Low frequency commands
|
// Low frequency demod related commands
|
||||||
|
// marshmellow
|
||||||
|
// note that many of these demods are not the slickest code and they often rely
|
||||||
|
// on peaks and clock instead of converting to clean signal.
|
||||||
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef LFDEMOD_H__
|
#ifndef LFDEMOD_H__
|
||||||
|
@ -13,17 +17,29 @@
|
||||||
|
|
||||||
int DetectASKClock(uint8_t dest[], size_t size, int clock);
|
int DetectASKClock(uint8_t dest[], size_t size, int clock);
|
||||||
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
||||||
uint64_t Em410xDecode(uint8_t *BitStream,size_t size);
|
uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
|
||||||
|
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||||
int manrawdecode(uint8_t *BitStream, size_t *size);
|
int manrawdecode(uint8_t *BitStream, size_t *size);
|
||||||
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset);
|
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
||||||
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
||||||
int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||||
int IOdemodFSK(uint8_t *dest, size_t size);
|
int IOdemodFSK(uint8_t *dest, size_t size);
|
||||||
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
||||||
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
|
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
|
||||||
int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
|
int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
|
||||||
|
void psk1TOpsk2(uint8_t *BitStream, size_t size);
|
||||||
int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
|
int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
|
||||||
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||||
void pskCleanWave(uint8_t *bitStream, size_t size);
|
void pskCleanWave(uint8_t *bitStream, size_t size);
|
||||||
|
int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
||||||
|
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
||||||
|
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
||||||
|
uint16_t countFC(uint8_t *BitStream, size_t size);
|
||||||
|
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
|
||||||
|
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||||
|
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||||
|
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||||
|
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||||
|
uint8_t justNoise(uint8_t *BitStream, size_t size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -370,7 +370,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
|
||||||
//* \fn AT91F_USB_SendData
|
//* \fn AT91F_USB_SendData
|
||||||
//* \brief Send Data through the control endpoint
|
//* \brief Send Data through the control endpoint
|
||||||
//*----------------------------------------------------------------------------
|
//*----------------------------------------------------------------------------
|
||||||
unsigned int csrTab[100];
|
unsigned int csrTab[100] = {0x00};
|
||||||
unsigned char csrIdx = 0;
|
unsigned char csrIdx = 0;
|
||||||
|
|
||||||
static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
|
static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#ifndef _USB_CDC_H_
|
#ifndef _USB_CDC_H_
|
||||||
#define _USB_CDC_H_
|
#define _USB_CDC_H_
|
||||||
|
|
||||||
#include <common.h>
|
#include "common.h"
|
||||||
|
|
||||||
void usb_disable();
|
void usb_disable();
|
||||||
void usb_enable();
|
void usb_enable();
|
||||||
|
|
20000
traces/AWID-15-259.pm3
Normal file
20000
traces/AWID-15-259.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/HID-weak-fob-11647.pm3
Normal file
20000
traces/HID-weak-fob-11647.pm3
Normal file
File diff suppressed because it is too large
Load diff
16000
traces/Paradox-96_40426-APJN08.pm3
Normal file
16000
traces/Paradox-96_40426-APJN08.pm3
Normal file
File diff suppressed because it is too large
Load diff
|
@ -22,3 +22,5 @@ EM4102-Fob.pm3: (ID: 0400193cbe)
|
||||||
ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name
|
ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name
|
||||||
ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name
|
ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name
|
||||||
indala-504278295.pm3: PSK 26 bit indala
|
indala-504278295.pm3: PSK 26 bit indala
|
||||||
|
AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259
|
||||||
|
HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable.
|
20000
traces/modulation-ask-biph-50.pm3
Normal file
20000
traces/modulation-ask-biph-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-100.pm3
Normal file
20000
traces/modulation-ask-man-100.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-128.pm3
Normal file
20000
traces/modulation-ask-man-128.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-16.pm3
Normal file
20000
traces/modulation-ask-man-16.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-32.pm3
Normal file
20000
traces/modulation-ask-man-32.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-40.pm3
Normal file
20000
traces/modulation-ask-man-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-8.pm3
Normal file
20000
traces/modulation-ask-man-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-32.pm3
Normal file
20000
traces/modulation-direct-32.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-40.pm3
Normal file
20000
traces/modulation-direct-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-50.pm3
Normal file
20000
traces/modulation-direct-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk1-50.pm3
Normal file
20000
traces/modulation-fsk1-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk1a-50.pm3
Normal file
20000
traces/modulation-fsk1a-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2-50.pm3
Normal file
20000
traces/modulation-fsk2-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2a-40.pm3
Normal file
20000
traces/modulation-fsk2a-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2a-50.pm3
Normal file
20000
traces/modulation-fsk2a-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk1-32-4.pm3
Normal file
20000
traces/modulation-psk1-32-4.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk1-64-8.pm3
Normal file
20000
traces/modulation-psk1-64-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk2-32-2.pm3
Normal file
20000
traces/modulation-psk2-32-2.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk3-32-8.pm3
Normal file
20000
traces/modulation-psk3-32-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue