-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "LCD.h"
LCDSend(PSETCON); // set contrast
LCDSend(0xDC);
-
+
// clear display
LCDSetXY(0,0);
LCDSend(PRAMWR); // Write to display
-#ifndef __LCD
-#define __LCD
+#ifndef __LCD_H
+#define __LCD_H
// The resolution of the LCD
#define LCD_XRES 132
void LCDSetPixel(unsigned char x, unsigned char y, unsigned char color);
void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsigned char y, unsigned char fcolor, unsigned char bcolor);
void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned char height, unsigned char color);
+
#endif
// Edits by Gerhard de Koning Gans, Sep 2007 (##)
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "legicrf.h"
#ifdef WITH_LCD
#define va_arg __builtin_va_arg
#define va_end __builtin_va_end
int kvsprintf(char const *fmt, void *arg, int radix, va_list ap);
-
+
#define abs(x) ( ((x)<0) ? -(x) : (x) )
va_start(ap, fmt);
kvsprintf(fmt, output_string, 10, ap);
va_end(ap);
-
+
DbpString(output_string);
}
// Vref = 3300mV, and an 10:1 voltage divider on the input
// can measure voltages up to 33000 mV
vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
-
+
Dbprintf("%d mV",vHf);
if (BUTTON_PRESS()) break;
}
{
char temp[48]; /* Limited data payload in USB packets */
DbpString("Prox/RFID mark3 RFID instrument");
-
- /* Try to find the bootrom version information. Expect to find a pointer at
+
+ /* Try to find the bootrom version information. Expect to find a pointer at
* symbol _bootphase1_version_pointer, perform slight sanity checks on the
* pointer, then use it.
*/
FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
DbpString(temp);
}
-
+
FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
DbpString(temp);
-
+
FpgaGatherVersion(temp, sizeof(temp));
DbpString(temp);
}
if (abs(lf_av - lf_baseline) > 10) LED_D_ON();
else LED_D_OFF();
}
-
+
++lf_count;
lf_av_new= ReadAdc(ADC_CHAN_LF);
// see if there's a significant change
if (abs(hf_av - hf_baseline) > 10) LED_B_ON();
else LED_B_OFF();
}
-
+
++hf_count;
hf_av_new= ReadAdc(ADC_CHAN_HF);
// see if there's a significant change
hf_count= 0;
}
}
-
+
if(mode == 2) {
if (limit == LF_ONLY) {
display_val = lf_av;
ReaderMifare(c->arg[0]);
break;
#endif
-
+
#ifdef WITH_ISO14443b
case CMD_SNOOP_ISO_14443:
SnoopIso14443();
SimulateIso14443Tag();
break;
#endif
-
+
#ifdef WITH_ISO14443a
case CMD_SIMULATE_TAG_ISO_14443a:
SimulateIso14443aTag(c->arg[0], c->arg[1]); // ## Simulate iso14443a tag - pass tag type & UID
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
for(;;);
break;
-
+
case CMD_DEVICE_INFO: {
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
void __attribute__((noreturn)) AppMain(void)
{
SpinDelay(100);
-
+
if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
/* Initialize common area */
memset(&common_area, 0, sizeof(common_area));
#ifndef __FONTS_H
#define __FONTS_H
+
extern const char FONT6x8[97][8];
extern const char FONT8x8F[97][8];
extern const char FONT8x16[97][16];
+
#endif
//
// Jonathan Westhues, April 2006
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
//-----------------------------------------------------------------------------
i=0;
while(FpgaImageLen-->0)
DownloadFPGA_byte(FpgaImage[(i++)^0x3]);
- /* Explanation of the magic in the above line:
+ /* Explanation of the magic in the above line:
* i^0x3 inverts the lower two bits of the integer i, counting backwards
* for each 4 byte increment. The generated sequence of (i++)^3 is
- * 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 etc. pp.
+ * 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 etc. pp.
*/
}
} else {
static int bitparse_init(void * start_address, void *end_address)
{
bitparse_initialized = 0;
-
+
if(memcmp(_bitparse_fixed_header, start_address, sizeof(_bitparse_fixed_header)) != 0) {
return 0; /* Not matched */
} else {
current_length += (*pos++) << 8;
current_length += (*pos++) << 0;
}
-
+
if(current_name != 'e' && current_length > 255) {
/* Maybe a parse error */
break;
}
-
+
if(current_name == section_name) {
/* Found it */
*section_start = pos;
result = 1;
break;
}
-
+
pos += current_length; /* Skip section */
}
-
+
return result;
}
unsigned int bitstream_length;
if(bitparse_find_section('e', &bitstream_start, &bitstream_length)) {
DownloadFPGA(bitstream_start, bitstream_length, 0);
-
+
return; /* All done */
}
}
-
+
/* Fallback for the old flash image format: Check for the magic marker 0xFFFFFFFF
- * 0xAA995566 at address 0x102000. This is raw bitstream with a size of 336,768 bits
+ * 0xAA995566 at address 0x102000. This is raw bitstream with a size of 336,768 bits
* = 10,524 DWORDs, stored as DWORDS e.g. little-endian in memory, but each DWORD
* is still to be transmitted in MSBit first order. Set the invert flag to indicate
* that the DownloadFPGA function should invert every 4 byte sequence when doing
void FpgaGatherVersion(char *dst, int len)
{
- char *fpga_info;
+ char *fpga_info;
unsigned int fpga_info_len;
dst[0] = 0;
if(!bitparse_find_section('e', &fpga_info, &fpga_info_len)) {
/*
* Hitag2 emulation
- *
+ *
* Contains state and functions for an emulated Hitag2 tag. Offers an entry
* point to handle commands, needs a callback to send response.
- *
+ *
* (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
*/
-#include <proxmark3.h>
+#include "proxmark3.h"
#include <stdint.h>
#include "apps.h"
struct hitag2_tag {
uint32_t uid;
- enum {
+ enum {
TAG_STATE_RESET, // Just powered up, awaiting GetSnr
TAG_STATE_ACTIVATING, // In activation phase (password mode), sent UID, awaiting reader password
TAG_STATE_AUTHENTICATING, // In activation phase (crypto mode), awaiting reader authentication
data = temp;
}
-
+
handle_command_retry:
switch(tag.state) {
case TAG_STATE_RESET:
/* transmission error */
DbpString("Transmission error (write) in activated state");
}
- }
-
+ }
+
}
case TAG_STATE_WRITING:
if(length == 32) {
done=1;
}
}
-
+
if(!done && !retry) {
/* We didn't respond, maybe our state is faulty. Reset and try again. */
retry=1;
static u32 _f20 (const u64 x)
{
u32 i5;
-
+
i5 = ((ht2_f4a >> i4 (x, 1, 2, 4, 5)) & 1)* 1
+ ((ht2_f4b >> i4 (x, 7,11,13,14)) & 1)* 2
+ ((ht2_f4b >> i4 (x,16,20,22,25)) & 1)* 4
+ ((ht2_f4b >> i4 (x,27,28,30,32)) & 1)* 8
+ ((ht2_f4a >> i4 (x,33,42,43,45)) & 1)*16;
-
+
return (ht2_f5c >> i5) & 1;
}
{
u32 i;
u64 x = ((key & 0xFFFF) << 32) + serial;
-
+
for (i = 0; i < 32; i++)
{
x >>= 1;
static u64 _hitag2_round (u64 *state)
{
u64 x = *state;
-
+
x = (x >> 1) +
((((x >> 0) ^ (x >> 2) ^ (x >> 3) ^ (x >> 6)
^ (x >> 7) ^ (x >> 8) ^ (x >> 16) ^ (x >> 22)
^ (x >> 23) ^ (x >> 26) ^ (x >> 30) ^ (x >> 41)
^ (x >> 42) ^ (x >> 43) ^ (x >> 46) ^ (x >> 47)) & 1) << 47);
-
+
*state = x;
return _f20 (x);
}
static u32 _hitag2_byte (u64 * x)
{
u32 i, c;
-
+
for (i = 0, c = 0; i < 8; i++) c += (u32) _hitag2_round (x) << (i^7);
return c;
}
/*
* Hitag2 emulation public interface
- *
+ *
* (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
*/
+#ifndef __HITAG2_H
+#define __HITAG2_H
+
typedef int (*hitag2_response_callback_t)(const char* response_data, const int response_length, const int fdt, void *cb_cookie);
extern int hitag2_init(void);
extern int hitag2_handle_command(const char* data, const int length, hitag2_response_callback_t cb, void *cb_cookie);
+
+#endif
// supported.
// Jonathan Westhues, split Nov 2006
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "iso14443crc.h"
Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE);
-
+
// Use a counter for blinking the LED
long ledCount=0;
long ledFlashAt=200000;
-
+
// And put the FPGA in the appropriate mode
// Signal field is off with the appropriate LED
LED_D_OFF();
LED_D_OFF();
ledCount=0;
}
-
+
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
(DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) {
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedResponse, Demod.len);
traceLen += Demod.len;
- if(traceLen > DEMOD_TRACE_SIZE) {
+ if(traceLen > DEMOD_TRACE_SIZE) {
DbpString("Reached trace limit");
goto done;
}
//
// Gerhard de Koning Gans - May 2008
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "iso14443crc.h"
//-----------------------------------------------------------------------------
// Generate the parity value for a byte sequence
-//
+//
//-----------------------------------------------------------------------------
DWORD GetParity(const BYTE * pbtCmd, int iLen)
{
int i;
DWORD dwPar = 0;
-
+
// Generate the encrypted data
for (i = 0; i < iLen; i++) {
// Save the encrypted parity bit
{
// Return when trace is full
if (traceLen >= TRACE_LENGTH) return FALSE;
-
+
// Trace the random, i'm curious
rsamples += iSamples;
trace[traceLen++] = ((rsamples >> 0) & 0xff);
static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait)
{
int c;
-
+
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-
+
if (wait)
if(*wait < 10)
*wait = 10;
-
+
for(c = 0; c < *wait;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing!
}
WDT_HIT();
}
-
+
c = 0;
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
//-----------------------------------------------------------------------------
// Prepare reader command to send to FPGA
-//
+//
//-----------------------------------------------------------------------------
void CodeIso14443aAsReaderPar(const BYTE * cmd, int len, DWORD dwParity)
{
int i, j;
int last;
BYTE b;
-
+
ToSendReset();
-
+
// Start of Communication (Seq. Z)
Sequence(SEC_Z);
last = 0;
-
+
// Generate send structure for the data bits
for (i = 0; i < len; i++) {
// Get the current byte to send
b = cmd[i];
-
+
for (j = 0; j < 8; j++) {
if (b & 1) {
// Sequence X
}
b >>= 1;
}
-
+
// Get the parity bit
if ((dwParity >> i) & 0x01) {
// Sequence X
}
}
}
-
+
// End of Communication
if (last == 0) {
// Sequence Z
}
// Sequence Y
Sequence(SEC_Y);
-
+
// Just to be sure!
Sequence(SEC_Y);
Sequence(SEC_Y);
Sequence(SEC_Y);
-
+
// Convert from last character reference to length
ToSendMax++;
}
int samples = 0;
ShortFrameFromReader(*bt);
-
+
// Select the card
- TransmitFor14443a(ToSend, ToSendMax, &samples, &wait);
-
+ TransmitFor14443a(ToSend, ToSendMax, &samples, &wait);
+
// Store reader command in buffer
if (tracing) LogTrace(bt,1,0,GetParity(bt,1),TRUE);
}
{
int wait = 0;
int samples = 0;
-
+
// This is tied to other size changes
- // BYTE* frame_addr = ((BYTE*)BigBuf) + 2024;
+ // BYTE* frame_addr = ((BYTE*)BigBuf) + 2024;
CodeIso14443aAsReaderPar(frame,len,par);
-
+
// Select the card
- TransmitFor14443a(ToSend, ToSendMax, &samples, &wait);
-
+ TransmitFor14443a(ToSend, ToSendMax, &samples, &wait);
+
// Store reader command in buffer
if (tracing) LogTrace(frame,len,0,par,TRUE);
}
// Mifare AUTH
BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };
// BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00 };
-
+
BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes
traceLen = 0;
{
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
ReaderTransmitShort(wupa);
-
+
// Test if the action was cancelled
if(BUTTON_PRESS()) {
break;
}
-
+
// Receive the ATQA
if (!ReaderReceive(receivedAnswer)) continue;
// Receive the UID
if (!ReaderReceive(receivedAnswer)) continue;
-
+
// Construct SELECT UID command
// First copy the 5 bytes (Mifare Classic) after the 93 70
memcpy(sel_uid+2,receivedAnswer,5);
// Transmit SELECT_UID
ReaderTransmit(sel_uid,sizeof(sel_uid));
-
+
// Receive the SAK
if (!ReaderReceive(receivedAnswer)) continue;
// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in
// which case we need to make a cascade 2 request and select - this is a long UID
- // When the UID is not complete, the 3nd bit (from the right) is set in the SAK.
+ // When the UID is not complete, the 3nd bit (from the right) is set in the SAK.
if (receivedAnswer[0] &= 0x04)
{
// Transmit SELECT_ALL
ReaderTransmit(sel_all_c2,sizeof(sel_all_c2));
-
+
// Receive the UID
if (!ReaderReceive(receivedAnswer)) continue;
-
+
// Construct SELECT UID command
memcpy(sel_uid_c2+2,receivedAnswer,5);
// Secondly compute the two CRC bytes at the end
AppendCrc14443a(sel_uid_c2,7);
-
+
// Transmit SELECT_UID
ReaderTransmit(sel_uid_c2,sizeof(sel_uid_c2));
-
+
// Receive the SAK
if (!ReaderReceive(receivedAnswer)) continue;
}
//-----------------------------------------------------------------------------
void ReaderMifare(DWORD parameter)
{
-
+
// Anticollision
BYTE wupa[] = { 0x52 };
BYTE sel_all[] = { 0x93,0x20 };
BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
-
+
// Mifare AUTH
BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };
BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
-
+
BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes
traceLen = 0;
tracing = false;
-
+
// Setup SSC
FpgaSetupSsc();
-
+
// Start from off (no field generated)
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(200);
-
+
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
-
+
// Now give it time to spin up.
// Signal field is on with the appropriate LED
LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
SpinDelay(200);
-
+
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
-
+
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
ReaderTransmitShort(wupa);
// Receive the ATQA
memcpy(sel_uid+2,receivedAnswer,5);
// Secondly compute the two CRC bytes at the end
AppendCrc14443a(sel_uid,7);
-
+
byte_t nt_diff = 0;
LED_A_OFF();
byte_t par = 0;
byte_t par_mask = 0xff;
byte_t par_low = 0;
BOOL led_on = TRUE;
-
+
tracing = FALSE;
byte_t nt[4];
byte_t nt_attacked[4];
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(200);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
-
+
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
ReaderTransmitShort(wupa);
-
+
// Test if the action was cancelled
if(BUTTON_PRESS()) {
break;
}
-
+
// Receive the ATQA
if (!ReaderReceive(receivedAnswer)) continue;
-
+
// Transmit SELECT_ALL
ReaderTransmit(sel_all,sizeof(sel_all));
-
+
// Receive the UID
if (!ReaderReceive(receivedAnswer)) continue;
-
+
// Transmit SELECT_UID
ReaderTransmit(sel_uid,sizeof(sel_uid));
-
+
// Receive the SAK
if (!ReaderReceive(receivedAnswer)) continue;
-
+
// Transmit MIFARE_CLASSIC_AUTH
ReaderTransmit(mf_auth,sizeof(mf_auth));
-
+
// Receive the (16 bit) "random" nonce
if (!ReaderReceive(receivedAnswer)) continue;
memcpy(nt,receivedAnswer,4);
// Transmit reader nonce and reader answer
ReaderTransmitPar(mf_nr_ar,sizeof(mf_nr_ar),par);
-
+
// Receive 4 bit answer
if (ReaderReceive(receivedAnswer))
{
- if (nt_diff == 0)
+ if (nt_diff == 0)
{
LED_A_ON();
memcpy(nt_attacked,nt,4);
if(led_on) LED_B_ON(); else LED_B_OFF();
par_list[nt_diff] = par;
ks_list[nt_diff] = receivedAnswer[0]^0x05;
-
+
// Test if the information is complete
if (nt_diff == 0x07) break;
-
+
nt_diff = (nt_diff+1) & 0x07;
mf_nr_ar[3] = nt_diff << 5;
par = par_low;
}
}
}
-
+
LogTraceInfo(sel_uid+2,4);
LogTraceInfo(nt,4);
LogTraceInfo(par_list,8);
LogTraceInfo(ks_list,8);
-
+
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// Also added additional reader commands (SELECT, READ etc.)
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
// FROM winsrc\prox.h //////////////////////////////////
{
size_t dest_len = strlen(dest);
size_t i;
-
+
for (i = 0 ; src[i] != '\0' ; i++)
dest[dest_len + i] = src[i];
dest[dest_len + i] = '\0';
-
+
return dest;
}
/*
* LEGIC RF simulation code
- *
+ *
* (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
*/
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "legicrf.h"
/* Start clock */
timer->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while(timer->TC_CV > 1) ; /* Wait till the clock has reset */
-
+
int i;
for(i=0; i<bits; i++) {
int starttime = timer->TC_CV;
} else {
bit_end = starttime + RWD_TIME_0;
}
-
+
/* RWD_TIME_PAUSE time off, then some time on, so that the complete bit time is
* RWD_TIME_x, where x is the bit to be transmitted */
AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
while(timer->TC_CV < pause_end) ;
AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT;
legic_prng_forward(1); /* bit duration is longest. use this time to forward the lfsr */
-
+
while(timer->TC_CV < bit_end) ;
}
-
+
{
/* One final pause to mark the end of the frame */
int pause_end = timer->TC_CV + RWD_TIME_PAUSE;
while(timer->TC_CV < pause_end) ;
AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT;
}
-
+
/* Reset the timer, to measure time until the start of the tag frame */
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1) ; /* Wait till the clock has reset */
/* Receive a frame from the card in reader emulation mode, the FPGA and
* timer must have been set up by LegicRfReader and frame_send_rwd.
- *
+ *
* The LEGIC RF protocol from card to reader does not include explicit
* frame start/stop information or length information. The reader must
* know beforehand how many bits it wants to receive. (Notably: a card
* sending a stream of 0-bits is indistinguishable from no card present.)
- *
+ *
* Receive methodology: There is a fancy correlator in hi_read_rx_xcorr, but
* I'm not smart enough to use it. Instead I have patched hi_read_tx to output
* the ADC signal with hysteresis on SSP_DIN. Bit-bang that signal and look
* expected for a 212kHz subcarrier, this was a 1-bit. For timing we use the
* timer that's still running from frame_send_rwd in order to get a synchronization
* with the frame that we just sent.
- *
- * FIXME: Because we're relying on the hysteresis to just do the right thing
+ *
+ * FIXME: Because we're relying on the hysteresis to just do the right thing
* the range is severely reduced (and you'll probably also need a good antenna).
- * So this should be fixed some time in the future for a proper receiver.
+ * So this should be fixed some time in the future for a proper receiver.
*/
static void frame_receive_rwd(struct legic_frame * const f, int bits, int crypt)
{
uint32_t data=0;
int i, old_level=0, edges=0;
int next_bit_at = TAG_TIME_WAIT;
-
-
+
+
if(bits > 16)
bits = 16;
while(timer->TC_CV < next_bit_at) ;
next_bit_at += TAG_TIME_BIT;
-
+
for(i=0; i<bits; i++) {
edges = 0;
old_level = level;
}
next_bit_at += TAG_TIME_BIT;
-
+
if(edges > 20 && edges < 60) { /* expected are 42 edges */
data ^= the_bit;
}
the_bit <<= 1;
}
-
+
f->data = data;
f->bits = bits;
-
+
/* Reset the timer, to synchronize the next frame */
timer->TC_CCR = AT91C_TC_SWTRG;
while(timer->TC_CV > 1) ; /* Wait till the clock has reset */
static uint32_t perform_setup_phase_rwd(int iv)
{
-
+
/* Switch on carrier and let the tag charge for 1ms */
AT91C_BASE_PIOA->PIO_SODR = GPIO_SSC_DOUT;
SpinDelay(1);
-
+
legic_prng_init(0); /* no keystream yet */
frame_send_rwd(iv, 7);
legic_prng_init(iv);
-
+
frame_clean(¤t_frame);
frame_receive_rwd(¤t_frame, 6, 1);
legic_prng_forward(1); /* we wait anyways */
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
FpgaSetupSsc();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
-
+
/* Bitbang the transmitter */
AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
-
+
setup_timer();
-
+
crc_init(&legic_crc, 4, 0x19 >> 1, 0x5, 0);
}
/* Switch off carrier, make sure tag is reset */
AT91C_BASE_PIOA->PIO_CODR = GPIO_SSC_DOUT;
SpinDelay(10);
-
+
WDT_HIT();
}
/* calculate crc for a legic command */
void LegicRfReader(int offset, int bytes) {
int byte_index=0, cmd_sz=0, card_sz=0;
-
+
LegicCommonInit();
memset(BigBuf, 0, 1024);
-
+
DbpString("setting up legic card");
uint32_t tag_type = perform_setup_phase_rwd(0x55);
switch(tag_type) {
/*
* LEGIC RF emulation public interface
- *
+ *
* (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
*/
-#ifndef LEGICRF_H_
-#define LEGICRF_H_
+#ifndef __LEGICRF_H
+#define __LEGICRF_H
extern void LegicRfSimulate(void);
extern void LegicRfReader(int bytes, int offset);
-#endif /* LEGICRF_H_ */
+
+#endif /* __LEGICRF_H */
// Also routines for raw mode reading/simulating of LF waveform
//
//-----------------------------------------------------------------------------
-#include <proxmark3.h>
+#include "proxmark3.h"
#include "apps.h"
#include "hitag2.h"
#include "crc16.h"
BYTE *dest = (BYTE *)BigBuf;
int n = sizeof(BigBuf);
int i;
-
+
memset(dest, 0, n);
i = 0;
for(;;) {
/* Make sure the tag is reset */
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelay(2500);
-
+
// see if 'h' was specified
if (command[strlen((char *) command) - 1] == 'h')
at134khz = TRUE;
i++;
if(i == period) {
i = 0;
- if (gap) {
+ if (gap) {
SHORT_COIL();
SpinDelayUs(gap);
}
/* Provides a framework for bidirectional LF tag communication
* Encoding is currently Hitag2, but the general idea can probably
* be transferred to other encodings.
- *
+ *
* The new FPGA code will, for the LF simulator mode, give on SSC_FRAME
* (PA15) a thresholded version of the signal from the ADC. Setting the
* ADC path to the low frequency peak detection signal, will enable a
* field is switched off, and high when the reader field is active. Due
* to the way that the signal looks like, mostly only the rising edge is
* useful, your mileage may vary.
- *
+ *
* Neat perk: PA15 can not only be used as a bit-banging GPIO, but is also
* TIOA1, which can be used as the capture input for timer 1. This should
* make it possible to measure the exact edge-to-edge time, without processor
* intervention.
- *
+ *
* Arguments: divisor is the divisor to be sent to the FPGA (e.g. 95 for 125kHz)
* t0 is the carrier frequency cycle duration in terms of MCK (384 for 125kHz)
- *
- * The following defines are in carrier periods:
+ *
+ * The following defines are in carrier periods:
*/
-#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
+#define HITAG_T_0_MIN 15 /* T[0] should be 18..22 */
#define HITAG_T_1_MIN 24 /* T[1] should be 26..30 */
#define HITAG_T_EOF 40 /* T_EOF should be > 36 */
#define HITAG_T_WRESP 208 /* T_wresp should be 204..212 */
#endif
char frame[10];
int frame_pos=0;
-
+
DbpString("Starting Hitag2 emulator, press button to end");
hitag2_init();
-
+
/* Set up simulator mode, frequency divisor which will drive the FPGA
* and analog mux selection.
*/
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
-
+
/* Set up Timer 1:
* Capture mode, timer source MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
* external trigger rising edge, load RA on rising edge of TIOA, load RB on rising
* edge of TIOA. Assign PA15 to TIOA1 (peripheral B)
*/
-
+
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_TC_LDRB_RISING;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN |
AT91C_TC_SWTRG;
-
+
/* calculate the new value for the carrier period in terms of TC1 values */
t0 = t0/2;
-
+
int overflow = 0;
while(!BUTTON_PRESS()) {
WDT_HIT();
((char*)BigBuf)[i] = ra;
i = (i+1) % 8000;
#endif
-
+
if(overflow || (ra > t0*HITAG_T_EOF) || (ra < t0*HITAG_T_0_MIN)) {
/* Ignore */
} else if(ra >= t0*HITAG_T_1_MIN ) {
frame_pos++;
}
}
-
+
overflow = 0;
LED_D_ON();
} else {
* have wrapped. Also, this marks the end of frame, and the
* still running counter can be used to determine the correct
* time for the start of the reply.
- */
+ */
overflow = 1;
-
+
if(frame_pos > 0) {
/* Have a frame, do something with it */
#if DEBUG_FRAME_CONTENTS
LED_B_OFF();
}
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset clock for the next bit */
-
+
}
static void hitag_send_frame(int t0, int frame_len, const char const * frame, int fdt)
{
OPEN_COIL();
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
-
+
/* Wait for HITAG_T_WRESP carrier periods after the last reader bit,
* not that since the clock counts since the rising edge, but T_wresp is
* with respect to the falling edge, we need to wait actually (T_wresp - T_g)
int saved_cmr = AT91C_BASE_TC1->TC_CMR;
AT91C_BASE_TC1->TC_CMR &= ~AT91C_TC_ETRGEDG; /* Disable external trigger for the clock */
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG; /* Reset the clock and use it for response timing */
-
+
int i;
for(i=0; i<5; i++)
hitag_send_bit(t0, 1); /* Start of frame */
-
+
for(i=0; i<frame_len; i++) {
hitag_send_bit(t0, !!(frame[i/ 8] & (1<<( 7-(i%8) ))) );
}
-
+
OPEN_COIL();
AT91C_BASE_TC1->TC_CMR = saved_cmr;
}
-//-----------------------------------------------------------------------------\r
-// Just vector to AppMain(). This is in its own file so that I can place it\r
-// with the linker script.\r
-// Jonathan Westhues, Mar 2006\r
-//-----------------------------------------------------------------------------\r
-#include <proxmark3.h>\r
-#include "apps.h"\r
-\r
-extern char __data_start__, __data_src_start__, __data_end__, __bss_start__, __bss_end__;\r
-void __attribute__((section(".startos"))) Vector(void)\r
-{\r
- /* Stack should have been set up by the bootloader */\r
- char *src, *dst, *end;\r
- \r
- /* Set up (that is: clear) BSS. */\r
- dst = &__bss_start__;\r
- end = &__bss_end__;\r
- while(dst < end) *dst++ = 0;\r
- \r
- /* Set up data segment: Copy from flash to ram */\r
- src = &__data_src_start__;\r
- dst = &__data_start__;\r
- end = &__data_end__;\r
- while(dst < end) *dst++ = *src++;\r
- \r
- AppMain();\r
-}\r
+//-----------------------------------------------------------------------------
+// Just vector to AppMain(). This is in its own file so that I can place it
+// with the linker script.
+// Jonathan Westhues, Mar 2006
+//-----------------------------------------------------------------------------
+#include "proxmark3.h"
+#include "apps.h"
+
+extern char __data_start__, __data_src_start__, __data_end__, __bss_start__, __bss_end__;
+void __attribute__((section(".startos"))) Vector(void)
+{
+ /* Stack should have been set up by the bootloader */
+ char *src, *dst, *end;
+
+ /* Set up (that is: clear) BSS. */
+ dst = &__bss_start__;
+ end = &__bss_end__;
+ while(dst < end) *dst++ = 0;
+
+ /* Set up data segment: Copy from flash to ram */
+ src = &__data_src_start__;
+ dst = &__data_start__;
+ end = &__data_end__;
+ while(dst < end) *dst++ = *src++;
+
+ AppMain();
+}
/*
- * bits32/stdint.h
+ * Replacement stdint.h because GCC doesn't come with it yet (C99)
*/
-#ifndef _BITSIZE_STDINT_H
-#define _BITSIZE_STDINT_H
+#ifndef __STDINT_H
+#define __STDINT_H
-typedef signed char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
-typedef int int_fast16_t;
-typedef int int_fast32_t;
+typedef int int_fast16_t;
+typedef int int_fast32_t;
-typedef unsigned int uint_fast16_t;
-typedef unsigned int uint_fast32_t;
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
-#define __INT64_C(c) c ## LL
-#define __UINT64_C(c) c ## ULL
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
-#define __PRI64_RANK "ll"
-#define __PRIFAST_RANK ""
-#define __PRIPTR_RANK ""
+#define __PRI64_RANK "ll"
+#define __PRIFAST_RANK ""
+#define __PRIPTR_RANK ""
-#endif /* _BITSIZE_STDINT_H */
+#endif /* __STDINT_H */
-//-----------------------------------------------------------------------------\r
-// Utility functions used in many places, not specific to any piece of code.\r
-// Jonathan Westhues, Sept 2005\r
-//-----------------------------------------------------------------------------\r
-#include <proxmark3.h>\r
-#include "apps.h"\r
-\r
-void *memcpy(void *dest, const void *src, int len)\r
-{\r
- BYTE *d = dest;\r
- const BYTE *s = src;\r
- while((len--) > 0) {\r
- *d = *s;\r
- d++;\r
- s++;\r
- }\r
- return dest;\r
-}\r
-\r
-void *memset(void *dest, int c, int len)\r
-{\r
- BYTE *d = dest;\r
- while((len--) > 0) {\r
- *d = c;\r
- d++;\r
- }\r
- return dest;\r
-}\r
-\r
-int memcmp(const void *av, const void *bv, int len)\r
-{\r
- const BYTE *a = av;\r
- const BYTE *b = bv;\r
-\r
- while((len--) > 0) {\r
- if(*a != *b) {\r
- return *a - *b;\r
- }\r
- a++;\r
- b++;\r
- }\r
- return 0;\r
-}\r
-\r
-int strlen(char *str)\r
-{\r
- int l = 0;\r
- while(*str) {\r
- l++;\r
- str++;\r
- }\r
- return l;\r
-}\r
-\r
-char* strncat(char *dest, const char *src, unsigned int n)\r
-{\r
- unsigned int dest_len = strlen(dest);\r
- unsigned int i;\r
- \r
- for (i = 0 ; i < n && src[i] != '\0' ; i++)\r
- dest[dest_len + i] = src[i];\r
- dest[dest_len + i] = '\0';\r
- \r
- return dest;\r
-}\r
-\r
-void num_to_bytes(uint64_t n, size_t len, byte_t* dest)\r
-{\r
- while (len--) {\r
- dest[len] = (byte_t) n;\r
- n >>= 8;\r
- }\r
-}\r
-\r
-uint64_t bytes_to_num(byte_t* src, size_t len)\r
-{\r
- uint64_t num = 0;\r
- while (len--)\r
- {\r
- num = (num << 8) | (*src);\r
- src++;\r
- }\r
- return num;\r
-}\r
-\r
-void LEDsoff()\r
-{\r
- LED_A_OFF();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
- LED_D_OFF();\r
-}\r
-\r
-// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]\r
-void LED(int led, int ms)\r
-{\r
- if (led & LED_RED)\r
- LED_C_ON();\r
- if (led & LED_ORANGE)\r
- LED_A_ON();\r
- if (led & LED_GREEN)\r
- LED_B_ON();\r
- if (led & LED_RED2)\r
- LED_D_ON();\r
-\r
- if (!ms)\r
- return;\r
-\r
- SpinDelay(ms);\r
-\r
- if (led & LED_RED)\r
- LED_C_OFF();\r
- if (led & LED_ORANGE)\r
- LED_A_OFF();\r
- if (led & LED_GREEN)\r
- LED_B_OFF();\r
- if (led & LED_RED2)\r
- LED_D_OFF();\r
-}\r
-\r
-\r
-// Determine if a button is double clicked, single clicked,\r
-// not clicked, or held down (for ms || 1sec)\r
-// In general, don't use this function unless you expect a\r
-// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead\r
-int BUTTON_CLICKED(int ms)\r
-{\r
- // Up to 500ms in between clicks to mean a double click\r
- int ticks = (48000 * (ms ? ms : 1000)) >> 10;\r
-\r
- // If we're not even pressed, forget about it!\r
- if (!BUTTON_PRESS())\r
- return BUTTON_NO_CLICK;\r
-\r
- // Borrow a PWM unit for my real-time clock\r
- AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
- // 48 MHz / 1024 gives 46.875 kHz\r
- AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
- AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
- AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
-\r
- WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
-\r
- int letoff = 0;\r
- for(;;)\r
- {\r
- WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
-\r
- // We haven't let off the button yet\r
- if (!letoff)\r
- {\r
- // We just let it off!\r
- if (!BUTTON_PRESS())\r
- {\r
- letoff = 1;\r
-\r
- // reset our timer for 500ms\r
- start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
- ticks = (48000 * (500)) >> 10;\r
- }\r
-\r
- // Still haven't let it off\r
- else\r
- // Have we held down a full second?\r
- if (now == (WORD)(start + ticks))\r
- return BUTTON_HOLD;\r
- }\r
-\r
- // We already let off, did we click again?\r
- else\r
- // Sweet, double click!\r
- if (BUTTON_PRESS())\r
- return BUTTON_DOUBLE_CLICK;\r
-\r
- // Have we ran out of time to double click?\r
- else\r
- if (now == (WORD)(start + ticks))\r
- // At least we did a single click\r
- return BUTTON_SINGLE_CLICK;\r
-\r
- WDT_HIT();\r
- }\r
-\r
- // We should never get here\r
- return BUTTON_ERROR;\r
-}\r
-\r
-// Determine if a button is held down\r
-int BUTTON_HELD(int ms)\r
-{\r
- // If button is held for one second\r
- int ticks = (48000 * (ms ? ms : 1000)) >> 10;\r
-\r
- // If we're not even pressed, forget about it!\r
- if (!BUTTON_PRESS())\r
- return BUTTON_NO_CLICK;\r
-\r
- // Borrow a PWM unit for my real-time clock\r
- AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
- // 48 MHz / 1024 gives 46.875 kHz\r
- AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
- AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
- AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
-\r
- WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
-\r
- for(;;)\r
- {\r
- WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
-\r
- // As soon as our button let go, we didn't hold long enough\r
- if (!BUTTON_PRESS())\r
- return BUTTON_SINGLE_CLICK;\r
-\r
- // Have we waited the full second?\r
- else\r
- if (now == (WORD)(start + ticks))\r
- return BUTTON_HOLD;\r
-\r
- WDT_HIT();\r
- }\r
-\r
- // We should never get here\r
- return BUTTON_ERROR;\r
-}\r
-\r
-// attempt at high resolution microsecond timer\r
-// beware: timer counts in 21.3uS increments (1024/48Mhz)\r
-void SpinDelayUs(int us)\r
-{\r
- int ticks = (48*us) >> 10;\r
-\r
- // Borrow a PWM unit for my real-time clock\r
- AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);\r
- // 48 MHz / 1024 gives 46.875 kHz\r
- AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);\r
- AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;\r
- AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;\r
-\r
- WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
-\r
- for(;;) {\r
- WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;\r
- if (now == (WORD)(start + ticks))\r
- return;\r
-\r
- WDT_HIT();\r
- }\r
-}\r
-\r
-void SpinDelay(int ms)\r
-{\r
- // convert to uS and call microsecond delay function\r
- SpinDelayUs(ms*1000);\r
-}\r
-\r
-/* Similar to FpgaGatherVersion this formats stored version information\r
- * into a string representation. It takes a pointer to the struct version_information,\r
- * verifies the magic properties, then stores a formatted string, prefixed by\r
- * prefix in dst.\r
- */\r
-void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)\r
-{\r
- struct version_information *v = (struct version_information*)version_information;\r
- dst[0] = 0;\r
- strncat(dst, prefix, len);\r
- if(v->magic != VERSION_INFORMATION_MAGIC) {\r
- strncat(dst, "Missing/Invalid version information", len);\r
- return;\r
- }\r
- if(v->versionversion != 1) {\r
- strncat(dst, "Version information not understood", len);\r
- return;\r
- }\r
- if(!v->present) {\r
- strncat(dst, "Version information not available", len);\r
- return;\r
- }\r
- \r
- strncat(dst, v->svnversion, len);\r
- if(v->clean == 0) {\r
- strncat(dst, "-unclean", len);\r
- } else if(v->clean == 2) {\r
- strncat(dst, "-suspect", len);\r
- }\r
- \r
- strncat(dst, " ", len);\r
- strncat(dst, v->buildtime, len);\r
-}\r
+//-----------------------------------------------------------------------------
+// Utility functions used in many places, not specific to any piece of code.
+// Jonathan Westhues, Sept 2005
+//-----------------------------------------------------------------------------
+#include "proxmark3.h"
+#include "apps.h"
+
+void *memcpy(void *dest, const void *src, int len)
+{
+ BYTE *d = dest;
+ const BYTE *s = src;
+ while((len--) > 0) {
+ *d = *s;
+ d++;
+ s++;
+ }
+ return dest;
+}
+
+void *memset(void *dest, int c, int len)
+{
+ BYTE *d = dest;
+ while((len--) > 0) {
+ *d = c;
+ d++;
+ }
+ return dest;
+}
+
+int memcmp(const void *av, const void *bv, int len)
+{
+ const BYTE *a = av;
+ const BYTE *b = bv;
+
+ while((len--) > 0) {
+ if(*a != *b) {
+ return *a - *b;
+ }
+ a++;
+ b++;
+ }
+ return 0;
+}
+
+int strlen(char *str)
+{
+ int l = 0;
+ while(*str) {
+ l++;
+ str++;
+ }
+ return l;
+}
+
+char* strncat(char *dest, const char *src, unsigned int n)
+{
+ unsigned int dest_len = strlen(dest);
+ unsigned int i;
+
+ for (i = 0 ; i < n && src[i] != '\0' ; i++)
+ dest[dest_len + i] = src[i];
+ dest[dest_len + i] = '\0';
+
+ return dest;
+}
+
+void num_to_bytes(uint64_t n, size_t len, byte_t* dest)
+{
+ while (len--) {
+ dest[len] = (byte_t) n;
+ n >>= 8;
+ }
+}
+
+uint64_t bytes_to_num(byte_t* src, size_t len)
+{
+ uint64_t num = 0;
+ while (len--)
+ {
+ num = (num << 8) | (*src);
+ src++;
+ }
+ return num;
+}
+
+void LEDsoff()
+{
+ LED_A_OFF();
+ LED_B_OFF();
+ LED_C_OFF();
+ LED_D_OFF();
+}
+
+// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
+void LED(int led, int ms)
+{
+ if (led & LED_RED)
+ LED_C_ON();
+ if (led & LED_ORANGE)
+ LED_A_ON();
+ if (led & LED_GREEN)
+ LED_B_ON();
+ if (led & LED_RED2)
+ LED_D_ON();
+
+ if (!ms)
+ return;
+
+ SpinDelay(ms);
+
+ if (led & LED_RED)
+ LED_C_OFF();
+ if (led & LED_ORANGE)
+ LED_A_OFF();
+ if (led & LED_GREEN)
+ LED_B_OFF();
+ if (led & LED_RED2)
+ LED_D_OFF();
+}
+
+
+// Determine if a button is double clicked, single clicked,
+// not clicked, or held down (for ms || 1sec)
+// In general, don't use this function unless you expect a
+// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
+int BUTTON_CLICKED(int ms)
+{
+ // Up to 500ms in between clicks to mean a double click
+ int ticks = (48000 * (ms ? ms : 1000)) >> 10;
+
+ // If we're not even pressed, forget about it!
+ if (!BUTTON_PRESS())
+ return BUTTON_NO_CLICK;
+
+ // Borrow a PWM unit for my real-time clock
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
+ // 48 MHz / 1024 gives 46.875 kHz
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
+ int letoff = 0;
+ for(;;)
+ {
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
+ // We haven't let off the button yet
+ if (!letoff)
+ {
+ // We just let it off!
+ if (!BUTTON_PRESS())
+ {
+ letoff = 1;
+
+ // reset our timer for 500ms
+ start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+ ticks = (48000 * (500)) >> 10;
+ }
+
+ // Still haven't let it off
+ else
+ // Have we held down a full second?
+ if (now == (WORD)(start + ticks))
+ return BUTTON_HOLD;
+ }
+
+ // We already let off, did we click again?
+ else
+ // Sweet, double click!
+ if (BUTTON_PRESS())
+ return BUTTON_DOUBLE_CLICK;
+
+ // Have we ran out of time to double click?
+ else
+ if (now == (WORD)(start + ticks))
+ // At least we did a single click
+ return BUTTON_SINGLE_CLICK;
+
+ WDT_HIT();
+ }
+
+ // We should never get here
+ return BUTTON_ERROR;
+}
+
+// Determine if a button is held down
+int BUTTON_HELD(int ms)
+{
+ // If button is held for one second
+ int ticks = (48000 * (ms ? ms : 1000)) >> 10;
+
+ // If we're not even pressed, forget about it!
+ if (!BUTTON_PRESS())
+ return BUTTON_NO_CLICK;
+
+ // Borrow a PWM unit for my real-time clock
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
+ // 48 MHz / 1024 gives 46.875 kHz
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
+ for(;;)
+ {
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
+ // As soon as our button let go, we didn't hold long enough
+ if (!BUTTON_PRESS())
+ return BUTTON_SINGLE_CLICK;
+
+ // Have we waited the full second?
+ else
+ if (now == (WORD)(start + ticks))
+ return BUTTON_HOLD;
+
+ WDT_HIT();
+ }
+
+ // We should never get here
+ return BUTTON_ERROR;
+}
+
+// attempt at high resolution microsecond timer
+// beware: timer counts in 21.3uS increments (1024/48Mhz)
+void SpinDelayUs(int us)
+{
+ int ticks = (48*us) >> 10;
+
+ // Borrow a PWM unit for my real-time clock
+ AT91C_BASE_PWMC->PWMC_ENA = PWM_CHANNEL(0);
+ // 48 MHz / 1024 gives 46.875 kHz
+ AT91C_BASE_PWMC_CH0->PWMC_CMR = PWM_CH_MODE_PRESCALER(10);
+ AT91C_BASE_PWMC_CH0->PWMC_CDTYR = 0;
+ AT91C_BASE_PWMC_CH0->PWMC_CPRDR = 0xffff;
+
+ WORD start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+
+ for(;;) {
+ WORD now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
+ if (now == (WORD)(start + ticks))
+ return;
+
+ WDT_HIT();
+ }
+}
+
+void SpinDelay(int ms)
+{
+ // convert to uS and call microsecond delay function
+ SpinDelayUs(ms*1000);
+}
+
+/* Similar to FpgaGatherVersion this formats stored version information
+ * into a string representation. It takes a pointer to the struct version_information,
+ * verifies the magic properties, then stores a formatted string, prefixed by
+ * prefix in dst.
+ */
+void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)
+{
+ struct version_information *v = (struct version_information*)version_information;
+ dst[0] = 0;
+ strncat(dst, prefix, len);
+ if(v->magic != VERSION_INFORMATION_MAGIC) {
+ strncat(dst, "Missing/Invalid version information", len);
+ return;
+ }
+ if(v->versionversion != 1) {
+ strncat(dst, "Version information not understood", len);
+ return;
+ }
+ if(!v->present) {
+ strncat(dst, "Version information not available", len);
+ return;
+ }
+
+ strncat(dst, v->svnversion, len);
+ if(v->clean == 0) {
+ strncat(dst, "-unclean", len);
+ } else if(v->clean == 2) {
+ strncat(dst, "-suspect", len);
+ }
+
+ strncat(dst, " ", len);
+ strncat(dst, v->buildtime, len);
+}
MC_FLASH_COMMAND_PAGEN((c->arg[0]-(int)&_flash_start)/AT91C_IFLASH_PAGE_SIZE) |
AT91C_MC_FCMD_START_PROG;
}
-
+
uint32_t sr;
-
+
while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & MC_FLASH_STATUS_READY))
;
- if(sr & (MC_FLASH_STATUS_LOCKE | MC_FLASH_STATUS_PROGE)) {
+ if(sr & (MC_FLASH_STATUS_LOCKE | MC_FLASH_STATUS_PROGE)) {
dont_ack = 1;
c->cmd = CMD_NACK;
UsbSendPacket(packet, len);
.extern CopyBootToRAM
-
+
.section .startup,"ax"
.code 32
.align 0
-.extern BootROM\r
- \r
-.section .startphase2,"ax"\r
- .code 32\r
- .align 0\r
-\r
-.global ramstart\r
-ramstart:\r
- ldr sp, .stack_end\r
- bl BootROM\r
-\r
- .stack_end:\r
- .word _stack_end\r
+.extern BootROM
+
+.section .startphase2,"ax"
+ .code 32
+ .align 0
+
+.global ramstart
+ramstart:
+ ldr sp, .stack_end
+ bl BootROM
+
+ .stack_end:
+ .word _stack_end
/*
- * bits32/stdint.h
+ * Replacement stdint.h because GCC doesn't come with it yet (C99)
*/
-#ifndef _BITSIZE_STDINT_H
-#define _BITSIZE_STDINT_H
+#ifndef __STDINT_H
+#define __STDINT_H
-typedef signed char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
+typedef signed char int8_t;
+typedef short int int16_t;
+typedef int int32_t;
+typedef long long int int64_t;
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+typedef unsigned short int uint16_t;
+typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
-typedef int int_fast16_t;
-typedef int int_fast32_t;
+typedef int int_fast16_t;
+typedef int int_fast32_t;
-typedef unsigned int uint_fast16_t;
-typedef unsigned int uint_fast32_t;
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
-#define __INT64_C(c) c ## LL
-#define __UINT64_C(c) c ## ULL
+#define __INT64_C(c) c ## LL
+#define __UINT64_C(c) c ## ULL
-#define __PRI64_RANK "ll"
-#define __PRIFAST_RANK ""
-#define __PRIPTR_RANK ""
+#define __PRI64_RANK "ll"
+#define __PRIFAST_RANK ""
+#define __PRIPTR_RANK ""
-#endif /* _BITSIZE_STDINT_H */
+#endif /* __STDINT_H */
-#include <proxmark3.h>
+#include "proxmark3.h"
/* This is the default version.c file that Makefile.common falls back to if perl is not available */
struct version_information __attribute__((section(".version_information"))) version_information = {
VERSION_INFORMATION_MAGIC,
* crc.h
*
* Generic CRC calculation code.
- *
+ *
*/
-#ifndef CRC_H_
-#define CRC_H_
+#ifndef __CRC_H
+#define __CRC_H
#include <stdint.h>
/* Update the crc state. data is the data of length data_width bits (only the the
* data_width lower-most bits are used).
- */
+ */
extern void crc_update(crc_t *crc, uint32_t data, int data_width);
/* Clean the crc state, e.g. reset it to initial_value */
.final_xor = (_final_xor), \
.mask = ((1L<<(_order))-1) }
-#endif /* CRC_H_ */
+#endif /* __CRC_H */
-#ifndef LEGIC_PRNG_H__
-#define LEGIC_PRNG_H__
+#ifndef __LEGIC_PRNG_H
+#define __LEGIC_PRNG_H
#include <stdint.h>
extern void legic_prng_init(uint8_t init);
-//-----------------------------------------------------------------------------\r
-// Definitions for all the types of commands that may be sent over USB; our\r
-// own protocol.\r
-// Jonathan Westhues, Mar 2006\r
-// Edits by Gerhard de Koning Gans, Sep 2007\r
-//-----------------------------------------------------------------------------\r
-\r
-#ifndef __USB_CMD_H\r
-#define __USB_CMD_H\r
-#ifdef _MSC_VER\r
-typedef DWORD uint32_t;\r
-typedef BYTE uint8_t;\r
-#define PACKED\r
-// stuff\r
-#else\r
-#include <stdint.h>\r
-#include <stdbool.h>\r
-#define PACKED __attribute__((packed))\r
-#endif\r
-\r
-typedef struct {\r
- uint32_t cmd;\r
- uint32_t arg[3];\r
- union {\r
- uint8_t asBytes[48];\r
- uint32_t asDwords[12];\r
- } d;\r
-} PACKED UsbCommand;\r
-\r
-// For the bootloader\r
-#define CMD_DEVICE_INFO 0x0000\r
-#define CMD_SETUP_WRITE 0x0001\r
-#define CMD_FINISH_WRITE 0x0003\r
-#define CMD_HARDWARE_RESET 0x0004\r
-#define CMD_START_FLASH 0x0005\r
-#define CMD_NACK 0x00fe\r
-#define CMD_ACK 0x00ff\r
-\r
-// For general mucking around\r
-#define CMD_DEBUG_PRINT_STRING 0x0100\r
-#define CMD_DEBUG_PRINT_INTEGERS 0x0101\r
-#define CMD_DEBUG_PRINT_BYTES 0x0102\r
-#define CMD_LCD_RESET 0x0103\r
-#define CMD_LCD 0x0104\r
-#define CMD_BUFF_CLEAR 0x0105\r
-#define CMD_READ_MEM 0x0106\r
-#define CMD_VERSION 0x0107\r
-\r
-// For low-frequency tags\r
-#define CMD_READ_TI_TYPE 0x0202\r
-#define CMD_WRITE_TI_TYPE 0x0203\r
-#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE 0x0204\r
-#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205\r
-#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206\r
-#define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K 0x0207\r
-#define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K 0x0208\r
-#define CMD_DOWNLOADED_SIM_SAMPLES_125K 0x0209\r
-#define CMD_SIMULATE_TAG_125K 0x020A\r
-#define CMD_HID_DEMOD_FSK 0x020B\r
-#define CMD_HID_SIM_TAG 0x020C\r
-#define CMD_SET_LF_DIVISOR 0x020D\r
-#define CMD_LF_SIMULATE_BIDIR 0x020E\r
-#define CMD_SET_ADC_MUX 0x020F\r
-/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */\r
-\r
-// For the 13.56 MHz tags\r
-#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300\r
-#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301\r
-#define CMD_READ_SRI512_TAG 0x0303\r
-#define CMD_READ_SRIX4K_TAG 0x0304\r
-#define CMD_READER_ISO_15693 0x0310\r
-#define CMD_SIMTAG_ISO_15693 0x0311\r
-#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380\r
-#define CMD_SIMULATE_TAG_ISO_14443 0x0381\r
-#define CMD_SNOOP_ISO_14443 0x0382\r
-#define CMD_SNOOP_ISO_14443a 0x0383\r
-#define CMD_SIMULATE_TAG_ISO_14443a 0x0384\r
-#define CMD_READER_ISO_14443a 0x0385\r
-#define CMD_SIMULATE_MIFARE_CARD 0x0386\r
-#define CMD_SIMULATE_TAG_LEGIC_RF 0x0387\r
-#define CMD_READER_LEGIC_RF 0x0388\r
-#define CMD_READER_MIFARE 0x0389\r
-\r
-// For measurements of the antenna tuning\r
-#define CMD_MEASURE_ANTENNA_TUNING 0x0400\r
-#define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401\r
-#define CMD_MEASURED_ANTENNA_TUNING 0x0410\r
-#define CMD_LISTEN_READER_FIELD 0x0420\r
-\r
-// For direct FPGA control\r
-#define CMD_FPGA_MAJOR_MODE_OFF 0x0500\r
-\r
-#define CMD_UNKNOWN 0xFFFF\r
-\r
-// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:\r
-/* Whether a bootloader that understands the common_area is present */ \r
-#define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0)\r
-\r
-/* Whether a osimage that understands the common_area is present */\r
-#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT (1<<1)\r
-\r
-/* Set if the bootloader is currently executing */\r
-#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM (1<<2)\r
-\r
-/* Set if the OS is currently executing */\r
-#define DEVICE_INFO_FLAG_CURRENT_MODE_OS (1<<3)\r
-\r
-/* Set if this device understands the extend start flash command */\r
-#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4)\r
-\r
-/* CMD_START_FLASH may have three arguments: start of area to flash, \r
- end of area to flash, optional magic.\r
- The bootrom will not allow to overwrite itself unless this magic\r
- is given as third parameter */\r
-\r
-#define START_FLASH_MAGIC 0x54494f44 // 'DOIT'\r
-\r
-#endif\r
+//-----------------------------------------------------------------------------
+// Definitions for all the types of commands that may be sent over USB; our
+// own protocol.
+// Jonathan Westhues, Mar 2006
+// Edits by Gerhard de Koning Gans, Sep 2007
+//-----------------------------------------------------------------------------
+
+#ifndef __USB_CMD_H
+#define __USB_CMD_H
+#ifdef _MSC_VER
+typedef DWORD uint32_t;
+typedef BYTE uint8_t;
+#define PACKED
+// stuff
+#else
+#include <stdint.h>
+#include <stdbool.h>
+#define PACKED __attribute__((packed))
+#endif
+
+typedef struct {
+ uint32_t cmd;
+ uint32_t arg[3];
+ union {
+ uint8_t asBytes[48];
+ uint32_t asDwords[12];
+ } d;
+} PACKED UsbCommand;
+
+// For the bootloader
+#define CMD_DEVICE_INFO 0x0000
+#define CMD_SETUP_WRITE 0x0001
+#define CMD_FINISH_WRITE 0x0003
+#define CMD_HARDWARE_RESET 0x0004
+#define CMD_START_FLASH 0x0005
+#define CMD_NACK 0x00fe
+#define CMD_ACK 0x00ff
+
+// For general mucking around
+#define CMD_DEBUG_PRINT_STRING 0x0100
+#define CMD_DEBUG_PRINT_INTEGERS 0x0101
+#define CMD_DEBUG_PRINT_BYTES 0x0102
+#define CMD_LCD_RESET 0x0103
+#define CMD_LCD 0x0104
+#define CMD_BUFF_CLEAR 0x0105
+#define CMD_READ_MEM 0x0106
+#define CMD_VERSION 0x0107
+
+// For low-frequency tags
+#define CMD_READ_TI_TYPE 0x0202
+#define CMD_WRITE_TI_TYPE 0x0203
+#define CMD_DOWNLOADED_RAW_BITS_TI_TYPE 0x0204
+#define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205
+#define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206
+#define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K 0x0207
+#define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K 0x0208
+#define CMD_DOWNLOADED_SIM_SAMPLES_125K 0x0209
+#define CMD_SIMULATE_TAG_125K 0x020A
+#define CMD_HID_DEMOD_FSK 0x020B
+#define CMD_HID_SIM_TAG 0x020C
+#define CMD_SET_LF_DIVISOR 0x020D
+#define CMD_LF_SIMULATE_BIDIR 0x020E
+#define CMD_SET_ADC_MUX 0x020F
+/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
+
+// For the 13.56 MHz tags
+#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
+#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301
+#define CMD_READ_SRI512_TAG 0x0303
+#define CMD_READ_SRIX4K_TAG 0x0304
+#define CMD_READER_ISO_15693 0x0310
+#define CMD_SIMTAG_ISO_15693 0x0311
+#define CMD_SIMULATE_TAG_HF_LISTEN 0x0380
+#define CMD_SIMULATE_TAG_ISO_14443 0x0381
+#define CMD_SNOOP_ISO_14443 0x0382
+#define CMD_SNOOP_ISO_14443a 0x0383
+#define CMD_SIMULATE_TAG_ISO_14443a 0x0384
+#define CMD_READER_ISO_14443a 0x0385
+#define CMD_SIMULATE_MIFARE_CARD 0x0386
+#define CMD_SIMULATE_TAG_LEGIC_RF 0x0387
+#define CMD_READER_LEGIC_RF 0x0388
+#define CMD_READER_MIFARE 0x0389
+
+// For measurements of the antenna tuning
+#define CMD_MEASURE_ANTENNA_TUNING 0x0400
+#define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401
+#define CMD_MEASURED_ANTENNA_TUNING 0x0410
+#define CMD_LISTEN_READER_FIELD 0x0420
+
+// For direct FPGA control
+#define CMD_FPGA_MAJOR_MODE_OFF 0x0500
+
+#define CMD_UNKNOWN 0xFFFF
+
+// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
+/* Whether a bootloader that understands the common_area is present */
+#define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0)
+
+/* Whether a osimage that understands the common_area is present */
+#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT (1<<1)
+
+/* Set if the bootloader is currently executing */
+#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM (1<<2)
+
+/* Set if the OS is currently executing */
+#define DEVICE_INFO_FLAG_CURRENT_MODE_OS (1<<3)
+
+/* Set if this device understands the extend start flash command */
+#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4)
+
+/* CMD_START_FLASH may have three arguments: start of area to flash,
+ end of area to flash, optional magic.
+ The bootrom will not allow to overwrite itself unless this magic
+ is given as third parameter */
+
+#define START_FLASH_MAGIC 0x54494f44 // 'DOIT'
+
+#endif