`export DEVKITARM=/c/devkitPro/devkitARM`
`export PATH=$PATH:$DEVKITARM/bin`
-### 6. Build and run
+### 6 - Install Strawberry Perl
+Download and install: http://strawberry-perl.googlecode.com/files/strawberry-perl-5.10.1.1.msi
+
+### 7. Build and run
Download and install Git for Windows: https://git-scm.com/download/win
- Run minimal system: `C:\Qt\msys\msys.bat`
break;
}
case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
+ // iceman; since changing fpga_bitstreams clears bigbuff, Its better to call it before.
+ // to be able to use this one for uploading data to device not only for LF, I use c->arg[1]
+ if ( c->arg[1] == 0 )
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ else
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
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);
// Set up the synchronous serial port, with the one set of options that we
// always use when we are talking to the FPGA. Both RX and TX are enabled.
//-----------------------------------------------------------------------------
-void FpgaSetupSsc(void) {
+void FpgaSetupSscExt(uint8_t clearPCER) {
// First configure the GPIOs, and get ourselves a clock.
AT91C_BASE_PIOA->PIO_ASR =
GPIO_SSC_FRAME |
GPIO_SSC_CLK;
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
- AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
+ if ( clearPCER )
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
+ else
+ AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_SSC);
// Now set up the SSC proper, starting from a known state.
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
}
-
+void FpgaSetupSsc(void) {
+ FpgaSetupSscExt(TRUE);
+}
//-----------------------------------------------------------------------------
// Set up DMA to receive samples from the FPGA. We will use the PDC, with
// a single buffer as a circular buffer (so that we just chain back to
void FpgaWriteConfWord(uint8_t v);
void FpgaDownloadAndGo(int bitstream_version);
void FpgaGatherVersion(int bitstream_version, char *dst, int len);
+void FpgaSetupSscExt(uint8_t clearPCER);
void FpgaSetupSsc(void);
void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, int len);
#define FPGA_BITSTREAM_LF 1
#define FPGA_BITSTREAM_HF 2
-
// Definitions for the FPGA commands.
#define FPGA_CMD_SET_CONFREG (1<<12)
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
// Options for the HF simulated tag, how to modulate
-#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
-#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
+#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0) // 0000
+#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0) // 0001
+#define FPGA_HF_SIMULATOR_MODULATE_212K (2<<0) // 0010
+#define FPGA_HF_SIMULATOR_MODULATE_424K (4<<0) // 0100
+#define FPGA_HF_SIMULATOR_MODULATE_424K_8BIT 0x5 // 0101
// no 848K
// Options for ISO14443A
* -TO VERIFY THIS BELOW-
* The mode FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_BPSK which we use to simulate tag
* works like this:
- * - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (9.44µS)
- * - A 0-bit input to the FPGA becomes an unmodulated time of 9.44µS
- *
+ * - A 1-bit input to the FPGA becomes 8 pulses at 847.5kHz (1.18µS / pulse) == 9.44us
+ * - A 0-bit input to the FPGA becomes an unmodulated time of 1.18µS or does it become 8 nonpulses for 9.44us
*
+ * FPGA doesn't seem to work with ETU. It seems to work with pulse / duration instead.
*
* Card sends data ub 847.e kHz subcarrier
- * 848k = 9.44µS = 128 fc
- * 424k = 18.88µS = 256 fc
- * 212k = 37.76µS = 512 fc
- * 106k = 75.52µS = 1024 fc
+ * subcar |duration| FC division
+ * -------+--------+------------
+ * 106kHz | 9.44µS | FC/128
+ * 212kHz | 4.72µS | FC/64
+ * 424kHz | 2.36µS | FC/32
+ * 848kHz | 1.18µS | FC/16
+ * -------+--------+------------
*
* Reader data transmission:
* - no modulation ONES
while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {};
b = AT91C_BASE_SSC->SSC_RHR; (void) b;
-
-
+
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
while(!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
*/
void ReadTItag(void)
{
+ StartTicks();
// some hardcoded initial params
// when we read a TI tag we sample the zerocross line at 2Mhz
// TI tags modulate a 1 as 16 cycles of 123.2Khz
DbpString("Info: CRC is good");
}
}
+ StopTicks();
}
void WriteTIbyte(uint8_t b)
HIGH(GPIO_SSC_DOUT);
// Charge TI tag for 50ms.
- SpinDelay(50);
+ WaitMS(50);
// stop modulating antenna and listen
LOW(GPIO_SSC_DOUT);
// if not provided a valid crc will be computed from the data and written.
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
{
+ StartTicks();
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if(crc == 0) {
crc = update_crc16(crc, (idlo)&0xff);
// modulate antenna
HIGH(GPIO_SSC_DOUT);
- SpinDelay(50); // charge time
+ WaitMS(50); // charge time
WriteTIbyte(0xbb); // keyword
WriteTIbyte(0xeb); // password
WriteTIbyte(0x00); // write frame lo
WriteTIbyte(0x03); // write frame hi
HIGH(GPIO_SSC_DOUT);
- SpinDelay(50); // programming time
+ WaitMS(50); // programming time
LED_A_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
DbpString("Now use `lf ti read` to check");
+ StopTicks();
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
int i = 0;
- uint8_t *tab = BigBuf_get_addr();
+ uint8_t *buf = BigBuf_get_addr();
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
+ //FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
+ //AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
+ StartTicks();
+
for(;;) {
WDT_HIT();
if (ledcontrol) LED_D_ON();
- //wait until SSC_CLK goes HIGH
+ // wait until SSC_CLK goes HIGH
+ // used as a simple detection of a reader field?
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
WDT_HIT();
- if ( usb_poll_validate_length() || BUTTON_PRESS() ) {
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- return;
- }
+ if ( usb_poll_validate_length() || BUTTON_PRESS() )
+ goto OUT;
}
- if(tab[i])
+ if(buf[i])
OPEN_COIL();
else
SHORT_COIL();
//wait until SSC_CLK goes LOW
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
WDT_HIT();
- if ( usb_poll_validate_length() || BUTTON_PRESS() ) {
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- return;
- }
+ if ( usb_poll_validate_length() || BUTTON_PRESS() )
+ goto OUT;
}
i++;
}
}
}
+OUT:
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ StopTicks();
+ LED_D_OFF();
+ DbpString("Simulation stopped");
+ return;
}
#define DEBUG_FRAME_CONTENTS 1
// 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.
+ // 50ms for the resonant antenna to settle.
SpinDelay(50);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
-
// start a 1.5ticks is 1us
StartTicks();
}
continue;
}
-
// skip until first high samples begin to change
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL){
// if just found start - recover last sample
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
//initialization of the timer
- AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
+ AT91C_BASE_PMC->PMC_PCER |= (0x1 << AT91C_ID_TC0);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK; //clock at 48/32 MHz
// Timers, Clocks functions used in LF or Legic where you would need detailed time.
//-----------------------------------------------------------------------------
#include "ticks.h"
-
// attempt at high resolution microsecond timer
// beware: timer counts in 21.3uS increments (1024/48Mhz)
void SpinDelayUs(int us) {
// microseconds timer
// -------------------------------------------------------------------------
void StartCountUS(void) {
- AT91C_BASE_PMC->PMC_PCER |= (1 << 12) | (1 << 13) | (1 << 14);
+ AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
// fast clock
return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV * 2) / 3);
}
-
// -------------------------------------------------------------------------
// Timer for iso14443 commands. Uses ssp_clk from FPGA
// -------------------------------------------------------------------------
void StartCountSspClk(void) {
- AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
+ AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
| AT91C_TCB_TC2XC2S_TIOA0; // XC2 Clock = TIOA0
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while (AT91C_BASE_TC2->TC_CV >= 1);
}
-
uint32_t RAMFUNC GetCountSspClk(void) {
uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
return tmp_count;
}
-
// -------------------------------------------------------------------------
// Timer for bitbanging, or LF stuff when you need a very precis timer
// 1us = 1.5ticks
//initialization of the timer
// tc1 is higher 0xFFFF0000
// tc0 is lower 0x0000FFFF
- AT91C_BASE_PMC->PMC_PCER |= (1 << 12) | (1 << 13) | (1 << 14);
+ AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK | // MCK(48MHz) / 32
// convert to bitstream if necessary
ChkBitstream(Cmd);
+ if (g_debugMode)
+ printf("DEBUG: Sending [%d bytes]\n", GraphTraceLen);
+
//can send only 512 bits at a time (1 byte sent per bit...)
- printf("Sending [%d bytes]", GraphTraceLen);
for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
UsbCommand c = {CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
}
clearCommandBuffer();
SendCommand(&c);
- WaitForResponse(CMD_ACK,NULL);
+ WaitForResponse(CMD_ACK, NULL);
printf(".");
}
- PrintAndLog("\nStarting to simulate");
+ PrintAndLog("Starting to simulate");
+
UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
clearCommandBuffer();
SendCommand(&c);
while(param_getchar(Cmd, cmdp) != 0x00) {
switch(param_getchar(Cmd, cmdp)) {
+ case 'H':
case 'h': return usage_lf_simask();
case 'i':
invert = 1;
setDemodBuf(data, dataLen, 0);
}
if (clk == 0) clk = 64;
- if (encoding == 0) clk = clk/2; //askraw needs to double the clock speed
+ if (encoding == 0) clk >>= 2; //askraw needs to double the clock speed
size_t size = DemodBufferLen;
#include <inttypes.h>
#include "cmdlfem4x.h"
-char *global_em410xId;
+uint64_t g_em410xid = 0;
static int CmdHelp(const char *Cmd);
PrintAndLog ("EM410x XL pattern found");
return 0;
}
- char id[12] = {0x00};
- //sprintf(id, "%010llx",lo);
- sprintf(id, "%010"PRIu64, lo);
-
- global_em410xId = id;
+ g_em410xid = lo;
return 1;
}
int CmdEM410xSim(const char *Cmd)
{
int i, n, j, binary[4], parity[4];
-
- char cmdp = param_getchar(Cmd, 0);
uint8_t uid[5] = {0x00};
+ char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: lf em4x em410xsim <UID> <clock>");
PrintAndLog("");
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
PrintAndLog("Press pm3-button to about simulation");
-
/* clear our graph */
ClearGraph(0);
- /* write 9 start bits */
- for (i = 0; i < 9; i++)
- AppendGraph(0, clock, 1);
-
- /* for each hex char */
- parity[0] = parity[1] = parity[2] = parity[3] = 0;
- for (i = 0; i < 10; i++)
- {
- /* read each hex char */
- sscanf(&Cmd[i], "%1x", &n);
- for (j = 3; j >= 0; j--, n/= 2)
- binary[j] = n % 2;
-
- /* append each bit */
- AppendGraph(0, clock, binary[0]);
- AppendGraph(0, clock, binary[1]);
- AppendGraph(0, clock, binary[2]);
- AppendGraph(0, clock, binary[3]);
-
- /* append parity bit */
- AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
-
- /* keep track of column parity */
- parity[0] ^= binary[0];
- parity[1] ^= binary[1];
- parity[2] ^= binary[2];
- parity[3] ^= binary[3];
- }
+ /* write 9 start bits */
+ for (i = 0; i < 9; i++)
+ AppendGraph(0, clock, 1);
+
+ /* for each hex char */
+ parity[0] = parity[1] = parity[2] = parity[3] = 0;
+ for (i = 0; i < 10; i++)
+ {
+ /* read each hex char */
+ sscanf(&Cmd[i], "%1x", &n);
+ for (j = 3; j >= 0; j--, n/= 2)
+ binary[j] = n % 2;
+
+ /* append each bit */
+ AppendGraph(0, clock, binary[0]);
+ AppendGraph(0, clock, binary[1]);
+ AppendGraph(0, clock, binary[2]);
+ AppendGraph(0, clock, binary[3]);
+
+ /* append parity bit */
+ AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
+
+ /* keep track of column parity */
+ parity[0] ^= binary[0];
+ parity[1] ^= binary[1];
+ parity[2] ^= binary[2];
+ parity[3] ^= binary[3];
+ }
- /* parity columns */
- AppendGraph(0, clock, parity[0]);
- AppendGraph(0, clock, parity[1]);
- AppendGraph(0, clock, parity[2]);
- AppendGraph(0, clock, parity[3]);
+ /* parity columns */
+ AppendGraph(0, clock, parity[0]);
+ AppendGraph(0, clock, parity[1]);
+ AppendGraph(0, clock, parity[2]);
+ AppendGraph(0, clock, parity[3]);
- /* stop bit */
+ /* stop bit */
AppendGraph(1, clock, 0);
CmdLFSim("0"); //240 start_gap.
}
//currently only supports manchester modulations
+// todo: helptext
int CmdEM410xWatchnSpoof(const char *Cmd)
{
+ // loops if the captured ID was in XL-format.
CmdEM410xWatch(Cmd);
- PrintAndLog("# Replaying captured ID: %s",global_em410xId);
+ PrintAndLog("# Replaying captured ID: %llu", g_em410xid);
CmdLFaskSim("");
return 0;
}
71f3a315ad26,
51044efb5aab,
ac70ca327a04,
-eb0a8ff88ade
\ No newline at end of file
+eb0a8ff88ade,
+#
+# Data from: https://github.com/RadioWar/NFCGUI
+44dd5a385aaf,
+21a600056cb0,
+b1aca33180a5,
+dd61eb6bce22,
+1565a172770f,
+3e84d2612e2a,
+f23442436765,
+79674f96c771,
+87df99d496cb,
+c5132c8980bc,
+a21680c27773,
+f26e21edcee2,
+675557ecc92e,
+f4396e468114,
+6db17c16b35b,
+4186562a5bb2,
+2feae851c199,
+db1a3338b2eb,
+157b10d84c6b,
+a643f952ea57,
+df37dcb6afb3,
+4c32baf326e0,
+91ce16c07ac5,
+3c5d1c2bcd18,
+c3f19ec592a2,
+f72a29005459,
+185fa3438949,
+321a695bd266,
+d327083a60a7,
+45635ef66ef3,
+5481986d2d62,
+cba6ae869ad5,
+645a166b1eeb,
+a7abbc77cc9e,
+f792c4c76a5c,
+bfb6796a11db
\ No newline at end of file
--]]
'668770666644',
'003003003003',
+ --[[
+ Data from: https://github.com/RadioWar/NFCGUI
+ --]]
+ '44dd5a385aaf',
+ '21a600056cb0',
+ 'b1aca33180a5',
+ 'dd61eb6bce22',
+ '1565a172770f',
+ '3e84d2612e2a',
+ 'f23442436765',
+ '79674f96c771',
+ '87df99d496cb',
+ 'c5132c8980bc',
+ 'a21680c27773',
+ 'f26e21edcee2',
+ '675557ecc92e',
+ 'f4396e468114',
+ '6db17c16b35b',
+ '4186562a5bb2',
+ '2feae851c199',
+ 'db1a3338b2eb',
+ '157b10d84c6b',
+ 'a643f952ea57',
+ 'df37dcb6afb3',
+ '4c32baf326e0',
+ '91ce16c07ac5',
+ '3c5d1c2bcd18',
+ 'c3f19ec592a2',
+ 'f72a29005459',
+ '185fa3438949',
+ '321a695bd266',
+ 'd327083a60a7',
+ '45635ef66ef3',
+ '5481986d2d62',
+ 'cba6ae869ad5',
+ '645a166b1eeb',
+ 'a7abbc77cc9e',
+ 'f792c4c76a5c',
+ 'bfb6796a11db',
}
---
example = "script run mifare_autopwn"
author = "Martin Holst Swende"
-
-
desc =
[[
This is a which automates cracking and dumping mifare classic cards. It sets itself into