From 7838f4beba79370f94c7a3de2cf34278f5d481c8 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 22 Jul 2015 23:00:52 +0200 Subject: [PATCH] MERGED: @holimans changes MERGED: @piwi changes MERGED: @marshmellows changes. I'm not even gonna try write up all that stuff.. ADD: changed some commands inside the "Hf 14a sim" on deviceside. ADD: @mobeius "two nonce" version for mfkey32. It is also inside the "hf 14a sim" with the "x" parameter. --- CHANGELOG.md | 8 +- armsrc/BigBuf.c | 17 +- armsrc/BigBuf.h | 4 +- armsrc/Makefile | 2 +- armsrc/appmain.c | 272 ++++++++++++++++++++++++++++-- armsrc/apps.h | 9 +- armsrc/des.c | 2 +- armsrc/desfire_crypto.c | 5 +- armsrc/fpgaloader.c | 8 + armsrc/fpgaloader.h | 1 + armsrc/iso14443a.c | 69 +++++--- armsrc/iso14443a.h | 4 +- armsrc/iso14443b.c | 1 + armsrc/legicrf.c | 6 +- armsrc/lfops.c | 2 +- armsrc/lfsampling.c | 2 +- armsrc/lfsampling.h | 4 + armsrc/mifarecmd.h | 7 +- armsrc/mifaresniff.h | 6 +- armsrc/mifareutil.h | 1 + bootrom/bootrom.c | 2 +- client/cmdhf14a.c | 2 + client/cmdhfmfu.c | 14 +- client/cmdhw.c | 41 ++++- client/cmdlfawid.c | 15 +- client/flash.c | 25 ++- client/flasher.c | 2 +- client/hid-flasher/usb_cmd.h | 3 + client/lualibs/commands.lua | 3 +- client/scripts/mifare_autopwn.lua | 29 +++- common/iso14443crc.c | 2 +- common/iso14443crc.h | 2 +- common/iso15693tools.c | 2 +- common/legic_prng.c | 2 +- common/usb_cdc.c | 16 ++ common/usb_cdc.h | 1 + include/usb_cmd.h | 2 + 37 files changed, 488 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb2df85e..5b7247c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,16 +5,22 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] ### Added +- ISO14443a stand-alone operation with ARM CFLAG="WITH_ISO14443a_StandAlone". This code can read & emulate two banks of 14a tag UIDs and write to "magic" cards (Craig Young) - AWID26 command context added as 'lf awid' containing realtime demodulation as well as cloning/simulation based on tag numbers (Craig Young) +- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman) +- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman) ### Changed - Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow) - EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers) +- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi) ## [2.2.0][2015-07-12] +### Changed +- Added `hf 14b raw -s` option to auto select a 14b std tag before raw command - Changed `hf 14b write` to `hf 14b sriwrite` as it only applied to sri tags (marshmellow) -- Added `hf 14b reader` to `hf search` (marshmellow) +- Added `hf 14b info` to `hf search` (marshmellow) - Added compression of fpga config and data, *BOOTROM REFLASH REQUIRED* (piwi) - Implemented better detection of mifare-tags that are not vulnerable to classic attacks (`hf mf mifare`, `hf mf nested`) (piwi) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index e8cf8028..3499d7c7 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -88,6 +88,16 @@ void BigBuf_free_keep_EM(void) } } +void BigBuf_print_status(void) +{ + Dbprintf("Memory"); + Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); + Dbprintf(" BigBuf_hi .............%d", BigBuf_hi); + Dbprintf("Tracing"); + Dbprintf(" tracing ................%d", tracing); + Dbprintf(" traceLen ...............%d", traceLen); +} + // return the maximum trace length (i.e. the unallocated size of BigBuf) uint16_t BigBuf_max_traceLen(void) @@ -168,8 +178,12 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ traceLen += iLen; // parity bytes - if (parity != NULL && iLen != 0) { + if (iLen != 0) { + if (parity != NULL) { memcpy(trace + traceLen, parity, num_paritybytes); + } else { + memset(trace + traceLen, 0x00, num_paritybytes); + } } traceLen += num_paritybytes; @@ -218,6 +232,7 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP return TRUE; } + // Emulator memory uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){ uint8_t* mem = BigBuf_get_EM_addr(); diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 0e2f1744..b859ffda 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -28,9 +28,9 @@ extern void BigBuf_Clear(void); extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); - +extern void BigBuf_print_status(void); extern uint16_t BigBuf_get_traceLen(void); -extern void clear_trace(); +extern void clear_trace(void); extern void set_tracing(bool enable); 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); diff --git a/armsrc/Makefile b/armsrc/Makefile index 16b98429..3559e482 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,7 +10,7 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE \ +APP_CFLAGS = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG -DWITH_CRC -DON_DEVICE \ -fno-strict-aliasing -ffunction-sections -fdata-sections #-DWITH_LCD diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 6996c82e..03e6eba2 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -25,10 +25,16 @@ #include #include "lfsampling.h" #include "BigBuf.h" +#include "mifareutil.h" #ifdef WITH_LCD #include "LCD.h" #endif +// Craig Young - 14a stand-alone code +#ifdef WITH_ISO14443a_StandAlone + #include "iso14443a.h" +#endif + #define abs(x) ( ((x)<0) ? -(x) : (x) ) //============================================================================= @@ -39,7 +45,7 @@ #define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits uint8_t ToSend[TOSEND_BUFFER_SIZE]; -int ToSendMax; +int ToSendMax = 0; static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); @@ -180,7 +186,7 @@ void MeasureAntennaTuning(void) int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV - LED_B_ON(); + LED_B_ON(); /* * Sweeps the useful LF range of the proxmark from @@ -212,17 +218,17 @@ void MeasureAntennaTuning(void) for (i=18; i >= 0; i--) LF_Results[i] = 0; - LED_A_ON(); + LED_A_ON(); // Let the FPGA drive the high-frequency antenna around 13.56 MHz. - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LED_A_OFF(); - LED_B_OFF(); + LED_A_OFF(); + LED_B_OFF(); return; } @@ -292,19 +298,27 @@ void SendVersion(void) uint32_t compressed_data_section_size = common_area.arg1; cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString)); } - -#ifdef WITH_LF -// samy's sniff and repeat routine -void SamyRun() +/** + * Prints runtime information about the PM3. +**/ +void SendStatus(void) { - DbpString("Stand-alone mode! No PC necessary."); - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + BigBuf_print_status(); + Fpga_print_status(); + printConfig(); //LF Sampling config + Dbprintf("Various"); + Dbprintf(" MF_DBGLEVEL......%d", MF_DBGLEVEL); + Dbprintf(" ToSendMax........%d",ToSendMax); + Dbprintf(" ToSendBit........%d",ToSendBit); +} - // 3 possible options? no just 2 for now -#define OPTS 2 +#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF) - int high[OPTS], low[OPTS]; +#define OPTS 2 +void StandAloneMode() +{ + DbpString("Stand-alone mode! No PC necessary."); // Oooh pretty -- notify user we're in elite samy mode now LED(LED_RED, 200); LED(LED_ORANGE, 200); @@ -316,6 +330,216 @@ void SamyRun() LED(LED_ORANGE, 200); LED(LED_RED, 200); +} + +#endif + + + +#ifdef WITH_ISO14443a_StandAlone +void StandAloneMode14a() +{ + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + + int selected = 0; + int playing = 0; + int cardRead[OPTS] = {0}; + uint8_t readUID[10] = {0}; + uint32_t uid_1st[OPTS]={0}; + uint32_t uid_2nd[OPTS]={0}; + + LED(selected + 1, 0); + + for (;;) + { + usb_poll(); + WDT_HIT(); + + // Was our button held down or pressed? + int button_pressed = BUTTON_HELD(1000); + SpinDelay(300); + + // Button was held for a second, begin recording + if (button_pressed > 0 && cardRead[selected] == 0) + { + LEDsoff(); + LED(selected + 1, 0); + LED(LED_RED2, 0); + + // record + Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected); + + // wait for button to be released + while(BUTTON_PRESS()) + WDT_HIT(); + /* need this delay to prevent catching some weird data */ + SpinDelay(500); + /* Code for reading from 14a tag */ + uint8_t uid[10] ={0}; + uint32_t cuid; + iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); + + for ( ; ; ) + { + WDT_HIT(); + if (!iso14443a_select_card(uid, NULL, &cuid)) + continue; + else + { + Dbprintf("Read UID:"); Dbhexdump(10,uid,0); + memcpy(readUID,uid,10*sizeof(uint8_t)); + uint8_t *dst = (uint8_t *)&uid_1st[selected]; + // Set UID byte order + for (int i=0; i<4; i++) + dst[i] = uid[3-i]; + dst = (uint8_t *)&uid_2nd[selected]; + for (int i=0; i<4; i++) + dst[i] = uid[7-i]; + break; + } + } + LEDsoff(); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + LED(LED_GREEN, 200); + LED(LED_ORANGE, 200); + + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + cardRead[selected] = 1; + + } + /* MF UID clone */ + else if (button_pressed > 0 && cardRead[selected] == 1) + { + LEDsoff(); + LED(selected + 1, 0); + LED(LED_ORANGE, 250); + + + // record + Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]); + + // wait for button to be released + while(BUTTON_PRESS()) + { + // Delay cloning until card is in place + WDT_HIT(); + } + Dbprintf("Starting clone. [Bank: %u]", selected); + // need this delay to prevent catching some weird data + SpinDelay(500); + // Begin clone function here: + /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards: + UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}}; + memcpy(c.d.asBytes, data, 16); + SendCommand(&c); + + Block read is similar: + UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}}; + We need to imitate that call with blockNo 0 to set a uid. + + The get and set commands are handled in this file: + // Work with "magic Chinese" card + case CMD_MIFARE_CSETBLOCK: + MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFARE_CGETBLOCK: + MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + // + break; + + mfCSetUID provides example logic for UID set workflow: + -Read block0 from card in field with MifareCGetBlock() + -Configure new values without replacing reserved bytes + memcpy(block0, uid, 4); // Copy UID bytes from byte array + // Mifare UID BCC + block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5 + Bytes 5-7 are reserved SAK and ATQA for mifare classic + -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it + */ + uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0}; + // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo + MifareCGetBlock(0x1F, 1, 0, oldBlock0); + Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]); + memcpy(newBlock0,oldBlock0,16); + // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic) + + newBlock0[0] = uid_1st[selected]>>24; + newBlock0[1] = 0xFF & (uid_1st[selected]>>16); + newBlock0[2] = 0xFF & (uid_1st[selected]>>8); + newBlock0[3] = 0xFF & (uid_1st[selected]); + newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3]; + // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain + MifareCSetBlock(0, 0xFF,0, newBlock0); + MifareCGetBlock(0x1F, 1, 0, testBlock0); + if (memcmp(testBlock0,newBlock0,16)==0) + { + DbpString("Cloned successfull!"); + cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it + } + LEDsoff(); + LED(selected + 1, 0); + // Finished recording + + // If we were previously playing, set playing off + // so next button push begins playing what we recorded + playing = 0; + + } + // Change where to record (or begin playing) + else if (button_pressed && cardRead[selected]) + { + // Next option if we were previously playing + if (playing) + selected = (selected + 1) % OPTS; + playing = !playing; + + LEDsoff(); + LED(selected + 1, 0); + + // Begin transmitting + if (playing) + { + LED(LED_GREEN, 0); + DbpString("Playing"); + while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec + Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected); + SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL); + } + //cardRead[selected] = 1; + Dbprintf("Done playing [Bank: %u]",selected); + + /* We pressed a button so ignore it here with a delay */ + SpinDelay(300); + + // when done, we're done playing, move to next option + selected = (selected + 1) % OPTS; + playing = !playing; + LEDsoff(); + LED(selected + 1, 0); + } + else + while(BUTTON_PRESS()) + WDT_HIT(); + } + } +} +#elif WITH_LF +// samy's sniff and repeat routine +void SamyRun() +{ + StandAloneMode(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + int high[OPTS], low[OPTS]; int selected = 0; int playing = 0; int cardRead = 0; @@ -439,8 +663,8 @@ void SamyRun() } } } -#endif +#endif /* OBJECTIVE Listen and detect an external reader. Determine the best location @@ -667,6 +891,7 @@ void UsbPacketReceived(uint8_t *packet, int len) break; case CMD_T55XX_WRITE_BLOCK: T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); + cmd_send(CMD_ACK,0,0,0,0,0); break; case CMD_T55XX_READ_TRACE: T55xxReadTrace(); @@ -954,7 +1179,12 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_VERSION: SendVersion(); break; - + case CMD_STATUS: + SendStatus(); + break; + case CMD_PING: + cmd_send(CMD_ACK,0,0,0,0,0); + break; #ifdef WITH_LCD case CMD_LCD_RESET: LCDReset(); @@ -1053,8 +1283,16 @@ void __attribute__((noreturn)) AppMain(void) WDT_HIT(); #ifdef WITH_LF +#ifndef WITH_ISO14443a_StandAlone if (BUTTON_HELD(1000) > 0) SamyRun(); +#endif +#endif +#ifdef WITH_ISO14443a +#ifdef WITH_ISO14443a_StandAlone + if (BUTTON_HELD(1000) > 0) + StandAloneMode14a(); +#endif #endif } } diff --git a/armsrc/apps.h b/armsrc/apps.h index a2812428..bb777eab 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -15,11 +15,10 @@ #include #include #include -#include -#include -#include -#include "../common/crc32.h" -#include "../common/lfdemod.h" +#include +#include "common.h" +#include "crc32.h" +#include "lfdemod.h" #include "BigBuf.h" #include "fpgaloader.h" #include "hitag2.h" diff --git a/armsrc/des.c b/armsrc/des.c index 172b3235..e72ebb2a 100644 --- a/armsrc/des.c +++ b/armsrc/des.c @@ -409,7 +409,6 @@ void tdes_dec(void* out, void* in, const uint8_t* key){ uint8_t i; unsigned char temp[8]; - uint8_t* tin = (uint8_t*) in; uint8_t* tout = (uint8_t*) out; @@ -432,6 +431,7 @@ void tdes_dec(void* out, void* in, const uint8_t* key){ } } + /******************************************************************************/ diff --git a/armsrc/desfire_crypto.c b/armsrc/desfire_crypto.c index 9ea07371..8bb80348 100644 --- a/armsrc/desfire_crypto.c +++ b/armsrc/desfire_crypto.c @@ -27,9 +27,8 @@ */ #include "desfire_crypto.h" -static void xor (const uint8_t *ivect, uint8_t *data, const size_t len); - -static size_t key_macing_length (desfirekey_t key); +static void xor (const uint8_t *ivect, uint8_t *data, const size_t len); +static size_t key_macing_length (desfirekey_t key); static void xor (const uint8_t *ivect, uint8_t *data, const size_t len) { for (size_t i = 0; i < len; i++) { diff --git a/armsrc/fpgaloader.c b/armsrc/fpgaloader.c index f8506550..b4117e82 100644 --- a/armsrc/fpgaloader.c +++ b/armsrc/fpgaloader.c @@ -560,3 +560,11 @@ void SetAdcMuxFor(uint32_t whichGpio) HIGH(whichGpio); } + +void Fpga_print_status(void) +{ + Dbprintf("Fgpa"); + if(downloaded_bitstream == FPGA_BITSTREAM_HF) Dbprintf(" mode.............HF"); + else if(downloaded_bitstream == FPGA_BITSTREAM_LF) Dbprintf(" mode.............LF"); + else Dbprintf(" mode.............%d", downloaded_bitstream); +} diff --git a/armsrc/fpgaloader.h b/armsrc/fpgaloader.h index 0bad3809..52d6c677 100644 --- a/armsrc/fpgaloader.h +++ b/armsrc/fpgaloader.h @@ -17,6 +17,7 @@ void FpgaGatherVersion(int bitstream_version, char *dst, int len); void FpgaSetupSsc(void); void SetupSpi(int mode); bool FpgaSetupSscDma(uint8_t *buf, int len); +void Fpga_print_status(); #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); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 9b7efaf6..38688a07 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -565,16 +565,18 @@ void RAMFUNC SniffIso14443a(uint8_t param) { // param: // bit 0 - trigger from first card answer // bit 1 - trigger from first reader 7-bit request - LEDsoff(); - iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); // Allocate memory from BigBuf for some buffers // free all previous allocations first BigBuf_free(); - + + // init trace buffer + clear_trace(); + set_tracing(TRUE); + // The command (reader -> tag) that we're receiving. uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); @@ -586,10 +588,6 @@ void RAMFUNC SniffIso14443a(uint8_t param) { // The DMA buffer, used to stream samples from the FPGA uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); - // init trace buffer - clear_trace(); - set_tracing(TRUE); - uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -715,12 +713,11 @@ void RAMFUNC SniffIso14443a(uint8_t param) { } } // main cycle - DbpString("COMMAND FINISHED"); - FpgaDisableSscDma(); + LEDsoff(); + Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); - LEDsoff(); } //----------------------------------------------------------------------------- @@ -1276,6 +1273,16 @@ void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data) ar_nr_responses[8], // AR2 ar_nr_responses[9] // NR2 ); + Dbprintf("../tools/mfkey/mfkey32v2 %06x%08x %08x %08x %08x %08x %08x %08x", + ar_nr_responses[0], // UID1 + ar_nr_responses[1], // UID2 + ar_nr_responses[2], // NT1 + ar_nr_responses[3], // AR1 + ar_nr_responses[4], // NR1 + ar_nr_responses[7], // NT2 + ar_nr_responses[8], // AR2 + ar_nr_responses[9] // NR2 + ); } uint8_t len = ar_nr_collected*5*4; cmd_send(CMD_ACK,CMD_SIMULATE_MIFARE_CARD,len,0,&ar_nr_responses,len); @@ -1298,9 +1305,15 @@ void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data) else { // Check for ISO 14443A-4 compliant commands, look at left nibble switch (receivedCmd[0]) { - + case 0x02: + case 0x03: { // IBlock (command no CID) + dynamic_response_info.response[0] = receivedCmd[0]; + dynamic_response_info.response[1] = 0x90; + dynamic_response_info.response[2] = 0x00; + dynamic_response_info.response_n = 3; + } break; case 0x0B: - case 0x0A: { // IBlock (command) + case 0x0A: { // IBlock (command CID) dynamic_response_info.response[0] = receivedCmd[0]; dynamic_response_info.response[1] = 0x00; dynamic_response_info.response[2] = 0x90; @@ -1320,15 +1333,17 @@ void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data) dynamic_response_info.response_n = 2; } break; - case 0xBA: { // - memcpy(dynamic_response_info.response,"\xAB\x00",2); - dynamic_response_info.response_n = 2; + case 0xBA: { // ping / pong + dynamic_response_info.response[0] = 0xAB; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response_n = 2; } break; case 0xCA: case 0xC2: { // Readers sends deselect command - memcpy(dynamic_response_info.response,"\xCA\x00",2); - dynamic_response_info.response_n = 2; + dynamic_response_info.response[0] = 0xCA; + dynamic_response_info.response[1] = 0x00; + dynamic_response_info.response_n = 2; } break; default: { @@ -1815,7 +1830,6 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive } } - void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) { CodeIso14443aBitsAsReaderPar(frame, bits, par); @@ -1831,13 +1845,11 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t } } - void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) { ReaderTransmitBitsPar(frame, len*8, par, timing); } - void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) { // Generate parity and redirect @@ -1846,7 +1858,6 @@ void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) ReaderTransmitBitsPar(frame, len, par, timing); } - void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) { // Generate parity and redirect @@ -2914,6 +2925,16 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * ar_nr_responses[8], // AR2 ar_nr_responses[9] // NR2 ); + Dbprintf("../tools/mfkey/mfkey32v2 %06x%08x %08x %08x %08x %08x %08x %08x", + ar_nr_responses[0], // UID1 + ar_nr_responses[1], // UID2 + ar_nr_responses[2], // NT1 + ar_nr_responses[3], // AR1 + ar_nr_responses[4], // NR1 + ar_nr_responses[7], // NT2 + ar_nr_responses[8], // AR2 + ar_nr_responses[9] // NR2 + ); } else { Dbprintf("Failed to obtain two AR/NR pairs!"); if(ar_nr_collected > 0 ) { @@ -3067,6 +3088,7 @@ void RAMFUNC SniffMifare(uint8_t param) { // And reset the Miller decoder including its (now outdated) input buffer UartInit(receivedCmd, receivedCmdPar); + // why not UartReset? } TagIsActive = (Demod.state != DEMOD_UNSYNCD); } @@ -3081,11 +3103,8 @@ void RAMFUNC SniffMifare(uint8_t param) { } // main cycle - DbpString("COMMAND FINISHED"); - FpgaDisableSscDma(); MfSniffEnd(); - - Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len); LEDsoff(); + Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len); } diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index 3344de43..81871dc7 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -12,8 +12,8 @@ #ifndef __ISO14443A_H #define __ISO14443A_H -#include "../include/common.h" -#include "../include/mifare.h" +#include "common.h" +#include "mifare.h" #include "mifaresniff.h" typedef struct { diff --git a/armsrc/iso14443b.c b/armsrc/iso14443b.c index daa219ce..fb8b4d66 100644 --- a/armsrc/iso14443b.c +++ b/armsrc/iso14443b.c @@ -525,6 +525,7 @@ static struct { * false if we are still waiting for some more * */ + #define abs(x) ( ((x)<0) ? -(x) : (x) ) static RAMFUNC int Handle14443bSamplesDemod(int ci, int cq) { int v = 0; diff --git a/armsrc/legicrf.c b/armsrc/legicrf.c index d11436ec..074a0f78 100644 --- a/armsrc/legicrf.c +++ b/armsrc/legicrf.c @@ -8,14 +8,14 @@ // LEGIC RF simulation code //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" #include "legicrf.h" -#include "../include/legic_prng.h" -#include "../common/crc.h" +#include "legic_prng.h" +#include "crc.h" static struct legic_frame { int bits; diff --git a/armsrc/lfops.c b/armsrc/lfops.c index b10b0c03..0cdd12d5 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -402,7 +402,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) for(;;) { //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS() || usb_poll()) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); return; } diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index f858dc1c..635934ef 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -17,7 +17,7 @@ sample_config config = { 1, 8, 1, 95, 0 } ; void printConfig() { - Dbprintf("Sampling config: "); + Dbprintf("LF Sampling config: "); Dbprintf(" [q] divisor: %d ", config.divisor); Dbprintf(" [b] bps: %d ", config.bits_per_sample); Dbprintf(" [d] decimation: %d ", config.decimation); diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h index 6c671ec8..7d3925cd 100644 --- a/armsrc/lfsampling.h +++ b/armsrc/lfsampling.h @@ -56,4 +56,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field); void setSamplingConfig(sample_config *sc); sample_config * getSamplingConfig(); + +void printConfig(); + + #endif // LFSAMPLING_H diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index 2c5a7e3f..3c00a343 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -13,15 +13,16 @@ #ifndef __MIFARECMD_H #define __MIFARECMD_H -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" -#include "../include/common.h" +#include "common.h" + #endif \ No newline at end of file diff --git a/armsrc/mifaresniff.h b/armsrc/mifaresniff.h index aa2a860f..22daffee 100644 --- a/armsrc/mifaresniff.h +++ b/armsrc/mifaresniff.h @@ -11,16 +11,16 @@ #ifndef __MIFARESNIFF_H #define __MIFARESNIFF_H -#include "../include/proxmark3.h" +#include "proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "../common/iso14443crc.h" +#include "iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" -#include "../include/common.h" +#include "common.h" #define SNF_INIT 0 #define SNF_NO_FIELD 1 diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 679b68d6..bf965d40 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -8,6 +8,7 @@ //----------------------------------------------------------------------------- // code for work with mifare cards. //----------------------------------------------------------------------------- +#include "crapto1.h" #ifndef __MIFAREUTIL_H #define __MIFAREUTIL_H diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index 7f4aa178..b522a164 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -148,7 +148,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY)); if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) { dont_ack = 1; - cmd_send(CMD_NACK,0,0,0,0,0); + cmd_send(CMD_NACK,sr,0,0,0,0); } } } break; diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 8d6afadd..8a6e6afd 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -549,6 +549,7 @@ int CmdHF14ASim(const char *Cmd) int len = (resp.arg[1] > sizeof(data)) ? sizeof(data) : resp.arg[1]; memcpy(data, resp.d.asBytes, len); tryMfk32(uid, data, key); + tryMfk32_moebius(uid, data, key); //tryMfk64(uid, data, key); PrintAndLog("--"); } @@ -726,6 +727,7 @@ int CmdHF14ACmdRaw(const char *cmd) { c.arg[1] = (datalen & 0xFFFF) | (numbits << 16); memcpy(c.d.asBytes,data,datalen); + clearCommandBuffer(); SendCommand(&c); if (reply) { diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index 3b577061..41ee59c1 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -1813,13 +1813,13 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ int CmdHF14AMfuELoad(const char *Cmd) { - FILE * f; - char filename[FILE_PATH_SIZE]; - char *fnameptr = filename; - char buf[64] = {0x00}; - uint8_t buf8[64] = {0x00}; - int i, len, blockNum, numBlocks; - int nameParamNo = 1; + //FILE * f; + //char filename[FILE_PATH_SIZE]; + //char *fnameptr = filename; + //char buf[64] = {0x00}; + //uint8_t buf8[64] = {0x00}; + //int i, len, blockNum, numBlocks; + //int nameParamNo = 1; char ctmp = param_getchar(Cmd, 0); diff --git a/client/cmdhw.c b/client/cmdhw.c index 0152f354..5f25241c 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -405,22 +405,45 @@ int CmdTune(const char *Cmd) int CmdVersion(const char *Cmd) { + clearCommandBuffer(); UsbCommand c = {CMD_VERSION}; static UsbCommand resp = {0, {0, 0, 0}}; - + if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && Cmd != NULL) { - PrintAndLog("Prox/RFID mark3 RFID instrument"); - PrintAndLog((char*)resp.d.asBytes); - lookupChipID(resp.arg[0], resp.arg[1]); - } - } else if (Cmd != NULL) { + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { PrintAndLog("Prox/RFID mark3 RFID instrument"); PrintAndLog((char*)resp.d.asBytes); lookupChipID(resp.arg[0], resp.arg[1]); } - + } else { + PrintAndLog("[[[ Cached information ]]]\n"); + PrintAndLog("Prox/RFID mark3 RFID instrument"); + PrintAndLog((char*)resp.d.asBytes); + lookupChipID(resp.arg[0], resp.arg[1]); + PrintAndLog(""); + } + return 0; +} + +int CmdStatus(const char *Cmd) +{ + UsbCommand c = {CMD_STATUS}; + SendCommand(&c); + return 0; +} + +int CmdPing(const char *Cmd) +{ + clearCommandBuffer(); + UsbCommand resp; + UsbCommand c = {CMD_PING}; + SendCommand(&c); + if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) { + PrintAndLog("Ping successfull"); + }else{ + PrintAndLog("Ping failed"); + } return 0; } @@ -437,6 +460,8 @@ static command_t CommandTable[] = {"setmux", CmdSetMux, 0, " -- Set the ADC mux to a specific value"}, {"tune", CmdTune, 0, "Measure antenna tuning"}, {"version", CmdVersion, 0, "Show version information about the connected Proxmark"}, + {"status", CmdStatus, 0, "Show runtime status information about the connected Proxmark"}, + {"ping", CmdPing, 0, "Test if the pm3 is responsive"}, {NULL, NULL, 0, NULL} }; diff --git a/client/cmdlfawid.c b/client/cmdlfawid.c index 233eb72c..5fdbf654 100644 --- a/client/cmdlfawid.c +++ b/client/cmdlfawid.c @@ -16,7 +16,7 @@ #include "cmdparser.h" // CmdsParse, CmdsHelp #include "cmdlfawid.h" // AWID function declarations #include "lfdemod.h" // parityTest - +#include "cmdmain.h" static int CmdHelp(const char *Cmd); @@ -69,6 +69,7 @@ int CmdAWIDDemodFSK(const char *Cmd) if (Cmd[0]=='h' || Cmd[0] == 'H') return usage_lf_awid_fskdemod(); UsbCommand c={CMD_AWID_DEMOD_FSK}; c.arg[0]=findone; + clearCommandBuffer(); SendCommand(&c); return 0; } @@ -167,17 +168,18 @@ int CmdAWIDSim(const char *Cmd) c.arg[2] = 96; // Bitstream length: 96-bits == 12 bytes for (i=0; i < 96; i++) c.d.asBytes[i] = (BS[i/8] & (1<<(7-(i%8))))?1:0; - SendCommand(&c); + clearCommandBuffer(); + SendCommand(&c); return 0; } int CmdAWIDClone(const char *Cmd) { +clearCommandBuffer(); uint32_t fc=0,cn=0,blocks[4] = {0x00107060, 0, 0, 0x11111111}, i=0; uint8_t BitStream[12]; uint8_t *BS=BitStream; - UsbCommand c; - + UsbCommand c, resp; if (sscanf(Cmd, "%u %u", &fc, &cn ) != 2) { return usage_lf_awid_clone(); @@ -206,6 +208,11 @@ int CmdAWIDClone(const char *Cmd) c.arg[1] = i; c.arg[2] = 0; SendCommand(&c); + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ + PrintAndLog("Error occurred, device did not respond during write operation."); + return -1; + } + } } return 0; diff --git a/client/flash.c b/client/flash.c index 4e222ece..d2163d9a 100644 --- a/client/flash.c +++ b/client/flash.c @@ -17,6 +17,7 @@ #include "elf.h" #include "proxendian.h" #include "usb_cmd.h" +#include "at91sam7s512.h" void SendCommand(UsbCommand* txcmd); void ReceiveCommand(UsbCommand* rxcmd); @@ -352,12 +353,11 @@ static int enter_bootloader(char *serial_port_name) return -1; } -static int wait_for_ack(void) +static int wait_for_ack(UsbCommand *ack) { - UsbCommand ack; - ReceiveCommand(&ack); - if (ack.cmd != CMD_ACK) { - printf("Error: Unexpected reply 0x%04"llx" (expected ACK)\n", ack.cmd); + ReceiveCommand(ack); + if (ack->cmd != CMD_ACK) { + printf("Error: Unexpected reply 0x%04"llx" (expected ACK)\n", ack->cmd); return -1; } return 0; @@ -389,7 +389,7 @@ int flash_start_flashing(int enable_bl_writes,char *serial_port_name) c.arg[2] = 0; } SendCommand(&c); - return wait_for_ack(); + return wait_for_ack(&c); } else { fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n"); fprintf(stderr, " It is recommended that you update your bootloader\n\n"); @@ -409,7 +409,18 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length) c.arg[0] = address; memcpy(c.d.asBytes, block_buf, length); SendCommand(&c); - return wait_for_ack(); + int ret = wait_for_ack(&c); + if (ret && c.arg[0]) { + uint32_t lock_bits = c.arg[0] >> 16; + bool lock_error = c.arg[0] & AT91C_MC_LOCKE; + bool prog_error = c.arg[0] & AT91C_MC_PROGE; + bool security_bit = c.arg[0] & AT91C_MC_SECURITY; + printf("%s", lock_error?" Lock Error\n":""); + printf("%s", prog_error?" Invalid Command or bad Keyword\n":""); + printf("%s", security_bit?" Security Bit is set!\n":""); + printf(" Lock Bits: 0x%04x\n", lock_bits); + } + return ret; } // Write a file's segments to Flash diff --git a/client/flasher.c b/client/flasher.c index e982ecf1..c273c1f3 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -13,7 +13,7 @@ #include "proxmark3.h" #include "flash.h" #include "uart.h" -#include "../include/usb_cmd.h" +#include "usb_cmd.h" #ifdef _WIN32 # define unlink(x) diff --git a/client/hid-flasher/usb_cmd.h b/client/hid-flasher/usb_cmd.h index 9a84186c..dfada01d 100644 --- a/client/hid-flasher/usb_cmd.h +++ b/client/hid-flasher/usb_cmd.h @@ -50,6 +50,9 @@ typedef struct { #define CMD_BUFF_CLEAR 0x0105 #define CMD_READ_MEM 0x0106 #define CMD_VERSION 0x0107 +#define CMD_STATUS 0x0108 +#define CMD_PING 0x0109 + // For low-frequency tags #define CMD_READ_TI_TYPE 0x0202 diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 1407f4be..1d4bd806 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -20,7 +20,8 @@ local _commands = { CMD_BUFF_CLEAR = 0x0105, CMD_READ_MEM = 0x0106, CMD_VERSION = 0x0107, - + CMD_STATUS = 0x0108, + CMD_PING = 0x0109, --// For low-frequency tags CMD_READ_TI_TYPE = 0x0202, CMD_WRITE_TI_TYPE = 0x0203, diff --git a/client/scripts/mifare_autopwn.lua b/client/scripts/mifare_autopwn.lua index eb98ffbf..9cc865f0 100644 --- a/client/scripts/mifare_autopwn.lua +++ b/client/scripts/mifare_autopwn.lua @@ -88,10 +88,33 @@ function mfcrack_inner() while not core.ukbhit() do local result = core.WaitForResponseTimeout(cmds.CMD_ACK,1000) if result then - -- Unpacking the three arg-parameters - local count,cmd,isOK = bin.unpack('LL',result) - if isOK ~= 1 then return nil, "Error occurred" end + --[[ + I don't understand, they cmd and args are defined as uint32_t, however, + looking at the returned data, they all look like 64-bit things: + + print("result", bin.unpack("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH", result)) + + FF 00 00 00 00 00 00 00 <-- 64 bits of data + FE FF FF FF 00 00 00 00 <-- 64 bits of data + 00 00 00 00 00 00 00 00 <-- 64 bits of data + 00 00 00 00 00 00 00 00 <-- 64 bits of data + 04 7F 12 E2 00 <-- this is where 'data' starts + + So below I use LI to pick out the "FEFF FFFF", don't know why it works.. + --]] + -- Unpacking the arg-parameters + local count,cmd,isOK = bin.unpack('LI',result) + --print("response", isOK)--FF FF FF FF + if isOK == 0xFFFFFFFF then + return nil, "Button pressed. Aborted." + elseif isOK == 0xFFFFFFFE then + return nil, "Card is not vulnerable to Darkside attack (doesn't send NACK on authentication requests). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys." + elseif isOK == 0xFFFFFFFD then + return nil, "Card is not vulnerable to Darkside attack (its random number generator is not predictable). You can try 'script run mfkeys' or 'hf mf chk' to test various known keys." + elseif isOK ~= 1 then + return nil, "Error occurred" + end -- The data-part is left diff --git a/common/iso14443crc.c b/common/iso14443crc.c index 851546ae..a6def1a9 100644 --- a/common/iso14443crc.c +++ b/common/iso14443crc.c @@ -6,7 +6,7 @@ // ISO14443 CRC calculation code. //----------------------------------------------------------------------------- -#include "../common/iso14443crc.h" +#include "iso14443crc.h" static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc) { diff --git a/common/iso14443crc.h b/common/iso14443crc.h index 80941116..87347714 100644 --- a/common/iso14443crc.h +++ b/common/iso14443crc.h @@ -8,7 +8,7 @@ #ifndef __ISO14443CRC_H #define __ISO14443CRC_H -#include "../include/common.h" +#include "common.h" //----------------------------------------------------------------------------- // Routines to compute the CRCs (two different flavours, just for confusion) diff --git a/common/iso15693tools.c b/common/iso15693tools.c index 0ec5492b..26e636ca 100644 --- a/common/iso15693tools.c +++ b/common/iso15693tools.c @@ -7,7 +7,7 @@ //----------------------------------------------------------------------------- -#include "../include/proxmark3.h" +#include "proxmark3.h" #include #include //#include "iso15693tools.h" diff --git a/common/legic_prng.c b/common/legic_prng.c index 322429ad..4f3b1ffe 100644 --- a/common/legic_prng.c +++ b/common/legic_prng.c @@ -6,7 +6,7 @@ // LEFIC's obfuscation function //----------------------------------------------------------------------------- -#include "../include/legic_prng.h" +#include "legic_prng.h" struct lfsr { uint8_t a; diff --git a/common/usb_cdc.c b/common/usb_cdc.c index ccbb3c50..3c6e9282 100644 --- a/common/usb_cdc.c +++ b/common/usb_cdc.c @@ -293,6 +293,22 @@ bool usb_poll() return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); } +/** + In github PR #129, some users appears to get a false positive from + usb_poll, which returns true, but the usb_read operation + still returns 0. + This check is basically the same as above, but also checks + that the length available to read is non-zero, thus hopefully fixes the + bug. +**/ +bool usb_poll_validate_length() +{ + + if (!usb_check()) return false; + if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false; + return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0; +} + //*---------------------------------------------------------------------------- //* \fn usb_read //* \brief Read available data from Endpoint OUT diff --git a/common/usb_cdc.h b/common/usb_cdc.h index 59e73a47..c42da8db 100644 --- a/common/usb_cdc.h +++ b/common/usb_cdc.h @@ -41,6 +41,7 @@ void usb_disable(); void usb_enable(); bool usb_check(); bool usb_poll(); +bool usb_poll_validate_length(); uint32_t usb_read(byte_t* data, size_t len); uint32_t usb_write(const byte_t* data, const size_t len); diff --git a/include/usb_cmd.h b/include/usb_cmd.h index bbdf69d5..353c6120 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -60,6 +60,8 @@ typedef struct{ #define CMD_BUFF_CLEAR 0x0105 #define CMD_READ_MEM 0x0106 #define CMD_VERSION 0x0107 +#define CMD_STATUS 0x0108 +#define CMD_PING 0x0109 // For low-frequency tags #define CMD_READ_TI_TYPE 0x0202 -- 2.39.5