Revert "Merge branch 'master' into hf_mf_sim"
This reverts commitcbea5d9d02, reversing changes made tob66152feb2.
This commit is contained in:
@@ -195,6 +195,47 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||
return true;
|
||||
}
|
||||
|
||||
int LogTraceHitag(const uint8_t *btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) {
|
||||
/**
|
||||
Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
|
||||
that this logger takes number of bits as argument, not number of bytes.
|
||||
**/
|
||||
|
||||
if (!tracing) return false;
|
||||
|
||||
uint8_t *trace = BigBuf_get_addr();
|
||||
uint32_t iLen = nbytes(iBits);
|
||||
// Return when trace is full
|
||||
if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return false;
|
||||
|
||||
//Hitag traces appear to use this traceformat:
|
||||
// 32 bits timestamp (little endian,Highest Bit used as readerToTag flag)
|
||||
// 32 bits parity
|
||||
// 8 bits size (number of bits in the trace entry, not number of bytes)
|
||||
// y Bytes data
|
||||
|
||||
rsamples += iSamples;
|
||||
trace[traceLen++] = ((rsamples >> 0) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 8) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 16) & 0xff);
|
||||
trace[traceLen++] = ((rsamples >> 24) & 0xff);
|
||||
|
||||
if (!readerToTag) {
|
||||
trace[traceLen - 1] |= 0x80;
|
||||
}
|
||||
|
||||
trace[traceLen++] = ((dwParity >> 0) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 8) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 16) & 0xff);
|
||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||
trace[traceLen++] = iBits;
|
||||
|
||||
memcpy(trace + traceLen, btBytes, iLen);
|
||||
traceLen += iLen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Emulator memory
|
||||
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length) {
|
||||
uint8_t *mem = BigBuf_get_EM_addr();
|
||||
|
||||
@@ -42,5 +42,6 @@ extern void set_tracing(bool enable);
|
||||
extern void set_tracelen(uint32_t value);
|
||||
extern bool get_tracing(void);
|
||||
extern bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
||||
extern int LogTraceHitag(const uint8_t *btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader);
|
||||
extern uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length);
|
||||
#endif /* __BIGBUF_H */
|
||||
|
||||
@@ -38,7 +38,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
|
||||
-DWITH_ISO14443a \
|
||||
-DWITH_ICLASS \
|
||||
-DWITH_FELICA \
|
||||
-DWITH_HFSNIFF \
|
||||
-DWITH_HFSNOOP \
|
||||
-DWITH_LF_SAMYRUN \
|
||||
-fno-strict-aliasing -ffunction-sections -fdata-sections
|
||||
|
||||
@@ -60,7 +60,7 @@ APP_CFLAGS = $(PLATFORM_DEFS) \
|
||||
|
||||
|
||||
SRC_LCD = fonts.c LCD.c
|
||||
SRC_LF = lfops.c hitag2_crypto.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c
|
||||
SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c
|
||||
SRC_ISO14443b = iso14443b.c
|
||||
|
||||
@@ -433,4 +433,4 @@ void RunMod() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,4 +20,4 @@
|
||||
|
||||
#define OPTS 2
|
||||
|
||||
#endif /* __HF_MATTYRUN_H */
|
||||
#endif /* __HF_MATTYRUN_H */
|
||||
@@ -259,4 +259,4 @@ void RunMod() {
|
||||
LED(selected + 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,4 +19,4 @@
|
||||
|
||||
#define OPTS 2
|
||||
|
||||
#endif /* __HF_YOUNG_H */
|
||||
#endif /* __HF_YOUNG_H */
|
||||
@@ -21,4 +21,4 @@
|
||||
|
||||
void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc);
|
||||
|
||||
#endif /* __LF_HIDBRUTE_H */
|
||||
#endif /* __LF_HIDBRUTE_H */
|
||||
@@ -164,4 +164,4 @@ void RunMod() {
|
||||
out:
|
||||
DbpString("[=] exiting");
|
||||
LEDsoff();
|
||||
}
|
||||
}
|
||||
@@ -18,4 +18,4 @@
|
||||
|
||||
#define OPTS 2
|
||||
|
||||
#endif /* __LF_PROXBRUTE_H */
|
||||
#endif /* __LF_PROXBRUTE_H */
|
||||
@@ -138,4 +138,4 @@ void RunMod() {
|
||||
out:
|
||||
DbpString("[=] exiting");
|
||||
LEDsoff();
|
||||
}
|
||||
}
|
||||
@@ -19,4 +19,4 @@
|
||||
|
||||
#define OPTS 2
|
||||
|
||||
#endif /* __LF_SAMYRUN_H */
|
||||
#endif /* __LF_SAMYRUN_H */
|
||||
@@ -16,4 +16,4 @@
|
||||
|
||||
extern void RunMod();
|
||||
|
||||
#endif /* __STANDALONE_H */
|
||||
#endif /* __STANDALONE_H */
|
||||
@@ -1167,4 +1167,4 @@ int main() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -31,4 +31,4 @@ int AesCtxIni(AesCtx *pCtx, unsigned char *pIV, unsigned char *pKey, unsigned in
|
||||
int AesEncrypt(AesCtx *pCtx, unsigned char *pData, unsigned char *pCipher, unsigned int DataLen);
|
||||
int AesDecrypt(AesCtx *pCtx, unsigned char *pCipher, unsigned char *pData, unsigned int CipherLen);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -650,8 +650,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
|
||||
ModThenAcquireRawAdcSamples125k(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
case CMD_LF_SNIFF_RAW_ADC_SAMPLES: {
|
||||
uint32_t bits = SniffLF();
|
||||
case CMD_LF_SNOOP_RAW_ADC_SAMPLES: {
|
||||
uint32_t bits = SnoopLF();
|
||||
cmd_send(CMD_ACK, bits, 0, 0, 0, 0);
|
||||
break;
|
||||
}
|
||||
@@ -664,13 +664,13 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
CmdHIDsimTAG(c->arg[0], c->arg[1], 1);
|
||||
break;
|
||||
case CMD_FSK_SIM_TAG:
|
||||
CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes, 1);
|
||||
CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
case CMD_ASK_SIM_TAG:
|
||||
CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes, 1);
|
||||
CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
case CMD_PSK_SIM_TAG:
|
||||
CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes, 1);
|
||||
CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
case CMD_HID_CLONE_TAG:
|
||||
CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
|
||||
@@ -765,8 +765,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HITAG
|
||||
case CMD_SNIFF_HITAG: // Eavesdrop Hitag tag, args = type
|
||||
SniffHitag(c->arg[0]);
|
||||
case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
|
||||
SnoopHitag(c->arg[0]);
|
||||
break;
|
||||
case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
|
||||
SimulateHitagTag((bool)c->arg[0], (byte_t *)c->d.asBytes);
|
||||
@@ -786,7 +786,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
case CMD_WR_HITAG_S: //writer for Hitag tags args=data to write,page and key or challenge
|
||||
if ((hitag_function)c->arg[0] < 10) {
|
||||
WritePageHitagS((hitag_function)c->arg[0], (hitag_data *)c->d.asBytes, c->arg[2]);
|
||||
} else {
|
||||
} else if ((hitag_function)c->arg[0] >= 10) {
|
||||
WriterHitag((hitag_function)c->arg[0], (hitag_data *)c->d.asBytes, c->arg[2]);
|
||||
}
|
||||
break;
|
||||
@@ -843,7 +843,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
case CMD_READ_SRI_TAG:
|
||||
ReadSTMemoryIso14443b(c->arg[0]);
|
||||
break;
|
||||
case CMD_SNIFF_ISO_14443B:
|
||||
case CMD_SNOOP_ISO_14443B:
|
||||
SniffIso14443b();
|
||||
break;
|
||||
case CMD_SIMULATE_TAG_ISO_14443B:
|
||||
@@ -862,7 +862,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
case CMD_FELICA_LITE_SIM:
|
||||
felica_sim_lite(c->arg[0]);
|
||||
break;
|
||||
case CMD_FELICA_SNIFF:
|
||||
case CMD_FELICA_SNOOP:
|
||||
felica_sniff(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
case CMD_FELICA_LITE_DUMP:
|
||||
@@ -871,7 +871,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ISO14443a
|
||||
case CMD_SNIFF_ISO_14443a:
|
||||
case CMD_SNOOP_ISO_14443a:
|
||||
SniffIso14443a(c->arg[0]);
|
||||
break;
|
||||
case CMD_READER_ISO_14443a:
|
||||
@@ -1003,7 +1003,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
|
||||
#ifdef WITH_ICLASS
|
||||
// Makes use of ISO14443a FPGA Firmware
|
||||
case CMD_SNIFF_ICLASS:
|
||||
case CMD_SNOOP_ICLASS:
|
||||
SniffIClass();
|
||||
break;
|
||||
case CMD_SIMULATE_TAG_ICLASS:
|
||||
@@ -1043,9 +1043,9 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_HFSNIFF
|
||||
#ifdef WITH_HFSNOOP
|
||||
case CMD_HF_SNIFFER:
|
||||
HfSniff(c->arg[0], c->arg[1]);
|
||||
HfSnoop(c->arg[0], c->arg[1]);
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -1322,12 +1322,10 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
// first mem page
|
||||
res = Flash_WriteDataCont(startidx, data, first_len);
|
||||
|
||||
isok = (res == first_len) ? 1 : 0;
|
||||
|
||||
// second mem page
|
||||
res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len);
|
||||
|
||||
isok &= (res == (len - first_len)) ? 1 : 0;
|
||||
isok = (res == (len - first_len)) ? 1 : 0;
|
||||
|
||||
} else {
|
||||
res = Flash_WriteDataCont(startidx, data, len);
|
||||
@@ -1391,7 +1389,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
FlashStop();
|
||||
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
BigBuf_free();
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -85,9 +85,9 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol);
|
||||
void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
|
||||
void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, int ledcontrol, int numcycles);
|
||||
void CmdHIDsimTAG(uint32_t hi, uint32_t lo, int ledcontrol);
|
||||
void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream, int ledcontrol);
|
||||
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream, int ledcontrol);
|
||||
void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream, int ledcontrol);
|
||||
void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
|
||||
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
|
||||
void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream);
|
||||
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol);
|
||||
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol); // Realtime demodulation mode for AWID26
|
||||
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol);
|
||||
@@ -222,12 +222,24 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks);
|
||||
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
|
||||
void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
|
||||
|
||||
// hitag2.h
|
||||
void SnoopHitag(uint32_t type);
|
||||
void SimulateHitagTag(bool tag_mem_supplied, byte_t *data);
|
||||
void ReaderHitag(hitag_function htf, hitag_data *htd);
|
||||
void WriterHitag(hitag_function htf, hitag_data *htd, int page);
|
||||
|
||||
//hitagS.h
|
||||
void SimulateHitagSTag(bool tag_mem_supplied, byte_t *data);
|
||||
void ReadHitagS(hitag_function htf, hitag_data *htd);
|
||||
void WritePageHitagS(hitag_function htf, hitag_data *htd, int page);
|
||||
void check_challenges(bool file_given, byte_t *data);
|
||||
|
||||
// cmd.h
|
||||
uint8_t cmd_receive(UsbCommand *cmd);
|
||||
uint8_t cmd_send(uint64_t cmd, uint64_t arg0, uint64_t arg1, uint64_t arg2, void *data, size_t len);
|
||||
|
||||
// util.h
|
||||
void HfSniff(int, int);
|
||||
void HfSnoop(int, int);
|
||||
|
||||
//felica.c
|
||||
extern void felica_sendraw(UsbCommand *c);
|
||||
|
||||
@@ -83,4 +83,4 @@ void Ring_Little_Star(uint16_t count) {
|
||||
Ring_BEE_TIME(note_1,2*count);
|
||||
LED_B_ON();
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -630,4 +630,4 @@ void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *i
|
||||
mifare_cypher_single_block(key, data + offset, ivect, direction, operation, block_size);
|
||||
offset += block_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,4 +152,4 @@ void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfire
|
||||
Desfire_aes_key_new(buffer, key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,4 @@ void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version,
|
||||
uint8_t Desfire_key_get_version(desfirekey_t key);
|
||||
void Desfire_key_set_version(desfirekey_t key, uint8_t version);
|
||||
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key);
|
||||
#endif
|
||||
#endif
|
||||
@@ -305,11 +305,6 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) {
|
||||
// initiate the PACE protocol
|
||||
// use the CAN for the password since that doesn't change
|
||||
func_return = EPA_PACE_MSE_Set_AT(pace_version_info, 2);
|
||||
// check if the command succeeded
|
||||
if (func_return != 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
||||
return;
|
||||
}
|
||||
|
||||
// now get the nonce
|
||||
uint8_t nonce[256] = {0};
|
||||
@@ -317,7 +312,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c) {
|
||||
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
|
||||
// check if the command succeeded
|
||||
if (func_return < 0) {
|
||||
EPA_PACE_Collect_Nonce_Abort(5, func_return);
|
||||
EPA_PACE_Collect_Nonce_Abort(4, func_return);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
|
||||
|
||||
int remFrames = (samplesToSkip) ? samplesToSkip : 0;
|
||||
|
||||
Dbprintf("Sniff FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||
Dbprintf("Snoop FelicaLiteS: Getting first %d frames, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
|
||||
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
|
||||
@@ -151,4 +151,4 @@ void Flashmem_print_status(void);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -4,9 +4,9 @@
|
||||
#include "util.h"
|
||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||
|
||||
static void RAMFUNC optimizedSniff(void);
|
||||
static void RAMFUNC optimizedSnoop(void);
|
||||
|
||||
static void RAMFUNC optimizedSniff(void) {
|
||||
static void RAMFUNC optimizedSnoop(void) {
|
||||
int n = BigBuf_max_traceLen() / sizeof(uint16_t); // take all memory
|
||||
|
||||
uint16_t *dest = (uint16_t *)BigBuf_get_addr();
|
||||
@@ -23,7 +23,7 @@ static void RAMFUNC optimizedSniff(void) {
|
||||
set_tracelen(BigBuf_max_traceLen());
|
||||
}
|
||||
|
||||
void HfSniff(int samplesToSkip, int triggersToSkip) {
|
||||
void HfSnoop(int samplesToSkip, int triggersToSkip) {
|
||||
BigBuf_free();
|
||||
BigBuf_Clear();
|
||||
|
||||
@@ -66,14 +66,14 @@ void HfSniff(int samplesToSkip, int triggersToSkip) {
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY))
|
||||
waitcount--;
|
||||
}
|
||||
optimizedSniff();
|
||||
optimizedSnoop();
|
||||
Dbprintf("Trigger kicked! Value: %d, Dumping Samples Hispeed now.", r);
|
||||
}
|
||||
|
||||
//Resetting Frame mode (First set in fpgaloader.c)
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
DbpString("HF Sniffing end");
|
||||
DbpString("HF Snoop end");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_D_OFF();
|
||||
}
|
||||
|
||||
465
armsrc/hitag2.c
465
armsrc/hitag2.c
@@ -3,35 +3,46 @@
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hitag2 emulation
|
||||
// Hitag2 emulation (preliminary test version)
|
||||
//
|
||||
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hitag2 complete rewrite of the code
|
||||
// - Fixed modulation/encoding issues
|
||||
// - Rewrote code for transponder emulation
|
||||
// - Added sniffing of transponder communication
|
||||
// - Added snooping of transponder communication
|
||||
// - Added reader functionality
|
||||
//
|
||||
// (c) 2012 Roel Verdult
|
||||
//-----------------------------------------------------------------------------
|
||||
// Piwi, 2019
|
||||
// Iceman, 2019
|
||||
|
||||
#include "hitag2.h"
|
||||
#include "hitag2_crypto.h"
|
||||
#include "hitag.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "hitag2.h"
|
||||
#include "string.h"
|
||||
#include "BigBuf.h"
|
||||
|
||||
static bool bQuiet;
|
||||
static bool bCrypto;
|
||||
static bool bAuthenticating;
|
||||
static bool bPwd;
|
||||
static bool bSuccessful;
|
||||
|
||||
struct hitag2_tag {
|
||||
uint32_t uid;
|
||||
enum {
|
||||
TAG_STATE_RESET = 0x01, // Just powered up, awaiting GetSnr
|
||||
TAG_STATE_ACTIVATING = 0x02, // In activation phase (password mode), sent UID, awaiting reader password
|
||||
TAG_STATE_ACTIVATED = 0x03, // Activation complete, awaiting read/write commands
|
||||
TAG_STATE_WRITING = 0x04, // In write command, awaiting sector contents to be written
|
||||
} state;
|
||||
unsigned int active_sector;
|
||||
uint8_t crypto_active;
|
||||
uint64_t cs;
|
||||
uint8_t sectors[12][4];
|
||||
};
|
||||
|
||||
static struct hitag2_tag tag = {
|
||||
.state = TAG_STATE_RESET,
|
||||
.sectors = { // Password mode: | Crypto mode:
|
||||
@@ -70,6 +81,87 @@ static uint8_t key[8];
|
||||
static uint8_t writedata[4];
|
||||
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.
|
||||
// For educational purposes only.
|
||||
// No warranties or guarantees of any kind.
|
||||
// This code is released into the public domain by its author.
|
||||
|
||||
// Basic macros:
|
||||
|
||||
#define u8 uint8_t
|
||||
#define u32 uint32_t
|
||||
#define u64 uint64_t
|
||||
#define rev8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7))
|
||||
#define rev16(x) (rev8 (x)+(rev8 (x>> 8)<< 8))
|
||||
#define rev32(x) (rev16(x)+(rev16(x>>16)<<16))
|
||||
#define rev64(x) (rev32(x)+(rev32(x>>32)<<32))
|
||||
#define bit(x,n) (((x)>>(n))&1)
|
||||
#define bit32(x,n) ((((x)[(n)>>5])>>((n)))&1)
|
||||
#define inv32(x,i,n) ((x)[(i)>>5]^=((u32)(n))<<((i)&31))
|
||||
#define rotl64(x, n) ((((u64)(x))<<((n)&63))+(((u64)(x))>>((0-(n))&63)))
|
||||
|
||||
// Single bit Hitag2 functions:
|
||||
#define i4(x,a,b,c,d) ((u32)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
|
||||
|
||||
static const u32 ht2_f4a = 0x2C79; // 0010 1100 0111 1001
|
||||
static const u32 ht2_f4b = 0x6671; // 0110 0110 0111 0001
|
||||
static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static u64 _hitag2_init(const u64 key, const u32 serial, const u32 IV) {
|
||||
u32 i;
|
||||
u64 x = ((key & 0xFFFF) << 32) + serial;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
x >>= 1;
|
||||
x += (u64)(_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// "MIKRON" = O N M I K R
|
||||
// Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||
// Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||
// Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||
//~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||
|
||||
// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||
// The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||
// The rest is encrypted by XORing it with the subsequent keystream.
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int hitag2_reset(void) {
|
||||
tag.state = TAG_STATE_RESET;
|
||||
tag.crypto_active = 0;
|
||||
@@ -81,13 +173,48 @@ static int hitag2_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv) {
|
||||
uint64_t key = ((uint64_t)tag->sectors[2][2]) |
|
||||
((uint64_t)tag->sectors[2][3] << 8) |
|
||||
((uint64_t)tag->sectors[1][0] << 16) |
|
||||
((uint64_t)tag->sectors[1][1] << 24) |
|
||||
((uint64_t)tag->sectors[1][2] << 32) |
|
||||
((uint64_t)tag->sectors[1][3] << 40);
|
||||
uint32_t uid = ((uint32_t)tag->sectors[0][0]) |
|
||||
((uint32_t)tag->sectors[0][1] << 8) |
|
||||
((uint32_t)tag->sectors[0][2] << 16) |
|
||||
((uint32_t)tag->sectors[0][3] << 24);
|
||||
uint32_t iv_ = (((uint32_t)(iv[0]))) |
|
||||
(((uint32_t)(iv[1])) << 8) |
|
||||
(((uint32_t)(iv[2])) << 16) |
|
||||
(((uint32_t)(iv[3])) << 24);
|
||||
tag->cs = _hitag2_init(rev64(key), rev32(uid), rev32(iv_));
|
||||
}
|
||||
|
||||
static int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is) {
|
||||
uint8_t authenticator_should[4];
|
||||
authenticator_should[0] = ~_hitag2_byte(cs);
|
||||
authenticator_should[1] = ~_hitag2_byte(cs);
|
||||
authenticator_should[2] = ~_hitag2_byte(cs);
|
||||
authenticator_should[3] = ~_hitag2_byte(cs);
|
||||
return (memcmp(authenticator_should, authenticator_is, 4) == 0);
|
||||
}
|
||||
|
||||
static int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, unsigned int bytes, unsigned int bits) {
|
||||
int i;
|
||||
for (i = 0; i < bytes; i++) data[i] ^= _hitag2_byte(cs);
|
||||
for (i = 0; i < bits; i++) data[bytes] ^= _hitag2_round(cs) << (7 - i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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
|
||||
#ifndef T0
|
||||
#define T0 192
|
||||
#endif
|
||||
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
|
||||
#define HITAG_FRAME_LEN 20
|
||||
#define HITAG_T_STOP 36 /* T_EOF should be > 36 */
|
||||
@@ -114,6 +241,7 @@ static int hitag2_init(void) {
|
||||
#define HITAG_T_TAG_CAPTURE_THREE_HALF 41
|
||||
#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57
|
||||
|
||||
|
||||
static void hitag_send_bit(int bit) {
|
||||
LED_A_ON();
|
||||
// Reset clock for the next bit
|
||||
@@ -151,6 +279,7 @@ static void hitag_send_frame(const uint8_t *frame, size_t frame_len) {
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
}
|
||||
|
||||
|
||||
static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen) {
|
||||
uint8_t rx_air[HITAG_FRAME_LEN];
|
||||
|
||||
@@ -269,8 +398,8 @@ static void hitag2_handle_reader_command(uint8_t *rx, const size_t rxlen, uint8_
|
||||
break;
|
||||
}
|
||||
|
||||
// LogTrace(rx, nbytes(rxlen), 0, 0, NULL, false);
|
||||
// LogTrace(tx, nbytes(txlen), 0, 0, NULL, true);
|
||||
// LogTraceHitag(rx,rxlen,0,0,false);
|
||||
// LogTraceHitag(tx,*txlen,0,0,true);
|
||||
|
||||
if (tag.crypto_active) {
|
||||
hitag2_cipher_transcrypt(&(tag.cs), tx, *txlen / 8, *txlen % 8);
|
||||
@@ -290,6 +419,7 @@ static void hitag_reader_send_bit(int bit) {
|
||||
|
||||
// Wait for 4-10 times the carrier period
|
||||
while (AT91C_BASE_TC0->TC_CV < T0 * 6);
|
||||
// SpinDelayUs(8*8);
|
||||
|
||||
// Disable modulation, just activates the field again
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
@@ -305,6 +435,7 @@ static void hitag_reader_send_bit(int bit) {
|
||||
LED_A_OFF();
|
||||
}
|
||||
|
||||
|
||||
static void hitag_reader_send_frame(const uint8_t *frame, size_t frame_len) {
|
||||
// Send the content of the frame
|
||||
for (size_t i = 0; i < frame_len; i++) {
|
||||
@@ -474,8 +605,8 @@ static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *
|
||||
if (!bCrypto) {
|
||||
uint64_t ui64key = key[0] | ((uint64_t)key[1]) << 8 | ((uint64_t)key[2]) << 16 | ((uint64_t)key[3]) << 24 | ((uint64_t)key[4]) << 32 | ((uint64_t)key[5]) << 40;
|
||||
uint32_t ui32uid = rx[0] | ((uint32_t)rx[1]) << 8 | ((uint32_t)rx[2]) << 16 | ((uint32_t)rx[3]) << 24;
|
||||
Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t)((REV64(ui64key)) >> 32), (uint32_t)((REV64(ui64key)) & 0xffffffff), REV32(ui32uid));
|
||||
cipher_state = _hitag2_init(REV64(ui64key), REV32(ui32uid), 0);
|
||||
Dbprintf("hitag2_crypto: key=0x%x%x uid=0x%x", (uint32_t)((rev64(ui64key)) >> 32), (uint32_t)((rev64(ui64key)) & 0xffffffff), rev32(ui32uid));
|
||||
cipher_state = _hitag2_init(rev64(ui64key), rev32(ui32uid), 0);
|
||||
memset(tx, 0x00, 4);
|
||||
memset(tx + 4, 0xff, 4);
|
||||
hitag2_cipher_transcrypt(&cipher_state, tx + 4, 4, 0);
|
||||
@@ -670,10 +801,7 @@ static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t
|
||||
return true;
|
||||
}
|
||||
|
||||
void SniffHitag(uint32_t type) {
|
||||
|
||||
StopTicks();
|
||||
|
||||
void SnoopHitag(uint32_t type) {
|
||||
int frame_count;
|
||||
int response;
|
||||
int overflow;
|
||||
@@ -686,8 +814,12 @@ void SniffHitag(uint32_t type) {
|
||||
size_t rxlen = 0;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
BigBuf_Clear_ext(false);
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
@@ -697,18 +829,19 @@ void SniffHitag(uint32_t type) {
|
||||
auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
DbpString("Starting Hitag2 sniffing");
|
||||
DbpString("Starting Hitag2 snoop");
|
||||
LED_D_ON();
|
||||
|
||||
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
|
||||
// and analog mux selection.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95);
|
||||
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;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
|
||||
// Disable modulation, we are going to eavesdrop, not modulate ;)
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
@@ -720,16 +853,14 @@ void SniffHitag(uint32_t type) {
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// Capture mode, defaul 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_BOTH | AT91C_TC_ABETRG | AT91C_TC_LDRA_BOTH;
|
||||
uint32_t t1_channel_mode = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_BOTH | AT91C_TC_ABETRG | AT91C_TC_LDRA_BOTH;
|
||||
AT91C_BASE_TC1->TC_CMR = t1_channel_mode;
|
||||
|
||||
// Enable and reset counter
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC1->TC_CV > 0) {}; // wait until TC0 returned to zero
|
||||
|
||||
// Reset the received frame, frame count and timing info
|
||||
memset(rx, 0x00, sizeof(rx));
|
||||
frame_count = 0;
|
||||
@@ -840,7 +971,10 @@ void SniffHitag(uint32_t type) {
|
||||
// Check if frame was captured
|
||||
if (rxlen > 0) {
|
||||
frame_count++;
|
||||
LogTrace(rx, nbytes(rxlen), response, 0, NULL, reader_frame);
|
||||
if (!LogTraceHitag(rx, rxlen, response, 0, reader_frame)) {
|
||||
DbpString("Trace full");
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if we recognize a valid authentication attempt
|
||||
if (nbytes(rxlen) == 8) {
|
||||
@@ -871,46 +1005,49 @@ void SniffHitag(uint32_t type) {
|
||||
// Reset the timer to restart while-loop that receives frames
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||
}
|
||||
LEDsoff();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
LED_D_OFF();
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// release allocated memory from BigBuff.
|
||||
BigBuf_free();
|
||||
StartTicks();
|
||||
|
||||
DbpString("Hitag2 sniffing end, use `lf hitag list` for annotations");
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LED_A_OFF();
|
||||
set_tracing(false);
|
||||
// Dbprintf("frame received: %d",frame_count);
|
||||
// Dbprintf("Authentication Attempts: %d",(auth_table_len/8));
|
||||
// DbpString("All done");
|
||||
}
|
||||
|
||||
void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||
|
||||
StopTicks();
|
||||
|
||||
int frame_count = 0, response = 0, overflow = 0;
|
||||
int frame_count;
|
||||
int response;
|
||||
int overflow;
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen = 0;
|
||||
uint8_t tx[HITAG_FRAME_LEN];
|
||||
size_t txlen = 0;
|
||||
bool bQuitTraceFull = false;
|
||||
bQuiet = false;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
BigBuf_free();
|
||||
BigBuf_Clear_ext(false);
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
auth_table_len = 0;
|
||||
auth_table_pos = 0;
|
||||
uint8_t *auth_table = BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
uint8_t *auth_table;
|
||||
|
||||
auth_table = (uint8_t *)BigBuf_malloc(AUTH_TABLE_LENGTH);
|
||||
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
|
||||
|
||||
// Reset the received frame, frame count and timing info
|
||||
memset(rx, 0x00, sizeof(rx));
|
||||
|
||||
DbpString("Starting Hitag2 simulation");
|
||||
|
||||
LED_D_ON();
|
||||
hitag2_init();
|
||||
|
||||
@@ -931,40 +1068,40 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||
// Set up simulator mode, frequency divisor which will drive the FPGA
|
||||
// and analog mux selection.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
SpinDelay(50);
|
||||
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;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
|
||||
// Disable modulation at default, which means release resistance
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
// Enable Peripheral Clock for
|
||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
// 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_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
|
||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// 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;
|
||||
// Reset the received frame, frame count and timing info
|
||||
memset(rx, 0x00, sizeof(rx));
|
||||
frame_count = 0;
|
||||
response = 0;
|
||||
overflow = 0;
|
||||
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC1->TC_CV > 0); // wait until TC0 returned to zero
|
||||
// Enable and reset counter
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
while (!BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||
// Watchdog hit
|
||||
@@ -1007,7 +1144,16 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||
// Check if frame was captured
|
||||
if (rxlen > 4) {
|
||||
frame_count++;
|
||||
LogTrace(rx, nbytes(rxlen), response, response, NULL, true);
|
||||
if (!bQuiet) {
|
||||
if (!LogTraceHitag(rx, rxlen, response, 0, true)) {
|
||||
DbpString("Trace full");
|
||||
if (bQuitTraceFull) {
|
||||
break;
|
||||
} else {
|
||||
bQuiet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Disable timer 1 with external trigger to avoid triggers during our own modulation
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
@@ -1024,8 +1170,19 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||
|
||||
// Send and store the tag answer (if there is any)
|
||||
if (txlen) {
|
||||
// Transmit the tag frame
|
||||
hitag_send_frame(tx, txlen);
|
||||
LogTrace(tx, nbytes(txlen), 0, 0, NULL, false);
|
||||
// Store the frame in the trace
|
||||
if (!bQuiet) {
|
||||
if (!LogTraceHitag(tx, txlen, 0, 0, false)) {
|
||||
DbpString("Trace full");
|
||||
if (bQuitTraceFull) {
|
||||
break;
|
||||
} else {
|
||||
bQuiet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the received frame and response timing info
|
||||
@@ -1043,25 +1200,17 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||
// Reset the timer to restart while-loop that receives frames
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_SWTRG;
|
||||
}
|
||||
|
||||
LEDsoff();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
LED_B_OFF();
|
||||
LED_D_OFF();
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// release allocated memory from BigBuff.
|
||||
BigBuf_free();
|
||||
|
||||
StartTicks();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
DbpString("Sim Stopped");
|
||||
set_tracing(false);
|
||||
}
|
||||
|
||||
void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
|
||||
StopTicks();
|
||||
|
||||
int frame_count = 0;
|
||||
int response = 0;
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
@@ -1084,6 +1233,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
Dbprintf("List identifier in password mode");
|
||||
memcpy(password, htd->pwd.password, 4);
|
||||
blocknr = 0;
|
||||
bQuiet = false;
|
||||
bPwd = false;
|
||||
break;
|
||||
}
|
||||
@@ -1091,6 +1241,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
DbpString("Authenticating using nr,ar pair:");
|
||||
memcpy(NrAr, htd->auth.NrAr, 8);
|
||||
Dbhexdump(8, NrAr, false);
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
break;
|
||||
@@ -1100,6 +1251,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
memcpy(key, htd->crypto.key, 6); //HACK; 4 or 6?? I read both in the code.
|
||||
Dbhexdump(6, key, false);
|
||||
blocknr = 0;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
break;
|
||||
@@ -1108,11 +1260,13 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
Dbprintf("Testing %d authentication attempts", (auth_table_len / 8));
|
||||
auth_table_pos = 0;
|
||||
memcpy(NrAr, auth_table, 8);
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
break;
|
||||
}
|
||||
case RHT2F_UID_ONLY: {
|
||||
blocknr = 0;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
break;
|
||||
@@ -1120,48 +1274,45 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
default: {
|
||||
Dbprintf("Error, unknown function: %d", htf);
|
||||
set_tracing(false);
|
||||
StartTicks();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
BigBuf_free();
|
||||
BigBuf_free();
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
|
||||
LED_D_ON();
|
||||
hitag2_init();
|
||||
|
||||
// Configure output and enable 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;
|
||||
|
||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
|
||||
// Configure output and enable 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;
|
||||
// RELAY_OFF();
|
||||
|
||||
// Disable modulation at default, which means enable the field
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
// Enable Peripheral Clock for
|
||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelay(30);
|
||||
|
||||
// PIO_A - BSR
|
||||
// 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 tag frames
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
|
||||
// TC1: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// external trigger rising edge, load RA on falling edge of TIOA.
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING;
|
||||
|
||||
@@ -1169,36 +1320,36 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
// synchronized startup procedure
|
||||
while (AT91C_BASE_TC0->TC_CV > 0) {}; // wait until TC0 returned to zero
|
||||
|
||||
// Tag specific configuration settings (sof, timings, etc.)
|
||||
if (htf < 10) {
|
||||
// hitagS settings
|
||||
reset_sof = 1;
|
||||
t_wait = 200;
|
||||
// DbpString("Configured for hitagS reader");
|
||||
} else if (htf < 20) {
|
||||
// hitag1 settings
|
||||
reset_sof = 1;
|
||||
t_wait = 200;
|
||||
// DbpString("Configured for hitag1 reader");
|
||||
} else if (htf < 30) {
|
||||
// hitag2 settings
|
||||
reset_sof = 4;
|
||||
t_wait = HITAG_T_WAIT_2;
|
||||
// DbpString("Configured for hitag2 reader");
|
||||
} else {
|
||||
Dbprintf("Error, unknown hitag reader type: %d", htf);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
uint8_t attempt_count = 0;
|
||||
|
||||
while (!bStop && !BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||
|
||||
while (!bStop && !BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||
|
||||
WDT_HIT();
|
||||
|
||||
// Check if frame was captured and store it
|
||||
if (rxlen > 0) {
|
||||
frame_count++;
|
||||
LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
|
||||
LogTraceHitag(rx, rxlen, response, 0, false);
|
||||
}
|
||||
|
||||
// By default reset the transmission buffer
|
||||
@@ -1225,7 +1376,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
attempt_count++; //attempt 3 times to get uid then quit
|
||||
if (!bStop && attempt_count == 3)
|
||||
bStop = true;
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -1254,7 +1405,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
// Add transmitted frame to total count
|
||||
if (txlen > 0) {
|
||||
frame_count++;
|
||||
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
|
||||
LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true);
|
||||
}
|
||||
|
||||
// Reset values for receiving frames
|
||||
@@ -1323,18 +1474,13 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
out:
|
||||
LEDsoff();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// release allocated memory from BigBuff.
|
||||
BigBuf_free();
|
||||
StartTicks();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
|
||||
if (bSuccessful)
|
||||
cmd_send(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48);
|
||||
@@ -1343,10 +1489,8 @@ out:
|
||||
}
|
||||
|
||||
void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
|
||||
StopTicks();
|
||||
|
||||
int frame_count = 0, response = 0;
|
||||
int frame_count;
|
||||
int response;
|
||||
uint8_t rx[HITAG_FRAME_LEN];
|
||||
size_t rxlen = 0;
|
||||
uint8_t txbuf[HITAG_FRAME_LEN];
|
||||
@@ -1358,13 +1502,17 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
int tag_sof;
|
||||
int t_wait = HITAG_T_WAIT_MAX;
|
||||
bool bStop;
|
||||
bool bQuitTraceFull = false;
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
|
||||
// Clean up trace and prepare it for storing frames
|
||||
set_tracing(true);
|
||||
clear_trace();
|
||||
|
||||
// Reset the return status
|
||||
bSuccessful = false;
|
||||
// DbpString("Starting Hitag reader family");
|
||||
|
||||
// Check configuration
|
||||
switch (htf) {
|
||||
@@ -1374,14 +1522,15 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
memcpy(writedata, htd->crypto.data, 4);
|
||||
Dbhexdump(6, key, false);
|
||||
blocknr = page;
|
||||
bQuiet = false;
|
||||
bCrypto = false;
|
||||
bAuthenticating = false;
|
||||
bQuitTraceFull = true;
|
||||
writestate = WRITE_STATE_START;
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
Dbprintf("Error, unknown function: %d", htf);
|
||||
StartTicks();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -1391,45 +1540,44 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
hitag2_init();
|
||||
|
||||
// Configure output and enable 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;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
|
||||
AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
|
||||
|
||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||
|
||||
// Set Frequency divisor which will drive the FPGA and analog mux selection
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
RELAY_OFF();
|
||||
|
||||
// Disable modulation at default, which means enable the field
|
||||
LOW(GPIO_SSC_DOUT);
|
||||
|
||||
// Enable Peripheral Clock for
|
||||
// TIMER_CLOCK0, used to measure exact timing before answering
|
||||
// TIMER_CLOCK1, used to capture edges of the tag frames
|
||||
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelay(30);
|
||||
|
||||
// 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 tag frames
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
|
||||
|
||||
// Disable timer during configuration
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
// TC0: Capture mode, default timer source = MCK/2 (TIMER_CLOCK1), no triggers
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
|
||||
// TC1: Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger,
|
||||
// external trigger rising edge, load RA on falling edge of TIOA.
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK
|
||||
| AT91C_TC_ETRGEDG_FALLING
|
||||
| AT91C_TC_ABETRG
|
||||
| AT91C_TC_LDRA_FALLING;
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV1_CLOCK | AT91C_TC_ETRGEDG_FALLING | AT91C_TC_ABETRG | AT91C_TC_LDRA_FALLING;
|
||||
|
||||
// Enable and reset counters
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
while (AT91C_BASE_TC0->TC_CV > 0) {};
|
||||
|
||||
// Reset the received frame, frame count and timing info
|
||||
frame_count = 0;
|
||||
response = 0;
|
||||
lastbit = 1;
|
||||
bStop = false;
|
||||
|
||||
@@ -1438,27 +1586,38 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
// hitagS settings
|
||||
reset_sof = 1;
|
||||
t_wait = 200;
|
||||
// DbpString("Configured for hitagS reader");
|
||||
} else if (htf < 20) {
|
||||
// hitag1 settings
|
||||
reset_sof = 1;
|
||||
t_wait = 200;
|
||||
// DbpString("Configured for hitag1 reader");
|
||||
} else if (htf < 30) {
|
||||
// hitag2 settings
|
||||
reset_sof = 4;
|
||||
t_wait = HITAG_T_WAIT_2;
|
||||
// DbpString("Configured for hitag2 reader");
|
||||
} else {
|
||||
Dbprintf("Error, unknown hitag reader type: %d", htf);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!bStop && !BUTTON_PRESS() && !usb_poll_validate_length()) {
|
||||
|
||||
while (!bStop && !BUTTON_PRESS()) {
|
||||
// Watchdog hit
|
||||
WDT_HIT();
|
||||
|
||||
// Check if frame was captured and store it
|
||||
if (rxlen > 0) {
|
||||
frame_count++;
|
||||
LogTrace(rx, nbytes(rxlen), response, response, NULL, false);
|
||||
if (!bQuiet) {
|
||||
if (!LogTraceHitag(rx, rxlen, response, 0, false)) {
|
||||
DbpString("Trace full");
|
||||
if (bQuitTraceFull) {
|
||||
break;
|
||||
} else {
|
||||
bQuiet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// By default reset the transmission buffer
|
||||
@@ -1484,7 +1643,9 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
// falling edge occured halfway the period. with respect to this falling edge,
|
||||
// we need to wait (T_Wait2 + half_tag_period) when the last was a 'one'.
|
||||
// All timer values are in terms of T0 units
|
||||
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit))) {};
|
||||
while (AT91C_BASE_TC0->TC_CV < T0 * (t_wait + (HITAG_T_TAG_HALF_PERIOD * lastbit)));
|
||||
|
||||
// Dbprintf("DEBUG: Sending reader frame");
|
||||
|
||||
// Transmit the reader frame
|
||||
hitag_reader_send_frame(tx, txlen);
|
||||
@@ -1495,7 +1656,16 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
// Add transmitted frame to total count
|
||||
if (txlen > 0) {
|
||||
frame_count++;
|
||||
LogTrace(tx, nbytes(txlen), HITAG_T_WAIT_2, HITAG_T_WAIT_2, NULL, true);
|
||||
if (!bQuiet) {
|
||||
// Store the frame in the trace
|
||||
if (!LogTraceHitag(tx, txlen, HITAG_T_WAIT_2, 0, true)) {
|
||||
if (bQuitTraceFull) {
|
||||
break;
|
||||
} else {
|
||||
bQuiet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset values for receiving frames
|
||||
@@ -1505,6 +1675,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
bSkip = true;
|
||||
tag_sof = reset_sof;
|
||||
response = 0;
|
||||
// Dbprintf("DEBUG: Waiting to receive frame");
|
||||
uint32_t errorCount = 0;
|
||||
|
||||
// Receive frame, watch for at most T0*EOF periods
|
||||
@@ -1577,7 +1748,6 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
}
|
||||
// if we saw over 100 wierd values break it probably isn't hitag...
|
||||
if (errorCount > 100) break;
|
||||
|
||||
// We can break this loop if we received the last bit from a frame
|
||||
if (AT91C_BASE_TC1->TC_CV > T0 * HITAG_T_EOF) {
|
||||
if (rxlen > 0) break;
|
||||
@@ -1590,15 +1760,14 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||
while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX));
|
||||
}
|
||||
}
|
||||
// Dbprintf("DEBUG: Done waiting for frame");
|
||||
|
||||
LEDsoff();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
set_tracing(false);
|
||||
|
||||
LED_B_OFF();
|
||||
LED_D_OFF();
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
|
||||
StartTicks();
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
// Dbprintf("frame received: %d",frame_count);
|
||||
// DbpString("All done");
|
||||
cmd_send(CMD_ACK, bSuccessful, 0, 0, (uint8_t *)tag.sectors, 48);
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// (c) 2012 Roel Verdult
|
||||
//
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hitag2 type prototyping
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _HITAG2_H_
|
||||
#define _HITAG2_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "hitag.h"
|
||||
|
||||
void SniffHitag(uint32_t type);
|
||||
void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data);
|
||||
void ReaderHitag(hitag_function htf, hitag_data *htd);
|
||||
void WriterHitag(hitag_function htf, hitag_data *htd, int page);
|
||||
|
||||
#endif
|
||||
@@ -1,116 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Hitag2 Crypto
|
||||
//
|
||||
// (c) 2009 Henryk Plötz <henryk@ploetzli.ch>
|
||||
// (c) 2012 Roel Verdult
|
||||
// (c) 2019 Iceman
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "hitag2_crypto.h"
|
||||
|
||||
/* 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.
|
||||
// For educational purposes only.
|
||||
// No warranties or guarantees of any kind.
|
||||
// This code is released into the public domain by its author.
|
||||
|
||||
// Single bit Hitag2 functions:
|
||||
#ifndef i4
|
||||
#define i4(x,a,b,c,d) ((uint32_t)((((x)>>(a))&1)+(((x)>>(b))&1)*2+(((x)>>(c))&1)*4+(((x)>>(d))&1)*8))
|
||||
#endif
|
||||
|
||||
static const uint32_t ht2_f4a = 0x2C79; // 0010 1100 0111 1001
|
||||
static const uint32_t ht2_f4b = 0x6671; // 0110 0110 0111 0001
|
||||
static const uint32_t ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
|
||||
uint32_t _f20(const uint64_t x) {
|
||||
uint32_t 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;
|
||||
}
|
||||
|
||||
uint64_t _hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t IV) {
|
||||
uint32_t i;
|
||||
uint64_t x = ((key & 0xFFFF) << 32) + serial;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
x >>= 1;
|
||||
x += (uint64_t)(_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t _hitag2_round(uint64_t *state) {
|
||||
uint64_t 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);
|
||||
}
|
||||
|
||||
// "MIKRON" = O N M I K R
|
||||
// Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
|
||||
// Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
|
||||
// Random = 65 6E 45 72 - Random IV, transmitted in clear
|
||||
//~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
|
||||
|
||||
// The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
|
||||
// The inverse of the first 4 bytes is sent to the tag to authenticate.
|
||||
// The rest is encrypted by XORing it with the subsequent keystream.
|
||||
|
||||
uint32_t _hitag2_byte(uint64_t *x) {
|
||||
uint32_t i, c;
|
||||
for (i = 0, c = 0; i < 8; i++) {
|
||||
c += (uint32_t) _hitag2_round(x) << (i ^ 7);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv) {
|
||||
uint64_t key = ((uint64_t)tag->sectors[2][2]) |
|
||||
((uint64_t)tag->sectors[2][3] << 8) |
|
||||
((uint64_t)tag->sectors[1][0] << 16) |
|
||||
((uint64_t)tag->sectors[1][1] << 24) |
|
||||
((uint64_t)tag->sectors[1][2] << 32) |
|
||||
((uint64_t)tag->sectors[1][3] << 40);
|
||||
uint32_t uid = ((uint32_t)tag->sectors[0][0]) |
|
||||
((uint32_t)tag->sectors[0][1] << 8) |
|
||||
((uint32_t)tag->sectors[0][2] << 16) |
|
||||
((uint32_t)tag->sectors[0][3] << 24);
|
||||
uint32_t iv_ = (((uint32_t)(iv[0]))) |
|
||||
(((uint32_t)(iv[1])) << 8) |
|
||||
(((uint32_t)(iv[2])) << 16) |
|
||||
(((uint32_t)(iv[3])) << 24);
|
||||
tag->cs = _hitag2_init(REV64(key), REV32(uid), REV32(iv_));
|
||||
}
|
||||
|
||||
int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is) {
|
||||
uint8_t authenticator_should[4];
|
||||
authenticator_should[0] = ~_hitag2_byte(cs);
|
||||
authenticator_should[1] = ~_hitag2_byte(cs);
|
||||
authenticator_should[2] = ~_hitag2_byte(cs);
|
||||
authenticator_should[3] = ~_hitag2_byte(cs);
|
||||
return (memcmp(authenticator_should, authenticator_is, 4) == 0);
|
||||
}
|
||||
|
||||
int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) {
|
||||
int i;
|
||||
for (i = 0; i < bytes; i++) data[i] ^= _hitag2_byte(cs);
|
||||
for (i = 0; i < bits; i++) data[bytes] ^= _hitag2_round(cs) << (7 - i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
#ifndef __HITAG2_CRYPTO_H
|
||||
#define __HITAG2_CRYPTO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "string.h"
|
||||
#include "util.h"
|
||||
|
||||
struct hitag2_tag {
|
||||
uint32_t uid;
|
||||
enum {
|
||||
TAG_STATE_RESET = 0x01, // Just powered up, awaiting GetSnr
|
||||
TAG_STATE_ACTIVATING = 0x02, // In activation phase (password mode), sent UID, awaiting reader password
|
||||
TAG_STATE_ACTIVATED = 0x03, // Activation complete, awaiting read/write commands
|
||||
TAG_STATE_WRITING = 0x04, // In write command, awaiting sector contents to be written
|
||||
} state;
|
||||
uint16_t active_sector;
|
||||
uint8_t crypto_active;
|
||||
uint64_t cs;
|
||||
uint8_t sectors[12][4];
|
||||
};
|
||||
|
||||
extern uint32_t _f20(const uint64_t x);
|
||||
extern uint64_t _hitag2_init(const uint64_t key, const uint32_t serial, const uint32_t IV);
|
||||
extern uint64_t _hitag2_round(uint64_t *state);
|
||||
extern uint32_t _hitag2_byte(uint64_t *x);
|
||||
extern void hitag2_cipher_reset(struct hitag2_tag *tag, const uint8_t *iv);
|
||||
extern int hitag2_cipher_authenticate(uint64_t *cs, const uint8_t *authenticator_is);
|
||||
extern int hitag2_cipher_transcrypt(uint64_t *cs, uint8_t *data, uint16_t bytes, uint16_t bits) ;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
766
armsrc/hitagS.c
766
armsrc/hitagS.c
File diff suppressed because it is too large
Load Diff
@@ -1,31 +0,0 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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.
|
||||
//-----------------------------------------------------------------------------
|
||||
// HitagS emulation (preliminary test version)
|
||||
//
|
||||
// (c) 2016 Oguzhan Cicek, Hendrik Schwartke, Ralf Spenneberg
|
||||
// <info@os-s.de>
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _HITAGS_H_
|
||||
#define _HITAGS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include "hitag2_crypto.h"
|
||||
#include "hitag.h"
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
#include "BigBuf.h"
|
||||
|
||||
void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data);
|
||||
void ReadHitagS(hitag_function htf, hitag_data *htd);
|
||||
void WritePageHitagS(hitag_function htf, hitag_data *htd, int page);
|
||||
void check_challenges(bool file_given, uint8_t *data);
|
||||
|
||||
#endif
|
||||
@@ -18,7 +18,7 @@
|
||||
//
|
||||
// FIX:
|
||||
// ====
|
||||
// We still have sometimes a demodulation error when sniffing iClass communication.
|
||||
// We still have sometimes a demodulation error when snooping iClass communication.
|
||||
// The resulting trace of a read-block-03 command may look something like this:
|
||||
//
|
||||
// + 22279: : 0c 03 e8 01
|
||||
@@ -2456,4 +2456,4 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
|
||||
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
switch_off();
|
||||
}
|
||||
}
|
||||
@@ -2781,7 +2781,7 @@ void DetectNACKbug() {
|
||||
bool received_nack;
|
||||
|
||||
// Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
|
||||
int32_t sync_cycles = PRNG_SEQUENCE_LENGTH;
|
||||
uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH;
|
||||
|
||||
BigBuf_free();
|
||||
BigBuf_Clear_ext(false);
|
||||
|
||||
@@ -1413,7 +1413,7 @@ static void iso1444b_setup_sniff(void) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
BigBuf_free();
|
||||
BigBuf_Clear_ext(false);
|
||||
clear_trace();
|
||||
clear_trace();//setup snoop
|
||||
set_tracing(true);
|
||||
|
||||
// Initialize Demod and Uart structs
|
||||
@@ -1570,7 +1570,6 @@ void iso14b_set_trigger(bool enable) {
|
||||
void SendRawCommand14443B_Ex(UsbCommand *c) {
|
||||
iso14b_command_t param = c->arg[0];
|
||||
size_t len = c->arg[1] & 0xffff;
|
||||
uint32_t timeout = c->arg[2];
|
||||
uint8_t *cmd = c->d.asBytes;
|
||||
uint8_t status = 0;
|
||||
uint32_t sendlen = sizeof(iso14b_card_select_t);
|
||||
@@ -1587,9 +1586,6 @@ void SendRawCommand14443B_Ex(UsbCommand *c) {
|
||||
clear_trace();
|
||||
}
|
||||
|
||||
if ((param & ISO14B_SET_TIMEOUT))
|
||||
iso14b_set_timeout(timeout);
|
||||
|
||||
set_tracing(true);
|
||||
|
||||
if ((param & ISO14B_SELECT_STD) == ISO14B_SELECT_STD) {
|
||||
@@ -1638,4 +1634,4 @@ out:
|
||||
switch_off(); // disconnect raw
|
||||
SpinDelay(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,8 +621,8 @@ void Iso15693InitReader(void) {
|
||||
|
||||
// Encode (into the ToSend buffers) an identify request, which is the first
|
||||
// thing that you must send to a tag to get a response.
|
||||
// It expects "out" to be at least CMD_ID_RESP large
|
||||
static void BuildIdentifyRequest(uint8_t *out) {
|
||||
|
||||
uint8_t cmd[CMD_ID_RESP] = {0, ISO15_CMD_INVENTORY, 0, 0, 0};
|
||||
// flags
|
||||
cmd[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
|
||||
@@ -665,7 +665,6 @@ static void BuildReadBlockRequest(uint8_t **out, uint8_t *uid, uint8_t blockNumb
|
||||
*/
|
||||
|
||||
// Now the VICC>VCD responses when we are simulating a tag
|
||||
// It expects "out" to be at least CMD_INV_RESP large
|
||||
static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) {
|
||||
|
||||
uint8_t cmd[CMD_INV_RESP] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
@@ -687,7 +686,7 @@ static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) {
|
||||
// CRC
|
||||
AddCrc(cmd, 10);
|
||||
CodeIso15693AsReader(cmd, CMD_INV_RESP);
|
||||
memcpy(out, cmd, CMD_INV_RESP);
|
||||
memcpy(out, cmd, CMD_ID_RESP);
|
||||
}
|
||||
|
||||
// Universal Method for sending to and recv bytes from a tag
|
||||
@@ -740,50 +739,50 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) {
|
||||
|
||||
if (len > 3) {
|
||||
if (d[0] & (1 << 3))
|
||||
strncat(status, "ProtExt ", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "ProtExt ", DBD15STATLEN);
|
||||
if (d[0] & 1) {
|
||||
// error
|
||||
strncat(status, "Error ", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "Error ", DBD15STATLEN);
|
||||
switch (d[1]) {
|
||||
case 0x01:
|
||||
strncat(status, "01: not supported", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "01: not supported", DBD15STATLEN);
|
||||
break;
|
||||
case 0x02:
|
||||
strncat(status, "02: not recognized", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "02: not recognized", DBD15STATLEN);
|
||||
break;
|
||||
case 0x03:
|
||||
strncat(status, "03: opt not supported", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "03: opt not supported", DBD15STATLEN);
|
||||
break;
|
||||
case 0x0f:
|
||||
strncat(status, "0F: no info", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "0F: no info", DBD15STATLEN);
|
||||
break;
|
||||
case 0x10:
|
||||
strncat(status, "10: dont exist", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "10: dont exist", DBD15STATLEN);
|
||||
break;
|
||||
case 0x11:
|
||||
strncat(status, "11: lock again", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "11: lock again", DBD15STATLEN);
|
||||
break;
|
||||
case 0x12:
|
||||
strncat(status, "12: locked", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "12: locked", DBD15STATLEN);
|
||||
break;
|
||||
case 0x13:
|
||||
strncat(status, "13: program error", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "13: program error", DBD15STATLEN);
|
||||
break;
|
||||
case 0x14:
|
||||
strncat(status, "14: lock error", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "14: lock error", DBD15STATLEN);
|
||||
break;
|
||||
default:
|
||||
strncat(status, "unknown error", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "unknown error", DBD15STATLEN);
|
||||
}
|
||||
strncat(status, " ", DBD15STATLEN - strlen(status));
|
||||
strncat(status, " ", DBD15STATLEN);
|
||||
} else {
|
||||
strncat(status, "No error ", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "No error ", DBD15STATLEN);
|
||||
}
|
||||
|
||||
if (CheckCrc(d, len))
|
||||
strncat(status, "[+] crc OK", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "[+] crc OK", DBD15STATLEN);
|
||||
else
|
||||
strncat(status, "[!] crc fail", DBD15STATLEN - strlen(status));
|
||||
strncat(status, "[!] crc fail", DBD15STATLEN);
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("%s", status);
|
||||
}
|
||||
@@ -1000,4 +999,4 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||
} else {
|
||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,13 @@
|
||||
#include "common.h"
|
||||
#include "flashmem.h" // persistence on mem
|
||||
|
||||
#ifndef SHORT_COIL
|
||||
# define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#endif
|
||||
#ifndef OPEN_COIL
|
||||
# define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
#endif
|
||||
|
||||
//#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (15fc)
|
||||
//#define WRITE_GAP 8*8 // 17*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (10fc)
|
||||
//#define WRITE_0 15*8 // 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (24fc)
|
||||
@@ -310,7 +317,7 @@ void ReadTItag(void) {
|
||||
// expected for either the low or high frequency
|
||||
if ((samples > (sampleslo - threshold)) && (samples < (sampleslo + threshold))) {
|
||||
// low frequency represents a 1
|
||||
shift3 |= (1u << 31);
|
||||
shift3 |= (1 << 31);
|
||||
} else if ((samples > (sampleshi - threshold)) && (samples < (sampleshi + threshold))) {
|
||||
// high frequency represents a 0
|
||||
} else {
|
||||
@@ -474,7 +481,7 @@ void AcquireTiType(void) {
|
||||
// unpack buffer
|
||||
for (i = TIBUFLEN - 1; i >= 0; i--) {
|
||||
for (j = 0; j < 32; j++) {
|
||||
if (buf[i] & (1u << j)) {
|
||||
if (buf[i] & (1 << j)) {
|
||||
dest[--n] = 1;
|
||||
} else {
|
||||
dest[--n] = -1;
|
||||
@@ -723,6 +730,8 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
|
||||
uint8_t halfFC = fc >> 1;
|
||||
uint8_t wavesPerClock = clock / fc;
|
||||
uint8_t mod = clock % fc; //modifier
|
||||
uint8_t modAdj = fc / mod; //how often to apply modifier
|
||||
bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk = true;
|
||||
|
||||
// loop through clock - step field clock
|
||||
for (uint8_t idx = 0; idx < wavesPerClock; idx++) {
|
||||
@@ -731,24 +740,20 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) {
|
||||
memset(dest + (*n) + (fc - halfFC), 1, halfFC);
|
||||
*n += fc;
|
||||
}
|
||||
if (mod > 0) {
|
||||
uint8_t modAdj = fc / mod; //how often to apply modifier
|
||||
bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk = true;
|
||||
(*modCnt)++;
|
||||
if (mod > 0)(*modCnt)++;
|
||||
|
||||
if (modAdjOk) { //fsk2
|
||||
if ((*modCnt % modAdj) == 0) { //if 4th 8 length wave in a rf/50 add extra 8 length wave
|
||||
memset(dest + (*n), 0, fc - halfFC);
|
||||
memset(dest + (*n) + (fc - halfFC), 1, halfFC);
|
||||
*n += fc;
|
||||
}
|
||||
}
|
||||
if (!modAdjOk) { //fsk1
|
||||
memset(dest + (*n), 0, mod - (mod >> 1));
|
||||
memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1);
|
||||
*n += mod;
|
||||
if ((mod > 0) && modAdjOk) { //fsk2
|
||||
if ((*modCnt % modAdj) == 0) { //if 4th 8 length wave in a rf/50 add extra 8 length wave
|
||||
memset(dest + (*n), 0, fc - halfFC);
|
||||
memset(dest + (*n) + (fc - halfFC), 1, halfFC);
|
||||
*n += fc;
|
||||
}
|
||||
}
|
||||
if (mod > 0 && !modAdjOk) { //fsk1
|
||||
memset(dest + (*n), 0, mod - (mod >> 1));
|
||||
memset(dest + (*n) + (mod - (mod >> 1)), 1, mod >> 1);
|
||||
*n += mod;
|
||||
}
|
||||
}
|
||||
|
||||
// prepare a waveform pattern in the buffer based on the ID given then
|
||||
@@ -824,7 +829,7 @@ void CmdHIDsimTAG(uint32_t hi, uint32_t lo, int ledcontrol) {
|
||||
// prepare a waveform pattern in the buffer based on the ID given then
|
||||
// simulate a FSK tag until the button is pressed
|
||||
// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock
|
||||
void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits, int ledcontrol) {
|
||||
void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
|
||||
// free eventually allocated BigBuf memory
|
||||
@@ -833,7 +838,7 @@ void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits, int
|
||||
clear_trace();
|
||||
set_tracing(false);
|
||||
|
||||
int n = 0, i = 0;
|
||||
int ledcontrol = 1, n = 0, i = 0;
|
||||
uint8_t fcHigh = arg1 >> 8;
|
||||
uint8_t fcLow = arg1 & 0xFF;
|
||||
uint16_t modCnt = 0;
|
||||
@@ -901,11 +906,11 @@ static void stAskSimBit(int *n, uint8_t clock) {
|
||||
}
|
||||
|
||||
// args clock, ask/man or askraw, invert, transmission separator
|
||||
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream, int ledcontrol) {
|
||||
void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
set_tracing(false);
|
||||
|
||||
int n = 0, i = 0;
|
||||
int ledcontrol = 1, n = 0, i = 0;
|
||||
uint8_t clk = (arg1 >> 8) & 0xFF;
|
||||
uint8_t encoding = arg1 & 0xFF;
|
||||
uint8_t separator = arg2 & 1;
|
||||
@@ -968,11 +973,11 @@ static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, b
|
||||
}
|
||||
|
||||
// args clock, carrier, invert,
|
||||
void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream, int ledcontrol) {
|
||||
void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) {
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
set_tracing(false);
|
||||
|
||||
int n = 0, i = 0;
|
||||
int ledcontrol = 1, n = 0, i = 0;
|
||||
uint8_t clk = arg1 >> 8;
|
||||
uint8_t carrier = arg1 & 0xFF;
|
||||
uint8_t invert = arg2 & 0xFF;
|
||||
@@ -1061,8 +1066,12 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||
}
|
||||
} else { //if bit 38 is not set then 37 bit format is used
|
||||
bitlen = 37;
|
||||
cardnum = (lo >> 1) & 0x7FFFF;
|
||||
fc = ((hi & 0xF) << 12) | (lo >> 20);
|
||||
fc = 0;
|
||||
cardnum = 0;
|
||||
if (bitlen == 37) {
|
||||
cardnum = (lo >> 1) & 0x7FFFF;
|
||||
fc = ((hi & 0xF) << 12) | (lo >> 20);
|
||||
}
|
||||
}
|
||||
Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
|
||||
hi,
|
||||
@@ -1373,6 +1382,8 @@ void T55xxResetRead(void) {
|
||||
//clear buffer now so it does not interfere with timing later
|
||||
BigBuf_Clear_keep_EM();
|
||||
|
||||
StartTicks();
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
@@ -1405,6 +1416,8 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
|
||||
bool testMode = arg & 0x4;
|
||||
uint32_t i = 0;
|
||||
|
||||
StartTicks();
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
@@ -1478,7 +1491,7 @@ void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
|
||||
// Read one card block in page [page]
|
||||
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||
LED_A_ON();
|
||||
bool PwdMode = arg0 & 0x1;
|
||||
bool PwdMode = arg0 & 0x1;
|
||||
uint8_t Page = (arg0 & 0x2) >> 1;
|
||||
bool brute_mem = arg0 & 0x4;
|
||||
|
||||
@@ -1500,6 +1513,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||
//make sure block is at max 7
|
||||
Block &= 0x7;
|
||||
|
||||
StartTicks();
|
||||
|
||||
// Set up FPGA, 125kHz to power up the tag
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
@@ -1576,23 +1591,26 @@ void T55xx_ChkPwds() {
|
||||
uint32_t candidate = 0;
|
||||
|
||||
#ifdef WITH_FLASH
|
||||
BigBuf_Clear_EM();
|
||||
uint16_t isok = 0;
|
||||
uint8_t counter[2] = {0x00, 0x00};
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter));
|
||||
if (isok != sizeof(counter))
|
||||
goto OUT;
|
||||
bool use_flashmem = true;
|
||||
if (use_flashmem) {
|
||||
BigBuf_Clear_EM();
|
||||
uint16_t isok = 0;
|
||||
uint8_t counter[2] = {0x00, 0x00};
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET, counter, sizeof(counter));
|
||||
if (isok != sizeof(counter))
|
||||
goto OUT;
|
||||
|
||||
pwdCount = counter[1] << 8 | counter[0];
|
||||
pwdCount = counter[1] << 8 | counter[0];
|
||||
|
||||
if (pwdCount == 0 || pwdCount == 0xFFFF)
|
||||
goto OUT;
|
||||
if (pwdCount == 0 && pwdCount == 0xFFFF)
|
||||
goto OUT;
|
||||
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwdCount * 4);
|
||||
if (isok != pwdCount * 4)
|
||||
goto OUT;
|
||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET + 2, pwds, pwdCount * 4);
|
||||
if (isok != pwdCount * 4)
|
||||
goto OUT;
|
||||
|
||||
Dbprintf("[=] Password dictionary count %d ", pwdCount);
|
||||
Dbprintf("[=] Password dictionary count %d ", pwdCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t pwd = 0, curr = 0, prev = 0;
|
||||
@@ -1643,6 +1661,8 @@ void T55xxWakeUp(uint32_t Pwd) {
|
||||
LED_B_ON();
|
||||
uint32_t i = 0;
|
||||
|
||||
StartTicks();
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
// make sure tag is fully powered up...
|
||||
|
||||
@@ -29,7 +29,7 @@ void printConfig() {
|
||||
|
||||
/**
|
||||
* Called from the USB-handler to set the sampling configuration
|
||||
* The sampling config is used for std reading and sniffing.
|
||||
* The sampling config is used for std reading and snooping.
|
||||
*
|
||||
* Other functions may read samples and ignore the sampling config,
|
||||
* such as functions to read the UID from a prox tag or similar.
|
||||
@@ -239,9 +239,9 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
|
||||
if (!silent)
|
||||
printConfig();
|
||||
LFSetupFPGAForADC(config.divisor, activeField);
|
||||
uint32_t ret = DoAcquisition_config(silent, sample_size);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
uint32_t ret = DoAcquisition_config(silent, sample_size);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,15 +250,15 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
|
||||
**/
|
||||
uint32_t SampleLF(bool printCfg, int sample_size) {
|
||||
BigBuf_Clear_ext(false);
|
||||
return ReadLF(true, printCfg, sample_size);
|
||||
return ReadLF(true, printCfg, sample_size);
|
||||
}
|
||||
/**
|
||||
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SniffLF() {
|
||||
uint32_t SnoopLF() {
|
||||
BigBuf_Clear_ext(false);
|
||||
return ReadLF(false, true, 0);
|
||||
return ReadLF(false, true, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,10 +427,12 @@ uint32_t doCotagAcquisitionManchester() {
|
||||
if (sample > COTAG_ONE_THRESHOLD) {
|
||||
prev = curr;
|
||||
curr = 1;
|
||||
} else if (sample < COTAG_ZERO_THRESHOLD) {
|
||||
}
|
||||
else if ( sample < COTAG_ZERO_THRESHOLD) {
|
||||
prev = curr;
|
||||
curr = 0;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
curr = prev;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ void doT55x7Acquisition(size_t sample_size);
|
||||
uint32_t SampleLF(bool silent, int sample_size);
|
||||
|
||||
/**
|
||||
* Initializes the FPGA for sniff-mode (field off), and acquires the samples.
|
||||
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
|
||||
* @return number of bits sampled
|
||||
**/
|
||||
uint32_t SniffLF();
|
||||
uint32_t SnoopLF();
|
||||
|
||||
// adds sample size to default options
|
||||
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after);
|
||||
@@ -67,7 +67,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field);
|
||||
|
||||
/**
|
||||
* Called from the USB-handler to set the sampling configuration
|
||||
* The sampling config is used for std reading and sniffing.
|
||||
* The sampling config is used for std reading and snooping.
|
||||
*
|
||||
* Other functions may read samples and ignore the sampling config,
|
||||
* such as functions to read the UID from a prox tag or similar.
|
||||
|
||||
@@ -1247,7 +1247,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||
|
||||
keyCount = size[1] << 8 | size[0];
|
||||
|
||||
if (keyCount == 0 || keyCount == 0xFFFF)
|
||||
if (keyCount == 0 && keyCount == 0xFFFF)
|
||||
goto OUT;
|
||||
|
||||
datain = BigBuf_malloc(keyCount * 6);
|
||||
@@ -2098,4 +2098,4 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
set_tracing(false);
|
||||
}
|
||||
}
|
||||
@@ -25,4 +25,4 @@
|
||||
#include "crc.h"
|
||||
#include "protocols.h"
|
||||
#include "parity.h"
|
||||
#endif
|
||||
#endif
|
||||
@@ -322,4 +322,4 @@ void RAMFUNC MfSniffSend() {
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK, 2, 0, 0, 0, 0); // 2 == data transfer finished.
|
||||
LED_B_OFF();
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,4 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui
|
||||
void RAMFUNC MfSniffSend(void);
|
||||
void MfSniffEnd(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -518,4 +518,4 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab) {
|
||||
tab[u + 2] = c + tab[u + 1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,4 @@ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p);
|
||||
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab);
|
||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -77,4 +77,4 @@ void __attribute__((section(".startos"))) Vector(void) {
|
||||
|
||||
AppMain();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -24,4 +24,4 @@ char *strcat(char *dest, const char *src);
|
||||
void strreverse(char s[]);
|
||||
void itoa(int n, char s[]);
|
||||
|
||||
#endif /* __STRING_H */
|
||||
#endif /* __STRING_H */
|
||||
@@ -44,4 +44,4 @@ extern void WaitUS(uint16_t us);
|
||||
extern void WaitMS(uint16_t ms);
|
||||
|
||||
extern void StopTicks(void);
|
||||
#endif
|
||||
#endif
|
||||
@@ -17,18 +17,7 @@
|
||||
#include "BigBuf.h"
|
||||
#include "ticks.h"
|
||||
|
||||
// Basic macros
|
||||
#ifndef SHORT_COIL
|
||||
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
|
||||
#endif
|
||||
|
||||
#ifndef OPEN_COIL
|
||||
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
|
||||
#endif
|
||||
|
||||
#ifndef BYTEx
|
||||
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
|
||||
#endif
|
||||
|
||||
#define LED_RED 1
|
||||
#define LED_ORANGE 2
|
||||
@@ -54,34 +43,6 @@
|
||||
# define NTIME(n) for (int _index = 0; _index < n; _index++)
|
||||
#endif
|
||||
|
||||
#ifndef REV8
|
||||
#define REV8(x) ((((x)>>7)&1)+((((x)>>6)&1)<<1)+((((x)>>5)&1)<<2)+((((x)>>4)&1)<<3)+((((x)>>3)&1)<<4)+((((x)>>2)&1)<<5)+((((x)>>1)&1)<<6)+(((x)&1)<<7))
|
||||
#endif
|
||||
|
||||
#ifndef REV16
|
||||
#define REV16(x) (REV8(x) + (REV8 (x >> 8) << 8))
|
||||
#endif
|
||||
|
||||
#ifndef REV32
|
||||
#define REV32(x) (REV16(x) + (REV16(x >> 16) << 16))
|
||||
#endif
|
||||
|
||||
#ifndef REV64
|
||||
#define REV64(x) (REV32(x) + (REV32(x >> 32) << 32))
|
||||
#endif
|
||||
|
||||
#ifndef BIT32
|
||||
#define BIT32(x,n) ((((x)[(n)>>5])>>((n)))&1)
|
||||
#endif
|
||||
|
||||
#ifndef INV32
|
||||
#define INV32(x,i,n) ((x)[(i)>>5]^=((uint32_t)(n))<<((i)&31))
|
||||
#endif
|
||||
|
||||
#ifndef ROTL64
|
||||
#define ROTL64(x, n) ((((uint64_t)(x))<<((n)&63))+(((uint64_t)(x))>>((0-(n))&63)))
|
||||
#endif
|
||||
|
||||
size_t nbytes(size_t nbits);
|
||||
|
||||
extern uint32_t reflect(uint32_t v, int b); // used in crc.c ...
|
||||
|
||||
Reference in New Issue
Block a user