From fc52fbd42f576d889826f4a0c60d18fad41bc3af Mon Sep 17 00:00:00 2001 From: pwpiwi <pwpiwi@users.noreply.github.com> Date: Wed, 20 Feb 2019 19:18:12 +0100 Subject: [PATCH] Add raw HF signal plotting (#786) * Add raw HF signal plotting * new fpga module hi_get_trace.v - store A/D converter output to circular buffer on FPGA * new command 'hf plot' - pull data from FPGA and display it in Graph Window --- CHANGELOG.md | 7 +- armsrc/appmain.c | 8 ++- armsrc/apps.h | 6 -- armsrc/fpgaloader.c | 22 +++++- armsrc/fpgaloader.h | 15 +++- armsrc/hfsnoop.c | 48 ++++++++++++- armsrc/hfsnoop.h | 17 +++++ armsrc/hitag2.c | 1 + armsrc/hitagS.c | 1 + armsrc/iclass.c | 1 + armsrc/iso14443a.c | 24 +++++-- armsrc/iso14443b.c | 4 +- armsrc/iso15693.c | 1 + armsrc/legicrf.c | 5 +- armsrc/legicrfsim.c | 5 +- armsrc/lfops.c | 1 + armsrc/lfsampling.c | 2 +- armsrc/mifarecmd.c | 2 +- armsrc/mifaresniff.c | 5 +- armsrc/pcf7931.c | 1 + client/cmdhf.c | 93 ++++++++++++++++++++----- client/cmdparser.h | 2 +- client/comms.c | 33 +++++++++ client/comms.h | 1 + common/fpga.h | 1 + fpga/Makefile | 2 +- fpga/fpga_hf.bit | Bin 42175 -> 42175 bytes fpga/fpga_hf.v | 34 +++++---- fpga/hi_get_trace.v | 160 +++++++++++++++++++++++++++++++++++++++++++ include/usb_cmd.h | 1 + 30 files changed, 441 insertions(+), 62 deletions(-) create mode 100644 armsrc/hfsnoop.h create mode 100644 fpga/hi_get_trace.v diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c285b4..c2bf52c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ### 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 @@ -25,8 +25,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - 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] diff --git a/armsrc/appmain.c b/armsrc/appmain.c index cdc784c0..2a16f5f0 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -30,6 +30,8 @@ #include "mifareutil.h" #include "pcf7931.h" #include "i2c.h" +#include "hfsnoop.h" +#include "fpgaloader.h" #ifdef WITH_LCD #include "LCD.h" #endif @@ -1323,11 +1325,16 @@ void UsbPacketReceived(uint8_t *packet, int len) 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(); @@ -1377,7 +1384,6 @@ void UsbPacketReceived(uint8_t *packet, int len) 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) { diff --git a/armsrc/apps.h b/armsrc/apps.h index fad9e6eb..aaa128ab 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -21,7 +21,6 @@ #include "mifare.h" #include "../common/crc32.h" #include "BigBuf.h" -#include "fpgaloader.h" extern const uint8_t OddByteParity[256]; extern int rsamples; // = 0; @@ -174,13 +173,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data); 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 diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index 45294d60..d1d527c4 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -166,7 +166,7 @@ bool FpgaSetupSscDma(uint8_t *buf, uint16_t sample_count) 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; } @@ -417,8 +417,10 @@ void FpgaDownloadAndGo(int bitstream_version) 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); @@ -454,16 +456,30 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) 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 diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 0600067e..006de8de 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -17,13 +17,15 @@ #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); @@ -33,9 +35,14 @@ 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) @@ -47,21 +54,27 @@ void SetAdcMuxFor(uint32_t whichGpio); #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) diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index e492c474..755ac0cc 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -1,10 +1,22 @@ +//----------------------------------------------------------------------------- +// 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) { @@ -74,3 +86,33 @@ void HfSnoop(int samplesToSkip, int triggersToSkip) 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); +} diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h new file mode 100644 index 00000000..8c45e170 --- /dev/null +++ b/armsrc/hfsnoop.h @@ -0,0 +1,17 @@ +//----------------------------------------------------------------------------- +// 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 diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 8e690a7b..0fd8d745 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -22,6 +22,7 @@ #include "hitag2.h" #include "string.h" #include "BigBuf.h" +#include "fpgaloader.h" static bool bQuiet; diff --git a/armsrc/hitagS.c b/armsrc/hitagS.c index 3c247d55..8a451606 100644 --- a/armsrc/hitagS.c +++ b/armsrc/hitagS.c @@ -20,6 +20,7 @@ #include "hitag2.h" #include "string.h" #include "BigBuf.h" +#include "fpgaloader.h" #define CRC_PRESET 0xFF #define CRC_POLYNOM 0x1D diff --git a/armsrc/iclass.c b/armsrc/iclass.c index d27fc1c6..be7da703 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -51,6 +51,7 @@ #include "protocols.h" #include "optimized_cipher.h" #include "usb_cdc.h" // for usb_poll_validate_length +#include "fpgaloader.h" static int timeout = 4096; diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 50160798..2fffe837 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -25,6 +25,7 @@ #include "BigBuf.h" #include "protocols.h" #include "parity.h" +#include "fpgaloader.h" typedef struct { enum { @@ -1771,7 +1772,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u 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); @@ -1793,7 +1796,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u } 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++) { @@ -1827,7 +1832,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u 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 @@ -1862,7 +1869,9 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u 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); @@ -2044,7 +2053,7 @@ void ReaderIso14443a(UsbCommand *c) // 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(); @@ -2058,6 +2067,7 @@ void ReaderIso14443a(UsbCommand *c) 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(); @@ -2099,6 +2109,7 @@ void ReaderIso14443a(UsbCommand *c) } } arg0 = ReaderReceive(buf, par); + FpgaDisableTracing(); LED_B_ON(); cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf)); @@ -2415,6 +2426,8 @@ void ReaderMifare(bool first_try) } } + FpgaDisableTracing(); + uint8_t buf[32]; memcpy(buf + 0, uid, 4); num_to_bytes(nt, 4, buf + 4); @@ -2587,6 +2600,7 @@ void RAMFUNC SniffMifare(uint8_t param) { DbpString("COMMAND FINISHED."); FpgaDisableSscDma(); + FpgaDisableTracing(); MfSniffEnd(); Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len); diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index 76d7a075..3ebaa539 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -10,12 +10,14 @@ // 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 diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9dc4bf18..13b8a174 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -60,6 +60,7 @@ #include "protocols.h" #include "cmd.h" #include "BigBuf.h" +#include "fpgaloader.h" #define arraylen(x) (sizeof(x)/sizeof((x)[0])) diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index d3fd35d1..947d6cd5 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -10,15 +10,16 @@ // 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; diff --git a/armsrc/legicrfsim.c b/armsrc/legicrfsim.c index 1411fbea..409235af 100644 --- a/armsrc/legicrfsim.c +++ b/armsrc/legicrfsim.c @@ -10,16 +10,17 @@ // 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 */ diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 1816bdca..81fdd7a6 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -18,6 +18,7 @@ #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. diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index ffbc0da8..03bccf41 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -12,7 +12,7 @@ #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 } ; diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index ca513cec..14ce1bcc 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -15,10 +15,10 @@ #include "mifarecmd.h" -#include "apps.h" #include "util.h" #include "parity.h" #include "crc.h" +#include "fpgaloader.h" #define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) #define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 5391e5f9..4dbcd904 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #include "mifaresniff.h" -#include "apps.h" + #include "proxmark3.h" #include "util.h" #include "string.h" @@ -18,6 +18,9 @@ #include "crapto1/crapto1.h" #include "mifareutil.h" #include "common.h" +#include "cmd.h" +#include "BigBuf.h" +#include "fpgaloader.h" static int sniffState = SNF_INIT; diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c index 16b7912d..9aa0d9be 100644 --- a/armsrc/pcf7931.c +++ b/armsrc/pcf7931.c @@ -4,6 +4,7 @@ #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 diff --git a/client/cmdhf.c b/client/cmdhf.c index f11c5b65..73b0bc76 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -11,10 +11,12 @@ #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" @@ -27,6 +29,9 @@ #include "cmdhftopaz.h" #include "cmdhflist.h" #include "cmdhffido.h" +#include "cmddata.h" +#include "graph.h" +#include "fpga.h" static int CmdHelp(const char *Cmd); @@ -73,31 +78,83 @@ int CmdHFSnoop(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) diff --git a/client/cmdparser.h b/client/cmdparser.h index 5217d04b..cd4d1625 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #ifndef CMDPARSER_H__ -#define CMDPARSER_H__ +#define CMDPARSER_H__ typedef struct command_s { diff --git a/client/comms.c b/client/comms.c index 190b9110..5af53715 100644 --- a/client/comms.c +++ b/client/comms.c @@ -301,6 +301,39 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon } +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) { diff --git a/client/comms.h b/client/comms.h index 68981165..65294695 100644 --- a/client/comms.h +++ b/client/comms.h @@ -35,5 +35,6 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo 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_ diff --git a/common/fpga.h b/common/fpga.h index b99a7593..65268ecf 100644 --- a/common/fpga.h +++ b/common/fpga.h @@ -10,6 +10,7 @@ #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; diff --git a/fpga/Makefile b/fpga/Makefile index 2f93e741..70b0b5fe 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -5,7 +5,7 @@ clean: $(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 diff --git a/fpga/fpga_hf.bit b/fpga/fpga_hf.bit index f16fd0614fbd2614e713a29da5f47a29094953e5..2ea2c24e76d0e4b64f173d48cf67dc299283e53d 100644 GIT binary patch literal 42175 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 H^0)s7_0XSf literal 42175 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 diff --git a/fpga/fpga_hf.v b/fpga/fpga_hf.v index 5d55cb89..ef935260 100644 --- a/fpga/fpga_hf.v +++ b/fpga/fpga_hf.v @@ -18,6 +18,7 @@ `include "hi_simulate.v" `include "hi_iso14443a.v" `include "hi_sniffer.v" +`include "hi_get_trace.v" `include "util.v" module fpga_hf( @@ -40,6 +41,7 @@ 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 @@ -48,6 +50,7 @@ always @(posedge ncs) 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 @@ -129,7 +132,7 @@ hi_iso14443a hisn( 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, @@ -137,6 +140,12 @@ hi_sniffer he( 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 @@ -144,19 +153,20 @@ hi_sniffer he( // 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; diff --git a/fpga/hi_get_trace.v b/fpga/hi_get_trace.v new file mode 100644 index 00000000..7acecf80 --- /dev/null +++ b/fpga/hi_get_trace.v @@ -0,0 +1,160 @@ +//----------------------------------------------------------------------------- +// +// 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 diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 4c27ac85..ef282256 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -220,6 +220,7 @@ typedef struct{ #define CMD_MIFARE_DESFIRE 0x072e #define CMD_HF_SNIFFER 0x0800 +#define CMD_HF_PLOT 0x0801 #define CMD_UNKNOWN 0xFFFF -- 2.39.5