### Fixed
- AC-Mode decoding for HitagS
- Wrong UID at HitagS simulation
-- 'hf 15 sim' now works as expected (piwi)
+- `hf 15 sim` now works as expected (piwi)
### Added
- Support Standard Communication Mode in HITAG S
- Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (Merlok)
- Added `lf paradox clone` to clone a Paradox card
- Added `emv` commmands working for both contactless and smart cards (Merlok)
-- Added 'hf 15 snoop' (piwi)
-
+- Added `hf 15 snoop` (piwi)
+- Added support for standard USB Smartcard Readers (piwi)
+- Added `hf plot` (piwi)
## [v3.1.0][2018-10-10]
#include "mifareutil.h"
#include "pcf7931.h"
#include "i2c.h"
+#include "hfsnoop.h"
+#include "fpgaloader.h"
#ifdef WITH_LCD
#include "LCD.h"
#endif
iClass_Clone(c->arg[0], c->arg[1], c->d.asBytes);
break;
#endif
+
#ifdef WITH_HFSNOOP
case CMD_HF_SNIFFER:
HfSnoop(c->arg[0], c->arg[1]);
break;
+ case CMD_HF_PLOT:
+ HfPlot();
+ break;
#endif
+
#ifdef WITH_SMARTCARD
case CMD_SMART_ATR: {
SmartCardAtr();
break;
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
-
LED_B_ON();
uint8_t *BigBuf = BigBuf_get_addr();
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
#include "mifare.h"
#include "../common/crc32.h"
#include "BigBuf.h"
-#include "fpgaloader.h"
extern const uint8_t OddByteParity[256];
extern int rsamples; // = 0;
void WritePageHitagS(hitag_function htf, hitag_data* htd,int page);
void check_challenges_cmd(bool file_given, byte_t* data, uint64_t tagMode);
-
-
// cmd.h
bool cmd_receive(UsbCommand* cmd);
bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
-/// util.h
-void HfSnoop(int , int);
-
#endif
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
AT91C_BASE_PDC_SSC->PDC_RCR = sample_count; // transfer this many samples
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address
- AT91C_BASE_PDC_SSC->PDC_RNCR = sample_count; // ... with same number of samples AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // go!
+ AT91C_BASE_PDC_SSC->PDC_RNCR = sample_count; // ... with same number of samples
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // go!
return true;
}
uint8_t output_buffer[OUTPUT_BUFFER_LEN] = {0x00};
// check whether or not the bitstream is already loaded
- if (downloaded_bitstream == bitstream_version)
+ if (downloaded_bitstream == bitstream_version) {
+ FpgaEnableTracing();
return;
+ }
// make sure that we have enough memory to decompress
BigBuf_free(); BigBuf_Clear_ext(false);
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
}
+
//-----------------------------------------------------------------------------
// Write the FPGA setup word (that determines what mode the logic is in, read
// vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to
// avoid changing this function's occurence everywhere in the source code.
//-----------------------------------------------------------------------------
-void FpgaWriteConfWord(uint8_t v)
+void FpgaWriteConfWord(uint16_t v)
{
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
}
+//-----------------------------------------------------------------------------
+// enable/disable FPGA internal tracing
+//-----------------------------------------------------------------------------
+void FpgaEnableTracing(void)
+{
+ FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1);
+}
+
+void FpgaDisableTracing(void)
+{
+ FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0);
+}
+
//-----------------------------------------------------------------------------
// Set up the CMOS switches that mux the ADC: four switches, independently
// closable, but should only close one at a time. Not an FPGA thing, but
#include <stdbool.h>
void FpgaSendCommand(uint16_t cmd, uint16_t v);
-void FpgaWriteConfWord(uint8_t v);
+void FpgaWriteConfWord(uint16_t v);
void FpgaDownloadAndGo(int bitstream_version);
void FpgaSetupSsc(uint8_t mode);
void SetupSpi(int mode);
bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count);
void Fpga_print_status();
int FpgaGetCurrent();
+void FpgaEnableTracing(void);
+void FpgaDisableTracing(void);
#define FpgaDisableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
#define FpgaEnableSscDma(void) AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN;
void SetAdcMuxFor(uint32_t whichGpio);
#define FPGA_BITSTREAM_HF 2
// Definitions for the FPGA commands.
+// BOTH
#define FPGA_CMD_SET_CONFREG (1<<12)
+// LF
#define FPGA_CMD_SET_DIVISOR (2<<12)
#define FPGA_CMD_SET_USER_BYTE1 (3<<12)
+// HF
+#define FPGA_CMD_TRACE_ENABLE (2<<12)
+
// Definitions for the FPGA configuration word.
// LF
#define FPGA_MAJOR_MODE_LF_ADC (0<<5)
#define FPGA_MAJOR_MODE_HF_SIMULATOR (2<<5)
#define FPGA_MAJOR_MODE_HF_ISO14443A (3<<5)
#define FPGA_MAJOR_MODE_HF_SNOOP (4<<5)
+#define FPGA_MAJOR_MODE_HF_GET_TRACE (5<<5)
// BOTH
#define FPGA_MAJOR_MODE_OFF (7<<5)
+
// Options for LF_ADC
#define FPGA_LF_ADC_READER_FIELD (1<<0)
+
// Options for LF_EDGE_DETECT
#define FPGA_CMD_SET_EDGE_DETECT_THRESHOLD FPGA_CMD_SET_USER_BYTE1
#define FPGA_LF_EDGE_DETECT_READER_FIELD (1<<0)
#define FPGA_LF_EDGE_DETECT_TOGGLE_MODE (1<<1)
+
// Options for the HF reader, tx to tag
#define FPGA_HF_READER_TX_SHALLOW_MOD (1<<0)
+
// Options for the HF reader, correlating against rx from tag
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
#define FPGA_HF_READER_RX_XCORR_AMPLITUDE (1<<3)
+
// Options for the HF simulated tag, how to modulate
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
+//-----------------------------------------------------------------------------
+// piwi, 2019
+//
+// 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.
+//-----------------------------------------------------------------------------
+// Routines to get sample data from FPGA.
+//-----------------------------------------------------------------------------
+
+#include "hfsnoop.h"
+
#include "proxmark3.h"
-#include "apps.h"
#include "BigBuf.h"
#include "util.h"
+#include "apps.h"
#include "usb_cdc.h" // for usb_poll_validate_length
-
-static void RAMFUNC optimizedSnoop(void);
+#include "fpga.h"
+#include "fpgaloader.h"
static void RAMFUNC optimizedSnoop(void)
{
LED_D_OFF();
}
+void HfPlot(void)
+{
+ uint8_t *buf = ToSend;
+ uint8_t *this_buf = buf;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
+ FpgaSetupSsc(FPGA_MAJOR_MODE_HF_GET_TRACE);
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
+ AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) this_buf; // start transfer to this memory address
+ AT91C_BASE_PDC_SSC->PDC_RCR = USB_CMD_DATA_SIZE; // transfer this many samples
+ buf[0] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; // clear receive register
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // Start DMA transfer
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_GET_TRACE); // let FPGA transfer its internal Block-RAM
+
+ LED_B_ON();
+ for(size_t i = 0; i < FPGA_TRACE_SIZE; i += USB_CMD_DATA_SIZE) {
+ // prepare next DMA transfer:
+ uint8_t *next_buf = buf + ((i + USB_CMD_DATA_SIZE) % (2 * USB_CMD_DATA_SIZE));
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)next_buf;
+ AT91C_BASE_PDC_SSC->PDC_RNCR = USB_CMD_DATA_SIZE;
+ size_t len = MIN(FPGA_TRACE_SIZE - i, USB_CMD_DATA_SIZE);
+ while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_ENDRX))) ; // wait for DMA transfer to complete
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, FPGA_TRACE_SIZE, this_buf, len);
+ this_buf = next_buf;
+ }
+ // Trigger a finish downloading signal with an ACK frame
+ cmd_send(CMD_ACK, 1, 0, FPGA_TRACE_SIZE, 0, 0);
+ LED_B_OFF();
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+}
--- /dev/null
+//-----------------------------------------------------------------------------
+// piwi, 2019
+//
+// 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.
+//-----------------------------------------------------------------------------
+// Routines to get sample data from FPGA.
+//-----------------------------------------------------------------------------
+
+#ifndef HFSNOOP_H__
+#define HFSNOOP_H__
+
+void HfSnoop(int samplesToSkip, int triggersToSkip);
+void HfPlot(void);
+
+#endif
#include "hitag2.h"
#include "string.h"
#include "BigBuf.h"
+#include "fpgaloader.h"
static bool bQuiet;
#include "hitag2.h"
#include "string.h"
#include "BigBuf.h"
+#include "fpgaloader.h"
#define CRC_PRESET 0xFF
#define CRC_POLYNOM 0x1D
#include "protocols.h"
#include "optimized_cipher.h"
#include "usb_cdc.h" // for usb_poll_validate_length
+#include "fpgaloader.h"
static int timeout = 4096;
#include "BigBuf.h"
#include "protocols.h"
#include "parity.h"
+#include "fpgaloader.h"
typedef struct {
enum {
if (anticollision) {
// SELECT_ALL
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
- if (!ReaderReceive(resp, resp_par)) return 0;
+ if (!ReaderReceive(resp, resp_par)) {
+ return 0;
+ }
if (Demod.collisionPos) { // we had a collision and need to construct the UID bit by bit
memset(uid_resp, 0, 4);
}
collision_answer_offset = uid_resp_bits%8;
ReaderTransmitBits(sel_uid, 16 + uid_resp_bits, NULL);
- if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) return 0;
+ if (!ReaderReceiveOffset(resp, collision_answer_offset, resp_par)) {
+ return 0;
+ }
}
// finally, add the last bits and BCC of the UID
for (uint16_t i = collision_answer_offset; i < (Demod.len-1)*8; i++, uid_resp_bits++) {
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
// Receive the SAK
- if (!ReaderReceive(resp, resp_par)) return 0;
+ if (!ReaderReceive(resp, resp_par)) {
+ return 0;
+ }
sak = resp[0];
// Test if more parts of the uid are coming
AppendCrc14443a(rats, 2);
ReaderTransmit(rats, sizeof(rats), NULL);
- if (!(len = ReaderReceive(resp, resp_par))) return 0;
+ if (!(len = ReaderReceive(resp, resp_par))) {
+ return 0;
+ }
if(p_hi14a_card) {
memcpy(p_hi14a_card->ats, resp, len);
// 1 - all is OK with ATS, 2 - without ATS
cantSELECT = true;
}
-
+ FpgaDisableTracing();
LED_B_ON();
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
LED_B_OFF();
if(param & ISO14A_APDU && !cantSELECT) {
uint8_t res;
arg0 = iso14_apdu(cmd, len, buf, &res);
+ FpgaDisableTracing();
LED_B_ON();
cmd_send(CMD_ACK, arg0, res, 0, buf, sizeof(buf));
LED_B_OFF();
}
}
arg0 = ReaderReceive(buf, par);
+ FpgaDisableTracing();
LED_B_ON();
cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
}
+ FpgaDisableTracing();
+
uint8_t buf[32];
memcpy(buf + 0, uid, 4);
num_to_bytes(nt, 4, buf + 4);
DbpString("COMMAND FINISHED.");
FpgaDisableSscDma();
+ FpgaDisableTracing();
MfSniffEnd();
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len);
// the `fake tag' modes.
//-----------------------------------------------------------------------------
+#include "iso14443b.h"
+
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
-
#include "iso14443crc.h"
+#include "fpgaloader.h"
#define RECEIVE_SAMPLES_TIMEOUT 1000 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA. 1000 seems to be much too high?
#define ISO14443B_DMA_BUFFER_SIZE 128
#include "protocols.h"
#include "cmd.h"
#include "BigBuf.h"
+#include "fpgaloader.h"
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
// LEGIC RF simulation code
//-----------------------------------------------------------------------------
+#include "legicrf.h"
+
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
-
-#include "legicrf.h"
#include "legic_prng.h"
#include "legic.h"
#include "crc.h"
+#include "fpgaloader.h"
static legic_card_select_t card;/* metadata of currently selected card */
static crc_t legic_crc;
// LEGIC RF simulation code
//-----------------------------------------------------------------------------
+#include "legicrfsim.h"
+
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include "string.h"
-
-#include "legicrfsim.h"
#include "legic_prng.h"
#include "legic.h"
#include "crc.h"
#include "usb_cdc.h" // for usb_poll_validate_length
+#include "fpgaloader.h"
static uint8_t* legic_mem; /* card memory, used for sim */
static legic_card_select_t card;/* metadata of currently selected card */
#include "lfsampling.h"
#include "protocols.h"
#include "usb_cdc.h" // for usb_poll_validate_length
+#include "fpgaloader.h"
/**
* Function to do a modulation and then get samples.
#include "string.h"
#include "lfsampling.h"
#include "usb_cdc.h" // for usb_poll_validate_length
-//#include "ticks.h" // for StartTicks
+#include "fpgaloader.h"
sample_config config = { 1, 8, 1, 95, 0 } ;
\r
#include "mifarecmd.h"\r
\r
-#include "apps.h"\r
#include "util.h"\r
#include "parity.h"\r
#include "crc.h"\r
+#include "fpgaloader.h"\r
\r
#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)\r
#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication \r
//-----------------------------------------------------------------------------
#include "mifaresniff.h"
-#include "apps.h"
+
#include "proxmark3.h"
#include "util.h"
#include "string.h"
#include "crapto1/crapto1.h"
#include "mifareutil.h"
#include "common.h"
+#include "cmd.h"
+#include "BigBuf.h"
+#include "fpgaloader.h"
static int sniffState = SNF_INIT;
#include "pcf7931.h"
#include "util.h"
#include "string.h"
+#include "fpgaloader.h"
#define T0_PCF 8 //period for the pcf7931 in us
#define ALLOC 16
#include "cmdhf.h"
+#include <math.h>
#include "usb_cmd.h"
#include "comms.h"
#include "ui.h"
#include "cmdparser.h"
+#include "cliparser/cliparser.h"
#include "cmdhf14a.h"
#include "cmdhf14b.h"
#include "cmdhf15.h"
#include "cmdhftopaz.h"
#include "cmdhflist.h"
#include "cmdhffido.h"
+#include "cmddata.h"
+#include "graph.h"
+#include "fpga.h"
static int CmdHelp(const char *Cmd);
return 0;
}
-static command_t CommandTable[] =
+
+// static void InterpolateShannon(int *source, size_t source_len, int *dest, size_t dest_len)
+// {
+ // int *buf = (int*)malloc(source_len * sizeof(int));
+ // memcpy(buf, source, source_len * sizeof(int));
+ // for (int i = 0; i < source_len; i++) {
+ // buf[i] += 128;
+ // }
+ // for (int i = 0; i < dest_len; i++) {
+ // float value = 0.0;
+ // for (int j = 0; j < source_len; j++) {
+ // if (i * source_len == j * dest_len) { // sin(0) / 0 = 1
+ // value += (float)buf[j];
+ // } else {
+ // value += (float)buf[j] * sin(((float)i*source_len/dest_len-j)*3.1415) / (((float)i*source_len/dest_len-j)*3.1415);
+ // }
+ // }
+ // dest[i] = value - 128;
+ // }
+ // free(buf);
+// }
+
+
+static int CmdHFPlot(const char *Cmd)
+{
+ CLIParserInit("hf plot",
+ "Plots HF signal after RF signal path and A/D conversion.",
+ "This can be used after any hf command and will show the last few milliseconds of the HF signal.\n"
+ "Note: If the last hf command terminated because of a timeout you will most probably see nothing.\n");
+ void* argtable[] = {
+ arg_param_begin,
+ arg_param_end
+ };
+ CLIExecWithReturn(Cmd, argtable, true);
+
+ uint8_t buf[FPGA_TRACE_SIZE];
+
+ if (GetFromFpgaRAM(buf, FPGA_TRACE_SIZE)) {
+ for (size_t i = 0; i < FPGA_TRACE_SIZE; i++) {
+ GraphBuffer[i] = (int)buf[i] - 128;
+ }
+ GraphTraceLen = FPGA_TRACE_SIZE;
+ // InterpolateShannon(GraphBuffer, FPGA_TRACE_SIZE, GraphBuffer, FPGA_TRACE_SIZE*8/7);
+ // GraphTraceLen = FPGA_TRACE_SIZE*8/7;
+ ShowGraphWindow();
+ RepaintGraphWindow();
+ }
+ return 0;
+}
+
+
+static command_t CommandTable[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"},
- {"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"},
- {"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
- {"epa", CmdHFEPA, 1, "{ German Identification Card... }"},
- {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
- {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
- {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
- {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
- {"mfp", CmdHFMFP, 1, "{ MIFARE Plus RFIDs... }"},
- {"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
- {"fido", CmdHFFido, 1, "{ FIDO and FIDO2 authenticators... }"},
- {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
- {"list", CmdHFList, 1, "List protocol data in trace buffer"},
- {"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"},
+ {"help", CmdHelp, 1, "This help"},
+ {"14a", CmdHF14A, 0, "{ ISO14443A RFIDs... }"},
+ {"14b", CmdHF14B, 0, "{ ISO14443B RFIDs... }"},
+ {"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
+ {"epa", CmdHFEPA, 0, "{ German Identification Card... }"},
+ {"legic", CmdHFLegic, 0, "{ LEGIC RFIDs... }"},
+ {"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
+ {"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
+ {"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
+ {"mfp", CmdHFMFP, 0, "{ MIFARE Plus RFIDs... }"},
+ {"topaz", CmdHFTopaz, 0, "{ TOPAZ (NFC Type 1) RFIDs... }"},
+ {"fido", CmdHFFido, 0, "{ FIDO and FIDO2 authenticators... }"},
+ {"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
+ {"list", CmdHFList, 1, "List protocol data in trace buffer"},
+ {"plot", CmdHFPlot, 0, "Plot signal"},
+ {"search", CmdHFSearch, 0, "Search for known HF tags [preliminary]"},
{"snoop", CmdHFSnoop, 0, "<samples to skip (10000)> <triggers to skip (1)> Generic HF Snoop"},
- {NULL, NULL, 0, NULL}
+ {NULL, NULL, 0, NULL}
};
int CmdHF(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
- return 0;
+ return 0;
}
int CmdHelp(const char *Cmd)
//-----------------------------------------------------------------------------
#ifndef CMDPARSER_H__
-#define CMDPARSER_H__
+#define CMDPARSER_H__
typedef struct command_s
{
}
+bool GetFromFpgaRAM(uint8_t *dest, int bytes)
+{
+ UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
+ SendCommand(&c);
+
+ uint64_t start_time = msclock();
+
+ UsbCommand response;
+
+ int bytes_completed = 0;
+ bool show_warning = true;
+ while(true) {
+ if (getCommand(&response)) {
+ if (response.cmd == CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {
+ int copy_bytes = MIN(bytes - bytes_completed, response.arg[1]);
+ memcpy(dest + response.arg[0], response.d.asBytes, copy_bytes);
+ bytes_completed += copy_bytes;
+ } else if (response.cmd == CMD_ACK) {
+ return true;
+ }
+ }
+
+ if (msclock() - start_time > 2000 && show_warning) {
+ PrintAndLog("Waiting for a response from the proxmark...");
+ PrintAndLog("You can cancel this operation by pressing the pm3 button");
+ show_warning = false;
+ }
+ }
+
+ return false;
+}
+
+
bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
char *portname = (char *)port;
if (!wait_for_port) {
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
bool WaitForResponse(uint32_t cmd, UsbCommand* response);
bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *response, size_t ms_timeout, bool show_warning);
+bool GetFromFpgaRAM(uint8_t *dest, int bytes);
#endif // COMMS_H_
#define FPGA_BITSTREAM_FIXED_HEADER_SIZE sizeof(bitparse_fixed_header)
#define FPGA_INTERLEAVE_SIZE 288
#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
+#define FPGA_TRACE_SIZE 3072
static const uint8_t bitparse_fixed_header[] = {0x00, 0x09, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x00, 0x01};
extern const int fpga_bitstream_num;
$(DELETE) *.bgn *.drc *.ncd *.ngd *_par.xrpt *-placed.* *-placed_pad.* *_usage.xml xst_hf.srp xst_lf.srp
$(DELETE) *.map *.ngc *.xrpt *.pcf *.rbt *_auto_* *.bld *.mrp *.ngm *.unroutes *_summary.xml netlist.lst xst
-fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v
+fpga_hf.ngc: fpga_hf.v fpga.ucf xst_hf.scr util.v hi_simulate.v hi_read_tx.v hi_read_rx_xcorr.v hi_iso14443a.v hi_sniffer.v hi_get_trace.v
$(DELETE) $@
$(XILINX_TOOLS_PREFIX)xst -ifn xst_hf.scr
`include "hi_simulate.v"
`include "hi_iso14443a.v"
`include "hi_sniffer.v"
+`include "hi_get_trace.v"
`include "util.v"
module fpga_hf(
reg [15:0] shift_reg;
reg [7:0] conf_word;
+reg trace_enable;
// We switch modes between transmitting to the 13.56 MHz tag and receiving
// from it, which means that we must make sure that we can do so without
begin
case(shift_reg[15:12])
4'b0001: conf_word <= shift_reg[7:0]; // FPGA_CMD_SET_CONFREG
+ 4'b0010: trace_enable <= shift_reg[0]; // FPGA_CMD_TRACE_ENABLE
endcase
end
hi_sniffer he(
pck0, ck_1356meg, ck_1356megb,
- he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4,
+ he_pwr_lo, he_pwr_hi, he_pwr_oe1, he_pwr_oe2, he_pwr_oe3, he_pwr_oe4,
adc_d, he_adc_clk,
he_ssp_frame, he_ssp_din, ssp_dout, he_ssp_clk,
cross_hi, cross_lo,
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
);
+hi_get_trace gt(
+ ck_1356megb,
+ adc_d, trace_enable, major_mode,
+ gt_ssp_frame, gt_ssp_din, gt_ssp_clk
+);
+
// Major modes:
// 000 -- HF reader, transmitting to tag; modulation depth selectable
// 010 -- HF simulated tag
// 011 -- HF ISO14443-A
// 100 -- HF Snoop
+// 101 -- HF get trace
// 111 -- everything off
-mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, 1'b0, 1'b0, 1'b0);
-mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, 1'b0, 1'b0, 1'b0);
-mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, 1'b0, 1'b0, 1'b0);
-mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, 1'b0, 1'b0, 1'b0);
-mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, 1'b0, 1'b0, 1'b0);
-mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, 1'b0, 1'b0, 1'b0);
+mux8 mux_ssp_clk (major_mode, ssp_clk, ht_ssp_clk, hrxc_ssp_clk, hs_ssp_clk, hisn_ssp_clk, he_ssp_clk, gt_ssp_clk, 1'b0, 1'b0);
+mux8 mux_ssp_din (major_mode, ssp_din, ht_ssp_din, hrxc_ssp_din, hs_ssp_din, hisn_ssp_din, he_ssp_din, gt_ssp_din, 1'b0, 1'b0);
+mux8 mux_ssp_frame (major_mode, ssp_frame, ht_ssp_frame, hrxc_ssp_frame, hs_ssp_frame, hisn_ssp_frame, he_ssp_frame, gt_ssp_frame, 1'b0, 1'b0);
+mux8 mux_pwr_oe1 (major_mode, pwr_oe1, ht_pwr_oe1, hrxc_pwr_oe1, hs_pwr_oe1, hisn_pwr_oe1, he_pwr_oe1, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe2 (major_mode, pwr_oe2, ht_pwr_oe2, hrxc_pwr_oe2, hs_pwr_oe2, hisn_pwr_oe2, he_pwr_oe2, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe3 (major_mode, pwr_oe3, ht_pwr_oe3, hrxc_pwr_oe3, hs_pwr_oe3, hisn_pwr_oe3, he_pwr_oe3, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_oe4 (major_mode, pwr_oe4, ht_pwr_oe4, hrxc_pwr_oe4, hs_pwr_oe4, hisn_pwr_oe4, he_pwr_oe4, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_lo (major_mode, pwr_lo, ht_pwr_lo, hrxc_pwr_lo, hs_pwr_lo, hisn_pwr_lo, he_pwr_lo, 1'b0, 1'b0, 1'b0);
+mux8 mux_pwr_hi (major_mode, pwr_hi, ht_pwr_hi, hrxc_pwr_hi, hs_pwr_hi, hisn_pwr_hi, he_pwr_hi, 1'b0, 1'b0, 1'b0);
+mux8 mux_adc_clk (major_mode, adc_clk, ht_adc_clk, hrxc_adc_clk, hs_adc_clk, hisn_adc_clk, he_adc_clk, 1'b0, 1'b0, 1'b0);
+mux8 mux_dbg (major_mode, dbg, ht_dbg, hrxc_dbg, hs_dbg, hisn_dbg, he_dbg, 1'b0, 1'b0, 1'b0);
// In all modes, let the ADC's outputs be enabled.
assign adc_noe = 1'b0;
--- /dev/null
+//-----------------------------------------------------------------------------
+//
+// piwi, Feb 2019
+//-----------------------------------------------------------------------------
+
+module hi_get_trace(
+ ck_1356megb,
+ adc_d, trace_enable, major_mode,
+ ssp_frame, ssp_din, ssp_clk
+);
+ input ck_1356megb;
+ input [7:0] adc_d;
+ input trace_enable;
+ input [2:0] major_mode;
+ output ssp_frame, ssp_din, ssp_clk;
+
+// constants for some major_modes:
+`define OFF 3'b111
+`define GET_TRACE 3'b101
+
+
+// clock divider
+reg [6:0] clock_cnt;
+always @(negedge ck_1356megb)
+begin
+ clock_cnt <= clock_cnt + 1;
+end
+
+// sample at 13,56MHz / 8. The highest signal frequency (subcarrier) is 848,5kHz, i.e. in this case we oversample by a factor of 2
+reg [2:0] sample_clock;
+always @(negedge ck_1356megb)
+begin
+ if (sample_clock == 3'd3)
+ sample_clock <= 3'd0;
+ else
+ sample_clock <= sample_clock + 1;
+end
+
+
+reg [11:0] addr;
+reg [11:0] start_addr;
+reg [2:0] previous_major_mode;
+reg write_enable1;
+reg write_enable2;
+always @(negedge ck_1356megb)
+begin
+ previous_major_mode <= major_mode;
+ if (major_mode == `GET_TRACE)
+ begin
+ write_enable1 <= 1'b0;
+ write_enable2 <= 1'b0;
+ if (previous_major_mode != `GET_TRACE) // just switched into GET_TRACE mode
+ addr <= start_addr;
+ if (clock_cnt == 7'd0)
+ begin
+ if (addr == 12'd3071)
+ addr <= 12'd0;
+ else
+ addr <= addr + 1;
+ end
+ end
+ else if (major_mode != `OFF)
+ begin
+ if (trace_enable)
+ begin
+ if (addr[11] == 1'b0)
+ begin
+ write_enable1 <= 1'b1;
+ write_enable2 <= 1'b0;
+ end
+ else
+ begin
+ write_enable1 <= 1'b0;
+ write_enable2 <= 1'b1;
+ end
+ if (sample_clock == 3'b000)
+ begin
+ if (addr == 12'd3071)
+ begin
+ addr <= 12'd0;
+ write_enable1 <= 1'b1;
+ write_enable2 <= 1'b0;
+ end
+ else
+ addr <= addr + 1;
+ end
+ end
+ else
+ begin
+ write_enable1 <= 1'b0;
+ write_enable2 <= 1'b0;
+ start_addr <= addr;
+ end
+ end
+ else // major_mode == `OFF
+ begin
+ write_enable1 <= 1'b0;
+ write_enable2 <= 1'b0;
+ if (previous_major_mode != `OFF && previous_major_mode != `GET_TRACE) // just switched off
+ start_addr <= addr;
+ end
+end
+
+
+// (2+1)k RAM
+reg [7:0] D_out1, D_out2;
+reg [7:0] ram1 [2047:0];
+reg [7:0] ram2 [1023:0];
+
+always @(negedge ck_1356megb)
+begin
+ if (write_enable1)
+ begin
+ ram1[addr[10:0]] <= adc_d;
+ D_out1 <= adc_d;
+ end
+ else
+ D_out1 <= ram1[addr[10:0]];
+ if (write_enable2)
+ begin
+ ram2[addr[9:0]] <= adc_d;
+ D_out2 <= adc_d;
+ end
+ else
+ D_out2 <= ram2[addr[9:0]];
+end
+
+
+// SSC communication to ARM
+reg ssp_clk;
+reg ssp_frame;
+reg [7:0] shift_out;
+
+always @(negedge ck_1356megb)
+begin
+ if(clock_cnt[3:0] == 4'd0) // update shift register every 16 clock cycles
+ begin
+ if(clock_cnt[6:4] == 3'd0) // either load new value
+ begin
+ if (addr[11] == 1'b0)
+ shift_out <= D_out1;
+ else
+ shift_out <= D_out2;
+ end
+ else // or shift left
+ shift_out[7:1] <= shift_out[6:0];
+ end
+
+ ssp_clk <= ~clock_cnt[3]; // ssp_clk frequency = 13,56MHz / 16 = 847,5 kHz
+
+ if(clock_cnt[6:4] == 3'b000) // set ssp_frame for 0...31
+ ssp_frame <= 1'b1;
+ else
+ ssp_frame <= 1'b0;
+
+end
+
+assign ssp_din = shift_out[7];
+
+endmodule
#define CMD_MIFARE_DESFIRE 0x072e
#define CMD_HF_SNIFFER 0x0800
+#define CMD_HF_PLOT 0x0801
#define CMD_UNKNOWN 0xFFFF