Merge branch 'master' of https://github.com/Proxmark/proxmark3
Conflicts: armsrc/Makefile armsrc/appmain.c armsrc/apps.h armsrc/epa.c armsrc/iclass.c armsrc/iso14443a.c armsrc/iso14443a.h armsrc/iso15693.c armsrc/lfops.c armsrc/mifarecmd.c armsrc/mifareutil.c armsrc/mifareutil.h armsrc/string.h armsrc/util.h bootrom/bootrom.c client/Makefile client/cmddata.c client/cmddata.h client/cmdhf.c client/cmdhf14a.c client/cmdhf14b.c client/cmdhf15.c client/cmdhficlass.c client/cmdhfmf.c client/cmdhfmfu.c client/cmdlf.c client/cmdlfem4x.c client/cmdlfhid.c client/cmdlfhitag.c client/cmdlfio.c client/cmdmain.c client/data.h client/flash.c client/graph.c client/graph.h client/loclass/elite_crack.c client/loclass/fileutils.c client/lualibs/commands.lua client/lualibs/html_dumplib.lua client/lualibs/mf_default_keys.lua client/lualibs/utils.lua client/mifarehost.c client/nonce2key/crapto1.c client/proxmark3.c client/scripting.c client/scripts/tnp3dump.lua client/scripts/tnp3sim.lua client/scripts/tracetest.lua common/Makefile.common common/cmd.c common/cmd.h common/lfdemod.c common/lfdemod.h common/usb_cdc.c common/usb_cdc.h include/usb_cmd.h
This commit is contained in:
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 */
|
||||
@@ -16,9 +16,9 @@ APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_
|
||||
#SRC_LCD = fonts.c LCD.c
|
||||
SRC_LF = lfops.c hitag2.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||
SRC_ISO14443b = iso14443.c
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c
|
||||
SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||
SRC_ISO14443b = iso14443.c
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c des.c aes.c
|
||||
SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c
|
||||
|
||||
THUMBSRC = start.c \
|
||||
@@ -41,7 +41,8 @@ ARMSRC = fpgaloader.c \
|
||||
$(SRC_CRAPTO1) \
|
||||
$(SRC_CRC) \
|
||||
legic_prng.c \
|
||||
iclass.c
|
||||
iclass.c \
|
||||
BigBuf.c \
|
||||
|
||||
|
||||
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
|
||||
|
||||
@@ -36,18 +36,12 @@
|
||||
// is the order in which they go out on the wire.
|
||||
//=============================================================================
|
||||
|
||||
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
||||
#define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
|
||||
uint8_t ToSend[TOSEND_BUFFER_SIZE];
|
||||
int ToSendMax;
|
||||
static int ToSendBit;
|
||||
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)
|
||||
{
|
||||
ToSendMax = -1;
|
||||
@@ -68,7 +62,7 @@ void ToSendStuffBit(int b)
|
||||
|
||||
ToSendBit++;
|
||||
|
||||
if(ToSendMax >= sizeof(ToSend)) {
|
||||
if(ToSendMax >= sizeof(ToSend)) {
|
||||
ToSendBit = 0;
|
||||
DbpString("ToSendStuffBit overflowed!");
|
||||
}
|
||||
@@ -246,7 +240,10 @@ void MeasureAntennaTuningHf(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;
|
||||
int i;
|
||||
int p = 0;
|
||||
@@ -281,7 +278,7 @@ void SimulateTagHfListen(void)
|
||||
p = 0;
|
||||
i++;
|
||||
|
||||
if(i >= FREE_BUFFER_SIZE) {
|
||||
if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -811,11 +808,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
MifareUC_Auth2(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
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;
|
||||
case CMD_MIFAREUC_READCARD:
|
||||
MifareUReadCard(c->arg[0],c->arg[1],c->d.asBytes);
|
||||
break;
|
||||
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFARE_READSC:
|
||||
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
@@ -870,27 +867,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_MIFARE_SNIFFER:
|
||||
SniffMifare(c->arg[0]);
|
||||
break;
|
||||
|
||||
// mifare desfire
|
||||
case CMD_MIFARE_DESFIRE_READBL:
|
||||
break;
|
||||
case CMD_MIFARE_DESFIRE_WRITEBL:
|
||||
break;
|
||||
case CMD_MIFARE_DESFIRE_AUTH1:
|
||||
MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFARE_DESFIRE_AUTH2:
|
||||
//MifareDES_Auth2(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
// case CMD_MIFARE_DES_READER:
|
||||
// ReaderMifareDES(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
//break;
|
||||
case CMD_MIFARE_DESFIRE_INFO:
|
||||
MifareDesfireGetInformation();
|
||||
break;
|
||||
case CMD_MIFARE_DESFIRE:
|
||||
MifareSendCommand(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -915,7 +891,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
break;
|
||||
|
||||
case CMD_BUFF_CLEAR:
|
||||
BufferClear();
|
||||
BigBuf_Clear();
|
||||
break;
|
||||
|
||||
case CMD_MEASURE_ANTENNA_TUNING:
|
||||
@@ -939,17 +915,18 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
|
||||
|
||||
LED_B_ON();
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
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);
|
||||
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
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
cmd_send(CMD_ACK,0,0,traceLen,0,0);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
|
||||
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);
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
break;
|
||||
|
||||
@@ -18,40 +18,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "../include/common.h"
|
||||
#include "../include/hitag2.h"
|
||||
#include "../include/mifare.h"
|
||||
|
||||
//#include <openssl/des.h>
|
||||
//#include <openssl/aes.h>
|
||||
//#include "des.h"
|
||||
//#include "aes.h"
|
||||
#include "../common/desfire.h"
|
||||
#include "../common/crc32.h"
|
||||
|
||||
// The large multi-purpose buffer, typically used to hold A/D samples,
|
||||
// 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)
|
||||
#include "BigBuf.h"
|
||||
|
||||
extern const uint8_t OddByteParity[256];
|
||||
extern uint8_t *trace; // = (uint8_t *) BigBuf;
|
||||
extern int traceLen; // = 0;
|
||||
extern int rsamples; // = 0;
|
||||
extern int tracing; // = TRUE;
|
||||
extern uint8_t trigger;
|
||||
@@ -82,7 +52,6 @@ void DoAcquisition125k();
|
||||
|
||||
extern int ToSendMax;
|
||||
extern uint8_t ToSend[];
|
||||
extern uint32_t BigBuf[];
|
||||
|
||||
/// fpga.h
|
||||
void FpgaSendCommand(uint16_t cmd, uint16_t v);
|
||||
@@ -130,6 +99,8 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0)
|
||||
#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5//101
|
||||
|
||||
// Options for ISO14443A
|
||||
#define FPGA_HF_ISO14443A_SNIFFER (0<<0)
|
||||
#define FPGA_HF_ISO14443A_TAGSIM_LISTEN (1<<0)
|
||||
@@ -181,7 +152,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data);
|
||||
void ReaderIso14443a(UsbCommand * c);
|
||||
// Also used in iclass.c
|
||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
||||
void GetParity(const uint8_t * pbtCmd, uint16_t len, uint8_t *parity);
|
||||
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
|
||||
void iso14a_set_trigger(bool enable);
|
||||
void iso14a_clear_trace();
|
||||
void iso14a_set_tracing(bool enable);
|
||||
@@ -231,17 +202,6 @@ void OnError(uint8_t reason);
|
||||
|
||||
|
||||
|
||||
// desfire_crypto.h
|
||||
void *mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, off_t offset, int communication_settings);
|
||||
void *mifare_cryto_postprocess_data (desfiretag_t tag, void *data, ssize_t *nbytes, int communication_settings);
|
||||
void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size);
|
||||
void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation);
|
||||
size_t key_block_size (const desfirekey_t key);
|
||||
size_t padded_data_length (const size_t nbytes, const size_t block_size);
|
||||
size_t maced_data_length (const desfirekey_t key, const size_t nbytes);
|
||||
size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings);
|
||||
void cmac_generate_subkeys (desfirekey_t key);
|
||||
void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
|
||||
|
||||
|
||||
/// iso15693.h
|
||||
|
||||
@@ -435,6 +435,8 @@ int EPA_Setup()
|
||||
|
||||
iso14a_set_timeout(10500);
|
||||
|
||||
iso14a_set_timeout(10500);
|
||||
|
||||
// select the card
|
||||
return_code = iso14443a_select_card(uid, &card_select_info, NULL);
|
||||
if (return_code != 1) {
|
||||
|
||||
116
armsrc/hitag2.c
116
armsrc/hitag2.c
@@ -24,15 +24,19 @@
|
||||
|
||||
static bool bQuiet;
|
||||
|
||||
bool bCrypto;
|
||||
bool bAuthenticating;
|
||||
bool bPwd;
|
||||
bool bSuccessful;
|
||||
static bool bCrypto;
|
||||
static bool bAuthenticating;
|
||||
static bool bPwd;
|
||||
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
|
||||
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
|
||||
rsamples += iSamples;
|
||||
@@ -85,21 +89,17 @@ static struct hitag2_tag tag = {
|
||||
},
|
||||
};
|
||||
|
||||
//#define TRACE_LENGTH 3000
|
||||
//uint8_t *trace = (uint8_t *) BigBuf;
|
||||
//int traceLen = 0;
|
||||
//int rsamples = 0;
|
||||
// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
|
||||
// Historically it used to be FREE_BUFFER_SIZE, which was 2744.
|
||||
#define AUTH_TABLE_LENGTH 2744
|
||||
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
|
||||
#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE
|
||||
byte_t* auth_table = (byte_t *)BigBuf+AUTH_TABLE_OFFSET;
|
||||
size_t auth_table_pos = 0;
|
||||
size_t auth_table_len = AUTH_TABLE_LENGTH;
|
||||
|
||||
byte_t password[4];
|
||||
byte_t NrAr[8];
|
||||
byte_t key[8];
|
||||
uint64_t cipher_state;
|
||||
static byte_t password[4];
|
||||
static byte_t NrAr[8];
|
||||
static byte_t key[8];
|
||||
static uint64_t cipher_state;
|
||||
|
||||
/* 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.
|
||||
@@ -177,14 +177,14 @@ static u32 _hitag2_byte (u64 * x)
|
||||
return c;
|
||||
}
|
||||
|
||||
int hitag2_reset(void)
|
||||
static int hitag2_reset(void)
|
||||
{
|
||||
tag.state = TAG_STATE_RESET;
|
||||
tag.crypto_active = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hitag2_init(void)
|
||||
static int hitag2_init(void)
|
||||
{
|
||||
// memcpy(&tag, &resetdata, sizeof(tag));
|
||||
hitag2_reset();
|
||||
@@ -300,7 +300,8 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
|
||||
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];
|
||||
|
||||
@@ -457,6 +458,7 @@ static void hitag_reader_send_bit(int bit) {
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
|
||||
{
|
||||
// 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;
|
||||
|
||||
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
|
||||
*txlen = 0;
|
||||
|
||||
@@ -530,7 +532,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
|
||||
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
|
||||
*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
|
||||
*txlen = 0;
|
||||
|
||||
@@ -663,7 +665,9 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
|
||||
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
|
||||
*txlen = 0;
|
||||
|
||||
@@ -675,17 +679,17 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||
if (bCrypto) {
|
||||
Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]);
|
||||
|
||||
// Removing failed entry from authentiations table
|
||||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
||||
auth_table_len -= 8;
|
||||
// Removing failed entry from authentiations table
|
||||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,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;
|
||||
if (auth_table_pos == auth_table_len) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry)
|
||||
|
||||
// Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry)
|
||||
memcpy(NrAr,auth_table+auth_table_pos,8);
|
||||
}
|
||||
*txlen = 5;
|
||||
@@ -718,6 +722,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void SnoopHitag(uint32_t type) {
|
||||
int frame_count;
|
||||
int response;
|
||||
@@ -730,13 +735,15 @@ void SnoopHitag(uint32_t type) {
|
||||
byte_t rx[HITAG_FRAME_LEN];
|
||||
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
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
DbpString("Starting Hitag2 snoop");
|
||||
LED_D_ON();
|
||||
@@ -760,7 +767,7 @@ void SnoopHitag(uint32_t type) {
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
|
||||
// Disable timer during configuration
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
@@ -940,13 +947,17 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||
bool bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
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
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
DbpString("Starting Hitag2 simulation");
|
||||
LED_D_ON();
|
||||
hitag2_init();
|
||||
@@ -1126,21 +1137,22 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
bool bStop;
|
||||
bool bQuitTraceFull = false;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
DbpString("Starting Hitag reader family");
|
||||
|
||||
// Check configuration
|
||||
switch(htf) {
|
||||
case RHT2F_PASSWORD: {
|
||||
Dbprintf("List identifier in password mode");
|
||||
Dbprintf("List identifier in password mode");
|
||||
memcpy(password,htd->pwd.password,4);
|
||||
blocknr = 0;
|
||||
blocknr = 0;
|
||||
bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
bPwd = false;
|
||||
@@ -1152,7 +1164,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
Dbhexdump(8,NrAr,false);
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
bAuthenticating = false;
|
||||
bQuitTraceFull = true;
|
||||
} break;
|
||||
|
||||
@@ -1160,17 +1172,17 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
||||
DbpString("Authenticating using key:");
|
||||
memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code.
|
||||
Dbhexdump(6,key,false);
|
||||
blocknr = 0;
|
||||
blocknr = 0;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
bAuthenticating = false;
|
||||
bQuitTraceFull = true;
|
||||
} break;
|
||||
|
||||
case RHT2F_TEST_AUTH_ATTEMPTS: {
|
||||
Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
|
||||
auth_table_pos = 0;
|
||||
memcpy(NrAr,auth_table,8);
|
||||
memcpy(NrAr, auth_table, 8);
|
||||
bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
|
||||
288
armsrc/iclass.c
288
armsrc/iclass.c
@@ -435,7 +435,7 @@ static RAMFUNC int ManchesterDecoding(int v)
|
||||
else {
|
||||
modulation = bit & Demod.syncBit;
|
||||
modulation |= ((bit << 1) ^ ((Demod.buffer & 0x08) >> 3)) & Demod.syncBit;
|
||||
|
||||
|
||||
Demod.samples += 4;
|
||||
|
||||
if(Demod.posCount==0) {
|
||||
@@ -642,21 +642,25 @@ void RAMFUNC SnoopIClass(void)
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// 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.
|
||||
uint8_t *tagToReaderResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
|
||||
uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE];
|
||||
|
||||
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
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
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;
|
||||
int8_t *upTo;
|
||||
uint8_t *upTo;
|
||||
int smpl;
|
||||
int maxBehindBy = 0;
|
||||
|
||||
@@ -689,7 +693,8 @@ void RAMFUNC SnoopIClass(void)
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
uint32_t time_0 = GetCountSspClk();
|
||||
|
||||
uint32_t time_start = 0;
|
||||
uint32_t time_stop = 0;
|
||||
|
||||
int div = 0;
|
||||
//int div2 = 0;
|
||||
@@ -704,7 +709,7 @@ void RAMFUNC SnoopIClass(void)
|
||||
(DMA_BUFFER_SIZE-1);
|
||||
if(behindBy > maxBehindBy) {
|
||||
maxBehindBy = behindBy;
|
||||
if(behindBy > 400) {
|
||||
if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||
goto done;
|
||||
}
|
||||
@@ -740,14 +745,15 @@ void RAMFUNC SnoopIClass(void)
|
||||
smpl = decbyter;
|
||||
if(OutOfNDecoding((smpl & 0xF0) >> 4)) {
|
||||
rsamples = samples - Uart.samples;
|
||||
time_stop = (GetCountSspClk()-time_0) << 4;
|
||||
LED_C_ON();
|
||||
|
||||
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,TRUE)) break;
|
||||
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, TRUE)) break;
|
||||
if(tracing) {
|
||||
if(tracing) {
|
||||
uint8_t parity[MAX_PARITY_SIZE];
|
||||
GetParity(Uart.output, Uart.byteCnt, parity);
|
||||
LogTrace(Uart.output,Uart.byteCnt, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, TRUE);
|
||||
LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@@ -758,6 +764,8 @@ void RAMFUNC SnoopIClass(void)
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
LED_B_OFF();
|
||||
Uart.byteCnt = 0;
|
||||
}else{
|
||||
time_start = (GetCountSspClk()-time_0) << 4;
|
||||
}
|
||||
decbyter = 0;
|
||||
}
|
||||
@@ -765,21 +773,24 @@ void RAMFUNC SnoopIClass(void)
|
||||
if(div > 3) {
|
||||
smpl = decbyte;
|
||||
if(ManchesterDecoding(smpl & 0x0F)) {
|
||||
time_stop = (GetCountSspClk()-time_0) << 4;
|
||||
|
||||
rsamples = samples - Demod.samples;
|
||||
LED_B_ON();
|
||||
|
||||
if(tracing) {
|
||||
if(tracing) {
|
||||
uint8_t parity[MAX_PARITY_SIZE];
|
||||
GetParity(Demod.output, Demod.len, parity);
|
||||
LogTrace(Demod.output, Demod.len, (GetCountSspClk()-time_0) << 4, (GetCountSspClk()-time_0) << 4, parity, FALSE);
|
||||
LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, FALSE);
|
||||
}
|
||||
|
||||
|
||||
// And ready to receive another response.
|
||||
memset(&Demod, 0, sizeof(Demod));
|
||||
Demod.output = tagToReaderResponse;
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
LED_C_OFF();
|
||||
}else{
|
||||
time_start = (GetCountSspClk()-time_0) << 4;
|
||||
}
|
||||
|
||||
div = 0;
|
||||
@@ -852,57 +863,93 @@ static int GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t encode4Bits(const uint8_t b)
|
||||
{
|
||||
uint8_t c = b & 0xF;
|
||||
// OTA, the least significant bits first
|
||||
// The columns are
|
||||
// 1 - Bit value to send
|
||||
// 2 - Reversed (big-endian)
|
||||
// 3 - Encoded
|
||||
// 4 - Hex values
|
||||
|
||||
switch(c){
|
||||
// 1 2 3 4
|
||||
case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
|
||||
case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
|
||||
case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
|
||||
case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
|
||||
case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
|
||||
case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
|
||||
case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
|
||||
case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9
|
||||
case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56
|
||||
case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96
|
||||
case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66
|
||||
case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6
|
||||
case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a
|
||||
case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a
|
||||
case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a
|
||||
default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Prepare tag messages
|
||||
//-----------------------------------------------------------------------------
|
||||
static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
|
||||
{
|
||||
//So far a dummy implementation, not used
|
||||
//int lastProxToAirDuration =0;
|
||||
|
||||
/*
|
||||
* SOF comprises 3 parts;
|
||||
* * An unmodulated time of 56.64 us
|
||||
* * 24 pulses of 423.75 KHz (fc/32)
|
||||
* * A logic 1, which starts with an unmodulated time of 18.88us
|
||||
* followed by 8 pulses of 423.75kHz (fc/32)
|
||||
*
|
||||
*
|
||||
* EOF comprises 3 parts:
|
||||
* - A logic 0 (which starts with 8 pulses of fc/32 followed by an unmodulated
|
||||
* time of 18.88us.
|
||||
* - 24 pulses of fc/32
|
||||
* - An unmodulated time of 56.64 us
|
||||
*
|
||||
*
|
||||
* A logic 0 starts with 8 pulses of fc/32
|
||||
* followed by an unmodulated time of 256/fc (~18,88us).
|
||||
*
|
||||
* A logic 0 starts with unmodulated time of 256/fc (~18,88us) followed by
|
||||
* 8 pulses of fc/32 (also 18.88us)
|
||||
*
|
||||
* The mode FPGA_HF_SIMULATOR_MODULATE_424K_8BIT which we use to simulate tag,
|
||||
* works like this.
|
||||
* - A 1-bit input to the FPGA becomes 8 pulses on 423.5kHz (fc/32) (18.88us).
|
||||
* - A 0-bit inptu to the FPGA becomes an unmodulated time of 18.88us
|
||||
*
|
||||
* In this mode the SOF can be written as 00011101 = 0x1D
|
||||
* The EOF can be written as 10111000 = 0xb8
|
||||
* A logic 1 is 01
|
||||
* A logic 0 is 10
|
||||
*
|
||||
* */
|
||||
|
||||
int i;
|
||||
|
||||
ToSendReset();
|
||||
|
||||
// Send SOF
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;//Proxtoair duration starts here
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x1D;
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
int j;
|
||||
uint8_t b = cmd[i];
|
||||
|
||||
// Data bits
|
||||
for(j = 0; j < 8; j++) {
|
||||
if(b & 1) {
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
} else {
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half
|
||||
ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Send EOF
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
|
||||
ToSend[++ToSendMax] = 0xB8;
|
||||
//lastProxToAirDuration = 8*ToSendMax - 3*8 - 3*8;//Not counting zeroes in the beginning or end
|
||||
|
||||
// Convert from last byte pos to length
|
||||
ToSendMax++;
|
||||
}
|
||||
@@ -915,21 +962,13 @@ static void CodeIClassTagSOF()
|
||||
|
||||
ToSendReset();
|
||||
// Send SOF
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
ToSend[++ToSendMax] = 0x00;
|
||||
ToSend[++ToSendMax] = 0xff;
|
||||
|
||||
ToSend[++ToSendMax] = 0x1D;
|
||||
// lastProxToAirDuration = 8*ToSendMax - 3*8;//Not counting zeroes in the beginning
|
||||
|
||||
|
||||
// Convert from last byte pos to length
|
||||
ToSendMax++;
|
||||
}
|
||||
|
||||
int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf);
|
||||
/**
|
||||
* @brief SimulateIClass simulates an iClass card.
|
||||
@@ -965,7 +1004,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||
else if(simType == 2)
|
||||
{
|
||||
|
||||
uint8_t mac_responses[64] = { 0 };
|
||||
uint8_t mac_responses[USB_CMD_DATA_SIZE] = { 0 };
|
||||
Dbprintf("Going into attack mode, %d CSNS sent", numberOfCSNS);
|
||||
// In this mode, a number of csns are within datain. We'll simulate each one, one at a time
|
||||
// in order to collect MAC's from the reader. This can later be used in an offlne-attack
|
||||
@@ -978,6 +1017,7 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||
memcpy(csn_crc, datain+(i*8), 8);
|
||||
if(doIClassSimulation(csn_crc,1,mac_responses+i*8))
|
||||
{
|
||||
cmd_send(CMD_ACK,CMD_SIMULATE_TAG_ICLASS,i,0,mac_responses,i*8);
|
||||
return; // Button pressed
|
||||
}
|
||||
}
|
||||
@@ -999,7 +1039,9 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
|
||||
*/
|
||||
int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader_mac_buf)
|
||||
{
|
||||
|
||||
// CSN followed by two CRC bytes
|
||||
uint8_t response1[] = { 0x0F} ;
|
||||
uint8_t response2[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t response3[] = { 0,0,0,0,0,0,0,0,0,0};
|
||||
memcpy(response3,csn,sizeof(response3));
|
||||
@@ -1022,33 +1064,34 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
// Reader 81 anticoll. CSN
|
||||
// Tag CSN
|
||||
|
||||
uint8_t *resp;
|
||||
int respLen;
|
||||
uint8_t* respdata = NULL;
|
||||
int respsize = 0;
|
||||
uint8_t sof = 0x0f;
|
||||
uint8_t *modulated_response;
|
||||
int modulated_response_size;
|
||||
uint8_t* trace_data = NULL;
|
||||
int trace_data_size = 0;
|
||||
//uint8_t sof = 0x0f;
|
||||
|
||||
// Respond SOF -- takes 8 bytes
|
||||
uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
// Respond SOF -- takes 1 bytes
|
||||
uint8_t *resp1 = BigBuf_malloc(2);
|
||||
int resp1Len;
|
||||
|
||||
// Anticollision CSN (rotated CSN)
|
||||
// 176: Takes 16 bytes for SOF/EOF and 10 * 16 = 160 bytes (2 bytes/bit)
|
||||
uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 10);
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp2 = BigBuf_malloc(28);
|
||||
int resp2Len;
|
||||
|
||||
// CSN
|
||||
// 176: Takes 16 bytes for SOF/EOF and 10 * 16 = 160 bytes (2 bytes/bit)
|
||||
uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 190);
|
||||
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte)
|
||||
uint8_t *resp3 = BigBuf_malloc(30);
|
||||
int resp3Len;
|
||||
|
||||
// e-Purse
|
||||
// 144: Takes 16 bytes for SOF/EOF and 8 * 16 = 128 bytes (2 bytes/bit)
|
||||
uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 370);
|
||||
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/bit)
|
||||
uint8_t *resp4 = BigBuf_malloc(20);
|
||||
int resp4Len;
|
||||
|
||||
// + 1720..
|
||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
|
||||
int len;
|
||||
|
||||
@@ -1091,11 +1134,6 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
LED_A_ON();
|
||||
bool buttonPressed = false;
|
||||
|
||||
/** Hack for testing
|
||||
memcpy(reader_mac_buf,csn,8);
|
||||
exitLoop = true;
|
||||
end hack **/
|
||||
|
||||
while(!exitLoop) {
|
||||
|
||||
LED_B_OFF();
|
||||
@@ -1114,35 +1152,35 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
// Okay, look at the command now.
|
||||
if(receivedCmd[0] == 0x0a ) {
|
||||
// Reader in anticollission phase
|
||||
resp = resp1; respLen = resp1Len; //order = 1;
|
||||
respdata = &sof;
|
||||
respsize = sizeof(sof);
|
||||
modulated_response = resp1; modulated_response_size = resp1Len; //order = 1;
|
||||
trace_data = response1;
|
||||
trace_data_size = sizeof(response1);
|
||||
} else if(receivedCmd[0] == 0x0c) {
|
||||
// Reader asks for anticollission CSN
|
||||
resp = resp2; respLen = resp2Len; //order = 2;
|
||||
respdata = response2;
|
||||
respsize = sizeof(response2);
|
||||
modulated_response = resp2; modulated_response_size = resp2Len; //order = 2;
|
||||
trace_data = response2;
|
||||
trace_data_size = sizeof(response2);
|
||||
//DbpString("Reader requests anticollission CSN:");
|
||||
} else if(receivedCmd[0] == 0x81) {
|
||||
// Reader selects anticollission CSN.
|
||||
// Tag sends the corresponding real CSN
|
||||
resp = resp3; respLen = resp3Len; //order = 3;
|
||||
respdata = response3;
|
||||
respsize = sizeof(response3);
|
||||
modulated_response = resp3; modulated_response_size = resp3Len; //order = 3;
|
||||
trace_data = response3;
|
||||
trace_data_size = sizeof(response3);
|
||||
//DbpString("Reader selects anticollission CSN:");
|
||||
} else if(receivedCmd[0] == 0x88) {
|
||||
// Read e-purse (88 02)
|
||||
resp = resp4; respLen = resp4Len; //order = 4;
|
||||
respdata = response4;
|
||||
respsize = sizeof(response4);
|
||||
modulated_response = resp4; modulated_response_size = resp4Len; //order = 4;
|
||||
trace_data = response4;
|
||||
trace_data_size = sizeof(response4);
|
||||
LED_B_ON();
|
||||
} else if(receivedCmd[0] == 0x05) {
|
||||
// Reader random and reader MAC!!!
|
||||
// Do not respond
|
||||
// We do not know what to answer, so lets keep quiet
|
||||
resp = resp1; respLen = 0; //order = 5;
|
||||
respdata = NULL;
|
||||
respsize = 0;
|
||||
modulated_response = resp1; modulated_response_size = 0; //order = 5;
|
||||
trace_data = NULL;
|
||||
trace_data_size = 0;
|
||||
if (breakAfterMacReceived){
|
||||
// dbprintf:ing ...
|
||||
Dbprintf("CSN: %02x %02x %02x %02x %02x %02x %02x %02x"
|
||||
@@ -1159,9 +1197,9 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
}
|
||||
} else if(receivedCmd[0] == 0x00 && len == 1) {
|
||||
// Reader ends the session
|
||||
resp = resp1; respLen = 0; //order = 0;
|
||||
respdata = NULL;
|
||||
respsize = 0;
|
||||
modulated_response = resp1; modulated_response_size = 0; //order = 0;
|
||||
trace_data = NULL;
|
||||
trace_data_size = 0;
|
||||
} else {
|
||||
//#db# Unknown command received from reader (len=5): 26 1 0 f6 a 44 44 44 44
|
||||
// Never seen this command before
|
||||
@@ -1171,9 +1209,9 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
receivedCmd[3], receivedCmd[4], receivedCmd[5],
|
||||
receivedCmd[6], receivedCmd[7], receivedCmd[8]);
|
||||
// Do not respond
|
||||
resp = resp1; respLen = 0; //order = 0;
|
||||
respdata = NULL;
|
||||
respsize = 0;
|
||||
modulated_response = resp1; modulated_response_size = 0; //order = 0;
|
||||
trace_data = NULL;
|
||||
trace_data_size = 0;
|
||||
}
|
||||
|
||||
if(cmdsRecvd > 100) {
|
||||
@@ -1183,9 +1221,11 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
else {
|
||||
cmdsRecvd++;
|
||||
}
|
||||
|
||||
if(respLen > 0) {
|
||||
SendIClassAnswer(resp, respLen, 21);
|
||||
/**
|
||||
A legit tag has about 380us delay between reader EOT and tag SOF.
|
||||
**/
|
||||
if(modulated_response_size > 0) {
|
||||
SendIClassAnswer(modulated_response, modulated_response_size, 1);
|
||||
t2r_time = GetCountSspClk();
|
||||
}
|
||||
|
||||
@@ -1194,9 +1234,9 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
GetParity(receivedCmd, len, parity);
|
||||
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, TRUE);
|
||||
|
||||
if (respdata != NULL) {
|
||||
GetParity(respdata, respsize, parity);
|
||||
LogTrace(respdata, respsize, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
|
||||
if (trace_data != NULL) {
|
||||
GetParity(trace_data, trace_data_size, parity);
|
||||
LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, FALSE);
|
||||
}
|
||||
if(!tracing) {
|
||||
DbpString("Trace full");
|
||||
@@ -1210,6 +1250,8 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
|
||||
//Dbprintf("%x", cmdsRecvd);
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
if(buttonPressed)
|
||||
{
|
||||
DbpString("Button pressed");
|
||||
@@ -1222,7 +1264,8 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
|
||||
int i = 0, d=0;//, u = 0, d = 0;
|
||||
uint8_t b = 0;
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
|
||||
//FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR|FPGA_HF_SIMULATOR_MODULATE_424K_8BIT);
|
||||
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
FpgaSetupSsc();
|
||||
@@ -1246,7 +1289,8 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, int delay)
|
||||
AT91C_BASE_SSC->SSC_THR = b;
|
||||
}
|
||||
|
||||
if (i > respLen +4) break;
|
||||
// if (i > respLen +4) break;
|
||||
if (i > respLen +1) break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1267,7 +1311,7 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
|
||||
if (wait)
|
||||
{
|
||||
if(*wait < 10) *wait = 10;
|
||||
|
||||
|
||||
for(c = 0; c < *wait;) {
|
||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
|
||||
@@ -1373,7 +1417,7 @@ void ReaderTransmitIClass(uint8_t* frame, int len)
|
||||
LED_A_ON();
|
||||
|
||||
// Store reader command in buffer
|
||||
if (tracing) {
|
||||
if (tracing) {
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(frame, len, par);
|
||||
LogTrace(frame, len, rsamples, rsamples, par, TRUE);
|
||||
@@ -1433,10 +1477,10 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
|
||||
int samples = 0;
|
||||
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return FALSE;
|
||||
rsamples += samples;
|
||||
if (tracing){
|
||||
uint8_t parity[MAX_PARITY_SIZE];
|
||||
GetParity(receivedAnswer, Demod.len, parity);
|
||||
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE);
|
||||
if (tracing) {
|
||||
uint8_t parity[MAX_PARITY_SIZE];
|
||||
GetParity(receivedAnswer, Demod.len, parity);
|
||||
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,FALSE);
|
||||
}
|
||||
if(samples == 0) return FALSE;
|
||||
return Demod.len;
|
||||
@@ -1492,7 +1536,7 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
|
||||
static uint8_t identify[] = { 0x0c };
|
||||
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
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;
|
||||
|
||||
@@ -1539,7 +1583,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||
|
||||
uint8_t card_data[24]={0};
|
||||
uint8_t last_csn[8]={0};
|
||||
|
||||
|
||||
int read_status= 0;
|
||||
bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE;
|
||||
bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC;
|
||||
@@ -1550,11 +1594,11 @@ void ReaderIClass(uint8_t arg0) {
|
||||
while(!BUTTON_PRESS())
|
||||
{
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
WDT_HIT();
|
||||
WDT_HIT();
|
||||
|
||||
read_status = handshakeIclassTag(card_data);
|
||||
|
||||
@@ -1579,7 +1623,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||
}
|
||||
//If 'get_cc' was specified and we didn't get a CC, we'll just keep trying...
|
||||
}
|
||||
LED_B_OFF();
|
||||
LED_B_OFF();
|
||||
}
|
||||
cmd_send(CMD_ACK,0,0,0,card_data, 0);
|
||||
LED_A_OFF();
|
||||
@@ -1613,16 +1657,16 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||
int keyaccess;
|
||||
} memory;
|
||||
|
||||
uint8_t* resp = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
|
||||
uint8_t resp[ICLASS_BUFFER_SIZE];
|
||||
|
||||
setupIclassReader();
|
||||
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -339,10 +339,10 @@ void SimulateIso14443Tag(void)
|
||||
uint8_t *resp;
|
||||
int respLen;
|
||||
|
||||
uint8_t *resp1 = (((uint8_t *)BigBuf) + 800);
|
||||
uint8_t *resp1 = BigBuf_get_addr() + 800;
|
||||
int resp1Len;
|
||||
|
||||
uint8_t *receivedCmd = (uint8_t *)BigBuf;
|
||||
uint8_t *receivedCmd = BigBuf_get_addr();
|
||||
int len;
|
||||
|
||||
int i;
|
||||
@@ -629,31 +629,32 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet)
|
||||
int gotFrame = FALSE;
|
||||
|
||||
//# define DMA_BUFFER_SIZE 8
|
||||
int8_t *dmaBuf;
|
||||
uint8_t *dmaBuf;
|
||||
|
||||
int lastRxCounter;
|
||||
int8_t *upTo;
|
||||
uint8_t *upTo;
|
||||
|
||||
int ci, cq;
|
||||
|
||||
int samples = 0;
|
||||
|
||||
// Clear out the state of the "UART" that receives from the tag.
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
memset(BigBuf, 0x00, 400);
|
||||
Demod.output = (uint8_t *)BigBuf;
|
||||
Demod.output = BigBuf;
|
||||
Demod.len = 0;
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
|
||||
// And the UART that receives from the reader
|
||||
Uart.output = (((uint8_t *)BigBuf) + 1024);
|
||||
Uart.output = BigBuf + 1024;
|
||||
Uart.byteCntMax = 100;
|
||||
Uart.state = STATE_UNSYNCD;
|
||||
|
||||
// Setup for the DMA.
|
||||
dmaBuf = (int8_t *)(BigBuf + 32);
|
||||
dmaBuf = BigBuf + 32;
|
||||
upTo = dmaBuf;
|
||||
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:
|
||||
if (weTx) LED_D_ON(); else LED_D_OFF();
|
||||
@@ -1012,20 +1013,21 @@ void RAMFUNC SnoopIso14443(void)
|
||||
int triggered = TRUE;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
BigBuf_free();
|
||||
// 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.
|
||||
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
|
||||
// into trace, along with its length and other annotations.
|
||||
uint8_t *trace = (uint8_t *)BigBuf;
|
||||
int traceLen = 0;
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
traceLen = 0;
|
||||
|
||||
// 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;
|
||||
int8_t *upTo;
|
||||
uint8_t *upTo;
|
||||
int ci, cq;
|
||||
int maxBehindBy = 0;
|
||||
|
||||
@@ -1034,7 +1036,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||
int samples = 0;
|
||||
|
||||
// Initialize the trace buffer
|
||||
memset(trace, 0x44, DEMOD_TRACE_SIZE);
|
||||
memset(trace, 0x44, BigBuf_max_traceLen());
|
||||
|
||||
// Set up the demodulator for tag -> reader responses.
|
||||
Demod.output = receivedResponse;
|
||||
@@ -1049,7 +1051,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||
|
||||
// Print some debug information about the buffer sizes
|
||||
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(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
|
||||
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
|
||||
@@ -1076,7 +1078,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||
(DEMOD_DMA_BUFFER_SIZE-1);
|
||||
if(behindBy > maxBehindBy) {
|
||||
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);
|
||||
goto done;
|
||||
}
|
||||
@@ -1147,7 +1149,7 @@ void RAMFUNC SnoopIso14443(void)
|
||||
trace[traceLen++] = Demod.len;
|
||||
memcpy(trace+traceLen, receivedResponse, Demod.len);
|
||||
traceLen += Demod.len;
|
||||
if(traceLen > DEMOD_TRACE_SIZE) {
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Reached trace limit");
|
||||
goto done;
|
||||
}
|
||||
@@ -1173,9 +1175,9 @@ done:
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
DbpString("Snoop statistics:");
|
||||
Dbprintf(" Max behind by: %i", maxBehindBy);
|
||||
Dbprintf(" Max behind by: %i", maxBehindBy);
|
||||
Dbprintf(" Uart State: %x", Uart.state);
|
||||
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
|
||||
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);
|
||||
|
||||
@@ -10,20 +10,19 @@
|
||||
// Routines to support ISO 14443 type A.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "../common/cmd.h"
|
||||
#include "../common/iso14443crc.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#include "iso14443crc.h"
|
||||
#include "iso14443a.h"
|
||||
#include "crapto1.h"
|
||||
#include "mifareutil.h"
|
||||
|
||||
static uint32_t iso14a_timeout;
|
||||
uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET;
|
||||
int rsamples = 0;
|
||||
int traceLen = 0;
|
||||
int tracing = TRUE;
|
||||
uint8_t trigger = 0;
|
||||
// the block number for the ISO14443-4 PCB
|
||||
@@ -148,7 +147,9 @@ void iso14a_set_trigger(bool enable) {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -169,7 +170,7 @@ byte_t oddparity (const byte_t bt)
|
||||
return OddByteParity[bt];
|
||||
}
|
||||
|
||||
void GetParity(const uint8_t * pbtCmd, uint16_t iLen, uint8_t *par)
|
||||
void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
|
||||
{
|
||||
uint16_t paritybit_cnt = 0;
|
||||
uint16_t paritybyte_cnt = 0;
|
||||
@@ -179,15 +180,15 @@ void GetParity(const uint8_t * pbtCmd, uint16_t iLen, uint8_t *par)
|
||||
// Generate the parity bits
|
||||
parityBits |= ((OddByteParity[pbtCmd[i]]) << (7-paritybit_cnt));
|
||||
if (paritybit_cnt == 7) {
|
||||
par[paritybyte_cnt] = parityBits; // save 8 Bits parity
|
||||
parityBits = 0; // and advance to next Parity Byte
|
||||
par[paritybyte_cnt] = parityBits; // save 8 Bits parity
|
||||
parityBits = 0; // and advance to next Parity Byte
|
||||
paritybyte_cnt++;
|
||||
paritybit_cnt = 0;
|
||||
} else {
|
||||
paritybit_cnt++;
|
||||
paritybit_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// save remaining parity bits
|
||||
par[paritybyte_cnt] = parityBits;
|
||||
|
||||
@@ -203,11 +204,13 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
{
|
||||
if (!tracing) return FALSE;
|
||||
|
||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint16_t duration = timestamp_end - timestamp_start;
|
||||
|
||||
// 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
|
||||
return FALSE;
|
||||
}
|
||||
@@ -218,7 +221,7 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
// 16 bits data length (little endian, Highest Bit used as readerToTag flag)
|
||||
// y Bytes data
|
||||
// x Bytes parity (one byte per 8 bytes data)
|
||||
|
||||
|
||||
// timestamp (start)
|
||||
trace[traceLen++] = ((timestamp_start >> 0) & 0xff);
|
||||
trace[traceLen++] = ((timestamp_start >> 8) & 0xff);
|
||||
@@ -228,28 +231,28 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
// duration
|
||||
trace[traceLen++] = ((duration >> 0) & 0xff);
|
||||
trace[traceLen++] = ((duration >> 8) & 0xff);
|
||||
|
||||
|
||||
// data length
|
||||
trace[traceLen++] = ((iLen >> 0) & 0xff);
|
||||
trace[traceLen++] = ((iLen >> 8) & 0xff);
|
||||
|
||||
|
||||
// readerToTag flag
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
// data bytes
|
||||
if (btBytes != NULL && iLen != 0) {
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
}
|
||||
traceLen += iLen;
|
||||
|
||||
traceLen += iLen;
|
||||
|
||||
// parity bytes
|
||||
if (parity != NULL && iLen != 0) {
|
||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
||||
}
|
||||
traceLen += num_paritybytes;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -307,7 +310,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
|
||||
Uart.twoBits = (Uart.twoBits << 8) | bit;
|
||||
|
||||
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
||||
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
||||
|
||||
if (Uart.highCnt < 7) { // wait for a stable unmodulated signal
|
||||
if (Uart.twoBits == 0xffff) {
|
||||
@@ -315,7 +318,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
} else {
|
||||
Uart.highCnt = 0;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
Uart.syncBit = 0xFFFF; // not set
|
||||
// look for 00xx1111 (the start bit)
|
||||
if ((Uart.twoBits & 0x6780) == 0x0780) Uart.syncBit = 7;
|
||||
@@ -355,9 +358,9 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Uart.bitCount = 0;
|
||||
Uart.shiftReg = 0;
|
||||
if((Uart.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
Uart.parityBits = 0;
|
||||
if((Uart.len&0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
Uart.parityBits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -374,32 +377,32 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Uart.bitCount = 0;
|
||||
Uart.shiftReg = 0;
|
||||
if ((Uart.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
if ((Uart.len&0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
Uart.parityBits = 0;
|
||||
}
|
||||
}
|
||||
} else { // no modulation in both halves - Sequence Y
|
||||
if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) { // Y after logic "0" - End of Communication
|
||||
Uart.state = STATE_UNSYNCD;
|
||||
Uart.bitCount--; // last "0" was part of EOC sequence
|
||||
Uart.shiftReg <<= 1; // drop it
|
||||
if(Uart.bitCount > 0) { // if we decoded some bits
|
||||
Uart.shiftReg >>= (9 - Uart.bitCount); // right align them
|
||||
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output
|
||||
Uart.parityBits <<= 1; // add a (void) parity bit
|
||||
Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align parity bits
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it
|
||||
return TRUE;
|
||||
} else if (Uart.len & 0x0007) { // there are some parity bits to store
|
||||
Uart.parityBits <<= (8 - (Uart.len & 0x0007)); // left align remaining parity bits
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
|
||||
Uart.bitCount--; // last "0" was part of EOC sequence
|
||||
Uart.shiftReg <<= 1; // drop it
|
||||
if(Uart.bitCount > 0) { // if we decoded some bits
|
||||
Uart.shiftReg >>= (9 - Uart.bitCount); // right align them
|
||||
Uart.output[Uart.len++] = (Uart.shiftReg & 0xff); // add last byte to the output
|
||||
Uart.parityBits <<= 1; // add a (void) parity bit
|
||||
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it
|
||||
return TRUE;
|
||||
} else if (Uart.len & 0x0007) { // there are some parity bits to store
|
||||
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
|
||||
}
|
||||
if ( Uart.len) {
|
||||
return TRUE; // we are finished with decoding the raw data sequence
|
||||
if (Uart.len) {
|
||||
return TRUE; // we are finished with decoding the raw data sequence
|
||||
} else {
|
||||
UartReset(); // Nothing receiver - start over
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Uart.state == STATE_START_OF_COMMUNICATION) { // error - must not follow directly after SOC
|
||||
UartReset();
|
||||
@@ -414,8 +417,8 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
Uart.parityBits |= ((Uart.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Uart.bitCount = 0;
|
||||
Uart.shiftReg = 0;
|
||||
if ((Uart.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
if ((Uart.len&0x0007) == 0) { // every 8 data bytes
|
||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // store 8 parity bits
|
||||
Uart.parityBits = 0;
|
||||
}
|
||||
}
|
||||
@@ -423,7 +426,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE; // not finished yet, need more data
|
||||
}
|
||||
@@ -527,8 +530,8 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||
Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Demod.bitCount = 0;
|
||||
Demod.shiftReg = 0;
|
||||
if((Demod.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits
|
||||
if((Demod.len&0x0007) == 0) { // every 8 data bytes
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits
|
||||
Demod.parityBits = 0;
|
||||
}
|
||||
}
|
||||
@@ -543,26 +546,26 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||
Demod.parityBits |= ((Demod.shiftReg >> 8) & 0x01); // store parity bit
|
||||
Demod.bitCount = 0;
|
||||
Demod.shiftReg = 0;
|
||||
if ((Demod.len & 0x0007) == 0) { // every 8 data bytes
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1
|
||||
if ((Demod.len&0x0007) == 0) { // every 8 data bytes
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // store 8 parity bits1
|
||||
Demod.parityBits = 0;
|
||||
}
|
||||
}
|
||||
Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
|
||||
} else { // no modulation in both halves - End of communication
|
||||
if(Demod.bitCount > 0) { // there are some remaining data bits
|
||||
Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits
|
||||
Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
|
||||
Demod.parityBits <<= 1; // add a (void) parity bit
|
||||
Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||
return TRUE;
|
||||
} else if (Demod.len & 0x0007) { // there are some parity bits to store
|
||||
Demod.parityBits <<= (8 - (Demod.len & 0x0007)); // left align remaining parity bits
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||
}
|
||||
if (Demod.len) {
|
||||
return TRUE; // we are finished with decoding the raw data sequence
|
||||
if(Demod.bitCount > 0) { // there are some remaining data bits
|
||||
Demod.shiftReg >>= (9 - Demod.bitCount); // right align the decoded bits
|
||||
Demod.output[Demod.len++] = Demod.shiftReg & 0xff; // and add them to the output
|
||||
Demod.parityBits <<= 1; // add a (void) parity bit
|
||||
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||
return TRUE;
|
||||
} else if (Demod.len & 0x0007) { // there are some parity bits to store
|
||||
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||
}
|
||||
if (Demod.len) {
|
||||
return TRUE; // we are finished with decoding the raw data sequence
|
||||
} else { // nothing received. Start over
|
||||
DemodReset();
|
||||
}
|
||||
@@ -590,9 +593,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// bit 1 - trigger from first reader 7-bit request
|
||||
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
// 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
|
||||
@@ -600,22 +600,25 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// triggered == FALSE -- to wait first for card
|
||||
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 length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET;
|
||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
|
||||
// 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;
|
||||
uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||
uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||
|
||||
// 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 previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
@@ -627,10 +630,10 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
|
||||
// Set up the demodulator for tag -> reader responses.
|
||||
DemodInit(receivedResponse, receivedResponsePar);
|
||||
|
||||
|
||||
// Set up the demodulator for the reader -> tag commands
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
|
||||
// Setup and start DMA.
|
||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
|
||||
|
||||
@@ -655,7 +658,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
// test for length of buffer
|
||||
if(dataLen > maxDataLen) {
|
||||
maxDataLen = dataLen;
|
||||
if(dataLen > 400) {
|
||||
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! dataLen=%d", dataLen);
|
||||
break;
|
||||
}
|
||||
@@ -687,12 +690,12 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = TRUE;
|
||||
|
||||
if(triggered) {
|
||||
if (!LogTrace(receivedCmd,
|
||||
Uart.len,
|
||||
Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
Uart.parity,
|
||||
TRUE)) break;
|
||||
if (!LogTrace(receivedCmd,
|
||||
Uart.len,
|
||||
Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
Uart.parity,
|
||||
TRUE)) break;
|
||||
}
|
||||
/* And ready to receive another command. */
|
||||
UartReset();
|
||||
@@ -709,12 +712,12 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
if(ManchesterDecoding(tagdata, 0, (rsamples-1)*4)) {
|
||||
LED_B_ON();
|
||||
|
||||
if (!LogTrace(receivedResponse,
|
||||
Demod.len,
|
||||
Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
Demod.parity,
|
||||
FALSE)) break;
|
||||
if (!LogTrace(receivedResponse,
|
||||
Demod.len,
|
||||
Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
Demod.parity,
|
||||
FALSE)) break;
|
||||
|
||||
if ((!triggered) && (param & 0x01)) triggered = TRUE;
|
||||
|
||||
@@ -745,7 +748,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||
//-----------------------------------------------------------------------------
|
||||
// Prepare tag messages
|
||||
//-----------------------------------------------------------------------------
|
||||
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity)
|
||||
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity)
|
||||
{
|
||||
ToSendReset();
|
||||
|
||||
@@ -763,7 +766,7 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *pa
|
||||
ToSend[++ToSendMax] = SEC_D;
|
||||
LastProxToAirDuration = 8 * ToSendMax - 4;
|
||||
|
||||
for( uint16_t i = 0; i < len; i++) {
|
||||
for(uint16_t i = 0; i < len; i++) {
|
||||
uint8_t b = cmd[i];
|
||||
|
||||
// Data bits
|
||||
@@ -884,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,
|
||||
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 {
|
||||
uint8_t* response;
|
||||
@@ -894,10 +897,6 @@ typedef struct {
|
||||
uint32_t ProxToAirDuration;
|
||||
} 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) {
|
||||
// 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
|
||||
@@ -909,7 +908,8 @@ 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
|
||||
//
|
||||
|
||||
|
||||
|
||||
// Prepare the tag modulation bits from the message
|
||||
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
||||
|
||||
@@ -930,15 +930,22 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||
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) {
|
||||
// Retrieve and store the current buffer index
|
||||
response_info->modulation = free_buffer_pointer;
|
||||
|
||||
// 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
|
||||
if (prepare_tag_modulation(response_info,max_buffer_size)) {
|
||||
if (prepare_tag_modulation(response_info, max_buffer_size)) {
|
||||
// Update the free buffer offset
|
||||
free_buffer_pointer += ToSendMax;
|
||||
return true;
|
||||
@@ -953,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)
|
||||
{
|
||||
// Enable and clear the trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
uint8_t sak;
|
||||
|
||||
// The first response contains the ATQA (note: bytes are transmitted in reverse order).
|
||||
@@ -1000,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
|
||||
uint8_t response2[5];
|
||||
uint8_t response2[5] = {0x00};
|
||||
|
||||
// Check if the uid uses the (optional) part
|
||||
uint8_t response2a[5];
|
||||
uint8_t response2a[5] = {0x00};
|
||||
|
||||
if (uid_2nd) {
|
||||
response2[0] = 0x88;
|
||||
num_to_bytes(uid_1st,3,response2+1);
|
||||
@@ -1024,18 +1028,18 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
|
||||
|
||||
// Prepare the mandatory SAK (for 4 and 7 byte UID)
|
||||
uint8_t response3[3];
|
||||
uint8_t response3[3] = {0x00};
|
||||
response3[0] = sak;
|
||||
ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
|
||||
|
||||
// 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;
|
||||
ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
|
||||
|
||||
uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
|
||||
uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS:
|
||||
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
||||
uint8_t response6[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS:
|
||||
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
||||
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
|
||||
// TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
|
||||
// TC(1) = 0x02: CID supported, NAD not supported
|
||||
@@ -1065,9 +1069,17 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
.modulation_n = 0
|
||||
};
|
||||
|
||||
// Reset the offset pointer of the free buffer
|
||||
reset_free_buffer();
|
||||
|
||||
BigBuf_free_keep_EM();
|
||||
|
||||
// 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
|
||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||
for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) {
|
||||
@@ -1088,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.
|
||||
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;
|
||||
tag_response_info_t* p_response;
|
||||
|
||||
@@ -1101,7 +1109,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
|
||||
if(!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
||||
DbpString("Button press");
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
p_response = NULL;
|
||||
@@ -1252,6 +1260,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||
|
||||
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
|
||||
LED_A_OFF();
|
||||
BigBuf_free_keep_EM();
|
||||
}
|
||||
|
||||
|
||||
@@ -1323,14 +1332,14 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
|
||||
}
|
||||
}
|
||||
|
||||
NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME);
|
||||
NextTransferTime = MAX(NextTransferTime, LastTimeProxToAirStart + REQUEST_GUARD_TIME);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Prepare reader command (in bits, support short frames) to send to FPGA
|
||||
//-----------------------------------------------------------------------------
|
||||
void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, uint16_t bits, const uint8_t *parity)
|
||||
void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity)
|
||||
{
|
||||
int i, j;
|
||||
int last;
|
||||
@@ -1411,7 +1420,7 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, uint16_t bits, const uint
|
||||
//-----------------------------------------------------------------------------
|
||||
// Prepare reader command to send to FPGA
|
||||
//-----------------------------------------------------------------------------
|
||||
void CodeIso14443aAsReaderPar(const uint8_t * cmd, uint16_t len, const uint8_t *parity)
|
||||
void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *parity)
|
||||
{
|
||||
CodeIso14443aBitsAsReaderPar(cmd, len*8, parity);
|
||||
}
|
||||
@@ -1595,7 +1604,7 @@ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool correctionNeeded){
|
||||
GetParity(resp, respLen, par);
|
||||
return EmSendCmdExPar(resp, respLen, correctionNeeded, par);
|
||||
}
|
||||
|
||||
|
||||
int EmSendCmd(uint8_t *resp, uint16_t respLen){
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(resp, respLen, par);
|
||||
@@ -1610,16 +1619,16 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
|
||||
uint8_t *tag_data, uint16_t tag_len, uint32_t tag_StartTime, uint32_t tag_EndTime, uint8_t *tag_Parity)
|
||||
{
|
||||
if (tracing) {
|
||||
// we cannot exactly measure the end and start of a received command from reader. However we know that the delay from
|
||||
// end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
|
||||
// with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated:
|
||||
uint16_t reader_modlen = reader_EndTime - reader_StartTime;
|
||||
uint16_t approx_fdt = tag_StartTime - reader_EndTime;
|
||||
uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
|
||||
reader_EndTime = tag_StartTime - exact_fdt;
|
||||
reader_StartTime = reader_EndTime - reader_modlen;
|
||||
if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) {
|
||||
return FALSE;
|
||||
// we cannot exactly measure the end and start of a received command from reader. However we know that the delay from
|
||||
// end of the received command to start of the tag's (simulated by us) answer is n*128+20 or n*128+84 resp.
|
||||
// with n >= 9. The start of the tags answer can be measured and therefore the end of the received command be calculated:
|
||||
uint16_t reader_modlen = reader_EndTime - reader_StartTime;
|
||||
uint16_t approx_fdt = tag_StartTime - reader_EndTime;
|
||||
uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
|
||||
reader_EndTime = tag_StartTime - exact_fdt;
|
||||
reader_StartTime = reader_EndTime - reader_modlen;
|
||||
if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) {
|
||||
return FALSE;
|
||||
} else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, FALSE));
|
||||
} else {
|
||||
return TRUE;
|
||||
@@ -1643,7 +1652,7 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
|
||||
|
||||
// Now get the answer from the card
|
||||
DemodInit(receivedResponse, receivedResponsePar);
|
||||
|
||||
|
||||
// clear RXRDY:
|
||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
|
||||
@@ -1685,23 +1694,23 @@ void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *tim
|
||||
|
||||
void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||
{
|
||||
// Generate parity and redirect
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(frame, len/8, par);
|
||||
ReaderTransmitBitsPar(frame, len, par, timing);
|
||||
// Generate parity and redirect
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(frame, len/8, par);
|
||||
ReaderTransmitBitsPar(frame, len, par, timing);
|
||||
}
|
||||
|
||||
void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||
{
|
||||
// Generate parity and redirect
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(frame, len, par);
|
||||
ReaderTransmitBitsPar(frame, len*8, par, timing);
|
||||
// Generate parity and redirect
|
||||
uint8_t par[MAX_PARITY_SIZE];
|
||||
GetParity(frame, len, par);
|
||||
ReaderTransmitBitsPar(frame, len*8, par, timing);
|
||||
}
|
||||
|
||||
int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
|
||||
{
|
||||
if (!GetIso14443aAnswerFromTag(receivedAnswer,parity,offset)) return FALSE;
|
||||
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return FALSE;
|
||||
if (tracing) {
|
||||
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
|
||||
}
|
||||
@@ -1720,34 +1729,26 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
||||
/* performs iso14443a anticollision procedure
|
||||
* fills the uid pointer unless NULL
|
||||
* fills resp_data unless NULL */
|
||||
int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) {
|
||||
|
||||
//uint8_t deselect[] = {0xc2}; //DESELECT
|
||||
//uint8_t halt[] = { 0x50, 0x00, 0x57, 0xCD }; // HALT
|
||||
uint8_t wupa[] = { 0x52 }; // WAKE-UP
|
||||
//uint8_t reqa[] = { 0x26 }; // REQUEST A
|
||||
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) {
|
||||
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
|
||||
uint8_t sel_all[] = { 0x93,0x20 };
|
||||
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 *resp = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET;
|
||||
uint8_t *resp_par = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
|
||||
uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
|
||||
uint8_t resp_par[MAX_PARITY_SIZE];
|
||||
byte_t uid_resp[4];
|
||||
size_t uid_resp_len;
|
||||
|
||||
uint8_t sak = 0x04; // cascade uid
|
||||
int cascade_level = 0;
|
||||
int len =0;
|
||||
|
||||
// test for the SKYLANDERS TOY.
|
||||
// ReaderTransmit(deselect,sizeof(deselect), NULL);
|
||||
// len = ReaderReceive(resp, resp_par);
|
||||
|
||||
int len;
|
||||
|
||||
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
||||
ReaderTransmitBitsPar(wupa,7,0, NULL);
|
||||
ReaderTransmitBitsPar(wupa,7,0, NULL);
|
||||
|
||||
// Receive the ATQA
|
||||
if(!ReaderReceive(resp, resp_par)) return 0;
|
||||
|
||||
|
||||
if(p_hi14a_card) {
|
||||
memcpy(p_hi14a_card->atqa, resp, 2);
|
||||
p_hi14a_card->uidlen = 0;
|
||||
@@ -1759,99 +1760,99 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
||||
memset(uid_ptr,0,10);
|
||||
}
|
||||
|
||||
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
|
||||
for(; sak & 0x04; cascade_level++) {
|
||||
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
||||
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
||||
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
|
||||
// which case we need to make a cascade 2 request and select - this is a long UID
|
||||
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
|
||||
for(; sak & 0x04; cascade_level++) {
|
||||
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
||||
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
||||
|
||||
// SELECT_ALL
|
||||
ReaderTransmit(sel_all,sizeof(sel_all), NULL);
|
||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||
|
||||
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
|
||||
memset(uid_resp, 0, 4);
|
||||
uint16_t uid_resp_bits = 0;
|
||||
uint16_t collision_answer_offset = 0;
|
||||
// anti-collision-loop:
|
||||
while (Demod.collisionPos) {
|
||||
Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
|
||||
for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point
|
||||
uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
|
||||
uid_resp[uid_resp_bits & 0xf8] |= UIDbit << (uid_resp_bits % 8);
|
||||
}
|
||||
uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position
|
||||
uid_resp_bits++;
|
||||
// construct anticollosion command:
|
||||
sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits
|
||||
for (uint16_t i = 0; i <= uid_resp_bits/8; i++) {
|
||||
sel_uid[2+i] = uid_resp[i];
|
||||
}
|
||||
collision_answer_offset = uid_resp_bits%8;
|
||||
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
|
||||
if (!ReaderReceiveOffset(resp, collision_answer_offset,resp_par)) return 0;
|
||||
}
|
||||
// finally, add the last bits and BCC of the UID
|
||||
for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
|
||||
uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01;
|
||||
uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8);
|
||||
}
|
||||
|
||||
} else { // no collision, use the response to SELECT_ALL as current uid
|
||||
memcpy(uid_resp,resp,4);
|
||||
}
|
||||
uid_resp_len = 4;
|
||||
|
||||
// calculate crypto UID. Always use last 4 Bytes.
|
||||
if(cuid_ptr) {
|
||||
*cuid_ptr = bytes_to_num(uid_resp, 4);
|
||||
}
|
||||
|
||||
// Construct SELECT UID command
|
||||
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
||||
memcpy(sel_uid+2,uid_resp,4); // the UID
|
||||
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
||||
AppendCrc14443a(sel_uid,7); // calculate and add CRC
|
||||
ReaderTransmit(sel_uid,sizeof(sel_uid), NULL);
|
||||
|
||||
// Receive the SAK
|
||||
// SELECT_ALL
|
||||
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||
sak = resp[0];
|
||||
|
||||
|
||||
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
|
||||
memset(uid_resp, 0, 4);
|
||||
uint16_t uid_resp_bits = 0;
|
||||
uint16_t collision_answer_offset = 0;
|
||||
// anti-collision-loop:
|
||||
while (Demod.collisionPos) {
|
||||
Dbprintf("Multiple tags detected. Collision after Bit %d", Demod.collisionPos);
|
||||
for (uint16_t i = collision_answer_offset; i < Demod.collisionPos; i++, uid_resp_bits++) { // add valid UID bits before collision point
|
||||
uint16_t UIDbit = (resp[i/8] >> (i % 8)) & 0x01;
|
||||
uid_resp[uid_resp_bits / 8] |= UIDbit << (uid_resp_bits % 8);
|
||||
}
|
||||
uid_resp[uid_resp_bits/8] |= 1 << (uid_resp_bits % 8); // next time select the card(s) with a 1 in the collision position
|
||||
uid_resp_bits++;
|
||||
// construct anticollosion command:
|
||||
sel_uid[1] = ((2 + uid_resp_bits/8) << 4) | (uid_resp_bits & 0x07); // length of data in bytes and bits
|
||||
for (uint16_t i = 0; i <= uid_resp_bits/8; i++) {
|
||||
sel_uid[2+i] = uid_resp[i];
|
||||
}
|
||||
collision_answer_offset = uid_resp_bits%8;
|
||||
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
|
||||
if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
|
||||
}
|
||||
// finally, add the last bits and BCC of the UID
|
||||
for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
|
||||
uint16_t UIDbit = (resp[i/8] >> (i%8)) & 0x01;
|
||||
uid_resp[uid_resp_bits/8] |= UIDbit << (uid_resp_bits % 8);
|
||||
}
|
||||
|
||||
} else { // no collision, use the response to SELECT_ALL as current uid
|
||||
memcpy(uid_resp, resp, 4);
|
||||
}
|
||||
uid_resp_len = 4;
|
||||
|
||||
// calculate crypto UID. Always use last 4 Bytes.
|
||||
if(cuid_ptr) {
|
||||
*cuid_ptr = bytes_to_num(uid_resp, 4);
|
||||
}
|
||||
|
||||
// Construct SELECT UID command
|
||||
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
||||
memcpy(sel_uid+2, uid_resp, 4); // the UID
|
||||
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
||||
AppendCrc14443a(sel_uid, 7); // calculate and add CRC
|
||||
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
||||
|
||||
// Receive the SAK
|
||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||
sak = resp[0];
|
||||
|
||||
// Test if more parts of the uid are coming
|
||||
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
|
||||
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
|
||||
// http://www.nxp.com/documents/application_note/AN10927.pdf
|
||||
uid_resp[0] = uid_resp[1];
|
||||
uid_resp[1] = uid_resp[2];
|
||||
uid_resp[2] = uid_resp[3];
|
||||
|
||||
uid_resp_len = 3;
|
||||
}
|
||||
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
|
||||
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
|
||||
// http://www.nxp.com/documents/application_note/AN10927.pdf
|
||||
uid_resp[0] = uid_resp[1];
|
||||
uid_resp[1] = uid_resp[2];
|
||||
uid_resp[2] = uid_resp[3];
|
||||
|
||||
if(uid_ptr) {
|
||||
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
||||
}
|
||||
uid_resp_len = 3;
|
||||
}
|
||||
|
||||
if(p_hi14a_card) {
|
||||
memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len);
|
||||
p_hi14a_card->uidlen += uid_resp_len;
|
||||
}
|
||||
}
|
||||
if(uid_ptr) {
|
||||
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
||||
}
|
||||
|
||||
if(p_hi14a_card) {
|
||||
p_hi14a_card->sak = sak;
|
||||
p_hi14a_card->ats_len = 0;
|
||||
}
|
||||
if(p_hi14a_card) {
|
||||
memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len);
|
||||
p_hi14a_card->uidlen += uid_resp_len;
|
||||
}
|
||||
}
|
||||
|
||||
if(p_hi14a_card) {
|
||||
p_hi14a_card->sak = sak;
|
||||
p_hi14a_card->ats_len = 0;
|
||||
}
|
||||
|
||||
// non iso14443a compliant tag
|
||||
if( (sak & 0x20) == 0) return 2;
|
||||
|
||||
|
||||
// Request for answer to select
|
||||
AppendCrc14443a(rats, 2);
|
||||
ReaderTransmit(rats, sizeof(rats), NULL);
|
||||
|
||||
|
||||
if (!(len = ReaderReceive(resp, resp_par))) return 0;
|
||||
|
||||
|
||||
@@ -1862,7 +1863,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
||||
|
||||
// reset the PCB block number
|
||||
iso14_pcb_blocknum = 0;
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
@@ -1873,7 +1874,8 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Signal field is on with the appropriate LED
|
||||
if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD || fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) {
|
||||
if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD
|
||||
|| fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN) {
|
||||
LED_D_ON();
|
||||
} else {
|
||||
LED_D_OFF();
|
||||
@@ -1886,7 +1888,7 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||
DemodReset();
|
||||
UartReset();
|
||||
NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
|
||||
iso14a_set_timeout(1050); // 10ms default 10*105 =
|
||||
iso14a_set_timeout(1050); // 10ms default
|
||||
}
|
||||
|
||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
||||
@@ -1901,7 +1903,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
||||
|
||||
ReaderTransmit(real_cmd, cmd_len+4, NULL);
|
||||
size_t len = ReaderReceive(data, parity);
|
||||
uint8_t * data_bytes = (uint8_t *) data;
|
||||
uint8_t *data_bytes = (uint8_t *) data;
|
||||
if (!len)
|
||||
return 0; //DATA LINK ERROR
|
||||
// if we received an I- or R(ACK)-Block with a block number equal to the
|
||||
@@ -1965,8 +1967,8 @@ void ReaderIso14443a(UsbCommand *c)
|
||||
len += 2;
|
||||
if (lenbits) lenbits += 16;
|
||||
}
|
||||
if(lenbits>0) {
|
||||
GetParity(cmd, lenbits/8, par);
|
||||
if(lenbits>0) {
|
||||
GetParity(cmd, lenbits/8, par);
|
||||
ReaderTransmitBitsPar(cmd, lenbits, par, NULL);
|
||||
} else {
|
||||
ReaderTransmit(cmd,len, NULL);
|
||||
@@ -2025,9 +2027,12 @@ void ReaderMifare(bool first_try)
|
||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
static uint8_t mf_nr_ar3;
|
||||
|
||||
uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t* receivedAnswerPar = (((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET);
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// free eventually allocated BigBuf memory. We want all for tracing.
|
||||
BigBuf_free();
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
@@ -2164,7 +2169,7 @@ void ReaderMifare(bool first_try)
|
||||
led_on = !led_on;
|
||||
if(led_on) LED_B_ON(); else LED_B_OFF();
|
||||
|
||||
par_list[nt_diff] = SwapBits(par[0], 8);
|
||||
par_list[nt_diff] = SwapBits(par[0], 8);
|
||||
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05;
|
||||
|
||||
// Test if the information is complete
|
||||
@@ -2237,10 +2242,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
uint32_t numReads = 0;//Counts numer of times reader read a block
|
||||
uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf();
|
||||
uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE;
|
||||
uint8_t* response = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* response_par = response + MAX_FRAME_SIZE;
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE];
|
||||
uint8_t response[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
|
||||
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
|
||||
@@ -2257,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};
|
||||
uint8_t ar_nr_collected = 0;
|
||||
|
||||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||
BigBuf_free_keep_EM();
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
@@ -2727,18 +2734,20 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
uint8_t *receivedCmdPar = ((uint8_t *)BigBuf) + RECV_CMD_PAR_OFFSET;
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RESP_OFFSET);
|
||||
uint8_t *receivedResponsePar = ((uint8_t *)BigBuf) + RECV_RESP_PAR_OFFSET;
|
||||
|
||||
uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedResponsePar[MAX_MIFARE_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
|
||||
uint8_t *dmaBuf = ((uint8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
||||
// free eventually allocated BigBuf memory
|
||||
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 previous_data = 0;
|
||||
int maxDataLen = 0;
|
||||
@@ -2797,7 +2806,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||
// test for length of buffer
|
||||
if(dataLen > maxDataLen) { // we are more behind than ever...
|
||||
maxDataLen = dataLen;
|
||||
if(dataLen > 400) {
|
||||
if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
|
||||
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ typedef struct {
|
||||
uint16_t bitCount;
|
||||
uint16_t collisionPos;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint16_t shiftReg;
|
||||
uint16_t samples;
|
||||
uint16_t len;
|
||||
@@ -61,8 +61,8 @@ typedef struct {
|
||||
uint16_t byteCntMax;
|
||||
uint16_t posCnt;
|
||||
uint16_t syncBit;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint8_t parityBits;
|
||||
uint8_t parityLen;
|
||||
uint16_t highCnt;
|
||||
uint16_t twoBits;
|
||||
uint32_t startTime, endTime;
|
||||
|
||||
@@ -58,13 +58,12 @@
|
||||
// *) document all the functions
|
||||
|
||||
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
#include "util.h"
|
||||
#include "apps.h"
|
||||
#include "string.h"
|
||||
#include "../common/iso15693tools.h"
|
||||
#include "../common/cmd.h"
|
||||
|
||||
#include "iso15693tools.h"
|
||||
#include "cmd.h"
|
||||
|
||||
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
@@ -297,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)
|
||||
{
|
||||
int c = 0;
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int getNext = 0;
|
||||
|
||||
int8_t prev = 0;
|
||||
@@ -447,12 +446,12 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
|
||||
static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
|
||||
{
|
||||
int c = 0;
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int getNext = 0;
|
||||
|
||||
int8_t prev = 0;
|
||||
|
||||
// NOW READ RESPONSE
|
||||
// NOW READ RESPONSE
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
//spindelay(60); // greg - experiment to get rid of some of the 0 byte/failed reads
|
||||
c = 0;
|
||||
@@ -468,7 +467,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
|
||||
// tone that the tag AM-modulates, so every other sample is I,
|
||||
// every other is Q. We just want power, so abs(I) + abs(Q) is
|
||||
// close to what we want.
|
||||
if (getNext) {
|
||||
if(getNext) {
|
||||
int8_t r;
|
||||
|
||||
if(b < 0) {
|
||||
@@ -597,7 +596,7 @@ static void BuildIdentifyRequest(void);
|
||||
//-----------------------------------------------------------------------------
|
||||
void AcquireRawAdcSamplesIso15693(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
int c = 0;
|
||||
int getNext = 0;
|
||||
@@ -679,7 +678,7 @@ void AcquireRawAdcSamplesIso15693(void)
|
||||
|
||||
void RecordRawAdcSamplesIso15693(void)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
int c = 0;
|
||||
int getNext = 0;
|
||||
@@ -690,8 +689,8 @@ void RecordRawAdcSamplesIso15693(void)
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Start from off (no field generated)
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
@@ -879,8 +878,8 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv)
|
||||
LED_D_OFF();
|
||||
|
||||
int answerLen=0;
|
||||
uint8_t *answer = (((uint8_t *)BigBuf) + 3660);
|
||||
if (recv!=NULL) memset(BigBuf + 3660, 0, 100);
|
||||
uint8_t *answer = BigBuf_get_addr() + 3660;
|
||||
if (recv != NULL) memset(answer, 0, 100);
|
||||
|
||||
if (init) Iso15693InitReader();
|
||||
|
||||
@@ -993,16 +992,16 @@ void SetDebugIso15693(uint32_t debug) {
|
||||
// Simulate an ISO15693 reader, perform anti-collision and then attempt to read a sector
|
||||
// all demodulation performed in arm rather than host. - greg
|
||||
//-----------------------------------------------------------------------------
|
||||
void ReaderIso15693(uint32_t parameter )
|
||||
void ReaderIso15693(uint32_t parameter)
|
||||
{
|
||||
LED_A_ON();
|
||||
LED_B_ON();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
|
||||
uint8_t *answer1 = (((uint8_t *)BigBuf) + 3660); //
|
||||
uint8_t *answer2 = (((uint8_t *)BigBuf) + 3760);
|
||||
uint8_t *answer3 = (((uint8_t *)BigBuf) + 3860);
|
||||
uint8_t *answer1 = BigBuf_get_addr() + 3660;
|
||||
uint8_t *answer2 = BigBuf_get_addr() + 3760;
|
||||
uint8_t *answer3 = BigBuf_get_addr() + 3860;
|
||||
|
||||
int answerLen1 = 0;
|
||||
int answerLen2 = 0;
|
||||
@@ -1014,9 +1013,9 @@ void ReaderIso15693(uint32_t parameter )
|
||||
int elapsed = 0;
|
||||
uint8_t TagUID[8] = {0x00};
|
||||
|
||||
|
||||
|
||||
// Blank arrays
|
||||
memset(BigBuf + 3660, 0x00, 300);
|
||||
memset(answer1, 0x00, 300);
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
@@ -1025,9 +1024,9 @@ void ReaderIso15693(uint32_t parameter )
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Start from off (no field generated)
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
// Give the tags time to energize
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||
SpinDelay(200);
|
||||
@@ -1066,7 +1065,7 @@ void ReaderIso15693(uint32_t parameter )
|
||||
Dbhexdump(answerLen1,answer1,true);
|
||||
|
||||
// UID is reverse
|
||||
if (answerLen1 >= 12)
|
||||
if (answerLen1>=12)
|
||||
Dbprintf("UID = %02hX%02hX%02hX%02hX%02hX%02hX%02hX%02hX",
|
||||
TagUID[7],TagUID[6],TagUID[5],TagUID[4],
|
||||
TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
|
||||
@@ -1080,14 +1079,14 @@ void ReaderIso15693(uint32_t parameter )
|
||||
DbdecodeIso15693Answer(answerLen3,answer3);
|
||||
Dbhexdump(answerLen3,answer3,true);
|
||||
|
||||
// read all pages
|
||||
if (answerLen1 >= 12 && DEBUG) {
|
||||
// read all pages
|
||||
if (answerLen1>=12 && DEBUG) {
|
||||
i=0;
|
||||
while (i < 32) { // sanity check, assume max 32 pages
|
||||
while (i<32) { // sanity check, assume max 32 pages
|
||||
BuildReadBlockRequest(TagUID,i);
|
||||
TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
|
||||
answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
|
||||
if (answerLen2 > 0) {
|
||||
TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);
|
||||
answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
|
||||
if (answerLen2>0) {
|
||||
Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
|
||||
DbdecodeIso15693Answer(answerLen2,answer2);
|
||||
Dbhexdump(answerLen2,answer2,true);
|
||||
@@ -1112,16 +1111,16 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
|
||||
uint8_t *buf = (((uint8_t *)BigBuf) + 3660); //
|
||||
uint8_t *buf = BigBuf_get_addr() + 3660;
|
||||
|
||||
int answerLen1 = 0;
|
||||
int samples = 0;
|
||||
int tsamples = 0;
|
||||
int wait = 0;
|
||||
int elapsed = 0;
|
||||
|
||||
|
||||
memset(buf, 0x00, 100);
|
||||
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
@@ -1129,8 +1128,8 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Start from off (no field generated)
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(200);
|
||||
|
||||
LED_A_OFF();
|
||||
LED_B_OFF();
|
||||
@@ -1147,7 +1146,7 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
|
||||
|
||||
BuildInventoryResponse(uid);
|
||||
|
||||
TransmitTo15693Reader(ToSend, ToSendMax, &tsamples, &wait);
|
||||
TransmitTo15693Reader(ToSend,ToSendMax, &tsamples, &wait);
|
||||
}
|
||||
|
||||
Dbprintf("%d octets read from reader command: %x %x %x %x %x %x %x %x %x", answerLen1,
|
||||
@@ -1214,7 +1213,7 @@ void BruteforceIso15693Afi(uint32_t speed)
|
||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]) {
|
||||
|
||||
int recvlen=0;
|
||||
uint8_t *recvbuf=(uint8_t *)BigBuf;
|
||||
uint8_t *recvbuf = BigBuf_get_addr();
|
||||
// UsbCommand n;
|
||||
|
||||
if (DEBUG) {
|
||||
|
||||
@@ -98,13 +98,14 @@ static uint32_t get_key_stream(int skip, int count)
|
||||
}
|
||||
|
||||
/* Write Time Data into LOG */
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
if(count == 6) { i = -1; } else { i = legic_read_count; }
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i] = legic_prng_count();
|
||||
((uint8_t*)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;
|
||||
((uint8_t*)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;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i] = count;
|
||||
BigBuf[OFFSET_LOG+128+i] = legic_prng_count();
|
||||
BigBuf[OFFSET_LOG+256+i*4] = (legic_prng_bc >> 0) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+1] = (legic_prng_bc >> 8) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+2] = (legic_prng_bc >>16) & 0xff;
|
||||
BigBuf[OFFSET_LOG+256+i*4+3] = (legic_prng_bc >>24) & 0xff;
|
||||
BigBuf[OFFSET_LOG+384+i] = count;
|
||||
|
||||
/* Generate KeyStream */
|
||||
for(i=0; i<count; i++) {
|
||||
@@ -426,6 +427,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||
|
||||
LegicCommonInit();
|
||||
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
memset(BigBuf, 0, 1024);
|
||||
|
||||
DbpString("setting up legic card");
|
||||
@@ -465,7 +467,7 @@ int LegicRfReader(int offset, int bytes) {
|
||||
LED_C_OFF();
|
||||
return -1;
|
||||
}
|
||||
((uint8_t*)BigBuf)[byte_index] = r;
|
||||
BigBuf[byte_index] = r;
|
||||
WDT_HIT();
|
||||
byte_index++;
|
||||
if(byte_index & 0x10) LED_C_ON(); else LED_C_OFF();
|
||||
@@ -480,7 +482,8 @@ int LegicRfReader(int offset, int bytes) {
|
||||
|
||||
void LegicRfWriter(int bytes, int offset) {
|
||||
int byte_index=0, addr_sz=0;
|
||||
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
|
||||
LegicCommonInit();
|
||||
|
||||
DbpString("setting up legic card");
|
||||
@@ -512,7 +515,7 @@ void LegicRfWriter(int bytes, int offset) {
|
||||
perform_setup_phase_rwd(SESSION_IV);
|
||||
legic_prng_forward(2);
|
||||
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()) {
|
||||
Dbprintf("operation aborted @ 0x%03.3x", byte_index);
|
||||
switch_off_tag_rwd();
|
||||
@@ -534,6 +537,8 @@ int timestamp;
|
||||
/* Handle (whether to respond) a frame in tag mode */
|
||||
static void frame_handle_tag(struct legic_frame const * const f)
|
||||
{
|
||||
uint8_t *BigBuf = BigBuf_get_addr();
|
||||
|
||||
/* First Part of Handshake (IV) */
|
||||
if(f->bits == 7) {
|
||||
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) {
|
||||
int key = get_key_stream(-1, 11); //legic_phase_drift, 11);
|
||||
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;
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
||||
BigBuf[OFFSET_LOG+legic_read_count] = (uint8_t)addr;
|
||||
legic_read_count++;
|
||||
|
||||
//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;
|
||||
Dbprintf("IV: %03.3x", legic_prng_iv);
|
||||
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++) {
|
||||
uint32_t t;
|
||||
t = ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4];
|
||||
t |= ((uint8_t*)BigBuf)[OFFSET_LOG+256+i*4+1] << 8;
|
||||
t |= ((uint8_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];
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+1] << 8;
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+2] <<16;
|
||||
t |= BigBuf[OFFSET_LOG+256+i*4+3] <<24;
|
||||
|
||||
Dbprintf("Cycles: %u, Frame Length: %u, Time: %u",
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+128+i],
|
||||
((uint8_t*)BigBuf)[OFFSET_LOG+384+i],
|
||||
BigBuf[OFFSET_LOG+128+i],
|
||||
BigBuf[OFFSET_LOG+384+i],
|
||||
t);
|
||||
}
|
||||
}
|
||||
|
||||
3064
armsrc/lfops.c
3064
armsrc/lfops.c
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@
|
||||
#include "mifarecmd.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "desfire.h"
|
||||
#include "../common/crc.h"
|
||||
|
||||
#include "crc.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticate, Read a MIFARE tag.
|
||||
@@ -76,7 +76,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
// ----------------------------- crypto1 destroy
|
||||
crypto1_destroy(pcs);
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||
@@ -104,14 +104,14 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
OnError(0);
|
||||
//OnError(0);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_ultra_auth1(cuid, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
OnError(1);
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part2: Fail...");
|
||||
OnError(1);
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,30 +161,30 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
|
||||
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);
|
||||
//OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
len = mifare_ultra_readblock(cuid, blockNo, dataout);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
|
||||
OnError(2);
|
||||
//OnError(2);
|
||||
return;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
len = mifare_ultra_halt(cuid);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
|
||||
OnError(3);
|
||||
//OnError(3);
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
cmd_send(CMD_ACK,1,0,0,dataout,16);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
@@ -261,14 +261,14 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t sectorNo = arg0;
|
||||
// params
|
||||
uint8_t sectorNo = arg0;
|
||||
int Pages = arg1;
|
||||
int count_Pages = 0;
|
||||
byte_t dataout[176] = {0x00};;
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
@@ -284,7 +284,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
if (!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
OnError(1);
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Read block %d error",i);
|
||||
OnError(2);
|
||||
//OnError(2);
|
||||
return;
|
||||
} else {
|
||||
count_Pages++;
|
||||
@@ -306,7 +306,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Halt error");
|
||||
OnError(3);
|
||||
//OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -400,49 +400,49 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
||||
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t blockdata[16] = {0x00};
|
||||
|
||||
memcpy(blockdata, datain, 16);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
memcpy(blockdata, datain,16);
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
|
||||
@@ -493,7 +493,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
|
||||
}
|
||||
|
||||
// Return 1 if the nonce is invalid else return 0
|
||||
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t * parity) {
|
||||
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
|
||||
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
|
||||
(oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \
|
||||
(oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0;
|
||||
@@ -529,11 +529,13 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
|
||||
uint32_t auth1_time, auth2_time;
|
||||
static uint16_t delta_time;
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(false);
|
||||
@@ -550,7 +552,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
WDT_HIT();
|
||||
|
||||
davg = dmax = 0;
|
||||
dmin = 2000;
|
||||
dmin = 2000;
|
||||
delta_time = 0;
|
||||
|
||||
for (rtr = 0; rtr < 17; rtr++) {
|
||||
@@ -605,7 +607,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
}
|
||||
}
|
||||
|
||||
if (rtr <= 1) return;
|
||||
if (rtr <= 1) return;
|
||||
|
||||
davg = (davg + (rtr - 1)/2) / (rtr - 1);
|
||||
|
||||
@@ -624,18 +626,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
// get crypted nonces for target sector
|
||||
for(i=0; i < 2; i++) { // look for exactly two different nonces
|
||||
|
||||
WDT_HIT();
|
||||
if(BUTTON_PRESS()) {
|
||||
DbpString("Nested: cancelled");
|
||||
crypto1_destroy(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
return;
|
||||
}
|
||||
|
||||
target_nt[i] = 0;
|
||||
while(target_nt[i] == 0) { // continue until we have an unambiguous nonce
|
||||
|
||||
|
||||
// prepare next select. No need to power down the card.
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");
|
||||
@@ -695,7 +688,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||
if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LED_C_OFF();
|
||||
|
||||
// ----------------------------- crypto1 destroy
|
||||
@@ -929,15 +922,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// reset FPGA and LED
|
||||
if (workFlags & 0x08) {
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
@@ -1048,14 +1041,14 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||
uint8_t data[18] = {0x00};
|
||||
uint32_t cuid = 0;
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
if (workFlags & 0x08) {
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
@@ -1113,8 +1106,8 @@ void MifareCIdent(){
|
||||
// variables
|
||||
byte_t isOK = 1;
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||
@@ -1133,7 +1126,7 @@ void MifareCIdent(){
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// DESFIRE
|
||||
//
|
||||
|
||||
@@ -1150,14 +1143,14 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
OnError(1);
|
||||
//OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_desfire_des_auth1(cuid, dataout)){
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Authentication part1: Fail.");
|
||||
OnError(4);
|
||||
//OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1173,7 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
if( isOK) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
|
||||
Dbprintf("Authentication part2: Failed");
|
||||
OnError(4);
|
||||
//OnError(4);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1190,4 +1183,4 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||
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 uint8_t sniffUIDType;
|
||||
static uint8_t sniffUID[8];
|
||||
static uint8_t sniffATQA[2];
|
||||
static uint8_t sniffUID[8] = {0x00};
|
||||
static uint8_t sniffATQA[2] = {0x00};
|
||||
static uint8_t sniffSAK;
|
||||
static uint8_t sniffBuf[16];
|
||||
static uint8_t sniffBuf[16] = {0x00};
|
||||
static uint32_t timerData = 0;
|
||||
|
||||
|
||||
@@ -151,12 +151,13 @@ bool intMfSniffSend() {
|
||||
int pckSize = 0;
|
||||
int pckLen = traceLen;
|
||||
int pckNum = 0;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
|
||||
FpgaDisableSscDma();
|
||||
while (pckLen > 0) {
|
||||
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
|
||||
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();
|
||||
|
||||
pckLen -= pckSize;
|
||||
|
||||
@@ -9,29 +9,18 @@
|
||||
// Work with mifare cards.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "../common/iso14443crc.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "iso14443a.h"
|
||||
#include "crapto1.h"
|
||||
#include "mifareutil.h"
|
||||
|
||||
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
|
||||
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
|
||||
uint8_t bt = 0;
|
||||
@@ -76,26 +65,26 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
|
||||
}
|
||||
|
||||
// send commands
|
||||
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)
|
||||
{
|
||||
return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, 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)
|
||||
{
|
||||
uint8_t dcmd[8];
|
||||
dcmd[0] = cmd;
|
||||
return mifare_sendcmd_shortex(pcs, crypted, cmd, data, answer, answer_parity, 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)
|
||||
{
|
||||
uint8_t dcmd[8];
|
||||
dcmd[0] = cmd;
|
||||
dcmd[1] = data[0];
|
||||
dcmd[2] = data[1];
|
||||
dcmd[2] = data[1];
|
||||
dcmd[3] = data[2];
|
||||
dcmd[4] = data[3];
|
||||
dcmd[5] = data[4];
|
||||
AppendCrc14443a(dcmd, 6);
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||
int len = ReaderReceive(answer, answer_parity);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
|
||||
return 2;
|
||||
AppendCrc14443a(dcmd, 6);
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), NULL);
|
||||
int len = ReaderReceive(answer, answer_parity);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout.");
|
||||
return 2;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@@ -117,13 +106,13 @@ int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uin
|
||||
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)
|
||||
{
|
||||
uint8_t dcmd[4], ecmd[4];
|
||||
}
|
||||
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)
|
||||
{
|
||||
uint8_t dcmd[4], ecmd[4];
|
||||
uint16_t pos, res;
|
||||
uint8_t par[1]; // 1 Byte parity is enough here
|
||||
dcmd[0] = cmd;
|
||||
@@ -149,7 +138,7 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
|
||||
int len = ReaderReceive(answer, par);
|
||||
|
||||
if (answer_parity) *answer_parity = par[0];
|
||||
|
||||
|
||||
if (crypted == CRYPT_ALL) {
|
||||
if (len == 1) {
|
||||
res = 0;
|
||||
@@ -175,7 +164,7 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo,
|
||||
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// variables
|
||||
int len;
|
||||
@@ -186,9 +175,9 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
|
||||
uint32_t nt, ntpp; // Supplied tag nonce
|
||||
|
||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// Transmit MIFARE_CLASSIC_AUTH
|
||||
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len);
|
||||
@@ -273,8 +262,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||
int len;
|
||||
uint8_t bt[2];
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -295,15 +284,15 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||
}
|
||||
|
||||
memcpy(blockData, receivedAnswer, 16);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mifare ultralight commands
|
||||
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
|
||||
|
||||
uint16_t len;
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
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) {
|
||||
@@ -327,8 +316,8 @@ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
|
||||
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
|
||||
uint16_t len;
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
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) {
|
||||
@@ -347,53 +336,53 @@ int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
}
|
||||
memcpy(blockData, receivedAnswer, 11);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t bt[2];
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
}
|
||||
|
||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t bt[2];
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
if (len != 18) {
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
if (len != 18) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: card timeout. len: %x", len);
|
||||
return 2;
|
||||
}
|
||||
|
||||
memcpy(bt, receivedAnswer + 16, 2);
|
||||
AppendCrc14443a(receivedAnswer, 16);
|
||||
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
|
||||
Dbprintf("Cmd Error: card timeout. len: %x", len);
|
||||
return 2;
|
||||
}
|
||||
|
||||
memcpy(bt, receivedAnswer + 16, 2);
|
||||
AppendCrc14443a(receivedAnswer, 16);
|
||||
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd CRC response error.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memcpy(blockData, receivedAnswer, 14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
// variables
|
||||
Dbprintf("Cmd CRC response error.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memcpy(blockData, receivedAnswer, 14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
// variables
|
||||
uint16_t len, i;
|
||||
uint32_t pos;
|
||||
uint8_t par[3] = {0}; // enough for 18 Bytes to send
|
||||
byte_t res;
|
||||
|
||||
uint8_t d_block[18], d_block_enc[18];
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
@@ -427,68 +416,68 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t par[3] = {0}; // enough for 18 parity bits
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(d_block, blockData, 16);
|
||||
AppendCrc14443a(d_block, 16);
|
||||
|
||||
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t par[3] = {0}; // enough for 18 parity bits
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t d_block[8] = {0x00};
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
d_block[0]= blockNo;
|
||||
memcpy(d_block+1,blockData,4);
|
||||
AppendCrc14443a(d_block, 6);
|
||||
|
||||
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(d_block, blockData, 16);
|
||||
AppendCrc14443a(d_block, 16);
|
||||
|
||||
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
|
||||
|
||||
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
{
|
||||
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t d_block[8] = {0x00};
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
d_block[0]= blockNo;
|
||||
memcpy(d_block+1,blockData,4);
|
||||
AppendCrc14443a(d_block, 6);
|
||||
|
||||
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
@@ -497,24 +486,24 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_halt(uint32_t uid)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_halt(uint32_t uid)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("halt error. response len: %x", len);
|
||||
return 1;
|
||||
Dbprintf("halt error. response len: %x", len);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
|
||||
// plus evtl. 8 sectors with 16 blocks each (4k cards)
|
||||
@@ -536,24 +525,24 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
|
||||
}
|
||||
|
||||
|
||||
// work with emulator memory
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
||||
// work with emulator memory
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int emlCheckValBl(int blockNum) {
|
||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
uint8_t* data = emCARD + blockNum * 16;
|
||||
|
||||
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) ||
|
||||
@@ -568,7 +557,7 @@ int emlCheckValBl(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;
|
||||
|
||||
if (emlCheckValBl(blockNum)) {
|
||||
@@ -576,12 +565,12 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
||||
}
|
||||
|
||||
memcpy(blReg, data, 4);
|
||||
*blBlock = data[12];
|
||||
*blBlock = data[12];
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
memcpy(data + 0, &blReg, 4);
|
||||
@@ -599,7 +588,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
|
||||
uint64_t emlGetKey(int sectorNum, int keyType) {
|
||||
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);
|
||||
return bytes_to_num(key, 6);
|
||||
@@ -610,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 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);
|
||||
|
||||
@@ -665,8 +654,8 @@ 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 = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
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) {
|
||||
@@ -695,8 +684,8 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
data[0] = 0xAF;
|
||||
memcpy(data+1,key,16);
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
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);
|
||||
|
||||
@@ -717,4 +706,4 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#define CRYPT_NONE 0
|
||||
#define CRYPT_ALL 1
|
||||
#define CRYPT_REQUEST 2
|
||||
#define AUTH_FIRST 0
|
||||
#define AUTH_FIRST 0
|
||||
#define AUTH_NESTED 2
|
||||
|
||||
// mifare 4bit card answers
|
||||
@@ -53,9 +53,8 @@ extern int MF_DBGLEVEL;
|
||||
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
|
||||
|
||||
//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_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);
|
||||
@@ -83,11 +82,6 @@ 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);
|
||||
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
|
||||
uint8_t NumBlocksPerSector(uint8_t sectorNo);
|
||||
uint8_t FirstBlockOfSector(uint8_t sectorNo);
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
int strlen(const char *str);
|
||||
RAMFUNC void *memcpy(void *dest, const void *src, int len);
|
||||
void *memset(void *dest, int c, int len);
|
||||
RAMFUNC int memcmp(const void *av, const void *bv, int len);
|
||||
RAMFUNC int memcmp(const void *av, const void *bv, int len);
|
||||
void memxor(uint8_t * dest, uint8_t * src, size_t len);
|
||||
char *strncat(char *dest, const char *src, unsigned int n);
|
||||
char *strcat(char *dest, const char *src);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
|
||||
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user