mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
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:
commit
64d1b4efc9
104 changed files with 462574 additions and 5340 deletions
97
armsrc/BigBuf.c
Normal file
97
armsrc/BigBuf.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, Aug 2005
|
||||
// Gerhard de Koning Gans, April 2008, May 2011
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// BigBuf and functions to allocate/free parts of it.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "string.h"
|
||||
|
||||
// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces.
|
||||
// Also used to hold various smaller buffers and the Mifare Emulator Memory.
|
||||
|
||||
// declare it as uint32_t to achieve alignment to 4 Byte boundary
|
||||
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
|
||||
|
||||
// High memory mark
|
||||
static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
||||
|
||||
// pointer to the emulator memory.
|
||||
static uint8_t *emulator_memory = NULL;
|
||||
|
||||
// trace related global variables
|
||||
// (only one left). ToDo: make this static as well?
|
||||
uint16_t traceLen = 0;
|
||||
|
||||
|
||||
// get the address of BigBuf
|
||||
uint8_t *BigBuf_get_addr(void)
|
||||
{
|
||||
return (uint8_t *)BigBuf;
|
||||
}
|
||||
|
||||
|
||||
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
|
||||
uint8_t *BigBuf_get_EM_addr(void)
|
||||
{
|
||||
if (emulator_memory == NULL) { // not yet allocated
|
||||
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
return emulator_memory;
|
||||
}
|
||||
|
||||
|
||||
// clear ALL of BigBuf
|
||||
void BigBuf_Clear(void)
|
||||
{
|
||||
memset(BigBuf,0,BIGBUF_SIZE);
|
||||
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||
}
|
||||
|
||||
|
||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||
// at the beginning of BigBuf is always for traces/samples
|
||||
uint8_t *BigBuf_malloc(uint16_t chunksize)
|
||||
{
|
||||
if (BigBuf_hi - chunksize < 0) {
|
||||
return NULL; // no memory left
|
||||
} else {
|
||||
chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
|
||||
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary
|
||||
return (uint8_t *)BigBuf + BigBuf_hi;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
|
||||
void BigBuf_free(void)
|
||||
{
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
emulator_memory = NULL;
|
||||
}
|
||||
|
||||
|
||||
// free allocated chunks EXCEPT the emulator memory
|
||||
void BigBuf_free_keep_EM(void)
|
||||
{
|
||||
if (emulator_memory != NULL) {
|
||||
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
|
||||
} else {
|
||||
BigBuf_hi = BIGBUF_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return the maximum trace length (i.e. the unallocated size of BigBuf)
|
||||
uint16_t BigBuf_max_traceLen(void)
|
||||
{
|
||||
return BigBuf_hi;
|
||||
}
|
34
armsrc/BigBuf.h
Normal file
34
armsrc/BigBuf.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Jonathan Westhues, Aug 2005
|
||||
// Gerhard de Koning Gans, April 2008, May 2011
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// BigBuf and functions to allocate/free parts of it.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __BIGBUF_H
|
||||
#define __BIGBUF_H
|
||||
|
||||
|
||||
#define BIGBUF_SIZE 40000
|
||||
#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
|
||||
#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
|
||||
#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
|
||||
#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
|
||||
#define CARD_MEMORY_SIZE 4096
|
||||
#define DMA_BUFFER_SIZE 128
|
||||
|
||||
extern uint8_t *BigBuf_get_addr(void);
|
||||
extern uint8_t *BigBuf_get_EM_addr(void);
|
||||
extern uint16_t BigBuf_max_traceLen(void);
|
||||
void BigBuf_Clear(void);
|
||||
extern uint8_t *BigBuf_malloc(uint16_t);
|
||||
extern void BigBuf_free(void);
|
||||
extern void BigBuf_free_keep_EM(void);
|
||||
|
||||
extern uint16_t traceLen;
|
||||
|
||||
#endif /* __BIGBUF_H */
|
|
@ -18,7 +18,7 @@ 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_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
|
||||
|
|
|
@ -42,12 +42,6 @@ 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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -871,27 +868,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
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
|
||||
|
||||
#ifdef WITH_ICLASS
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -679,7 +683,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
|
|||
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
|
||||
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;
|
||||
|
@ -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,14 +735,16 @@ 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();
|
||||
|
||||
|
@ -940,12 +947,16 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
|||
bool bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
byte_t* auth_table;
|
||||
BigBuf_free();
|
||||
auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
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 simulation");
|
||||
LED_D_ON();
|
||||
|
@ -1133,6 +1144,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
|
|||
// Clean up trace and prepare it for storing frames
|
||||
iso14a_set_tracing(TRUE);
|
||||
iso14a_clear_trace();
|
||||
|
||||
DbpString("Starting Hitag reader family");
|
||||
|
||||
// Check configuration
|
||||
|
|
258
armsrc/iclass.c
258
armsrc/iclass.c
|
@ -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,6 +745,7 @@ 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;
|
||||
|
@ -747,7 +753,7 @@ void RAMFUNC SnoopIClass(void)
|
|||
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) {
|
||||
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;
|
||||
}
|
||||
b >>= 1;
|
||||
}
|
||||
ToSend[++ToSendMax] = encode4Bits(b & 0xF); //Least significant half
|
||||
ToSend[++ToSendMax] = encode4Bits((b >>4) & 0xF);//Most significant half
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -1550,7 +1594,7 @@ void ReaderIClass(uint8_t arg0) {
|
|||
while(!BUTTON_PRESS())
|
||||
{
|
||||
|
||||
if(traceLen > TRACE_SIZE) {
|
||||
if(traceLen > BigBuf_max_traceLen()) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
@ -1613,7 +1657,7 @@ 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();
|
||||
|
||||
|
@ -1622,7 +1666,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -203,11 +204,13 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
|||
{
|
||||
if (!tracing) return FALSE;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||
uint16_t 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -910,6 +909,7 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
|||
// 166 bytes, since every bit that needs to be send costs us a byte
|
||||
//
|
||||
|
||||
|
||||
// Prepare the tag modulation bits from the message
|
||||
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
||||
|
||||
|
@ -930,12 +930,19 @@ 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)) {
|
||||
|
@ -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,12 +1028,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
|||
response2[4] = response2[0] ^ response2[1] ^ response2[2] ^ response2[3];
|
||||
|
||||
// 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]);
|
||||
|
||||
|
@ -1065,8 +1069,16 @@ 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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1721,26 +1730,18 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
|||
* 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
|
||||
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);
|
||||
|
@ -1779,7 +1780,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
|||
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] |= 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++;
|
||||
|
@ -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) {
|
||||
|
@ -2025,8 +2027,11 @@ 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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,7 +446,7 @@ 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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -1000,9 +999,9 @@ void ReaderIso15693(uint32_t parameter )
|
|||
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;
|
||||
|
@ -1016,7 +1015,7 @@ void ReaderIso15693(uint32_t parameter )
|
|||
|
||||
|
||||
// Blank arrays
|
||||
memset(BigBuf + 3660, 0x00, 300);
|
||||
memset(answer1, 0x00, 300);
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
|
@ -1112,7 +1111,7 @@ 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;
|
||||
|
@ -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,6 +482,7 @@ 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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
618
armsrc/lfops.c
618
armsrc/lfops.c
|
@ -8,25 +8,66 @@
|
|||
// Also routines for raw mode reading/simulating of LF waveform
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "../common/crc16.h"
|
||||
#include "../common/lfdemod.h"
|
||||
#include "hitag2.h"
|
||||
#include "crc16.h"
|
||||
#include "string.h"
|
||||
#include "crapto1.h"
|
||||
#include "mifareutil.h"
|
||||
#include "../include/hitag2.h"
|
||||
#include "lfdemod.h"
|
||||
|
||||
// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
|
||||
// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
|
||||
// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
|
||||
// T0 = TIMER_CLOCK1 / 125000 = 192
|
||||
#define T0 192
|
||||
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
/**
|
||||
* Does the sample acquisition. If threshold is specified, the actual sampling
|
||||
* is not commenced until the threshold has been reached.
|
||||
* @param trigger_threshold - the threshold
|
||||
* @param silent - is true, now outputs are made. If false, dbprints the status
|
||||
*/
|
||||
void DoAcquisition125k_internal(int trigger_threshold,bool silent)
|
||||
{
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int n = BigBuf_max_traceLen();
|
||||
int i;
|
||||
|
||||
memset(dest, 0, n);
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (trigger_threshold != -1 && dest[i] < trigger_threshold)
|
||||
continue;
|
||||
else
|
||||
trigger_threshold = -1;
|
||||
if (++i >= n) break;
|
||||
}
|
||||
}
|
||||
if(!silent)
|
||||
{
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Perform sample aquisition.
|
||||
*/
|
||||
void DoAcquisition125k(int trigger_threshold)
|
||||
{
|
||||
DoAcquisition125k_internal(trigger_threshold, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
|
||||
* if not already loaded, sets divisor and starts up the antenna.
|
||||
* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
|
||||
* 0 or 95 ==> 125 KHz
|
||||
*
|
||||
**/
|
||||
void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||
{
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
@ -41,76 +82,52 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
|
|||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelay(150);
|
||||
|
||||
SpinDelay(50);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the FPGA, and acquires the samples.
|
||||
**/
|
||||
void AcquireRawAdcSamples125k(int divisor)
|
||||
{
|
||||
LFSetupFPGAForADC(divisor, true);
|
||||
DoAcquisition125k();
|
||||
// Now call the acquisition routine
|
||||
DoAcquisition125k_internal(-1,false);
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for snoop-mode, and acquires the samples.
|
||||
**/
|
||||
|
||||
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
|
||||
{
|
||||
LFSetupFPGAForADC(divisor, false);
|
||||
DoAcquisition125k_threshold(trigger_threshold);
|
||||
}
|
||||
|
||||
// split into two routines so we can avoid timing issues after sending commands //
|
||||
void DoAcquisition125k_internal(int trigger_threshold, bool silent)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint16_t i = 0;
|
||||
memset(dest, 0x00, BIGBUF_SIZE);
|
||||
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
LED_D_OFF();
|
||||
if (trigger_threshold != -1 && dest[i] < trigger_threshold)
|
||||
continue;
|
||||
else
|
||||
trigger_threshold = -1;
|
||||
if (++i >= BIGBUF_SIZE) break;
|
||||
}
|
||||
}
|
||||
if (!silent){
|
||||
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
|
||||
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
|
||||
}
|
||||
}
|
||||
void DoAcquisition125k_threshold(int trigger_threshold) {
|
||||
DoAcquisition125k_internal(trigger_threshold, true);
|
||||
}
|
||||
void DoAcquisition125k() {
|
||||
DoAcquisition125k_internal(-1, true);
|
||||
DoAcquisition125k(trigger_threshold);
|
||||
}
|
||||
|
||||
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
|
||||
{
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
/* Make sure the tag is reset */
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelay(2500);
|
||||
|
||||
int divisor = 95; // 125 KHz
|
||||
// see if 'h' was specified
|
||||
if (command[strlen((char *) command) - 1] == 'h')
|
||||
divisor = 88; // 134.8 KHz
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
int divisor_used = 95; // 125 KHz
|
||||
// see if 'h' was specified
|
||||
|
||||
if (command[strlen((char *) command) - 1] == 'h')
|
||||
divisor_used = 88; // 134.8 KHz
|
||||
|
||||
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelay(50);
|
||||
|
||||
// And a little more time for the tag to fully power up
|
||||
SpinDelay(2000);
|
||||
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
|
@ -121,7 +138,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
LED_D_ON();
|
||||
|
@ -133,7 +150,8 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
|
|||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
SpinDelayUs(delay_off);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// now do the read
|
||||
|
@ -159,9 +177,8 @@ void ReadTItag(void)
|
|||
#define FREQLO 123200
|
||||
#define FREQHI 134200
|
||||
|
||||
signed char *dest = (signed char *)BigBuf;
|
||||
int n = sizeof(BigBuf);
|
||||
|
||||
signed char *dest = (signed char *)BigBuf_get_addr();
|
||||
uint16_t n = BigBuf_max_traceLen();
|
||||
// 128 bit shift register [shift3:shift2:shift1:shift0]
|
||||
uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
|
||||
|
||||
|
@ -289,17 +306,17 @@ void WriteTIbyte(uint8_t b)
|
|||
{
|
||||
if (b&(1<<i)) {
|
||||
// stop modulating antenna
|
||||
SHORT_COIL();
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
SpinDelayUs(1000);
|
||||
// modulate antenna
|
||||
OPEN_COIL();
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
SpinDelayUs(1000);
|
||||
} else {
|
||||
// stop modulating antenna
|
||||
SHORT_COIL();
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
SpinDelayUs(300);
|
||||
// modulate antenna
|
||||
OPEN_COIL();
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
SpinDelayUs(1700);
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +330,8 @@ void AcquireTiType(void)
|
|||
#define TIBUFLEN 1250
|
||||
|
||||
// clear buffer
|
||||
memset(BigBuf,0,sizeof(BigBuf));
|
||||
uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr();
|
||||
memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t));
|
||||
|
||||
// Set up the synchronous serial port
|
||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
|
||||
|
@ -361,7 +379,7 @@ void AcquireTiType(void)
|
|||
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
|
||||
|
||||
char *dest = (char *)BigBuf;
|
||||
char *dest = (char *)BigBuf_get_addr();
|
||||
n = TIBUFLEN*32;
|
||||
// unpack buffer
|
||||
for (i=TIBUFLEN-1; i>=0; i--) {
|
||||
|
@ -447,167 +465,61 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
|
|||
DbpString("Now use tiread to check");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// PIO_CODR = Clear Output Data Register
|
||||
// PIO_SODR = Set Output Data Register
|
||||
//#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x)
|
||||
//#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x)
|
||||
void SimulateTagLowFrequency( uint16_t period, uint32_t gap, uint8_t ledcontrol)
|
||||
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
|
||||
{
|
||||
int i;
|
||||
uint8_t *tab = BigBuf_get_addr();
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
|
||||
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
|
||||
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
|
||||
i = 0;
|
||||
for(;;) {
|
||||
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
|
||||
if(BUTTON_PRESS()) {
|
||||
DbpString("Stopped");
|
||||
return;
|
||||
}
|
||||
WDT_HIT();
|
||||
}
|
||||
|
||||
if (ledcontrol)
|
||||
LED_D_ON();
|
||||
|
||||
uint16_t i = 0;
|
||||
uint8_t send = 0;
|
||||
|
||||
//int overflow = 0;
|
||||
uint8_t *buf = (uint8_t *)BigBuf;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
RELAY_OFF();
|
||||
|
||||
// Configure output pin that is connected to the FPGA (for modulating)
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
|
||||
if(tab[i])
|
||||
OPEN_COIL();
|
||||
else
|
||||
SHORT_COIL();
|
||||
|
||||
// Enable Peripheral Clock for TIMER_CLOCK0, used to measure exact timing before answering
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
|
||||
|
||||
// Enable Peripheral Clock for TIMER_CLOCK1, used to capture edges of the reader frames
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// external trigger rising edge, load RA on rising edge of TIOA.
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_RISING | AT91C_TC_ABETRG | AT91C_TC_LDRA_RISING;
|
||||
|
||||
// Enable and reset counter
|
||||
//AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
|
||||
// Receive frame, watch for at most T0*EOF periods
|
||||
while (AT91C_BASE_TC1->TC_CV < T0 * 55) {
|
||||
|
||||
// Check if rising edge in modulation is detected
|
||||
if(AT91C_BASE_TC1->TC_SR & AT91C_TC_LDRAS) {
|
||||
// Retrieve the new timing values
|
||||
//int ra = (AT91C_BASE_TC1->TC_RA/T0) + overflow;
|
||||
//Dbprintf("Timing value - %d %d", ra, overflow);
|
||||
//overflow = 0;
|
||||
|
||||
// Reset timer every frame, we have to capture the last edge for timing
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
send = 1;
|
||||
|
||||
LED_B_ON();
|
||||
}
|
||||
}
|
||||
|
||||
if ( send ) {
|
||||
// Disable timer 1 with external trigger to avoid triggers during our own modulation
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// Wait for HITAG_T_WAIT_1 carrier periods after the last reader bit,
|
||||
// not that since the clock counts since the rising edge, but T_Wait1 is
|
||||
// with respect to the falling edge, we need to wait actually (T_Wait1 - T_Low)
|
||||
// periods. The gap time T_Low varies (4..10). All timer values are in
|
||||
// terms of T0 units
|
||||
while(AT91C_BASE_TC0->TC_CV < T0 * 16 );
|
||||
|
||||
// datat kommer in som 1 bit för varje position i arrayn
|
||||
for(i = 0; i < period; ++i) {
|
||||
|
||||
// Reset clock for the next bit
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
|
||||
|
||||
if ( buf[i] > 0 )
|
||||
HIGH(GPIO_SSC_DOUT);
|
||||
else
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
while(AT91C_BASE_TC0->TC_CV < T0 * 1 );
|
||||
}
|
||||
// Drop modulation
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
// Enable and reset external trigger in timer for capturing future frames
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
send = 0;
|
||||
|
||||
// Save the timer overflow, will be 0 when frame was received
|
||||
//overflow += (AT91C_BASE_TC1->TC_CV/T0);
|
||||
|
||||
// Reset the timer to restart while-loop that receives frames
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||
}
|
||||
|
||||
LED_B_OFF();
|
||||
if (ledcontrol)
|
||||
LED_D_OFF();
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
DbpString("Sim Stopped");
|
||||
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
|
||||
if(BUTTON_PRESS()) {
|
||||
DbpString("Stopped");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void SimulateTagLowFrequencyA(int len, int gap)
|
||||
{
|
||||
uint8_t *buf = (uint8_t *)BigBuf;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE); // new izsh toggle mode!
|
||||
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
SpinDelay(5);
|
||||
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
|
||||
int i = 0;
|
||||
while(!BUTTON_PRESS()) {
|
||||
WDT_HIT();
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
}
|
||||
|
||||
if ( buf[i] > 0 )
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
else
|
||||
AT91C_BASE_SSC->SSC_THR = 0x00;
|
||||
|
||||
++i;
|
||||
LED_A_ON();
|
||||
if (i >= len){
|
||||
i++;
|
||||
if(i == period) {
|
||||
i = 0;
|
||||
if (gap) {
|
||||
SHORT_COIL();
|
||||
SpinDelayUs(gap);
|
||||
}
|
||||
}
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
|
||||
(void)r;
|
||||
LED_A_OFF();
|
||||
}
|
||||
}
|
||||
DbpString("lf simulate stopped");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
}
|
||||
|
||||
#define DEBUG_FRAME_CONTENTS 1
|
||||
void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
||||
|
@ -615,8 +527,8 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
|
|||
}
|
||||
|
||||
// compose fc/8 fc/10 waveform
|
||||
static void fc(int c, uint16_t *n) {
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
static void fc(int c, int *n) {
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int idx;
|
||||
|
||||
// for when we want an fc8 pattern every 4 logical bits
|
||||
|
@ -663,9 +575,9 @@ static void fc(int c, uint16_t *n) {
|
|||
|
||||
// prepare a waveform pattern in the buffer based on the ID given then
|
||||
// simulate a HID tag until the button is pressed
|
||||
void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol)
|
||||
void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
|
||||
{
|
||||
uint16_t n = 0, i = 0;
|
||||
int n=0, i=0;
|
||||
/*
|
||||
HID tag bitstream format
|
||||
The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
|
||||
|
@ -711,7 +623,6 @@ void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol)
|
|||
|
||||
if (ledcontrol)
|
||||
LED_A_ON();
|
||||
|
||||
SimulateTagLowFrequency(n, 0, ledcontrol);
|
||||
|
||||
if (ledcontrol)
|
||||
|
@ -721,11 +632,13 @@ void CmdHIDsimTAG(int hi, int lo, uint8_t ledcontrol)
|
|||
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
|
||||
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
const size_t sizeOfBigBuff = BigBuf_max_traceLen();
|
||||
size_t size = 0;
|
||||
uint32_t hi2=0, hi=0, lo=0;
|
||||
|
||||
int idx=0;
|
||||
// Configure to go in 125Khz listen mode
|
||||
LFSetupFPGAForADC(0, true);
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
|
||||
|
@ -733,31 +646,21 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
if (ledcontrol) LED_A_ON();
|
||||
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
|
||||
// FSK demodulator
|
||||
int bitLen = HIDdemodFSK(dest,BIGBUF_SIZE,&hi2,&hi,&lo);
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
if (bitLen > 0 && lo > 0){
|
||||
size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
|
||||
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
|
||||
|
||||
if (idx>0 && lo>0){
|
||||
// final loop, go over previously decoded manchester data and decode into usable tag ID
|
||||
// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
|
||||
|
||||
if (hi2 != 0){
|
||||
//extra large HID tags
|
||||
if (hi2 != 0){ //extra large HID tags
|
||||
Dbprintf("TAG ID: %x%08x%08x (%d)",
|
||||
(unsigned int) hi2,
|
||||
(unsigned int) hi,
|
||||
(unsigned int) lo,
|
||||
(unsigned int) (lo >> 1) & 0xFFFF);
|
||||
|
||||
} else {
|
||||
//standard HID tags <38 bits
|
||||
(unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
|
||||
}else { //standard HID tags <38 bits
|
||||
//Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
|
||||
uint8_t bitlen = 0;
|
||||
uint32_t fc = 0;
|
||||
uint32_t cardnum = 0;
|
||||
|
||||
if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used
|
||||
uint32_t lo2=0;
|
||||
lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
|
||||
|
@ -795,16 +698,16 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
fc = ((hi&0xF)<<12)|(lo>>20);
|
||||
}
|
||||
}
|
||||
//Dbprintf("TAG ID: %x%08x (%d)",
|
||||
// (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
|
||||
Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
|
||||
(unsigned int) hi,
|
||||
(unsigned int) lo,
|
||||
(unsigned int) (lo >> 1) & 0xFFFF,
|
||||
(unsigned int) bitlen,
|
||||
(unsigned int) fc,
|
||||
(unsigned int) cardnum);
|
||||
(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
|
||||
(unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
|
||||
}
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
*high = hi;
|
||||
*low = lo;
|
||||
return;
|
||||
}
|
||||
// reset
|
||||
|
@ -818,13 +721,13 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
|
||||
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint32_t bitLen = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
size_t size=0, idx=0;
|
||||
int clk=0, invert=0, errCnt=0;
|
||||
uint64_t lo=0;
|
||||
|
||||
// Configure to go in 125Khz listen mode
|
||||
LFSetupFPGAForADC(0, true);
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
|
||||
|
@ -832,33 +735,39 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
|||
if (ledcontrol) LED_A_ON();
|
||||
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
|
||||
// FSK demodulator
|
||||
bitLen = BIGBUF_SIZE;
|
||||
errCnt = askmandemod(dest,&bitLen,&clk,&invert);
|
||||
if ( errCnt < 0 ) continue;
|
||||
|
||||
size = BigBuf_max_traceLen();
|
||||
//Dbprintf("DEBUG: Buffer got");
|
||||
//askdemod and manchester decode
|
||||
errCnt = askmandemod(dest, &size, &clk, &invert);
|
||||
//Dbprintf("DEBUG: ASK Got");
|
||||
WDT_HIT();
|
||||
|
||||
lo = Em410xDecode(dest,bitLen);
|
||||
|
||||
if ( lo <= 0) continue;
|
||||
|
||||
if (errCnt>=0){
|
||||
lo = Em410xDecode(dest, &size, &idx);
|
||||
//Dbprintf("DEBUG: EM GOT");
|
||||
if (lo>0){
|
||||
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
|
||||
(uint32_t)(lo>>32),
|
||||
(uint32_t)lo,
|
||||
(uint32_t)(lo&0xFFFF),
|
||||
(uint32_t)((lo>>16LL) & 0xFF),
|
||||
(uint32_t)(lo & 0xFFFFFF)
|
||||
);
|
||||
|
||||
(uint32_t)(lo & 0xFFFFFF));
|
||||
}
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
*high=lo>>32;
|
||||
*low=lo & 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
|
||||
} else{
|
||||
//Dbprintf("DEBUG: No Tag");
|
||||
}
|
||||
WDT_HIT();
|
||||
lo = clk = invert = errCnt = 0;
|
||||
lo = 0;
|
||||
clk=0;
|
||||
invert=0;
|
||||
errCnt=0;
|
||||
size=0;
|
||||
}
|
||||
DbpString("Stopped");
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
|
@ -866,28 +775,24 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
|
|||
|
||||
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||
{
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int idx=0;
|
||||
uint32_t code=0, code2=0;
|
||||
uint8_t version=0;
|
||||
uint8_t facilitycode=0;
|
||||
uint16_t number=0;
|
||||
|
||||
LFSetupFPGAForADC(0, true);
|
||||
// Configure to go in 125Khz listen mode
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
while(!BUTTON_PRESS()) {
|
||||
|
||||
WDT_HIT();
|
||||
if (ledcontrol) LED_A_ON();
|
||||
|
||||
DoAcquisition125k_internal(-1,true);
|
||||
|
||||
idx = IOdemodFSK(dest, BIGBUF_SIZE);
|
||||
|
||||
if ( idx < 0 )
|
||||
continue;
|
||||
|
||||
//fskdemod and get start index
|
||||
WDT_HIT();
|
||||
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
|
||||
if (idx>0){
|
||||
//valid tag found
|
||||
|
||||
//Index map
|
||||
//0 10 20 30 40 50 60
|
||||
|
@ -898,7 +803,6 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
//
|
||||
//XSF(version)facility:codeone+codetwo
|
||||
//Handle the data
|
||||
|
||||
if(findone){ //only print binary if we are doing one
|
||||
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
|
||||
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
|
||||
|
@ -908,7 +812,6 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
|
||||
Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
|
||||
}
|
||||
|
||||
code = bytebits_to_byte(dest+idx,32);
|
||||
code2 = bytebits_to_byte(dest+idx+32,32);
|
||||
version = bytebits_to_byte(dest+idx+27,8); //14,4
|
||||
|
@ -916,8 +819,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
|
||||
|
||||
Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
|
||||
// if we're only looking for one tag
|
||||
if (findone){
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
//LED_A_OFF();
|
||||
*high=code;
|
||||
*low=code2;
|
||||
return;
|
||||
}
|
||||
code=code2=0;
|
||||
|
@ -925,7 +832,8 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
number=0;
|
||||
idx=0;
|
||||
}
|
||||
|
||||
WDT_HIT();
|
||||
}
|
||||
DbpString("Stopped");
|
||||
if (ledcontrol) LED_A_OFF();
|
||||
}
|
||||
|
@ -989,20 +897,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
* To compensate antenna falling times shorten the write times
|
||||
* and enlarge the gap ones.
|
||||
*/
|
||||
#define START_GAP 30*8 // 10 - 50fc 250
|
||||
#define WRITE_GAP 20*8 // 8 - 30fc
|
||||
#define WRITE_0 24*8 // 16 - 31fc 24fc 192
|
||||
#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550
|
||||
|
||||
// VALUES TAKEN FROM EM4x function: SendForward
|
||||
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
|
||||
// WRITE_GAP = 128; (16*8)
|
||||
// WRITE_1 = 256 32*8; (32*8)
|
||||
|
||||
// These timings work for 4469/4269/4305 (with the 55*8 above)
|
||||
// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
|
||||
|
||||
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
|
||||
#define START_GAP 250
|
||||
#define WRITE_GAP 160
|
||||
#define WRITE_0 144 // 192
|
||||
#define WRITE_1 400 // 432 for T55x7; 448 for E5550
|
||||
|
||||
// Write one bit to card
|
||||
void T55xxWriteBit(int bit)
|
||||
|
@ -1010,7 +908,7 @@ void T55xxWriteBit(int bit)
|
|||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
if (!bit)
|
||||
if (bit == 0)
|
||||
SpinDelayUs(WRITE_0);
|
||||
else
|
||||
SpinDelayUs(WRITE_1);
|
||||
|
@ -1021,11 +919,16 @@ void T55xxWriteBit(int bit)
|
|||
// Write one card block in page 0, no lock
|
||||
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
//unsigned int i; //enio adjustment 12/10/14
|
||||
uint32_t i;
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
@ -1061,17 +964,27 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
|
|||
// Read one card block in page 0
|
||||
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
||||
{
|
||||
uint8_t *dest = get_bigbufptr_recvrespbuf();
|
||||
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
//int m=0, i=0; //enio adjustment 12/10/14
|
||||
uint32_t m=0, i=0;
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
|
||||
// Clear destination buffer before sending the command 0x80 = average.
|
||||
memset(dest, 0x80, bufferlength);
|
||||
LED_D_ON();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
// Wait for config.. (192+8190xPOW)x8 == 67ms
|
||||
LFSetupFPGAForADC(0, true);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
|
@ -1090,40 +1003,53 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
|
|||
T55xxWriteBit(Block & i);
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
//AT91C_BASE_SSC->SSC_THR = 0xff;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
++i;
|
||||
LED_D_OFF();
|
||||
if (i >= bufferlength) break;
|
||||
// we don't care about actual value, only if it's more or less than a
|
||||
// threshold essentially we capture zero crossings for later analysis
|
||||
// if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
|
||||
i++;
|
||||
if (i >= m) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
DbpString("DONE!");
|
||||
}
|
||||
|
||||
// Read card traceability data (page 1)
|
||||
void T55xxReadTrace(void){
|
||||
uint8_t *dest = get_bigbufptr_recvrespbuf();
|
||||
uint16_t bufferlength = T55xx_SAMPLES_SIZE;
|
||||
uint32_t i = 0;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int m=0, i=0;
|
||||
|
||||
// Clear destination buffer before sending the command 0x80 = average
|
||||
memset(dest, 0x80, bufferlength);
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
FpgaSetupSsc();
|
||||
|
||||
LFSetupFPGAForADC(0, true);
|
||||
LED_D_ON();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
// And for the tag to fully power up
|
||||
SpinDelay(150);
|
||||
|
||||
// Now start writting
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
|
||||
|
@ -1132,34 +1058,25 @@ void T55xxReadTrace(void){
|
|||
T55xxWriteBit(1); //Page 1
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn();
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
|
||||
AT91C_BASE_SSC->SSC_THR = 0x43;
|
||||
LED_D_ON();
|
||||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
++i;
|
||||
LED_D_OFF();
|
||||
|
||||
if (i >= bufferlength) break;
|
||||
i++;
|
||||
if (i >= m) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
void TurnReadLFOn(){
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
//SpinDelay(30);
|
||||
SpinDelayUs(8*150);
|
||||
DbpString("DONE!");
|
||||
}
|
||||
|
||||
/*-------------- Cloning routines -----------*/
|
||||
|
@ -1418,6 +1335,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
|
|||
// Clone Indala 64-bit tag by UID to T55x7
|
||||
void CopyIndala64toT55x7(int hi, int lo)
|
||||
{
|
||||
|
||||
//Program the 2 data blocks for supplied 64bit UID
|
||||
// and the block 0 for Indala64 format
|
||||
T55xxWriteBlock(hi,1,0,0);
|
||||
|
@ -1431,10 +1349,12 @@ void CopyIndala64toT55x7(int hi, int lo)
|
|||
// T5567WriteBlock(0x603E1042,0);
|
||||
|
||||
DbpString("DONE!");
|
||||
|
||||
}
|
||||
|
||||
void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
|
||||
{
|
||||
|
||||
//Program the 7 data blocks for supplied 224bit UID
|
||||
// and the block 0 for Indala224 format
|
||||
T55xxWriteBlock(uid1,1,0,0);
|
||||
|
@ -1453,6 +1373,7 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
|
|||
// T5567WriteBlock(0x603E10E2,0);
|
||||
|
||||
DbpString("DONE!");
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1462,8 +1383,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
|
|||
int DemodPCF7931(uint8_t **outBlocks) {
|
||||
uint8_t BitStream[256];
|
||||
uint8_t Blocks[8][16];
|
||||
uint8_t *GraphBuffer = (uint8_t *)BigBuf;
|
||||
int GraphTraceLen = sizeof(BigBuf);
|
||||
uint8_t *GraphBuffer = BigBuf_get_addr();
|
||||
int GraphTraceLen = BigBuf_max_traceLen();
|
||||
int i, j, lastval, bitidx, half_switch;
|
||||
int clock = 64;
|
||||
int tolerance = clock / 8;
|
||||
|
@ -1602,6 +1523,7 @@ int IsBlock1PCF7931(uint8_t *Block) {
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ALLOC 16
|
||||
|
||||
void ReadPCF7931() {
|
||||
|
@ -1861,7 +1783,6 @@ void SendForward(uint8_t fwd_bit_count) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void EM4xLogin(uint32_t Password) {
|
||||
|
||||
uint8_t fwd_bit_count;
|
||||
|
@ -1879,14 +1800,9 @@ void EM4xLogin(uint32_t Password) {
|
|||
|
||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||
|
||||
uint8_t *dest = (uint8_t *)BigBuf;
|
||||
uint16_t bufferlength = 12000;
|
||||
uint32_t i = 0;
|
||||
|
||||
// Clear destination buffer before sending the command 0x80 = average.
|
||||
memset(dest, 0x80, bufferlength);
|
||||
|
||||
uint8_t fwd_bit_count;
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
int m=0, i=0;
|
||||
|
||||
//If password mode do login
|
||||
if (PwdMode == 1) EM4xLogin(Pwd);
|
||||
|
@ -1895,6 +1811,9 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
|||
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
|
||||
fwd_bit_count += Prepare_Addr( Address );
|
||||
|
||||
m = BigBuf_max_traceLen();
|
||||
// Clear destination buffer before sending the command
|
||||
memset(dest, 128, m);
|
||||
// Connect the A/D to the peak-detected low-frequency path.
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
// Now set up the SSC to get the ADC samples that are now streaming at us.
|
||||
|
@ -1902,9 +1821,6 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
|||
|
||||
SendForward(fwd_bit_count);
|
||||
|
||||
// // Turn field on to read the response
|
||||
// TurnReadLFOn();
|
||||
|
||||
// Now do the acquisition
|
||||
i = 0;
|
||||
for(;;) {
|
||||
|
@ -1913,12 +1829,10 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
|||
}
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
++i;
|
||||
if (i >= bufferlength) break;
|
||||
i++;
|
||||
if (i >= m) break;
|
||||
}
|
||||
}
|
||||
|
||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -168,21 +168,21 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
|||
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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -624,15 +626,6 @@ 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
|
||||
|
||||
|
@ -929,8 +922,8 @@ 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) {
|
||||
|
@ -1048,8 +1041,8 @@ 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();
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -186,8 +175,8 @@ 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);
|
||||
|
@ -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);
|
||||
|
@ -302,8 +291,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
|||
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) {
|
||||
|
@ -353,8 +342,8 @@ 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;
|
||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||
|
||||
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
|
@ -392,8 +381,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
|||
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);
|
||||
|
@ -435,8 +424,8 @@ 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;
|
||||
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);
|
||||
|
@ -466,8 +455,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
|||
{
|
||||
uint16_t len;
|
||||
uint8_t d_block[8] = {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];
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
d_block[0]= blockNo;
|
||||
|
@ -487,8 +476,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc
|
|||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
{
|
||||
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) {
|
||||
|
@ -503,8 +492,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
|||
int mifare_ultra_halt(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(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
|
@ -538,22 +527,22 @@ 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();
|
||||
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)) {
|
||||
|
@ -581,7 +570,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
|
|||
}
|
||||
|
||||
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
|
||||
uint8_t* emCARD = get_bigbufptr_emlcardmem();
|
||||
uint8_t* emCARD = BigBuf_get_EM_addr();
|
||||
uint8_t* data = emCARD + blockNum * 16;
|
||||
|
||||
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);
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ 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);
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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 )
|
||||
|
||||
|
|
|
@ -9,18 +9,16 @@ include ../common/Makefile.common
|
|||
CC=gcc
|
||||
CXX=g++
|
||||
#COMMON_FLAGS = -m32
|
||||
|
||||
VPATH = ../common
|
||||
OBJDIR = obj
|
||||
|
||||
LDLIBS = -L/mingw/lib -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lm -lreadline -lpthread -lcrypto -lgdi32
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
||||
LDFLAGS = $(COMMON_FLAGS)
|
||||
CFLAGS = -std=c99 -lcrypto -I. -I../include -I../common -I/mingw/include -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||
LUAPLATFORM = generic
|
||||
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui -I$(QTDIR)/include/QtWidgets -I/mingw/include
|
||||
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
|
||||
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
||||
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
||||
MOC = $(QTDIR)/bin/moc
|
||||
LUAPLATFORM = mingw
|
||||
else ifeq ($(platform),Darwin)
|
||||
|
@ -62,7 +60,6 @@ CMDSRCS = nonce2key/crapto1.c\
|
|||
loclass/ikeys.c \
|
||||
loclass/elite_crack.c\
|
||||
loclass/fileutils.c\
|
||||
loclass/hash1_brute.c \
|
||||
mifarehost.c\
|
||||
crc16.c \
|
||||
iso14443crc.c \
|
||||
|
@ -81,11 +78,8 @@ CMDSRCS = nonce2key/crapto1.c\
|
|||
cmdhficlass.c \
|
||||
cmdhfmf.c \
|
||||
cmdhfmfu.c \
|
||||
cmdhfmfdes.c \
|
||||
cmdhfdes.c \
|
||||
cmdhw.c \
|
||||
cmdlf.c \
|
||||
cmdlfawid26.c \
|
||||
cmdlfio.c \
|
||||
cmdlfhid.c \
|
||||
cmdlfem4x.c \
|
||||
|
@ -99,6 +93,7 @@ CMDSRCS = nonce2key/crapto1.c\
|
|||
scripting.c\
|
||||
cmdscript.c\
|
||||
pm3_bitlib.c\
|
||||
aes.c\
|
||||
|
||||
|
||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||
|
|
1454
client/aes.c
Normal file
1454
client/aes.c
Normal file
File diff suppressed because it is too large
Load diff
257
client/aes.h
Normal file
257
client/aes.h
Normal file
|
@ -0,0 +1,257 @@
|
|||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2014, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_AES_H
|
||||
#define POLARSSL_AES_H
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_FILE)
|
||||
#include "polarssl_config.h"
|
||||
#else
|
||||
#include POLARSSL_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* padlock.c and aesni.c rely on these values! */
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_AES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
||||
* - for alignment purposes if VIA padlock is used, and/or
|
||||
* - to simplify key expansion in the 256-bit case by
|
||||
* generating an extra round key
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t *rk; /*!< AES round keys */
|
||||
uint32_t buf[68]; /*!< unaligned data */
|
||||
}
|
||||
aes_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize AES context
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
*/
|
||||
void aes_init( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear AES context
|
||||
*
|
||||
* \param ctx AES context to be cleared
|
||||
*/
|
||||
void aes_free( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (encryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int aes_crypt_cbc( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb128( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB8 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb8( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /*POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ctr( aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_AES_ALT */
|
||||
#include "aes_alt.h"
|
||||
#endif /* POLARSSL_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int aes_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
1123
client/cmddata.c
1123
client/cmddata.c
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@
|
|||
command_t * CmdDataCommands();
|
||||
|
||||
int CmdData(const char *Cmd);
|
||||
|
||||
void printDemodBuff();
|
||||
int CmdAmp(const char *Cmd);
|
||||
int Cmdaskdemod(const char *Cmd);
|
||||
int Cmdaskrawdemod(const char *Cmd);
|
||||
|
@ -26,10 +26,15 @@ int CmdBitstream(const char *Cmd);
|
|||
int CmdBuffClear(const char *Cmd);
|
||||
int CmdDec(const char *Cmd);
|
||||
int CmdDetectClockRate(const char *Cmd);
|
||||
int CmdFSKdemodAWID(const char *Cmd);
|
||||
int CmdFSKdemod(const char *Cmd);
|
||||
int CmdFSKdemodHID(const char *Cmd);
|
||||
int CmdFSKdemodIO(const char *Cmd);
|
||||
int CmdFSKdemodParadox(const char *Cmd);
|
||||
int CmdFSKdemodPyramid(const char *Cmd);
|
||||
int CmdFSKrawdemod(const char *Cmd);
|
||||
int CmdDetectNRZpskClockRate(const char *Cmd);
|
||||
int CmdpskNRZrawDemod(const char *Cmd);
|
||||
int CmdGrid(const char *Cmd);
|
||||
int CmdHexsamples(const char *Cmd);
|
||||
int CmdHide(const char *Cmd);
|
||||
|
@ -43,10 +48,18 @@ int CmdManchesterMod(const char *Cmd);
|
|||
int CmdNorm(const char *Cmd);
|
||||
int CmdPlot(const char *Cmd);
|
||||
int CmdSamples(const char *Cmd);
|
||||
int CmdTuneSamples(const char *Cmd);
|
||||
int CmdSave(const char *Cmd);
|
||||
int CmdScale(const char *Cmd);
|
||||
int CmdThreshold(const char *Cmd);
|
||||
int CmdDirectionalThreshold(const char *Cmd);
|
||||
int CmdZerocrossings(const char *Cmd);
|
||||
int CmdTuneSamples(const char *Cmd);
|
||||
int CmdIndalaDecode(const char *Cmd);
|
||||
|
||||
#define MAX_DEMOD_BUF_LEN (1024*128)
|
||||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
extern int DemodBufferLen;
|
||||
|
||||
#define BIGBUF_SIZE 40000
|
||||
|
||||
#endif
|
||||
|
|
275
client/cmdhf.c
275
client/cmdhf.c
|
@ -23,8 +23,6 @@
|
|||
#include "cmdhficlass.h"
|
||||
#include "cmdhfmf.h"
|
||||
#include "cmdhfmfu.h"
|
||||
#include "cmdhfmfdes.h"
|
||||
#include "cmdhfdes.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
@ -34,8 +32,6 @@ int CmdHFTune(const char *Cmd)
|
|||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
// for the time being. Need better Bigbuf handling.
|
||||
#define TRACE_SIZE 3000
|
||||
|
||||
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
|
||||
/*
|
||||
|
@ -130,19 +126,24 @@ NXP/Philips CUSTOM COMMANDS
|
|||
#define ICLASS_CMD_READ_OR_IDENTIFY 0x0C
|
||||
#define ICLASS_CMD_SELECT 0x81
|
||||
#define ICLASS_CMD_PAGESEL 0x84
|
||||
#define ICLASS_CMD_READCHECK 0x88
|
||||
#define ICLASS_CMD_READCHECK_KD 0x88
|
||||
#define ICLASS_CMD_READCHECK_KC 0x18
|
||||
#define ICLASS_CMD_CHECK 0x05
|
||||
#define ICLASS_CMD_SOF 0x0F
|
||||
#define ICLASS_CMD_DETECT 0x0F
|
||||
#define ICLASS_CMD_HALT 0x00
|
||||
#define ICLASS_CMD_UPDATE 0x87
|
||||
#define ICLASS_CMD_ACT 0x8E
|
||||
#define ICLASS_CMD_READ4 0x06
|
||||
|
||||
#define ISO14443_CMD_REQA 0x26
|
||||
#define ISO14443_CMD_READBLOCK 0x30
|
||||
#define ISO14443_CMD_WUPA 0x52
|
||||
#define ISO14443_CMD_ANTICOLL_OR_SELECT 0x93
|
||||
#define ISO14443_CMD_ANTICOLL_OR_SELECT_2 0x95
|
||||
#define ISO14443_CMD_WRITEBLOCK 0xA0 // or 0xA2 ?
|
||||
#define ISO14443_CMD_HALT 0x50
|
||||
#define ISO14443_CMD_RATS 0xE0
|
||||
|
||||
#define ISO14443A_CMD_REQA 0x26
|
||||
#define ISO14443A_CMD_READBLOCK 0x30
|
||||
#define ISO14443A_CMD_WUPA 0x52
|
||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
||||
#define ISO14443A_CMD_WRITEBLOCK 0xA0 // or 0xA2 ?
|
||||
#define ISO14443A_CMD_HALT 0x50
|
||||
#define ISO14443A_CMD_RATS 0xE0
|
||||
|
||||
#define MIFARE_AUTH_KEYA 0x60
|
||||
#define MIFARE_AUTH_KEYB 0x61
|
||||
|
@ -178,17 +179,20 @@ NXP/Philips CUSTOM COMMANDS
|
|||
#define ISO15693_READ_MULTI_SECSTATUS 0x2C
|
||||
|
||||
|
||||
#define ISO_14443A 0
|
||||
#define ICLASS 1
|
||||
#define ISO_14443B 2
|
||||
|
||||
|
||||
void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
{
|
||||
switch(cmd[0])
|
||||
{
|
||||
case ISO14443_CMD_WUPA: snprintf(exp,size,"WUPA"); break;
|
||||
case ISO14443_CMD_ANTICOLL_OR_SELECT:{
|
||||
case ISO14443A_CMD_WUPA: snprintf(exp,size,"WUPA"); break;
|
||||
case ISO14443A_CMD_ANTICOLL_OR_SELECT:{
|
||||
// 93 20 = Anticollision (usage: 9320 - answer: 4bytes UID+1byte UID-bytes-xor)
|
||||
// 93 70 = Select (usage: 9370+5bytes 9320 answer - answer: 1byte SAK)
|
||||
if(cmd[2] == 0x70)
|
||||
if(cmd[1] == 0x70)
|
||||
{
|
||||
snprintf(exp,size,"SELECT_UID"); break;
|
||||
}else
|
||||
|
@ -196,7 +200,7 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
snprintf(exp,size,"ANTICOLL"); break;
|
||||
}
|
||||
}
|
||||
case ISO14443_CMD_ANTICOLL_OR_SELECT_2:{
|
||||
case ISO14443A_CMD_ANTICOLL_OR_SELECT_2:{
|
||||
//95 20 = Anticollision of cascade level2
|
||||
//95 70 = Select of cascade level2
|
||||
if(cmd[2] == 0x70)
|
||||
|
@ -207,17 +211,17 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
snprintf(exp,size,"ANTICOLL-2"); break;
|
||||
}
|
||||
}
|
||||
case ISO14443_CMD_REQA: snprintf(exp,size,"REQA"); break;
|
||||
case ISO14443_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
|
||||
case ISO14443_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
|
||||
case ISO14443_CMD_HALT: snprintf(exp,size,"HALT"); break;
|
||||
case ISO14443_CMD_RATS: snprintf(exp,size,"RATS"); break;
|
||||
case ISO14443A_CMD_REQA: snprintf(exp,size,"REQA"); break;
|
||||
case ISO14443A_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
|
||||
case ISO14443A_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
|
||||
case ISO14443A_CMD_HALT: snprintf(exp,size,"HALT"); break;
|
||||
case ISO14443A_CMD_RATS: snprintf(exp,size,"RATS"); break;
|
||||
case MIFARE_CMD_INC: snprintf(exp,size,"INC(%d)",cmd[1]); break;
|
||||
case MIFARE_CMD_DEC: snprintf(exp,size,"DEC(%d)",cmd[1]); break;
|
||||
case MIFARE_CMD_RESTORE: snprintf(exp,size,"RESTORE(%d)",cmd[1]); break;
|
||||
case MIFARE_CMD_TRANSFER: snprintf(exp,size,"TRANSFER(%d)",cmd[1]); break;
|
||||
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A"); break;
|
||||
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B"); break;
|
||||
case MIFARE_AUTH_KEYA: snprintf(exp,size,"AUTH-A(%d)",cmd[1]); break;
|
||||
case MIFARE_AUTH_KEYB: snprintf(exp,size,"AUTH-B(%d)",cmd[1]); break;
|
||||
case MIFARE_MAGICMODE: snprintf(exp,size,"MAGIC"); break;
|
||||
default: snprintf(exp,size,"?"); break;
|
||||
}
|
||||
|
@ -238,11 +242,15 @@ void annotateIclass(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
break;
|
||||
}
|
||||
case ICLASS_CMD_SELECT: snprintf(exp,size,"SELECT"); break;
|
||||
case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL"); break;
|
||||
case ICLASS_CMD_READCHECK: snprintf(exp,size,"READCHECK"); break;
|
||||
case ICLASS_CMD_PAGESEL: snprintf(exp,size,"PAGESEL(%d)", cmd[1]); break;
|
||||
case ICLASS_CMD_READCHECK_KC:snprintf(exp,size,"READCHECK[Kc](%d)", cmd[1]); break;
|
||||
case ICLASS_CMD_READCHECK_KD:snprintf(exp,size,"READCHECK[Kd](%d)", cmd[1]); break;
|
||||
case ICLASS_CMD_CHECK: snprintf(exp,size,"CHECK"); break;
|
||||
case ICLASS_CMD_SOF: snprintf(exp,size,"SOF"); break;
|
||||
case ICLASS_CMD_DETECT: snprintf(exp,size,"DETECT"); break;
|
||||
case ICLASS_CMD_HALT: snprintf(exp,size,"HALT"); break;
|
||||
case ICLASS_CMD_UPDATE: snprintf(exp,size,"UPDATE(%d)",cmd[1]); break;
|
||||
case ICLASS_CMD_ACT: snprintf(exp,size,"ACT"); break;
|
||||
case ICLASS_CMD_READ4: snprintf(exp,size,"READ4(%d)",cmd[1]); break;
|
||||
default: snprintf(exp,size,"?"); break;
|
||||
}
|
||||
return;
|
||||
|
@ -279,8 +287,102 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
}
|
||||
}
|
||||
}
|
||||
void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||
{
|
||||
switch(cmd[0]){
|
||||
case ISO14443B_REQB : snprintf(exp,size,"REQB");break;
|
||||
case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break;
|
||||
case ISO14443B_HALT : snprintf(exp,size,"HALT");break;
|
||||
default: snprintf(exp,size ,"?");break;
|
||||
}
|
||||
|
||||
uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool showWaitCycles)
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iso14443B_CRC_Ok Checks CRC in command or response
|
||||
* @param isResponse
|
||||
* @param data
|
||||
* @param len
|
||||
* @return 0 : CRC-command, CRC not ok
|
||||
* 1 : CRC-command, CRC ok
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
|
||||
uint8_t iso14443B_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
{
|
||||
uint8_t b1,b2;
|
||||
|
||||
if(len <= 2) return 2;
|
||||
|
||||
ComputeCrc14443(CRC_14443_B, data, len-2, &b1, &b2);
|
||||
if(b1 != data[len-2] || b2 != data[len-1]) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief iclass_CRC_Ok Checks CRC in command or response
|
||||
* @param isResponse
|
||||
* @param data
|
||||
* @param len
|
||||
* @return 0 : CRC-command, CRC not ok
|
||||
* 1 : CRC-command, CRC ok
|
||||
* 2 : Not crc-command
|
||||
*/
|
||||
uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||
{
|
||||
if(len < 4) return 2;//CRC commands (and responses) are all at least 4 bytes
|
||||
|
||||
uint8_t b1, b2;
|
||||
|
||||
if(!isResponse)//Commands to tag
|
||||
{
|
||||
/**
|
||||
These commands should have CRC. Total length leftmost
|
||||
4 READ
|
||||
4 READ4
|
||||
12 UPDATE - unsecured, ends with CRC16
|
||||
14 UPDATE - secured, ends with signature instead
|
||||
4 PAGESEL
|
||||
**/
|
||||
if(len == 4 || len == 12)//Covers three of them
|
||||
{
|
||||
//Don't include the command byte
|
||||
ComputeCrc14443(CRC_ICLASS, (data+1), len-3, &b1, &b2);
|
||||
return b1 == data[len -2] && b2 == data[len-1];
|
||||
}
|
||||
return 2;
|
||||
}else{
|
||||
/**
|
||||
These tag responses should have CRC. Total length leftmost
|
||||
|
||||
10 READ data[8] crc[2]
|
||||
34 READ4 data[32]crc[2]
|
||||
10 UPDATE data[8] crc[2]
|
||||
10 SELECT csn[8] crc[2]
|
||||
10 IDENTIFY asnb[8] crc[2]
|
||||
10 PAGESEL block1[8] crc[2]
|
||||
10 DETECT csn[8] crc[2]
|
||||
|
||||
These should not
|
||||
|
||||
4 CHECK chip_response[4]
|
||||
8 READCHECK data[8]
|
||||
1 ACTALL sof[1]
|
||||
1 ACT sof[1]
|
||||
|
||||
In conclusion, without looking at the command; any response
|
||||
of length 10 or 34 should have CRC
|
||||
**/
|
||||
if(len != 10 && len != 34) return true;
|
||||
|
||||
ComputeCrc14443(CRC_ICLASS, data, len-2, &b1, &b2);
|
||||
return b1 == data[len -2] && b2 == data[len-1];
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
|
||||
{
|
||||
bool isResponse;
|
||||
uint16_t duration, data_len, parity_len;
|
||||
|
@ -288,10 +390,10 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
|||
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
|
||||
char explanation[30] = {0};
|
||||
|
||||
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
|
||||
|
||||
first_timestamp = *((uint32_t *)(trace));
|
||||
timestamp = *((uint32_t *)(trace + tracepos));
|
||||
// Break and stick with current result if buffer was not completely full
|
||||
if (timestamp == 0x44444444) return TRACE_SIZE;
|
||||
|
||||
tracepos += 4;
|
||||
duration = *((uint16_t *)(trace + tracepos));
|
||||
|
@ -307,8 +409,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
|||
}
|
||||
parity_len = (data_len-1)/8 + 1;
|
||||
|
||||
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
|
||||
return TRACE_SIZE;
|
||||
if (tracepos + data_len + parity_len > traceLen) {
|
||||
return traceLen;
|
||||
}
|
||||
|
||||
uint8_t *frame = trace + tracepos;
|
||||
|
@ -335,47 +437,45 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
|||
}
|
||||
}
|
||||
//--- Draw the CRC column
|
||||
bool crcError = false;
|
||||
uint8_t crcStatus = 2;
|
||||
|
||||
if (data_len > 2) {
|
||||
uint8_t b1, b2;
|
||||
if(iclass)
|
||||
if(protocol == ICLASS)
|
||||
{
|
||||
if(!isResponse && data_len == 4 ) {
|
||||
// Rough guess that this is a command from the reader
|
||||
// For iClass the command byte is not part of the CRC
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
|
||||
} else {
|
||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||
}
|
||||
crcStatus = iclass_CRC_check(isResponse, frame, data_len);
|
||||
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
crcError = true;
|
||||
}else if (protocol == ISO_14443B)
|
||||
{
|
||||
crcStatus = iso14443B_CRC_check(isResponse, frame, data_len);
|
||||
}
|
||||
|
||||
} else {//Iso 14443a
|
||||
else if (protocol == ISO_14443A){//Iso 14443a
|
||||
|
||||
ComputeCrc14443(CRC_14443_A, frame, data_len-2, &b1, &b2);
|
||||
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
if(!(isResponse & (data_len < 6)))
|
||||
{
|
||||
crcError = true;
|
||||
crcStatus = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
char *crc = crcError ? "!crc" :" ";
|
||||
//0 CRC-command, CRC not ok
|
||||
//1 CRC-command, CRC ok
|
||||
//2 Not crc-command
|
||||
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
|
||||
|
||||
EndOfTransmissionTimestamp = timestamp + duration;
|
||||
|
||||
if(!isResponse)
|
||||
{
|
||||
if(iclass)
|
||||
if(protocol == ICLASS)
|
||||
annotateIclass(explanation,sizeof(explanation),frame,data_len);
|
||||
else
|
||||
else if (protocol == ISO_14443A)
|
||||
annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
|
||||
else if(protocol == ISO_14443B)
|
||||
annotateIso14443b(explanation,sizeof(explanation),frame,data_len);
|
||||
}
|
||||
|
||||
int num_lines = (data_len - 1)/16 + 1;
|
||||
|
@ -396,6 +496,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
|||
}
|
||||
}
|
||||
|
||||
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
|
||||
|
||||
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||
|
||||
if (showWaitCycles && !isResponse && next_isResponse) {
|
||||
|
@ -408,9 +510,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
|||
(next_timestamp - EndOfTransmissionTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
return tracepos;
|
||||
}
|
||||
|
||||
|
||||
int CmdHFList(const char *Cmd)
|
||||
{
|
||||
bool showWaitCycles = false;
|
||||
|
@ -418,9 +522,9 @@ int CmdHFList(const char *Cmd)
|
|||
int tlen = param_getstr(Cmd,0,type);
|
||||
char param = param_getchar(Cmd, 1);
|
||||
bool errors = false;
|
||||
bool iclass = false;
|
||||
uint8_t protocol = 0;
|
||||
//Validate params
|
||||
if(tlen == 0 || (strcmp(type, "iclass") != 0 && strcmp(type,"14a") != 0))
|
||||
if(tlen == 0)
|
||||
{
|
||||
errors = true;
|
||||
}
|
||||
|
@ -428,34 +532,69 @@ int CmdHFList(const char *Cmd)
|
|||
{
|
||||
errors = true;
|
||||
}
|
||||
if(!errors)
|
||||
{
|
||||
if(strcmp(type, "iclass") == 0)
|
||||
{
|
||||
protocol = ICLASS;
|
||||
}else if(strcmp(type, "14a") == 0)
|
||||
{
|
||||
protocol = ISO_14443A;
|
||||
}
|
||||
else if(strcmp(type, "14b") == 0)
|
||||
{
|
||||
protocol = ISO_14443B;
|
||||
}else if(strcmp(type,"raw")== 0)
|
||||
{
|
||||
protocol = -1;//No crc, no annotations
|
||||
}else{
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors) {
|
||||
PrintAndLog("List protocol data in trace buffer.");
|
||||
PrintAndLog("Usage: hf list [14a|iclass] [f]");
|
||||
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
||||
PrintAndLog(" iclass - interpret data as iclass communications");
|
||||
PrintAndLog("Usage: hf list <protocol> [f]");
|
||||
PrintAndLog(" f - show frame delay times as well");
|
||||
PrintAndLog("Supported <protocol> values:");
|
||||
PrintAndLog(" raw - just show raw data without annotations");
|
||||
PrintAndLog(" 14a - interpret data as iso14443a communications");
|
||||
PrintAndLog(" 14b - interpret data as iso14443b communications");
|
||||
PrintAndLog(" iclass - interpret data as iclass communications");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("example: hf list 14a f");
|
||||
PrintAndLog("example: hf list iclass");
|
||||
return 0;
|
||||
}
|
||||
if(strcmp(type, "iclass") == 0)
|
||||
{
|
||||
iclass = true;
|
||||
}
|
||||
|
||||
|
||||
if (param == 'f') {
|
||||
showWaitCycles = true;
|
||||
}
|
||||
|
||||
|
||||
uint8_t trace[TRACE_SIZE];
|
||||
uint8_t *trace;
|
||||
uint16_t tracepos = 0;
|
||||
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
trace = malloc(USB_CMD_DATA_SIZE);
|
||||
|
||||
PrintAndLog("Recorded Activity");
|
||||
// Query for the size of the trace
|
||||
UsbCommand response;
|
||||
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, &response);
|
||||
uint16_t traceLen = response.arg[2];
|
||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||
uint8_t *p = realloc(trace, traceLen);
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(trace);
|
||||
return 2;
|
||||
}
|
||||
trace = p;
|
||||
GetFromBigBuf(trace, traceLen, 0);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
}
|
||||
|
||||
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
|
||||
|
@ -464,10 +603,12 @@ int CmdHFList(const char *Cmd)
|
|||
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
|
||||
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
|
||||
|
||||
while(tracepos < TRACE_SIZE)
|
||||
while(tracepos < traceLen)
|
||||
{
|
||||
tracepos = printTraceLine(tracepos, trace, iclass, showWaitCycles);
|
||||
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
|
||||
}
|
||||
|
||||
free(trace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -483,8 +624,6 @@ static command_t CommandTable[] =
|
|||
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
|
||||
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
|
||||
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
|
||||
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
|
||||
{"des", CmdHFDES, 0, "{ MIFARE DESfire}"},
|
||||
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
|
||||
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
#include "../common/iso14443crc.h"
|
||||
#include "iso14443crc.h"
|
||||
#include "data.h"
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf14a.h"
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
#include "cmdmain.h"
|
||||
#include "../include/mifare.h"
|
||||
#include "mifare.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static void waitCmd(uint8_t iLen);
|
||||
|
@ -112,20 +112,15 @@ const manufactureName manufactureMapping[] = {
|
|||
// returns description of the best match
|
||||
char* getTagInfo(uint8_t uid) {
|
||||
|
||||
int i, best = -1;
|
||||
int i;
|
||||
int len = sizeof(manufactureMapping) / sizeof(manufactureName);
|
||||
|
||||
for ( i = 0; i < len; ++i ) {
|
||||
if ( uid == manufactureMapping[i].uid) {
|
||||
if (best == -1) {
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best>=0) return manufactureMapping[best].desc;
|
||||
|
||||
for ( i = 0; i < len; ++i )
|
||||
if ( uid == manufactureMapping[i].uid)
|
||||
return manufactureMapping[i].desc;
|
||||
|
||||
//No match, return default
|
||||
return manufactureMapping[len-1].desc;
|
||||
}
|
||||
|
||||
int CmdHF14AList(const char *Cmd)
|
||||
|
@ -417,9 +412,9 @@ int CmdHF14ASim(const char *Cmd)
|
|||
PrintAndLog(" syntax: hf 14a sim <type> <uid>");
|
||||
PrintAndLog(" types: 1 = MIFARE Classic");
|
||||
PrintAndLog(" 2 = MIFARE Ultralight");
|
||||
PrintAndLog(" 3 = MIFARE DESFIRE");
|
||||
PrintAndLog(" 3 = MIFARE Desfire");
|
||||
PrintAndLog(" 4 = ISO/IEC 14443-4");
|
||||
PrintAndLog(" 5 = MIFARE TNP3XXX");
|
||||
PrintAndLog(" 5 = MIFARE Tnp3xxx");
|
||||
PrintAndLog("");
|
||||
return 1;
|
||||
}
|
||||
|
@ -485,7 +480,8 @@ int CmdHF14ASim(const char *Cmd)
|
|||
int CmdHF14ASnoop(const char *Cmd) {
|
||||
int param = 0;
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h') {
|
||||
uint8_t ctmp = param_getchar(Cmd, 0) ;
|
||||
if (ctmp == 'h' || ctmp == 'H') {
|
||||
PrintAndLog("It get data from the field and saves it into command buffer.");
|
||||
PrintAndLog("Buffer accessible from command hf list 14a.");
|
||||
PrintAndLog("Usage: hf 14a snoop [c][r]");
|
||||
|
@ -496,7 +492,7 @@ int CmdHF14ASnoop(const char *Cmd) {
|
|||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
char ctmp = param_getchar(Cmd, i);
|
||||
ctmp = param_getchar(Cmd, i);
|
||||
if (ctmp == 'c' || ctmp == 'C') param |= 0x01;
|
||||
if (ctmp == 'r' || ctmp == 'R') param |= 0x02;
|
||||
}
|
||||
|
@ -675,7 +671,7 @@ static command_t CommandTable[] =
|
|||
{"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"},
|
||||
{"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
|
||||
{"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
|
||||
{"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
|
||||
{"sim", CmdHF14ASim, 0, "<UID> -- Simulate ISO 14443a tag"},
|
||||
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
|
||||
{"raw", CmdHF14ACmdRaw, 0, "Send raw hex data to tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
|
|
|
@ -145,11 +145,25 @@ demodError:
|
|||
|
||||
int CmdHF14BList(const char *Cmd)
|
||||
{
|
||||
uint8_t got[TRACE_BUFFER_SIZE];
|
||||
GetFromBigBuf(got,sizeof(got),0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
||||
|
||||
PrintAndLog("recorded activity:");
|
||||
// Query for the actual size of the trace
|
||||
UsbCommand response;
|
||||
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, &response);
|
||||
uint16_t traceLen = response.arg[2];
|
||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||
uint8_t *p = realloc(got, traceLen);
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(got);
|
||||
return 2;
|
||||
}
|
||||
got = p;
|
||||
GetFromBigBuf(got, traceLen, 0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
}
|
||||
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
|
||||
PrintAndLog(" time :rssi: who bytes");
|
||||
PrintAndLog("---------+----+----+-----------");
|
||||
|
||||
|
@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd)
|
|||
|
||||
for(;;) {
|
||||
|
||||
if(i >= TRACE_BUFFER_SIZE) { break; }
|
||||
if(i >= traceLen) { break; }
|
||||
|
||||
bool isResponse;
|
||||
int timestamp = *((uint32_t *)(got+i));
|
||||
|
@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd)
|
|||
if(len > 100) {
|
||||
break;
|
||||
}
|
||||
if(i + len >= TRACE_BUFFER_SIZE) {
|
||||
if(i + len >= traceLen) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd)
|
|||
prev = timestamp;
|
||||
i += (len + 9);
|
||||
}
|
||||
free(got);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -336,13 +351,13 @@ int CmdHF14BCmdRaw (const char *cmd) {
|
|||
PrintAndLog("Invalid char on input");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (datalen == 0) {
|
||||
if (datalen == 0)
|
||||
{
|
||||
PrintAndLog("Missing data input");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(crc) {
|
||||
if(crc)
|
||||
{
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_B, data, datalen, &first, &second);
|
||||
data[datalen++] = first;
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include "util.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhf15.h"
|
||||
#include "../common/iso15693tools.h"
|
||||
#include "iso15693tools.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
#define FrameSOF Iso15693FrameSOF
|
||||
|
@ -45,7 +45,6 @@
|
|||
#define Crc(data,datalen) Iso15693Crc(data,datalen)
|
||||
#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
|
||||
#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
|
||||
#define TRACE_BUFF_SIZE 12000
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
typedef struct {
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmdhficlass.h"
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "cmdmain.h"
|
||||
#include "loclass/des.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "cmdparser.h"
|
||||
#include "cmdhflegic.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
#include "util.h"
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static command_t CommandTable[] =
|
||||
|
|
195
client/cmdhfmf.c
195
client/cmdhfmf.c
|
@ -7,7 +7,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// High frequency MIFARE commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "../include/mifare.h"
|
||||
|
||||
#include "cmdhfmf.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
@ -470,6 +470,8 @@ int CmdHF14AMfRestore(const char *Cmd)
|
|||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||
if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {
|
||||
PrintAndLog("File reading error (dumpkeys.bin).");
|
||||
|
||||
fclose(fkeys);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -477,6 +479,7 @@ int CmdHF14AMfRestore(const char *Cmd)
|
|||
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {
|
||||
if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {
|
||||
PrintAndLog("File reading error (dumpkeys.bin).");
|
||||
fclose(fkeys);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
@ -690,13 +693,6 @@ int CmdHF14AMfNested(const char *Cmd)
|
|||
bool calibrate = true;
|
||||
for (i = 0; i < NESTED_SECTOR_RETRY; i++) {
|
||||
for (uint8_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) {
|
||||
|
||||
if (ukbhit()) {
|
||||
printf("\naborted via keyboard!\n");
|
||||
free(e_sector);
|
||||
return 2;
|
||||
}
|
||||
|
||||
for (trgKeyType = 0; trgKeyType < 2; trgKeyType++) {
|
||||
if (e_sector[sectorNo].foundKey[trgKeyType]) continue;
|
||||
PrintAndLog("-----------------------------------------------");
|
||||
|
@ -1016,12 +1012,16 @@ int CmdHF14AMf1kSim(const char *Cmd)
|
|||
uint8_t exitAfterNReads = 0;
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h') {
|
||||
uint8_t cmdp = param_getchar(Cmd, 0);
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') {
|
||||
PrintAndLog("Usage: hf mf sim u <uid (8 hex symbols)> n <numreads> i x");
|
||||
PrintAndLog(" h this help");
|
||||
PrintAndLog(" u (Optional) UID. If not specified, the UID from emulator memory will be used");
|
||||
PrintAndLog(" n (Optional) Automatically exit simulation after <numreads> blocks have been read by reader. 0 = infinite");
|
||||
PrintAndLog(" i (Optional) Interactive, means that console will not be returned until simulation finishes or is aborted");
|
||||
PrintAndLog(" x (Optional) Crack, performs the 'reader attack', nr/ar attack against a legitimate reader, fishes out the key(s)");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample: hf mf sim u 0a0a0a0a ");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1102,7 +1102,7 @@ int CmdHF14AMfDbg(const char *Cmd)
|
|||
int CmdHF14AMfEGet(const char *Cmd)
|
||||
{
|
||||
uint8_t blockNo = 0;
|
||||
uint8_t data[16];
|
||||
uint8_t data[16] = {0x00};
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf eget <block number>");
|
||||
|
@ -1169,14 +1169,11 @@ int CmdHF14AMfELoad(const char *Cmd)
|
|||
FILE * f;
|
||||
char filename[FILE_PATH_SIZE];
|
||||
char *fnameptr = filename;
|
||||
char buf[64];
|
||||
uint8_t buf8[64];
|
||||
char buf[64] = {0x00};
|
||||
uint8_t buf8[64] = {0x00};
|
||||
int i, len, blockNum, numBlocks;
|
||||
int nameParamNo = 1;
|
||||
|
||||
memset(filename, 0, sizeof(filename));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
|
||||
if ( ctmp == 'h' || ctmp == 0x00) {
|
||||
|
@ -1246,11 +1243,13 @@ int CmdHF14AMfELoad(const char *Cmd)
|
|||
fclose(f);
|
||||
return 3;
|
||||
}
|
||||
printf(".");
|
||||
blockNum++;
|
||||
|
||||
if (blockNum >= numBlocks) break;
|
||||
}
|
||||
fclose(f);
|
||||
printf("\n");
|
||||
|
||||
if ((blockNum != numBlocks)) {
|
||||
PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);
|
||||
|
@ -1452,7 +1451,7 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
|||
char ctmp = param_getchar(Cmd, 1);
|
||||
if (ctmp == 'w' || ctmp == 'W') wipeCard = 1;
|
||||
|
||||
PrintAndLog("--wipe card:%02x uid:%s", wipeCard, sprint_hex(uid, 4));
|
||||
PrintAndLog("--wipe card:%s uid:%s", (wipeCard)?"YES":"NO", sprint_hex(uid, 4));
|
||||
|
||||
res = mfCSetUID(uid, oldUid, wipeCard);
|
||||
if (res) {
|
||||
|
@ -1467,11 +1466,10 @@ int CmdHF14AMfCSetUID(const char *Cmd)
|
|||
|
||||
int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||
{
|
||||
uint8_t uid[8];
|
||||
uint8_t memBlock[16];
|
||||
uint8_t uid[8] = {0x00};
|
||||
uint8_t memBlock[16] = {0x00};
|
||||
uint8_t blockNo = 0;
|
||||
int res;
|
||||
memset(memBlock, 0x00, sizeof(memBlock));
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf csetblk <block number> <block data (32 hex symbols)>");
|
||||
|
@ -1496,7 +1494,6 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
|||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLog("UID:%s", sprint_hex(uid, 4));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1511,11 +1508,8 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
|||
uint8_t fillFromEmulator = 0;
|
||||
int i, len, blockNum, flags;
|
||||
|
||||
// memset(filename, 0, sizeof(filename));
|
||||
// memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
||||
PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");
|
||||
PrintAndLog("It loads magic Chinese card from the file `filename.eml`");
|
||||
PrintAndLog("or from emulator memory (option `e`)");
|
||||
PrintAndLog("Usage: hf mf cload <file name w/o `.eml`>");
|
||||
PrintAndLog(" or: hf mf cload e ");
|
||||
|
@ -1562,7 +1556,9 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
|||
blockNum = 0;
|
||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
||||
while(!feof(f)){
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
PrintAndLog("File reading error.");
|
||||
return 2;
|
||||
|
@ -1597,6 +1593,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
|||
PrintAndLog("Loaded from file: %s", filename);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||
|
@ -1628,10 +1625,9 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
|||
|
||||
|
||||
int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||
uint8_t memBlock[16];
|
||||
uint8_t memBlock[16] = {0x00};
|
||||
uint8_t sectorNo = 0;
|
||||
int i, res, flags;
|
||||
memset(memBlock, 0x00, sizeof(memBlock));
|
||||
|
||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
||||
|
@ -1769,18 +1765,19 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
int res = 0;
|
||||
int len = 0;
|
||||
int blockLen = 0;
|
||||
int num = 0;
|
||||
int pckNum = 0;
|
||||
int num = 0;
|
||||
uint8_t uid[7];
|
||||
uint8_t uid_len;
|
||||
uint8_t atqa[2];
|
||||
uint8_t atqa[2] = {0x00};
|
||||
uint8_t sak;
|
||||
bool isTag;
|
||||
uint8_t buf[3000];
|
||||
uint8_t * bufPtr = buf;
|
||||
memset(buf, 0x00, 3000);
|
||||
uint8_t *buf = NULL;
|
||||
uint16_t bufsize = 0;
|
||||
uint8_t *bufPtr = NULL;
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h') {
|
||||
char ctmp = param_getchar(Cmd, 0);
|
||||
if ( ctmp == 'h' || ctmp == 'H' ) {
|
||||
PrintAndLog("It continuously gets data from the field and saves it to: log, emulator, emulator file.");
|
||||
PrintAndLog("You can specify:");
|
||||
PrintAndLog(" l - save encrypted sequence to logfile `uid.log`");
|
||||
|
@ -1793,7 +1790,7 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
char ctmp = param_getchar(Cmd, i);
|
||||
ctmp = param_getchar(Cmd, i);
|
||||
if (ctmp == 'l' || ctmp == 'L') wantLogToFile = true;
|
||||
if (ctmp == 'd' || ctmp == 'D') wantDecrypt = true;
|
||||
//if (ctmp == 'e' || ctmp == 'E') wantSaveToEml = true; TODO
|
||||
|
@ -1823,29 +1820,44 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
|
||||
res = resp.arg[0] & 0xff;
|
||||
len = resp.arg[1];
|
||||
num = resp.arg[2];
|
||||
uint16_t traceLen = resp.arg[1];
|
||||
len = resp.arg[2];
|
||||
|
||||
if (res == 0) return 0;
|
||||
if (res == 1) {
|
||||
if (num ==0) {
|
||||
if (res == 0) return 0; // we are done
|
||||
|
||||
if (res == 1) { // there is (more) data to be transferred
|
||||
if (pckNum == 0) { // first packet, (re)allocate necessary buffer
|
||||
if (traceLen > bufsize) {
|
||||
uint8_t *p;
|
||||
if (buf == NULL) { // not yet allocated
|
||||
p = malloc(traceLen);
|
||||
} else { // need more memory
|
||||
p = realloc(buf, traceLen);
|
||||
}
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(buf);
|
||||
return 2;
|
||||
}
|
||||
buf = p;
|
||||
}
|
||||
bufPtr = buf;
|
||||
memset(buf, 0x00, 3000);
|
||||
bufsize = traceLen;
|
||||
memset(buf, 0x00, traceLen);
|
||||
}
|
||||
memcpy(bufPtr, resp.d.asBytes, len);
|
||||
bufPtr += len;
|
||||
pckNum++;
|
||||
}
|
||||
if (res == 2) {
|
||||
|
||||
if (res == 2) { // received all data, start displaying
|
||||
blockLen = bufPtr - buf;
|
||||
bufPtr = buf;
|
||||
printf(">\n");
|
||||
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
|
||||
num = 0;
|
||||
while (bufPtr - buf < blockLen) {
|
||||
bufPtr += 6;
|
||||
bufPtr += 6; // skip (void) timing information
|
||||
len = *((uint16_t *)bufPtr);
|
||||
|
||||
if(len & 0x8000) {
|
||||
isTag = true;
|
||||
len &= 0x7fff;
|
||||
|
@ -1854,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
}
|
||||
bufPtr += 2;
|
||||
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
|
||||
|
||||
memcpy(uid, bufPtr + 2, 7);
|
||||
memcpy(atqa, bufPtr + 2 + 7, 2);
|
||||
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
|
||||
sak = bufPtr[11];
|
||||
|
||||
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
|
||||
sprint_hex(uid + (7 - uid_len), uid_len),
|
||||
atqa[1],
|
||||
|
@ -1877,109 +1887,20 @@ int CmdHF14AMfSniff(const char *Cmd){
|
|||
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
|
||||
if (wantDecrypt)
|
||||
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
|
||||
num++;
|
||||
}
|
||||
bufPtr += len;
|
||||
bufPtr += ((len-1)/8+1); // ignore parity
|
||||
num++;
|
||||
}
|
||||
pckNum = 0;
|
||||
}
|
||||
} // resp not NULL
|
||||
} // while (true)
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Tries to identify cardsize.
|
||||
// Returns <num> where num is:
|
||||
// -1 unidentified
|
||||
// 0 - MINI (320bytes)
|
||||
// 1 - 1K
|
||||
// 2 - 2K
|
||||
// 4 - 4K
|
||||
int GetCardSize()
|
||||
{
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
|
||||
if(resp.arg[0] == 0) {
|
||||
PrintAndLog("iso14443a card select failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes;
|
||||
|
||||
PrintAndLog("Trying to detect card size.");
|
||||
|
||||
uint16_t atqa = 0;
|
||||
uint8_t sak = 0;
|
||||
atqa = (card->atqa[1] & 0xff) << 8;
|
||||
atqa += card->atqa[0] & 0xff;
|
||||
sak = card->sak;
|
||||
|
||||
// https://code.google.com/p/libnfc/source/browse/libnfc/target-subr.c
|
||||
|
||||
PrintAndLog("found ATAQ: %04X SAK: %02X", atqa, sak);
|
||||
|
||||
|
||||
// NXP MIFARE Mini 0.3k
|
||||
if ( ( (atqa & 0xff0f) == 0x0004) && (sak == 0x09) ) return 0;
|
||||
|
||||
// MIFARE Classic 1K
|
||||
if ( ((atqa & 0xff0f) == 0x0004) && (sak == 0x08) ) return 1;
|
||||
|
||||
// MIFARE Classik 4K
|
||||
if ( ((atqa & 0xff0f) == 0x0002) && (sak == 0x18) ) return 4;
|
||||
|
||||
// SmartMX with MIFARE 1K emulation
|
||||
if ( ((atqa & 0xf0ff) == 0x0004) ) return 1;
|
||||
|
||||
// SmartMX with MIFARE 4K emulation
|
||||
if ( ((atqa & 0xf0ff) == 0x0002) ) return 4;
|
||||
|
||||
// Infineon MIFARE CLASSIC 1K
|
||||
if ( ((atqa & 0xffff) == 0x0004) && (sak == 0x88) ) return 1;
|
||||
|
||||
// MFC 4K emulated by Nokia 6212 Classic
|
||||
if ( ((atqa & 0xffff) == 0x0002) && (sak == 0x38) ) return 4;
|
||||
|
||||
// MFC 4K emulated by Nokia 6131 NFC
|
||||
if ( ((atqa & 0xffff) == 0x0008) && (sak == 0x38) ) return 4;
|
||||
|
||||
|
||||
//PrintAndLog("BEFOOO 1K %02X", (atqa & 0xff0f));
|
||||
|
||||
// MIFARE Plus (4 Byte UID or 4 Byte RID)
|
||||
// MIFARE Plus (7 Byte UID)
|
||||
if (
|
||||
((atqa & 0xffff) == 0x0002) |
|
||||
((atqa & 0xffff) == 0x0004) |
|
||||
((atqa & 0xffff) == 0x0042) |
|
||||
((atqa & 0xffff) == 0x0044)
|
||||
)
|
||||
{
|
||||
switch(sak){
|
||||
case 0x08:
|
||||
case 0x10: {
|
||||
//case 0x20:
|
||||
PrintAndLog("2");
|
||||
return 2;
|
||||
break;
|
||||
}
|
||||
case 0x11:
|
||||
case 0x18:{
|
||||
//case 0x20:
|
||||
PrintAndLog("4");
|
||||
return 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// High frequency MIFARE ULTRALIGHT (C) commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <openssl/des.h>
|
||||
//#include <openssl/des.h>
|
||||
#include "loclass/des.h"
|
||||
#include "cmdhfmfu.h"
|
||||
#include "cmdhfmf.h"
|
||||
#include "cmdhf14a.h"
|
||||
|
@ -16,11 +17,7 @@
|
|||
#define MAX_ULTRA_BLOCKS 0x0f
|
||||
#define MAX_ULTRAC_BLOCKS 0x2f
|
||||
//#define MAX_ULTRAC_BLOCKS 0x2c
|
||||
uint8_t key1_blnk_data[16] = { 0x00 };
|
||||
uint8_t key2_defa_data[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
|
||||
uint8_t key3_3des_data[16] = { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 };
|
||||
uint8_t key4_nfc_data[16] = { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 };
|
||||
uint8_t key5_ones_data[16] = { 0x01 };
|
||||
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
@ -336,33 +333,19 @@ int CmdHF14AMfUDump(const char *Cmd){
|
|||
else
|
||||
len = param_getstr(Cmd,1,filename);
|
||||
|
||||
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
|
||||
if (len > FILE_PATH_SIZE-5) len = FILE_PATH_SIZE-5;
|
||||
|
||||
// user supplied filename?
|
||||
if (len < 1) {
|
||||
|
||||
// UID = data 0-1-2 4-5-6-7 (skips a beat)
|
||||
sprintf(fnameptr, "%02X", data[0]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[1]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[2]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[4]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[5]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[6]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr, "%02X", data[7]);
|
||||
fnameptr += 2;
|
||||
sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin",
|
||||
data[0],data[1], data[2], data[4],data[5],data[6], data[7]);
|
||||
|
||||
} else {
|
||||
fnameptr += len;
|
||||
sprintf(fnameptr + len," .bin");
|
||||
}
|
||||
|
||||
// add file extension
|
||||
sprintf(fnameptr, ".bin");
|
||||
|
||||
if ((fout = fopen(filename,"wb")) == NULL) {
|
||||
PrintAndLog("Could not create file name %s", filename);
|
||||
|
@ -393,62 +376,49 @@ void rol (uint8_t *data, const size_t len){
|
|||
//
|
||||
int CmdHF14AMfucAuth(const char *Cmd){
|
||||
|
||||
uint8_t blockNo = 0, keyNo = 0;
|
||||
uint8_t e_RndB[8] = {0x00};
|
||||
uint32_t cuid = 0;
|
||||
unsigned char RndARndB[16] = {0x00};
|
||||
uint8_t key[16] = {0x00};
|
||||
DES_cblock RndA, RndB;
|
||||
DES_cblock iv;
|
||||
DES_key_schedule ks1,ks2;
|
||||
DES_cblock key1,key2;
|
||||
uint8_t default_keys[5][16] = {
|
||||
{ 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
|
||||
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
|
||||
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
|
||||
{ 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
|
||||
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } // all ones
|
||||
};
|
||||
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
//
|
||||
memset(iv, 0, 8);
|
||||
|
||||
uint8_t keyNo = 0;
|
||||
bool errors = false;
|
||||
//Change key to user defined one
|
||||
if (cmdp == 'k' || cmdp == 'K'){
|
||||
keyNo = param_get8(Cmd, 1);
|
||||
if(keyNo >= 4) errors = true;
|
||||
}
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') {
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (errors) {
|
||||
PrintAndLog("Usage: hf mfu cauth k <key number>");
|
||||
PrintAndLog(" 1 = all zeros key");
|
||||
PrintAndLog(" 2 = 0x00-0x0F key");
|
||||
PrintAndLog(" 3 = nfc key");
|
||||
PrintAndLog(" 4 = all ones key");
|
||||
PrintAndLog(" defaults to 3DES standard key");
|
||||
PrintAndLog(" 0 (default): 3DES standard key");
|
||||
PrintAndLog(" 1 : all zeros key");
|
||||
PrintAndLog(" 2 : 0x00-0x0F key");
|
||||
PrintAndLog(" 3 : nfc key");
|
||||
PrintAndLog(" 4 : all ones key");
|
||||
PrintAndLog(" sample : hf mfu cauth k");
|
||||
PrintAndLog(" : hf mfu cauth k 3");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Change key to user defined one
|
||||
if (cmdp == 'k' || cmdp == 'K'){
|
||||
|
||||
keyNo = param_get8(Cmd, 1);
|
||||
|
||||
switch(keyNo){
|
||||
case 0:
|
||||
memcpy(key,key1_blnk_data,16);
|
||||
break;
|
||||
case 1:
|
||||
memcpy(key,key2_defa_data,16);
|
||||
break;
|
||||
case 2:
|
||||
memcpy(key,key4_nfc_data,16);
|
||||
break;
|
||||
case 3:
|
||||
memcpy(key,key5_ones_data,16);
|
||||
break;
|
||||
default:
|
||||
memcpy(key,key3_3des_data,16);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
memcpy(key,key3_3des_data,16);
|
||||
}
|
||||
|
||||
memcpy(key1,key,8);
|
||||
memcpy(key2,key+8,8);
|
||||
DES_set_key((DES_cblock *)key1,&ks1);
|
||||
DES_set_key((DES_cblock *)key2,&ks2);
|
||||
uint8_t random_a[8] = { 1,1,1,1,1,1,1,1 };
|
||||
//uint8_t enc_random_a[8] = { 0 };
|
||||
uint8_t random_b[8] = { 0 };
|
||||
uint8_t enc_random_b[8] = { 0 };
|
||||
uint8_t random_a_and_b[16] = { 0 };
|
||||
des3_context ctx = { 0 };
|
||||
uint8_t *key = default_keys[keyNo];
|
||||
uint8_t blockNo = 0;
|
||||
uint32_t cuid = 0;
|
||||
|
||||
//Auth1
|
||||
UsbCommand c = {CMD_MIFAREUC_AUTH1, {blockNo}};
|
||||
|
@ -461,8 +431,9 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
|||
|
||||
if (isOK){
|
||||
PrintAndLog("enc(RndB):%s", sprint_hex(data+1, 8));
|
||||
memcpy(e_RndB,data+1,8);
|
||||
memcpy(enc_random_b,data+1,8);
|
||||
} else {
|
||||
PrintAndLog("Auth failed");
|
||||
return 2; // auth failed.
|
||||
}
|
||||
} else {
|
||||
|
@ -470,21 +441,46 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
|||
return 1;
|
||||
}
|
||||
|
||||
//Do crypto magic
|
||||
DES_random_key(&RndA);
|
||||
DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
|
||||
PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
|
||||
PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
|
||||
rol(RndB,8);
|
||||
memcpy(RndARndB,RndA,8);
|
||||
memcpy(RndARndB+8,RndB,8);
|
||||
PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
|
||||
DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
|
||||
PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
|
||||
uint8_t iv[8] = { 0 };
|
||||
// Do we need random ? Right now we use all ones, is that random enough ?
|
||||
// DES_random_key(&RndA);
|
||||
|
||||
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
|
||||
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
|
||||
|
||||
des3_set2key_dec(&ctx, key);
|
||||
|
||||
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||
, DES_DECRYPT // int mode
|
||||
, sizeof(random_b) // size_t length
|
||||
, iv // unsigned char iv[8]
|
||||
, enc_random_b // const unsigned char *input
|
||||
, random_b // unsigned char *output
|
||||
);
|
||||
|
||||
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
|
||||
|
||||
rol(random_b,8);
|
||||
memcpy(random_a_and_b ,random_a,8);
|
||||
memcpy(random_a_and_b+8,random_b,8);
|
||||
|
||||
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
|
||||
|
||||
des3_set2key_enc(&ctx, key);
|
||||
|
||||
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||
, DES_ENCRYPT // int mode
|
||||
, sizeof(random_a_and_b) // size_t length
|
||||
, enc_random_b // unsigned char iv[8]
|
||||
, random_a_and_b // const unsigned char *input
|
||||
, random_a_and_b // unsigned char *output
|
||||
);
|
||||
|
||||
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
|
||||
|
||||
//Auth2
|
||||
UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
|
||||
memcpy(d.d.asBytes,RndARndB, 16);
|
||||
memcpy(d.d.asBytes,random_a_and_b, 16);
|
||||
SendCommand(&d);
|
||||
|
||||
UsbCommand respb;
|
||||
|
@ -504,7 +500,102 @@ int CmdHF14AMfucAuth(const char *Cmd){
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
A test function to validate that the polarssl-function works the same
|
||||
was as the openssl-implementation.
|
||||
Commented out, since it requires openssl
|
||||
|
||||
int CmdTestDES(const char * cmd)
|
||||
{
|
||||
uint8_t key[16] = {0x00};
|
||||
|
||||
memcpy(key,key3_3des_data,16);
|
||||
DES_cblock RndA, RndB;
|
||||
|
||||
PrintAndLog("----------OpenSSL DES implementation----------");
|
||||
{
|
||||
uint8_t e_RndB[8] = {0x00};
|
||||
unsigned char RndARndB[16] = {0x00};
|
||||
|
||||
DES_cblock iv = { 0 };
|
||||
DES_key_schedule ks1,ks2;
|
||||
DES_cblock key1,key2;
|
||||
|
||||
memcpy(key,key3_3des_data,16);
|
||||
memcpy(key1,key,8);
|
||||
memcpy(key2,key+8,8);
|
||||
|
||||
|
||||
DES_set_key((DES_cblock *)key1,&ks1);
|
||||
DES_set_key((DES_cblock *)key2,&ks2);
|
||||
|
||||
DES_random_key(&RndA);
|
||||
PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
|
||||
PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
|
||||
//void DES_ede2_cbc_encrypt(const unsigned char *input,
|
||||
// unsigned char *output, long length, DES_key_schedule *ks1,
|
||||
// DES_key_schedule *ks2, DES_cblock *ivec, int enc);
|
||||
DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
|
||||
|
||||
PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
|
||||
rol(RndB,8);
|
||||
memcpy(RndARndB,RndA,8);
|
||||
memcpy(RndARndB+8,RndB,8);
|
||||
PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
|
||||
DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
|
||||
PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
|
||||
|
||||
}
|
||||
PrintAndLog("----------PolarSSL implementation----------");
|
||||
{
|
||||
uint8_t random_a[8] = { 0 };
|
||||
uint8_t enc_random_a[8] = { 0 };
|
||||
uint8_t random_b[8] = { 0 };
|
||||
uint8_t enc_random_b[8] = { 0 };
|
||||
uint8_t random_a_and_b[16] = { 0 };
|
||||
des3_context ctx = { 0 };
|
||||
|
||||
memcpy(random_a, RndA,8);
|
||||
|
||||
uint8_t output[8] = { 0 };
|
||||
uint8_t iv[8] = { 0 };
|
||||
|
||||
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
|
||||
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
|
||||
|
||||
des3_set2key_dec(&ctx, key);
|
||||
|
||||
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||
, DES_DECRYPT // int mode
|
||||
, sizeof(random_b) // size_t length
|
||||
, iv // unsigned char iv[8]
|
||||
, enc_random_b // const unsigned char *input
|
||||
, random_b // unsigned char *output
|
||||
);
|
||||
|
||||
PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
|
||||
|
||||
rol(random_b,8);
|
||||
memcpy(random_a_and_b ,random_a,8);
|
||||
memcpy(random_a_and_b+8,random_b,8);
|
||||
|
||||
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
|
||||
|
||||
des3_set2key_enc(&ctx, key);
|
||||
|
||||
des3_crypt_cbc(&ctx // des3_context *ctx
|
||||
, DES_ENCRYPT // int mode
|
||||
, sizeof(random_a_and_b) // size_t length
|
||||
, enc_random_b // unsigned char iv[8]
|
||||
, random_a_and_b // const unsigned char *input
|
||||
, random_a_and_b // unsigned char *output
|
||||
);
|
||||
|
||||
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
**/
|
||||
//
|
||||
// Ultralight C Read Single Block
|
||||
//
|
||||
|
@ -634,6 +725,7 @@ static command_t CommandTable[] =
|
|||
{"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
|
||||
{"cwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
|
||||
{"cauth", CmdHF14AMfucAuth, 0,"try a Ultralight C Authentication"},
|
||||
//{"testdes", CmdTestDES , 1, "Test DES"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
113
client/cmdlf.c
113
client/cmdlf.c
|
@ -19,8 +19,8 @@
|
|||
#include "cmdparser.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmddata.h"
|
||||
#include "util.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlfawid26.h"
|
||||
#include "cmdlfhid.h"
|
||||
#include "cmdlfti.h"
|
||||
#include "cmdlfem4x.h"
|
||||
|
@ -71,7 +71,7 @@ int CmdFlexdemod(const char *Cmd)
|
|||
}
|
||||
}
|
||||
if (start == GraphTraceLen - LONG_WAIT) {
|
||||
//PrintAndLog("nothing to wait for");
|
||||
PrintAndLog("nothing to wait for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ int CmdIndalaDemod(const char *Cmd)
|
|||
}
|
||||
|
||||
if (start == rawbit - uidlen + 1) {
|
||||
//PrintAndLog("nothing to wait for");
|
||||
PrintAndLog("nothing to wait for");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -373,9 +373,6 @@ int CmdLFRead(const char *Cmd)
|
|||
}
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
|
||||
CmdSamples("");
|
||||
ShowGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -391,7 +388,7 @@ static void ChkBitstream(const char *str)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//appears to attempt to simulate manchester
|
||||
int CmdLFSim(const char *Cmd)
|
||||
{
|
||||
int i,j;
|
||||
|
@ -468,22 +465,16 @@ int CmdLFSnoop(const char *Cmd)
|
|||
sscanf(Cmd, "h %"lli, &c.arg[1]);
|
||||
} else if (sscanf(Cmd, "%"lli" %"lli, &c.arg[0], &c.arg[1]) < 1) {
|
||||
PrintAndLog("usage 1: snoop");
|
||||
PrintAndLog(" 2: snoop {l,h} [trigger threshold]");
|
||||
PrintAndLog(" 2: snoop <l|h> [trigger threshold]");
|
||||
PrintAndLog(" 3: snoop <divisor> [trigger threshold]");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Sample: lf snoop l 200");
|
||||
PrintAndLog(" : lf snoop 95 200");
|
||||
return 0;
|
||||
}
|
||||
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
|
||||
#define BUFF_SIZE 8000
|
||||
uint8_t data[BUFF_SIZE] = {0x00};
|
||||
|
||||
GetFromBigBuf(data,BUFF_SIZE,0);
|
||||
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
|
||||
|
||||
SetGraphBuf(data, BUFF_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -578,39 +569,53 @@ int CmdLFfind(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!offline || (cmdp != '1') ){
|
||||
if (!offline && (cmdp != '1')){
|
||||
ans=CmdLFRead("");
|
||||
ans=CmdSamples("20000");
|
||||
} else if (GraphTraceLen < 1000) {
|
||||
PrintAndLog("Data in Graphbuffer was too small.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
PrintAndLog("Checking for known tags:");
|
||||
|
||||
ans = Cmdaskmandemod("");
|
||||
PrintAndLog("ASK_MAN: %s", (ans) ? "YES":"NO" );
|
||||
|
||||
ans = CmdFSKdemodHID("");
|
||||
PrintAndLog("HID: %s", (ans) ? "YES":"NO" );
|
||||
|
||||
PrintAndLog("NOTE: some demods output possible binary\n if it finds something that looks like a tag");
|
||||
PrintAndLog("\nChecking for known tags:\n");
|
||||
ans=CmdFSKdemodIO("");
|
||||
PrintAndLog("IO prox: %s", (ans) ? "YES":"NO" );
|
||||
|
||||
ans = CmdIndalaDemod("");
|
||||
PrintAndLog("Indala (64): %s", (ans) ? "YES":"NO" );
|
||||
|
||||
ans = CmdIndalaDemod("224");
|
||||
PrintAndLog("Indala (224): %s", (ans) ? "YES":"NO" );
|
||||
|
||||
// ans = CmdVchDemod("");
|
||||
// PrintAndLog("VeriChip: %s", (ans) ? "YES":"NO" );
|
||||
|
||||
// ans = CmdFlexdemod("");
|
||||
// PrintAndLog("FlexPass: %s", (ans) ? "YES":"NO" );
|
||||
|
||||
if (!ans)
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid IO Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
ans=CmdFSKdemodPyramid("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Pyramid ID Found!");
|
||||
return 1;
|
||||
}
|
||||
ans=CmdFSKdemodParadox("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Paradox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
ans=CmdFSKdemodAWID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid AWID ID Found!");
|
||||
return 1;
|
||||
}
|
||||
ans=CmdFSKdemodHID("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid HID Prox ID Found!");
|
||||
return 1;
|
||||
}
|
||||
//add psk and indala
|
||||
ans=CmdIndalaDecode("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Indala ID Found!");
|
||||
return 1;
|
||||
}
|
||||
ans=Cmdaskmandemod("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid EM410x ID Found!");
|
||||
return 1;
|
||||
}
|
||||
PrintAndLog("No Known Tags Found!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -618,29 +623,23 @@ static command_t CommandTable[] =
|
|||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
|
||||
|
||||
{"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
|
||||
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
|
||||
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
|
||||
{"io", CmdLFIO, 1, "{ ioProx tags... }"},
|
||||
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (UID in HEX)(option 'l' for 224 UID"},
|
||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||
|
||||
|
||||
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
|
||||
{"read", CmdLFRead, 0, "['h' or <divisor>] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"},
|
||||
{"search", CmdLFfind, 1, "Read and Search for valid known tag (in offline mode it you can load first then search)"},
|
||||
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
{"simman", CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
|
||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
|
||||
|
||||
{"awid26", CmdLFAWID26, 1, "{ AWID26 tags }"},
|
||||
{"em4x", CmdLFEM4X, 1, "{ EM4X tags }"},
|
||||
{"hid", CmdLFHID, 1, "{ HID tags }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders }"},
|
||||
{"io", CmdLFIO, 1, "{ ioProx tags }"},
|
||||
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 tags }"},
|
||||
{"ti", CmdLFTI, 1, "{ TI tags }"},
|
||||
{"t55xx", CmdLFT55XX, 1, "{ T55xx tags }"},
|
||||
|
||||
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders... }"},
|
||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
|
||||
{"pcf7931", CmdLFPCF7931, 1, "{PCF7931 RFIDs...}"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,17 +13,12 @@
|
|||
#include <inttypes.h>
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "graph.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmddata.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlfem4x.h"
|
||||
#include "util.h"
|
||||
#include "data.h"
|
||||
#define LF_TRACE_BUFF_SIZE 12000
|
||||
#define LF_BITSSTREAM_LEN 1000
|
||||
|
||||
char *global_em410xId;
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
@ -56,15 +51,19 @@ int CmdEM410xRead(const char *Cmd)
|
|||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN];
|
||||
high = low = 0;
|
||||
|
||||
// get clock
|
||||
clock = GetClock(Cmd, 0);
|
||||
/* Detect high and lows and clock */
|
||||
for (i = 0; i < GraphTraceLen; i++)
|
||||
{
|
||||
if (GraphBuffer[i] > high)
|
||||
high = GraphBuffer[i];
|
||||
else if (GraphBuffer[i] < low)
|
||||
low = GraphBuffer[i];
|
||||
}
|
||||
|
||||
// Detect high and lows and clock
|
||||
DetectHighLowInGraph( &high, &low, TRUE);
|
||||
/* get clock */
|
||||
clock = GetClock(Cmd, high, 0);
|
||||
|
||||
PrintAndLog("NUMNUM");
|
||||
|
||||
// parity for our 4 columns
|
||||
/* parity for our 4 columns */
|
||||
parity[0] = parity[1] = parity[2] = parity[3] = 0;
|
||||
header = rows = 0;
|
||||
|
||||
|
@ -104,7 +103,7 @@ int CmdEM410xRead(const char *Cmd)
|
|||
|
||||
retest:
|
||||
/* We go till 5 before the graph ends because we'll get that far below */
|
||||
for (i = 0; i < bit2idx - 5; i++)
|
||||
for (i = 1; i < bit2idx - 5; i++)
|
||||
{
|
||||
/* Step 2: We have our header but need our tag ID */
|
||||
if (header == 9 && rows < 10)
|
||||
|
@ -539,22 +538,6 @@ int CmdReadWord(const char *Cmd)
|
|||
c.arg[1] = Word;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
|
||||
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
|
||||
|
||||
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset..
|
||||
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
|
||||
|
||||
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
|
||||
GraphBuffer[j] = ((int)data[j]);
|
||||
}
|
||||
GraphTraceLen = LF_TRACE_BUFF_SIZE;
|
||||
|
||||
uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};
|
||||
uint8_t * bitstream = bits;
|
||||
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream,LF_BITSSTREAM_LEN);
|
||||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -579,22 +562,6 @@ int CmdReadWordPWD(const char *Cmd)
|
|||
c.arg[1] = Word;
|
||||
c.arg[2] = Password;
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
|
||||
uint8_t data[LF_TRACE_BUFF_SIZE] = {0x00};
|
||||
|
||||
GetFromBigBuf(data,LF_TRACE_BUFF_SIZE,0); //3560 -- should be offset..
|
||||
WaitForResponseTimeout(CMD_ACK,NULL, 1500);
|
||||
|
||||
for (int j = 0; j < LF_TRACE_BUFF_SIZE; j++) {
|
||||
GraphBuffer[j] = ((int)data[j]);
|
||||
}
|
||||
GraphTraceLen = LF_TRACE_BUFF_SIZE;
|
||||
|
||||
uint8_t bits[LF_BITSSTREAM_LEN] = {0x00};
|
||||
uint8_t * bitstream = bits;
|
||||
manchester_decode(GraphBuffer, LF_TRACE_BUFF_SIZE, bitstream, LF_BITSSTREAM_LEN);
|
||||
RepaintGraphWindow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -650,280 +617,20 @@ int CmdWriteWordPWD(const char *Cmd)
|
|||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"410xdemod", CmdEMdemodASK, 0, "[clock rate] -- Extract ID from EM410x tag"},
|
||||
{"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
|
||||
{"410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
|
||||
{"replay", MWRem4xReplay, 0, "Watches for tag and simulates manchester encoded em4x tag"},
|
||||
{"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||
{"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||
{"410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||
{"4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
|
||||
{"rd", CmdReadWord, 1, "<Word 1-15> -- Read EM4xxx word data"},
|
||||
{"rdpwd", CmdReadWordPWD, 1, "<Word 1-15> <Password> -- Read EM4xxx word data in password mode "},
|
||||
{"wr", CmdWriteWord, 1, "<Data> <Word 1-15> -- Write EM4xxx word data"},
|
||||
{"wrpwd", CmdWriteWordPWD, 1, "<Data> <Word 1-15> <Password> -- Write EM4xxx word data in password mode"},
|
||||
{"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
|
||||
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
|
||||
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
|
||||
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
|
||||
{"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
|
||||
{"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
|
||||
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
|
||||
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
|
||||
{"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
|
||||
{"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
|
||||
{"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
//Confirms the parity of a bitstream as well as obtaining the data (TagID) from within the appropriate memory space.
|
||||
//Arguments:
|
||||
// Pointer to a string containing the desired bitsream
|
||||
// Pointer to a string that will receive the decoded tag ID
|
||||
// Length of the bitsream pointed at in the first argument, char* _strBitStream
|
||||
//Retuns:
|
||||
//1 Parity confirmed
|
||||
//0 Parity not confirmed
|
||||
int ConfirmEm410xTagParity( char* _strBitStream, char* pID, int LengthOfBitstream )
|
||||
{
|
||||
int i = 0;
|
||||
int rows = 0;
|
||||
int Parity[4] = {0x00};
|
||||
char ID[11] = {0x00};
|
||||
int k = 0;
|
||||
int BitStream[70] = {0x00};
|
||||
int counter = 0;
|
||||
//prepare variables
|
||||
for ( i = 0; i <= LengthOfBitstream; i++)
|
||||
{
|
||||
if (_strBitStream[i] == '1')
|
||||
{
|
||||
k =1;
|
||||
memcpy(&BitStream[i], &k,4);
|
||||
}
|
||||
else if (_strBitStream[i] == '0')
|
||||
{
|
||||
k = 0;
|
||||
memcpy(&BitStream[i], &k,4);
|
||||
}
|
||||
}
|
||||
while ( counter < 2 )
|
||||
{
|
||||
//set/reset variables and counters
|
||||
memset(ID,0x00,sizeof(ID));
|
||||
memset(Parity,0x00,sizeof(Parity));
|
||||
rows = 0;
|
||||
for ( i = 9; i <= LengthOfBitstream; i++)
|
||||
{
|
||||
if ( rows < 10 )
|
||||
{
|
||||
if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
|
||||
{
|
||||
sprintf(ID+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
|
||||
rows++;
|
||||
/* Keep parity info and move four bits ahead*/
|
||||
Parity[0] ^= BitStream[i];
|
||||
Parity[1] ^= BitStream[i+1];
|
||||
Parity[2] ^= BitStream[i+2];
|
||||
Parity[3] ^= BitStream[i+3];
|
||||
i += 4;
|
||||
}
|
||||
}
|
||||
if ( rows == 10 )
|
||||
{
|
||||
if ( BitStream[i] == Parity[0] && BitStream[i+1] == Parity[1] &&
|
||||
BitStream[i+2] == Parity[2] && BitStream[i+3] == Parity[3] &&
|
||||
BitStream[i+4] == 0)
|
||||
{
|
||||
memcpy(pID,ID,strlen(ID));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("[PARITY ->]Failed. Flipping Bits, and rechecking parity for bitstream:\n[PARITY ->]");
|
||||
for (k = 0; k < LengthOfBitstream; k++)
|
||||
{
|
||||
BitStream[k] ^= 1;
|
||||
printf("%i", BitStream[k]);
|
||||
}
|
||||
puts(" ");
|
||||
counter++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//Reads and demodulates an em410x RFID tag. It further allows slight modification to the decoded bitstream
|
||||
//Once a suitable bitstream has been identified, and if needed, modified, it is replayed. Allowing emulation of the
|
||||
//"stolen" rfid tag.
|
||||
//No meaningful returns or arguments.
|
||||
int MWRem4xReplay(const char* Cmd)
|
||||
{
|
||||
// //header traces
|
||||
// static char ArrayTraceZero[] = { '0','0','0','0','0','0','0','0','0' };
|
||||
// static char ArrayTraceOne[] = { '1','1','1','1','1','1','1','1','1' };
|
||||
// //local string variables
|
||||
// char strClockRate[10] = {0x00};
|
||||
// char strAnswer[4] = {0x00};
|
||||
// char strTempBufferMini[2] = {0x00};
|
||||
// //our outbound bit-stream
|
||||
// char strSimulateBitStream[65] = {0x00};
|
||||
// //integers
|
||||
// int iClockRate = 0;
|
||||
// int needle = 0;
|
||||
// int j = 0;
|
||||
// int iFirstHeaderOffset = 0x00000000;
|
||||
// int numManchesterDemodBits=0;
|
||||
// //boolean values
|
||||
// bool bInverted = false;
|
||||
// //pointers to strings. memory will be allocated.
|
||||
// char* pstrInvertBitStream = 0x00000000;
|
||||
// char* pTempBuffer = 0x00000000;
|
||||
// char* pID = 0x00000000;
|
||||
// char* strBitStreamBuffer = 0x00000000;
|
||||
|
||||
|
||||
// puts("###################################");
|
||||
// puts("#### Em4x Replay ##");
|
||||
// puts("#### R.A.M. June 2013 ##");
|
||||
// puts("###################################");
|
||||
// //initialize
|
||||
// CmdLFRead("");
|
||||
// //Collect ourselves 10,000 samples
|
||||
// CmdSamples("10000");
|
||||
// puts("[->]preforming ASK demodulation\n");
|
||||
// //demodulate ask
|
||||
// Cmdaskdemod("0");
|
||||
// iClockRate = DetectClock(0);
|
||||
// sprintf(strClockRate, "%i\n",iClockRate);
|
||||
// printf("[->]Detected ClockRate: %s\n", strClockRate);
|
||||
|
||||
// //If detected clock rate is something completely unreasonable, dont go ahead
|
||||
// if ( iClockRate < 0xFFFE )
|
||||
// {
|
||||
// pTempBuffer = (char*)malloc(MAX_GRAPH_TRACE_LEN);
|
||||
// if (pTempBuffer == 0x00000000)
|
||||
// return 0;
|
||||
// memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN);
|
||||
// //Preform manchester de-modulation and display in a single line.
|
||||
// numManchesterDemodBits = CmdManchesterDemod( strClockRate );
|
||||
// //note: numManchesterDemodBits is set above in CmdManchesterDemod()
|
||||
// if ( numManchesterDemodBits == 0 )
|
||||
// return 0;
|
||||
// strBitStreamBuffer = malloc(numManchesterDemodBits+1);
|
||||
// if ( strBitStreamBuffer == 0x00000000 )
|
||||
// return 0;
|
||||
// memset(strBitStreamBuffer, 0x00, (numManchesterDemodBits+1));
|
||||
// //fill strBitStreamBuffer with demodulated, string formatted bits.
|
||||
// for ( j = 0; j <= numManchesterDemodBits; j++ )
|
||||
// {
|
||||
// sprintf(strTempBufferMini, "%i",BitStream[j]);
|
||||
// strcat(strBitStreamBuffer,strTempBufferMini);
|
||||
// }
|
||||
// printf("[->]Demodulated Bitstream: \n%s\n", strBitStreamBuffer);
|
||||
// //Reset counter and select most probable bit stream
|
||||
// j = 0;
|
||||
// while ( j < numManchesterDemodBits )
|
||||
// {
|
||||
// memset(strSimulateBitStream,0x00,64);
|
||||
// //search for header of nine (9) 0's : 000000000 or nine (9) 1's : 1111 1111 1
|
||||
// if ( ( strncmp(strBitStreamBuffer+j, ArrayTraceZero, sizeof(ArrayTraceZero)) == 0 ) ||
|
||||
// ( strncmp(strBitStreamBuffer+j, ArrayTraceOne, sizeof(ArrayTraceOne)) == 0 ) )
|
||||
// {
|
||||
// iFirstHeaderOffset = j;
|
||||
// memcpy(strSimulateBitStream, strBitStreamBuffer+j,64);
|
||||
// printf("[->]Offset of Header");
|
||||
// if ( strncmp(strBitStreamBuffer+iFirstHeaderOffset, "0", 1) == 0 )
|
||||
// printf("'%s'", ArrayTraceZero );
|
||||
// else
|
||||
// printf("'%s'", ArrayTraceOne );
|
||||
// printf(": %i\nHighlighted string : %s\n",iFirstHeaderOffset,strSimulateBitStream);
|
||||
// //allow us to escape loop or choose another frame
|
||||
// puts("[<-]Are we happy with this sample? [Y]es/[N]o");
|
||||
// gets(strAnswer);
|
||||
// if ( ( strncmp(strAnswer,"y",1) == 0 ) || ( strncmp(strAnswer,"Y",1) == 0 ) )
|
||||
// {
|
||||
// j = numManchesterDemodBits+1;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// j++;
|
||||
// }
|
||||
// }
|
||||
// else return 0;
|
||||
|
||||
// //Do we want the buffer inverted?
|
||||
// memset(strAnswer, 0x00, sizeof(strAnswer));
|
||||
// printf("[<-]Do you wish to invert the highlighted bitstream? [Y]es/[N]o\n");
|
||||
// gets(strAnswer);
|
||||
// if ( ( strncmp("y", strAnswer,1) == 0 ) || ( strncmp("Y", strAnswer, 1 ) == 0 ) )
|
||||
// {
|
||||
// //allocate heap memory
|
||||
// pstrInvertBitStream = (char*)malloc(numManchesterDemodBits);
|
||||
// if ( pstrInvertBitStream != 0x00000000 )
|
||||
// {
|
||||
// memset(pstrInvertBitStream,0x00,numManchesterDemodBits);
|
||||
// bInverted = true;
|
||||
// //Invert Bitstream
|
||||
// for ( needle = 0; needle <= numManchesterDemodBits; needle++ )
|
||||
// {
|
||||
// if (strSimulateBitStream[needle] == '0')
|
||||
// strcat(pstrInvertBitStream,"1");
|
||||
// else if (strSimulateBitStream[needle] == '1')
|
||||
// strcat(pstrInvertBitStream,"0");
|
||||
// }
|
||||
// printf("[->]Inverted bitstream: %s\n", pstrInvertBitStream);
|
||||
// }
|
||||
// }
|
||||
// //Confirm parity of selected string
|
||||
// pID = (char*)malloc(11);
|
||||
// if (pID != 0x00000000)
|
||||
// {
|
||||
// memset(pID, 0x00, 11);
|
||||
// if (ConfirmEm410xTagParity(strSimulateBitStream,pID, 64) == 1)
|
||||
// {
|
||||
// printf("[->]Parity confirmed for selected bitstream!\n");
|
||||
// printf("[->]Tag ID was detected as: [hex]:%s\n",pID );
|
||||
// }
|
||||
// else
|
||||
// printf("[->]Parity check failed for the selected bitstream!\n");
|
||||
// }
|
||||
|
||||
// //Spoof
|
||||
// memset(strAnswer, 0x00, sizeof(strAnswer));
|
||||
// printf("[<-]Do you wish to continue with the EM4x simulation? [Y]es/[N]o\n");
|
||||
// gets(strAnswer);
|
||||
// if ( ( strncmp(strAnswer,"y",1) == 0 ) || ( strncmp(strAnswer,"Y",1) == 0 ) )
|
||||
// {
|
||||
// strcat(pTempBuffer, strClockRate);
|
||||
// strcat(pTempBuffer, " ");
|
||||
// if (bInverted == true)
|
||||
// strcat(pTempBuffer,pstrInvertBitStream);
|
||||
// if (bInverted == false)
|
||||
// strcat(pTempBuffer,strSimulateBitStream);
|
||||
// //inform the user
|
||||
// puts("[->]Starting simulation now: \n");
|
||||
// //Simulate tag with prepared buffer.
|
||||
// CmdLFSimManchester(pTempBuffer);
|
||||
// }
|
||||
// else if ( ( strcmp("n", strAnswer) == 0 ) || ( strcmp("N", strAnswer ) == 0 ) )
|
||||
// printf("[->]Exiting procedure now...\n");
|
||||
// else
|
||||
// printf("[->]Erroneous selection\nExiting procedure now....\n");
|
||||
|
||||
// //Clean up -- Exit function
|
||||
// //clear memory, then release pointer.
|
||||
// if ( pstrInvertBitStream != 0x00000000 )
|
||||
// {
|
||||
// memset(pstrInvertBitStream,0x00,numManchesterDemodBits);
|
||||
// free(pstrInvertBitStream);
|
||||
// }
|
||||
// if ( pTempBuffer != 0x00000000 )
|
||||
// {
|
||||
// memset(pTempBuffer,0x00,MAX_GRAPH_TRACE_LEN);
|
||||
// free(pTempBuffer);
|
||||
// }
|
||||
// if ( pID != 0x00000000 )
|
||||
// {
|
||||
// memset(pID,0x00,11);
|
||||
// free(pID);
|
||||
// }
|
||||
// if ( strBitStreamBuffer != 0x00000000 )
|
||||
// {
|
||||
// memset(strBitStreamBuffer,0x00,numManchesterDemodBits);
|
||||
// free(strBitStreamBuffer);
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdLFEM4X(const char *Cmd)
|
||||
{
|
||||
CmdsParse(CommandTable, Cmd);
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "cmdparser.h"
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
#include "util.h"
|
||||
#include "../include/hitag2.h"
|
||||
#include "hitag2.h"
|
||||
#include "sleep.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
|
@ -29,11 +29,26 @@ size_t nbytes(size_t nbits) {
|
|||
|
||||
int CmdLFHitagList(const char *Cmd)
|
||||
{
|
||||
uint8_t got[TRACE_BUFFER_SIZE];
|
||||
GetFromBigBuf(got,sizeof(got),0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
|
||||
|
||||
PrintAndLog("recorded activity:");
|
||||
// Query for the actual size of the trace
|
||||
UsbCommand response;
|
||||
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, &response);
|
||||
uint16_t traceLen = response.arg[2];
|
||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||
uint8_t *p = realloc(got, traceLen);
|
||||
if (p == NULL) {
|
||||
PrintAndLog("Cannot allocate memory for trace");
|
||||
free(got);
|
||||
return 2;
|
||||
}
|
||||
got = p;
|
||||
GetFromBigBuf(got, traceLen, 0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
}
|
||||
|
||||
PrintAndLog("recorded activity (TraceLen = %d bytes):");
|
||||
PrintAndLog(" ETU :nbits: who bytes");
|
||||
PrintAndLog("---------+-----+----+-----------");
|
||||
|
||||
|
@ -57,7 +72,7 @@ int CmdLFHitagList(const char *Cmd)
|
|||
|
||||
for (;;) {
|
||||
|
||||
if(i >= TRACE_BUFFER_SIZE) { break; }
|
||||
if(i > traceLen) { break; }
|
||||
|
||||
bool isResponse;
|
||||
int timestamp = *((uint32_t *)(got+i));
|
||||
|
@ -82,7 +97,7 @@ int CmdLFHitagList(const char *Cmd)
|
|||
if (len > 100) {
|
||||
break;
|
||||
}
|
||||
if (i + len >= TRACE_BUFFER_SIZE) { break;}
|
||||
if (i + len > traceLen) { break;}
|
||||
|
||||
uint8_t *frame = (got+i+9);
|
||||
|
||||
|
@ -114,7 +129,6 @@ int CmdLFHitagList(const char *Cmd)
|
|||
(isResponse ? "TAG" : " "),
|
||||
line);
|
||||
|
||||
|
||||
if (pf) {
|
||||
fprintf(pf," +%7d: %3d: %s %s\n",
|
||||
(prev < 0 ? 0 : (timestamp - prev)),
|
||||
|
@ -132,6 +146,7 @@ int CmdLFHitagList(const char *Cmd)
|
|||
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
|
||||
}
|
||||
|
||||
free(got);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "cmdparser.h"
|
||||
#include "proxmark3.h"
|
||||
#include "data.h"
|
||||
#include "../include/usb_cmd.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "ui.h"
|
||||
#include "cmdhf.h"
|
||||
#include "cmddata.h"
|
||||
|
@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC)
|
|||
} break;
|
||||
|
||||
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
|
||||
sample_buf_len += UC->arg[1];
|
||||
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
|
||||
} break;
|
||||
|
||||
|
|
|
@ -16,11 +16,9 @@
|
|||
#include "cmdmain.h"
|
||||
|
||||
uint8_t* sample_buf;
|
||||
size_t sample_buf_len;
|
||||
|
||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
|
||||
{
|
||||
sample_buf_len = 0;
|
||||
sample_buf = dest;
|
||||
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
|
||||
SendCommand(&c);
|
||||
|
|
|
@ -13,13 +13,9 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
|
||||
#define TRACE_BUFFER_SIZE 4096
|
||||
#define FILE_PATH_SIZE 1000
|
||||
#define SAMPLE_BUFFER_SIZE 64
|
||||
|
||||
extern uint8_t* sample_buf;
|
||||
extern size_t sample_buf_len;
|
||||
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "flash.h"
|
||||
#include "elf.h"
|
||||
#include "proxendian.h"
|
||||
#include "../include/usb_cmd.h"
|
||||
#include "usb_cmd.h"
|
||||
|
||||
void SendCommand(UsbCommand* txcmd);
|
||||
void ReceiveCommand(UsbCommand* rxcmd);
|
||||
|
|
|
@ -22,20 +22,18 @@ int GraphTraceLen;
|
|||
void AppendGraph(int redraw, int clock, int bit)
|
||||
{
|
||||
int i;
|
||||
int half = (int)(clock/2);
|
||||
int firstbit = bit ^ 1;
|
||||
|
||||
for (i = 0; i < half; ++i)
|
||||
GraphBuffer[GraphTraceLen++] = firstbit;
|
||||
for (i = 0; i < (int)(clock / 2); ++i)
|
||||
GraphBuffer[GraphTraceLen++] = bit ^ 1;
|
||||
|
||||
for (i = 0; i <= half; ++i)
|
||||
for (i = (int)(clock / 2); i < clock; ++i)
|
||||
GraphBuffer[GraphTraceLen++] = bit;
|
||||
|
||||
if (redraw)
|
||||
RepaintGraphWindow();
|
||||
}
|
||||
|
||||
/* clear out our graph window */
|
||||
// clear out our graph window
|
||||
int ClearGraph(int redraw)
|
||||
{
|
||||
int gtl = GraphTraceLen;
|
||||
|
@ -49,7 +47,9 @@ int ClearGraph(int redraw)
|
|||
return gtl;
|
||||
}
|
||||
|
||||
void SetGraphBuf(uint8_t *buff, int size)
|
||||
// DETECT CLOCK NOW IN LFDEMOD.C
|
||||
|
||||
void setGraphBuf(uint8_t *buff, size_t size)
|
||||
{
|
||||
if ( buff == NULL ) return;
|
||||
|
||||
|
@ -58,56 +58,49 @@ void SetGraphBuf(uint8_t *buff, int size)
|
|||
size = MAX_GRAPH_TRACE_LEN;
|
||||
ClearGraph(0);
|
||||
for (; i < size; ++i){
|
||||
GraphBuffer[i] = buff[i];
|
||||
GraphBuffer[i]=buff[i]-128;
|
||||
}
|
||||
GraphTraceLen=size;
|
||||
RepaintGraphWindow();
|
||||
return;
|
||||
}
|
||||
|
||||
// Copies grahpbuff to buff.
|
||||
// while triming values to the range -127 -- 127.
|
||||
int GetFromGraphBuf(uint8_t *buff)
|
||||
size_t getFromGraphBuf(uint8_t *buff)
|
||||
{
|
||||
if ( buff == NULL ) return -1;
|
||||
uint32_t i = 0;
|
||||
|
||||
for (; i < GraphTraceLen; ++i){
|
||||
|
||||
// trim upper and lower values.
|
||||
if (GraphBuffer[i] > 127)
|
||||
GraphBuffer[i] = 127;
|
||||
else if (GraphBuffer[i] < -127)
|
||||
GraphBuffer[i] = -127;
|
||||
if ( buff == NULL ) return 0;
|
||||
|
||||
uint32_t i;
|
||||
for (i=0;i<GraphTraceLen;++i){
|
||||
if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
|
||||
if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
|
||||
buff[i]=(uint8_t)(GraphBuffer[i]+128);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
/* Get or auto-detect clock rate */
|
||||
int GetClock(const char *str, int verbose)
|
||||
|
||||
|
||||
// Get or auto-detect clock rate
|
||||
int GetClock(const char *str, int peak, int verbose)
|
||||
{
|
||||
int clock;
|
||||
|
||||
sscanf(str, "%i", &clock);
|
||||
if (!strcmp(str, ""))
|
||||
clock = 0;
|
||||
|
||||
/* Auto-detect clock */
|
||||
if (!clock) {
|
||||
|
||||
uint8_t grph[MAX_GRAPH_TRACE_LEN] = {0x00};
|
||||
int size = GetFromGraphBuf(grph);
|
||||
if ( size < 0 ) {
|
||||
// Auto-detect clock
|
||||
if (!clock)
|
||||
{
|
||||
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
||||
size_t size = getFromGraphBuf(grph);
|
||||
if ( size == 0 ) {
|
||||
PrintAndLog("Failed to copy from graphbuffer");
|
||||
return -1;
|
||||
}
|
||||
clock = DetectASKClock(grph,size,0);
|
||||
|
||||
/* Only print this message if we're not looping something */
|
||||
if (verbose)
|
||||
// Only print this message if we're not looping something
|
||||
if (!verbose){
|
||||
PrintAndLog("Auto-detected clock rate: %d", clock);
|
||||
}
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
|
||||
|
@ -142,3 +135,28 @@ void DetectHighLowInGraph(int *high, int *low, bool addFuzz) {
|
|||
*low = (int)(*low * .88);
|
||||
}
|
||||
}
|
||||
|
||||
int GetNRZpskClock(const char *str, int peak, int verbose)
|
||||
{
|
||||
int clock;
|
||||
sscanf(str, "%i", &clock);
|
||||
if (!strcmp(str, ""))
|
||||
clock = 0;
|
||||
|
||||
// Auto-detect clock
|
||||
if (!clock)
|
||||
{
|
||||
uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
|
||||
size_t size = getFromGraphBuf(grph);
|
||||
if ( size == 0 ) {
|
||||
PrintAndLog("Failed to copy from graphbuffer");
|
||||
return -1;
|
||||
}
|
||||
clock = DetectpskNRZClock(grph,size,0);
|
||||
// Only print this message if we're not looping something
|
||||
if (!verbose){
|
||||
PrintAndLog("Auto-detected clock rate: %d", clock);
|
||||
}
|
||||
}
|
||||
return clock;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,16 @@
|
|||
|
||||
#ifndef GRAPH_H__
|
||||
#define GRAPH_H__
|
||||
#include <stdint.h>
|
||||
|
||||
void AppendGraph(int redraw, int clock, int bit);
|
||||
int ClearGraph(int redraw);
|
||||
int GetFromGraphBuf(uint8_t *buff);
|
||||
int GetClock(const char *str, int verbose);
|
||||
void SetGraphBuf(uint8_t *buff,int size);
|
||||
//int DetectClock(int peak);
|
||||
size_t getFromGraphBuf(uint8_t *buff);
|
||||
int GetClock(const char *str, int peak, int verbose);
|
||||
int GetNRZpskClock(const char *str, int peak, int verbose);
|
||||
void setGraphBuf(uint8_t *buff, size_t size);
|
||||
|
||||
bool HasGraphData();
|
||||
void DetectHighLowInGraph(int *high, int *low, bool addFuzz);
|
||||
|
||||
|
|
|
@ -30,9 +30,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with IClassCipher. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "cipher.h"
|
||||
#include "cipherutils.h"
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -30,9 +30,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with IClassCipher. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef CIPHER_H
|
||||
#define CIPHER_H
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -30,7 +30,10 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with IClassCipher. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -30,9 +30,13 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with IClassCipher. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef CIPHERUTILS_H
|
||||
#define CIPHERUTILS_H
|
||||
#include <stdint.h>
|
||||
|
|
|
@ -28,6 +28,12 @@
|
|||
#define POLARSSL_DES_H
|
||||
|
||||
//#include "config.h"
|
||||
/**
|
||||
* \def POLARSSL_CIPHER_MODE_CBC
|
||||
*
|
||||
* Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
|
||||
*/
|
||||
#define POLARSSL_CIPHER_MODE_CBC
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
|
@ -552,6 +552,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[])
|
|||
*/
|
||||
int bruteforceFile(const char *filename, uint16_t keytable[])
|
||||
{
|
||||
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if(!f) {
|
||||
prnlog("Failed to read from file '%s'", filename);
|
||||
|
@ -659,6 +660,21 @@ int _test_iclass_key_permutation()
|
|||
prnlog("[+] Iclass key permutation OK!");
|
||||
return 0;
|
||||
}
|
||||
int _testHash1()
|
||||
{
|
||||
uint8_t csn[8]= {0x01,0x02,0x03,0x04,0xF7,0xFF,0x12,0xE0};
|
||||
uint8_t k[8] = {0};
|
||||
hash1(csn, k);
|
||||
uint8_t expected[8] = {0x7E,0x72,0x2F,0x40,0x2D,0x02,0x51,0x42};
|
||||
if(memcmp(k,expected,8) != 0)
|
||||
{
|
||||
prnlog("Error with hash1!");
|
||||
printarr("calculated", k, 8);
|
||||
printarr("expected", expected, 8);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testElite()
|
||||
{
|
||||
|
@ -691,11 +707,13 @@ int testElite()
|
|||
prnlog("[+] Hash2 looks fine...");
|
||||
}
|
||||
|
||||
prnlog("[+] Testing key diversification ...");
|
||||
|
||||
int errors = 0 ;
|
||||
prnlog("[+] Testing hash1...");
|
||||
errors += _testHash1();
|
||||
prnlog("[+] Testing key diversification ...");
|
||||
errors +=_test_iclass_key_permutation();
|
||||
errors += _testBruteforce();
|
||||
|
||||
return errors;
|
||||
|
||||
}
|
||||
|
|
|
@ -78,31 +78,18 @@ int saveFile(const char *preferredName, const char *suffix, const void* data, si
|
|||
/*Opening file for writing in binary mode*/
|
||||
FILE *fileHandle=fopen(fileName,"wb");
|
||||
if(!fileHandle) {
|
||||
PrintAndLog("Failed to write to file '%s'", fileName);
|
||||
prnlog("Failed to write to file '%s'", fileName);
|
||||
free(fileName);
|
||||
return 1;
|
||||
}
|
||||
fwrite(data, 1, datalen, fileHandle);
|
||||
fclose(fileHandle);
|
||||
PrintAndLog("Saved data to '%s'", fileName);
|
||||
prnlog("Saved data to '%s'", fileName);
|
||||
free(fileName);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int loadFile(const char *fileName, void* data, size_t datalen)
|
||||
{
|
||||
FILE *filehandle = fopen(fileName, "rb");
|
||||
if(!filehandle) {
|
||||
PrintAndLog("Failed to read from file '%s'", fileName);
|
||||
free(filehandle);
|
||||
return 1;
|
||||
}
|
||||
fread(data,datalen,1,filehandle);
|
||||
fclose(filehandle);
|
||||
free(filehandle);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Utility function to print to console. This is used consistently within the library instead
|
||||
* of printf, but it actually only calls printf (and adds a linebreak).
|
||||
|
|
BIN
client/loclass/iclass_dump.bin
Normal file
BIN
client/loclass/iclass_dump.bin
Normal file
Binary file not shown.
|
@ -18,10 +18,6 @@
|
|||
* Flavio D. Garcia, Gerhard de Koning Gans, Roel Verdult and
|
||||
* Milosch Meriac in the paper "Dismantling IClass".
|
||||
*
|
||||
* This is a reference implementation of iclass key diversification. I'm sure it can be
|
||||
* optimized heavily. It is written for ease of understanding and correctness, please take it
|
||||
* and tweak it and make a super fast version instead, using this for testing and verification.
|
||||
|
||||
* Copyright (C) 2014 Martin Holst Swende
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify
|
||||
|
@ -34,8 +30,12 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with IClassCipher. If not, see <http://www.gnu.org/licenses/>.
|
||||
* along with loclass. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
|
||||
|
||||
|
|
4
client/loclass/loclass_main.h
Normal file
4
client/loclass/loclass_main.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#ifndef LOCLASS_MAIN_H
|
||||
#define LOCLASS_MAIN_H
|
||||
|
||||
#endif // LOCLASS_MAIN_H
|
|
@ -38,7 +38,6 @@
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cipherutils.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
@ -56,11 +55,15 @@ int unitTests()
|
|||
errors += testMAC();
|
||||
errors += doKeyTests(0);
|
||||
errors += testElite();
|
||||
if(errors)
|
||||
{
|
||||
prnlog("OBS! There were errors!!!");
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
int showHelp()
|
||||
{
|
||||
prnlog("Usage: iclazz [options]");
|
||||
prnlog("Usage: loclass [options]");
|
||||
prnlog("Options:");
|
||||
prnlog("-t Perform self-test");
|
||||
prnlog("-h Show this help");
|
||||
|
|
|
@ -212,7 +212,6 @@ function Command:getBytes()
|
|||
local data = self.data
|
||||
local cmd = self.cmd
|
||||
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
|
||||
|
||||
return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
|
||||
end
|
||||
return _commands
|
|
@ -49,7 +49,7 @@ end
|
|||
|
||||
local function save_TEXT(data,filename)
|
||||
-- Open the output file
|
||||
local outfile = io.open(filename, "wb")
|
||||
local outfile = io.open(filename, "w")
|
||||
if outfile == nil then
|
||||
return oops(string.format("Could not write to file %s",tostring(filename)))
|
||||
end
|
||||
|
@ -195,4 +195,6 @@ return {
|
|||
convert_eml_to_bin = convert_eml_to_bin,
|
||||
SaveAsBinary = save_BIN,
|
||||
SaveAsText = save_TEXT,
|
||||
SaveAsBinary = save_BIN,
|
||||
SaveAsText = save_TEXT,
|
||||
}
|
||||
|
|
|
@ -161,6 +161,20 @@ local _keys = {
|
|||
'b5ff67cba951',
|
||||
}
|
||||
|
||||
--[[
|
||||
Kiev metro cards
|
||||
--]]
|
||||
'8fe644038790',
|
||||
'f14ee7cae863',
|
||||
'632193be1c3c',
|
||||
'569369c5a0e5',
|
||||
'9de89e070277',
|
||||
'eff603e1efe9',
|
||||
'644672bd4afe',
|
||||
|
||||
'b5ff67cba951',
|
||||
}
|
||||
|
||||
---
|
||||
-- The keys above have just been pasted in, for completeness sake. They contain duplicates.
|
||||
-- We need to weed the duplicates out before we expose the list to someone who actually wants to use them
|
||||
|
|
|
@ -108,6 +108,24 @@ local Utils =
|
|||
return retval
|
||||
end,
|
||||
|
||||
-- input parameter is a string
|
||||
-- Swaps the endianess and returns a string,
|
||||
-- IE: 'cd7a' -> '7acd' -> 0x7acd
|
||||
SwapEndiannessStr = function(s, len)
|
||||
if s == nil then return nil end
|
||||
if #s == 0 then return '' end
|
||||
if type(s) ~= 'string' then return nil end
|
||||
|
||||
local retval
|
||||
if len == 16 then
|
||||
retval = s:sub(3,4)..s:sub(1,2)
|
||||
elseif len == 24 then
|
||||
retval = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||
elseif len == 32 then
|
||||
retval = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)
|
||||
end
|
||||
return retval
|
||||
end,
|
||||
------------ CONVERSIONS
|
||||
|
||||
--
|
||||
|
@ -116,7 +134,7 @@ local Utils =
|
|||
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0
|
||||
while IN>0 do
|
||||
I=I+1
|
||||
IN,D=math.floor(IN/B),math.mod(IN,B)+1
|
||||
IN , D = math.floor(IN/B), math.modf(IN,B)+1
|
||||
OUT=string.sub(K,D,D)..OUT
|
||||
end
|
||||
return OUT
|
||||
|
|
|
@ -72,7 +72,6 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
|
|||
uint16_t i, len;
|
||||
uint32_t uid;
|
||||
UsbCommand resp;
|
||||
|
||||
StateList_t statelists[2];
|
||||
struct Crypto1State *p1, *p2, *p3, *p4;
|
||||
|
||||
|
@ -232,14 +231,27 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
|||
// "MAGIC" CARD
|
||||
|
||||
int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {
|
||||
|
||||
uint8_t oldblock0[16] = {0x00};
|
||||
uint8_t block0[16] = {0x00};
|
||||
memcpy(block0, uid, 4);
|
||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC
|
||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7)
|
||||
block0[5] = 0x08;
|
||||
block0[6] = 0x04;
|
||||
block0[7] = 0x00;
|
||||
//block0[5] = 0x08;
|
||||
//block0[6] = 0x04;
|
||||
//block0[7] = 0x00;
|
||||
|
||||
block0[5] = 0x01; //sak
|
||||
block0[6] = 0x01;
|
||||
block0[7] = 0x0f;
|
||||
|
||||
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
|
||||
if ( old == 0) {
|
||||
memcpy(block0+8, oldblock0+8, 8);
|
||||
PrintAndLog("block 0: %s", sprint_hex(block0,16));
|
||||
} else {
|
||||
PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0.");
|
||||
}
|
||||
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
||||
}
|
||||
|
||||
|
@ -253,8 +265,10 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
|
|||
UsbCommand resp;
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
isOK = resp.arg[0] & 0xff;
|
||||
if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);
|
||||
if (!isOK) return 2;
|
||||
if (uid != NULL)
|
||||
memcpy(uid, resp.d.asBytes, 4);
|
||||
if (!isOK)
|
||||
return 2;
|
||||
} else {
|
||||
PrintAndLog("Command execute timeout");
|
||||
return 1;
|
||||
|
@ -286,9 +300,9 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
|||
static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};
|
||||
|
||||
// variables
|
||||
char logHexFileName[200] = {0x00};
|
||||
char logHexFileName[FILE_PATH_SIZE] = {0x00};
|
||||
static uint8_t traceCard[4096] = {0x00};
|
||||
static char traceFileName[200] = {0x00};
|
||||
static char traceFileName[FILE_PATH_SIZE] = {0x00};
|
||||
static int traceState = TRACE_IDLE;
|
||||
static uint8_t traceCurBlock = 0;
|
||||
static uint8_t traceCurKey = 0;
|
||||
|
@ -323,20 +337,28 @@ int isBlockTrailer(int blockN) {
|
|||
|
||||
int loadTraceCard(uint8_t *tuid) {
|
||||
FILE * f;
|
||||
char buf[64];
|
||||
uint8_t buf8[64];
|
||||
char buf[64] = {0x00};
|
||||
uint8_t buf8[64] = {0x00};
|
||||
int i, blockNum;
|
||||
|
||||
if (!isTraceCardEmpty()) saveTraceCard();
|
||||
if (!isTraceCardEmpty())
|
||||
saveTraceCard();
|
||||
|
||||
memset(traceCard, 0x00, 4096);
|
||||
memcpy(traceCard, tuid + 3, 4);
|
||||
|
||||
FillFileNameByUID(traceFileName, tuid, ".eml", 7);
|
||||
|
||||
f = fopen(traceFileName, "r");
|
||||
if (!f) return 1;
|
||||
if (!f) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
blockNum = 0;
|
||||
|
||||
while(!feof(f)){
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
PrintAndLog("File reading error.");
|
||||
|
@ -368,22 +390,30 @@ int saveTraceCard(void) {
|
|||
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0;
|
||||
|
||||
f = fopen(traceFileName, "w+");
|
||||
if ( !f ) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 64; i++) { // blocks
|
||||
for (int j = 0; j < 16; j++) // bytes
|
||||
fprintf(f, "%02x", *(traceCard + i * 16 + j));
|
||||
fprintf(f,"\n");
|
||||
}
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {
|
||||
|
||||
if (traceCrypto1) crypto1_destroy(traceCrypto1);
|
||||
if (traceCrypto1)
|
||||
crypto1_destroy(traceCrypto1);
|
||||
|
||||
traceCrypto1 = NULL;
|
||||
|
||||
if (wantSaveToEmlFile) loadTraceCard(tuid);
|
||||
if (wantSaveToEmlFile)
|
||||
loadTraceCard(tuid);
|
||||
|
||||
traceCard[4] = traceCard[0] ^ traceCard[1] ^ traceCard[2] ^ traceCard[3];
|
||||
traceCard[5] = sak;
|
||||
memcpy(&traceCard[6], atqa, 2);
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct {
|
|||
int foundKey[2];
|
||||
} sector;
|
||||
|
||||
extern char logHexFileName[200];
|
||||
extern char logHexFileName[FILE_PATH_SIZE];
|
||||
|
||||
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * ResultKeys, bool calibrate);
|
||||
int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key);
|
||||
|
|
2179
client/polarssl_config.h
Normal file
2179
client/polarssl_config.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -18,8 +18,8 @@
|
|||
#include "util.h"
|
||||
#include "nonce2key/nonce2key.h"
|
||||
#include "../common/iso15693tools.h"
|
||||
#include <openssl/aes.h>
|
||||
#include "../common/crc16.h"
|
||||
#include "aes.h"
|
||||
/**
|
||||
* The following params expected:
|
||||
* UsbCommand c
|
||||
|
@ -240,10 +240,10 @@ static int l_aes(lua_State *L)
|
|||
|
||||
const char *p_encTxt = luaL_checklstring(L, 2, &size);
|
||||
|
||||
unsigned char indata[AES_BLOCK_SIZE] = {0x00};
|
||||
unsigned char outdata[AES_BLOCK_SIZE] = {0x00};
|
||||
unsigned char aes_key[AES_BLOCK_SIZE] = {0x00};
|
||||
unsigned char iv[AES_BLOCK_SIZE] = {0x00};
|
||||
unsigned char indata[16] = {0x00};
|
||||
unsigned char outdata[16] = {0x00};
|
||||
unsigned char aes_key[16] = {0x00};
|
||||
unsigned char iv[16] = {0x00};
|
||||
|
||||
// convert key to bytearray
|
||||
for (i = 0; i < 32; i += 2) {
|
||||
|
@ -255,10 +255,14 @@ static int l_aes(lua_State *L)
|
|||
sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
|
||||
}
|
||||
|
||||
AES_KEY key;
|
||||
AES_set_decrypt_key(aes_key, 128, &key);
|
||||
AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
|
||||
//AES_KEY key;
|
||||
//AES_set_decrypt_key(aes_key, 128, &key);
|
||||
//AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
|
||||
|
||||
aes_context ctx;
|
||||
aes_init(&ctx);
|
||||
aes_setkey_enc(&ctx,(const unsigned char *)p_key,128);
|
||||
aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata );
|
||||
//Push decrypted array as a string
|
||||
lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
|
||||
return 1;// return 1 to signal one return value
|
||||
|
|
63
client/scripts/remagic.lua
Normal file
63
client/scripts/remagic.lua
Normal file
|
@ -0,0 +1,63 @@
|
|||
local getopt = require('getopt')
|
||||
|
||||
example = "script run remagic"
|
||||
author = "Iceman"
|
||||
|
||||
desc =
|
||||
[[
|
||||
This is a script that tries to bring back a chinese magic card (1k generation1)
|
||||
from the dead when it's block 0 has been written with bad values.
|
||||
|
||||
Arguments:
|
||||
-h this help
|
||||
]]
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
if DEBUG then
|
||||
print("###", args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
function oops(err)
|
||||
print("ERROR: ",err)
|
||||
end
|
||||
|
||||
---
|
||||
-- Usage help
|
||||
function help()
|
||||
print(desc)
|
||||
print("Example usage")
|
||||
print(example)
|
||||
end
|
||||
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'h') do
|
||||
if o == "h" then help() return end
|
||||
end
|
||||
|
||||
local _cmds = {
|
||||
--[[
|
||||
--]]
|
||||
[0] = "hf 14a raw -p -a -b 7 40",
|
||||
[1] = "hf 14a raw -p -a 43",
|
||||
[2] = "hf 14a raw -c -p -a A000",
|
||||
[3] = "hf 14a raw -c -p -a 01 02 03 04 04 98 02 00 00 00 00 00 00 00 10 01",
|
||||
}
|
||||
core.clearCommandBuffer()
|
||||
|
||||
local i
|
||||
--for _,c in pairs(_cmds) do
|
||||
for i = 0, 3 do
|
||||
print ( _cmds[i] )
|
||||
core.console( _cmds[i] )
|
||||
end
|
||||
end
|
||||
|
||||
main(args)
|
|
@ -249,18 +249,19 @@ local function main(args)
|
|||
end
|
||||
end
|
||||
|
||||
-- Write dump to files
|
||||
if not DEBUG then
|
||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
|
||||
print(("Wrote a BIN dump to the file %s"):format(foo))
|
||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
|
||||
print(("Wrote a EML dump to the file %s"):format(bar))
|
||||
end
|
||||
|
||||
local uid = block0:sub(1,8)
|
||||
local itemtype = block1:sub(1,4)
|
||||
local cardid = block1:sub(9,24)
|
||||
|
||||
-- Write dump to files
|
||||
if not DEBUG then
|
||||
local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'_uid_'..uid..'.bin')
|
||||
print(("Wrote a BIN dump to the file %s"):format(foo))
|
||||
local bar = dumplib.SaveAsText(emldata, outputTemplate..'_uid_'..uid..'.eml')
|
||||
print(("Wrote a EML dump to the file %s"):format(bar))
|
||||
end
|
||||
|
||||
-- Show info
|
||||
print( string.rep('--',20) )
|
||||
print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
|
||||
|
|
|
@ -241,18 +241,20 @@ local function main(args)
|
|||
local cmdSetDbgOff = "hf mf dbg 0"
|
||||
core.console( cmdSetDbgOff)
|
||||
|
||||
-- Look for tag present on reader,
|
||||
result, err = lib14a.read1443a(false)
|
||||
if not result then return oops(err) end
|
||||
-- if not loadFromDump then
|
||||
-- -- Look for tag present on reader,
|
||||
-- result, err = lib14a.read1443a(false)
|
||||
-- if not result then return oops(err) end
|
||||
|
||||
core.clearCommandBuffer()
|
||||
-- core.clearCommandBuffer()
|
||||
|
||||
if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
|
||||
return oops('This is not a TNP3xxx tag. aborting.')
|
||||
end
|
||||
-- if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
|
||||
-- return oops('This is not a TNP3xxx tag. aborting.')
|
||||
-- end
|
||||
|
||||
-- Show tag info
|
||||
print((' Found tag : %s'):format(result.name))
|
||||
-- -- Show tag info
|
||||
-- print((' Found tag : %s'):format(result.name))
|
||||
-- end
|
||||
|
||||
-- Load dump.bin file
|
||||
print( (' Load data from %s'):format(inputTemplate))
|
||||
|
@ -349,7 +351,7 @@ local function main(args)
|
|||
err = LoadEmulator(blocks)
|
||||
if err then return oops(err) end
|
||||
core.clearCommandBuffer()
|
||||
print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
|
||||
print('The simulation is now prepared.\n --> run \"hf mf sim u '..uid..' x\" <--')
|
||||
end
|
||||
end
|
||||
main(args)
|
|
@ -84,16 +84,18 @@ local function main(args)
|
|||
local files = {}
|
||||
|
||||
-- Find a set of traces staring with EM
|
||||
local p = io.popen(tracesEM)
|
||||
local p = assert( io.popen(tracesEM))
|
||||
for file in p:lines() do
|
||||
table.insert(files, file)
|
||||
end
|
||||
p.close();
|
||||
|
||||
-- Find a set of traces staring with MOD
|
||||
p = io.popen(tracesMOD)
|
||||
p = assert( io.popen(tracesMOD) )
|
||||
for file in p:lines() do
|
||||
table.insert(files, file)
|
||||
end
|
||||
p.close();
|
||||
|
||||
local cmdLFSEARCH = "lf search 1"
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
|
|||
|
||||
LIBS = -lgcc
|
||||
|
||||
LIBS = -lgcc
|
||||
|
||||
THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
|
||||
ARMOBJ = $(ARMSRC:%.c=$(OBJDIR)/%.o)
|
||||
ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(ASMSRC))
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
#include "string.h"
|
||||
#include "../include/proxmark3.h"
|
||||
#include "proxmark3.h"
|
||||
|
||||
bool cmd_receive(UsbCommand* cmd) {
|
||||
|
||||
|
|
|
@ -33,8 +33,8 @@
|
|||
#ifndef _PROXMARK_CMD_H_
|
||||
#define _PROXMARK_CMD_H_
|
||||
|
||||
#include "../include/common.h"
|
||||
#include "../include/usb_cmd.h"
|
||||
#include "common.h"
|
||||
#include "usb_cmd.h"
|
||||
#include "usb_cdc.h"
|
||||
|
||||
bool cmd_receive(UsbCommand* cmd);
|
||||
|
|
1350
common/lfdemod.c
1350
common/lfdemod.c
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,11 @@
|
|||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Low frequency commands
|
||||
// Low frequency demod related commands
|
||||
// marshmellow
|
||||
// note that many of these demods are not the slickest code and they often rely
|
||||
// on peaks and clock instead of converting to clean signal.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef LFDEMOD_H__
|
||||
|
@ -12,14 +16,30 @@
|
|||
#include <stdint.h>
|
||||
|
||||
int DetectASKClock(uint8_t dest[], size_t size, int clock);
|
||||
int askmandemod(uint8_t *BinStream,uint32_t *BitLen,int *clk, int *invert);
|
||||
uint64_t Em410xDecode(uint8_t *BitStream,uint32_t BitLen);
|
||||
int manrawdecode(uint8_t *BitStream, int *bitLen);
|
||||
int BiphaseRawDecode(uint8_t * BitStream, int *bitLen, int offset);
|
||||
int askrawdemod(uint8_t *BinStream, int *bitLen,int *clk, int *invert);
|
||||
int HIDdemodFSK(uint8_t *dest, size_t size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||
int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
||||
uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
|
||||
int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||
int manrawdecode(uint8_t *BitStream, size_t *size);
|
||||
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
|
||||
int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
|
||||
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||
int IOdemodFSK(uint8_t *dest, size_t size);
|
||||
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
|
||||
uint32_t bytebits_to_byte(uint8_t* src, int numbits);
|
||||
uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
|
||||
int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
|
||||
void psk1TOpsk2(uint8_t *BitStream, size_t size);
|
||||
int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
|
||||
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
|
||||
void pskCleanWave(uint8_t *bitStream, size_t size);
|
||||
int PyramiddemodFSK(uint8_t *dest, size_t *size);
|
||||
int AWIDdemodFSK(uint8_t *dest, size_t *size);
|
||||
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
|
||||
uint16_t countFC(uint8_t *BitStream, size_t size);
|
||||
uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
|
||||
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
|
||||
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
|
||||
uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||
uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
uint8_t justNoise(uint8_t *BitStream, size_t size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
*/
|
||||
|
||||
#include "usb_cdc.h"
|
||||
#include "../include/config_gpio.h"
|
||||
#include "config_gpio.h"
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
@ -370,7 +370,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
|
|||
//* \fn AT91F_USB_SendData
|
||||
//* \brief Send Data through the control endpoint
|
||||
//*----------------------------------------------------------------------------
|
||||
unsigned int csrTab[100];
|
||||
unsigned int csrTab[100] = {0x00};
|
||||
unsigned char csrIdx = 0;
|
||||
|
||||
static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#ifndef _USB_CDC_H_
|
||||
#define _USB_CDC_H_
|
||||
|
||||
#include "../include/common.h"
|
||||
#include "common.h"
|
||||
|
||||
void usb_disable();
|
||||
void usb_enable();
|
||||
|
|
BIN
fpga/fpga_hf.bit
BIN
fpga/fpga_hf.bit
Binary file not shown.
BIN
fpga/fpga_lf.bit
BIN
fpga/fpga_lf.bit
Binary file not shown.
|
@ -50,12 +50,38 @@ begin
|
|||
else if(~(| adc_d[7:5])) after_hysteresis = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// Divide 13.56 MHz by 32 to produce the SSP_CLK
|
||||
// The register is bigger to allow higher division factors of up to /128
|
||||
reg [6:0] ssp_clk_divider;
|
||||
reg [10:0] ssp_clk_divider;
|
||||
|
||||
always @(posedge adc_clk)
|
||||
ssp_clk_divider <= (ssp_clk_divider + 1);
|
||||
assign ssp_clk = ssp_clk_divider[4];
|
||||
|
||||
reg ssp_clk;
|
||||
reg ssp_frame;
|
||||
always @(negedge adc_clk)
|
||||
begin
|
||||
//If we're in 101, we only need a new bit every 8th carrier bit (53Hz). Otherwise, get next bit at 424Khz
|
||||
if(mod_type == 3'b101)
|
||||
begin
|
||||
if(ssp_clk_divider[7:0] == 8'b00000000)
|
||||
ssp_clk <= 1'b0;
|
||||
if(ssp_clk_divider[7:0] == 8'b10000000)
|
||||
ssp_clk <= 1'b1;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
if(ssp_clk_divider[4:0] == 5'd0)//[4:0] == 5'b00000)
|
||||
ssp_clk <= 1'b1;
|
||||
if(ssp_clk_divider[4:0] == 5'd16) //[4:0] == 5'b10000)
|
||||
ssp_clk <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//assign ssp_clk = ssp_clk_divider[4];
|
||||
|
||||
// Divide SSP_CLK by 8 to produce the byte framing signal; the phase of
|
||||
// this is arbitrary, because it's just a bitstream.
|
||||
|
@ -69,7 +95,8 @@ reg [2:0] ssp_frame_divider_from_arm;
|
|||
always @(negedge ssp_clk)
|
||||
ssp_frame_divider_from_arm <= (ssp_frame_divider_from_arm + 1);
|
||||
|
||||
reg ssp_frame;
|
||||
|
||||
|
||||
always @(ssp_frame_divider_to_arm or ssp_frame_divider_from_arm or mod_type)
|
||||
if(mod_type == 3'b000) // not modulating, so listening, to ARM
|
||||
ssp_frame = (ssp_frame_divider_to_arm == 3'b000);
|
||||
|
@ -90,7 +117,7 @@ always @(mod_type or ssp_clk or ssp_dout)
|
|||
modulating_carrier <= ssp_dout ^ ssp_clk_divider[3]; // XOR means BPSK
|
||||
else if(mod_type == 3'b010)
|
||||
modulating_carrier <= ssp_dout & ssp_clk_divider[5]; // switch 212kHz subcarrier on/off
|
||||
else if(mod_type == 3'b100)
|
||||
else if(mod_type == 3'b100 || mod_type == 3'b101)
|
||||
modulating_carrier <= ssp_dout & ssp_clk_divider[4]; // switch 424kHz modulation on/off
|
||||
else
|
||||
modulating_carrier <= 1'b0; // yet unused
|
||||
|
@ -106,7 +133,7 @@ assign pwr_oe4 = modulating_carrier;
|
|||
// This one is always on, so that we can watch the carrier.
|
||||
assign pwr_oe3 = 1'b0;
|
||||
|
||||
assign dbg = after_hysteresis;
|
||||
assign dbg = modulating_carrier;
|
||||
//reg dbg;
|
||||
//always @(ssp_dout)
|
||||
// dbg <= ssp_dout;
|
||||
|
|
16000
traces/ATA5577-HIDemu-FC1-C9.pm3
Normal file
16000
traces/ATA5577-HIDemu-FC1-C9.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/AWID-15-259.pm3
Normal file
20000
traces/AWID-15-259.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/HID-weak-fob-11647.pm3
Normal file
20000
traces/HID-weak-fob-11647.pm3
Normal file
File diff suppressed because it is too large
Load diff
16000
traces/Paradox-96_40426-APJN08.pm3
Normal file
16000
traces/Paradox-96_40426-APJN08.pm3
Normal file
File diff suppressed because it is too large
Load diff
|
@ -15,3 +15,12 @@ Transit999-best.pm3: Transit 999 format (UID 99531670)
|
|||
The files 'modulation-'... are all encoded with identical data (hex 00 01 02 03 04 05 06 07 08 09 0A 0B)
|
||||
for the purpose of recognition and testing of demodulation schemes. They were created by writing Q5 tags
|
||||
appropriately configured. The raw data is in 'modulation-data.dat'.
|
||||
|
||||
ata5577-HIDemu-FC1-C9.pm3: ata5577 in hid prox 26 bit emulation facility code:1 card#:9
|
||||
casi-12ed825c29.pm3: casi rusco 40 bit (EM410x ID: 12ed825c29)
|
||||
EM4102-Fob.pm3: (ID: 0400193cbe)
|
||||
ioprox-XSF-01-3B-44725.pm3: IO Prox FSK RF/64 ID in name
|
||||
ioprox-XSF-01-BE-03011.pm3: IO Prox FSK RF/64 ID in name
|
||||
indala-504278295.pm3: PSK 26 bit indala
|
||||
AWID-15-259.pm3: AWID FSK RF/50 FC: 15 Card: 259
|
||||
HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but just readable.
|
20000
traces/modulation-ask-biph-50.pm3
Normal file
20000
traces/modulation-ask-biph-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-100.pm3
Normal file
20000
traces/modulation-ask-man-100.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-128.pm3
Normal file
20000
traces/modulation-ask-man-128.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-16.pm3
Normal file
20000
traces/modulation-ask-man-16.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-32.pm3
Normal file
20000
traces/modulation-ask-man-32.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-40.pm3
Normal file
20000
traces/modulation-ask-man-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-ask-man-8.pm3
Normal file
20000
traces/modulation-ask-man-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-32.pm3
Normal file
20000
traces/modulation-direct-32.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-40.pm3
Normal file
20000
traces/modulation-direct-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-direct-50.pm3
Normal file
20000
traces/modulation-direct-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk1-50.pm3
Normal file
20000
traces/modulation-fsk1-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk1a-50.pm3
Normal file
20000
traces/modulation-fsk1a-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2-50.pm3
Normal file
20000
traces/modulation-fsk2-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2a-40.pm3
Normal file
20000
traces/modulation-fsk2a-40.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-fsk2a-50.pm3
Normal file
20000
traces/modulation-fsk2a-50.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk1-32-4.pm3
Normal file
20000
traces/modulation-psk1-32-4.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk1-64-8.pm3
Normal file
20000
traces/modulation-psk1-64-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk2-32-2.pm3
Normal file
20000
traces/modulation-psk2-32-2.pm3
Normal file
File diff suppressed because it is too large
Load diff
20000
traces/modulation-psk3-32-8.pm3
Normal file
20000
traces/modulation-psk3-32-8.pm3
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue