Merge branch 'master' of github.com:RfidResearchGroup/proxmark3
[RRG-proxmark3.git] / armsrc / Standalone / hf_bog.c
blob1d766aa52e4c9ca7e113329f1ad69134e25e62a4
1 //-----------------------------------------------------------------------------
2 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
3 // at your option, any later version. See the LICENSE.txt file for the text of
4 // the license.
5 //-----------------------------------------------------------------------------
6 // main code for standalone HF Sniff (and ULC/NTAG/ULEV1 pwd storing)
7 //-----------------------------------------------------------------------------
9 /*
10 This can actually be used in two separate ways.
11 It can either be used to just HF 14a sniff on the go and/or grab the
12 authentication attempts for ULC/NTAG/ULEV1 into the flash mem (RDV4).
14 The retrieved sniffing session can be acquired by connecting the device
15 to a client that supports the reconnect capability and issue 'hf 14a list'.
17 In order to view the grabbed authentication attempts in the flash mem,
18 you can simply run 'script run mem_readpwd' or just 'mem dump p l 256'
19 from the client to view the stored quadlets.
22 #include "standalone.h" // standalone definitions
23 #include "proxmark3_arm.h"
24 #include "iso14443a.h"
25 #include "protocols.h"
26 #include "util.h"
27 #include "spiffs.h"
28 #include "appmain.h"
29 #include "fpgaloader.h"
30 #include "dbprint.h"
31 #include "ticks.h"
32 #include "BigBuf.h"
33 #include "string.h"
35 #define DELAY_READER_AIR2ARM_AS_SNIFFER (2 + 3 + 8)
36 #define DELAY_TAG_AIR2ARM_AS_SNIFFER (3 + 14 + 8)
38 // Maximum number of auth attempts per standalone session
39 #define MAX_PWDS_PER_SESSION 64
41 #define HF_BOG_LOGFILE "hf_bog.log"
43 // This is actually copied from SniffIso14443a
44 static void RAMFUNC SniffAndStore(uint8_t param) {
46 iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
48 // Allocate memory from BigBuf for some buffers
49 // free all previous allocations first
50 BigBuf_free();
51 BigBuf_Clear_ext(false);
52 clear_trace();
53 set_tracing(true);
55 // Array to store the authpwds
56 uint8_t *capturedPwds = BigBuf_malloc(4 * MAX_PWDS_PER_SESSION);
58 // The command (reader -> tag) that we're receiving.
59 uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
60 uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
62 // The response (tag -> reader) that we're receiving.
63 uint8_t *receivedResp = BigBuf_malloc(MAX_FRAME_SIZE);
64 uint8_t *receivedRespPar = BigBuf_malloc(MAX_PARITY_SIZE);
66 // The DMA buffer, used to stream samples from the FPGA
67 uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE);
68 uint8_t *data = dmaBuf;
70 uint8_t previous_data = 0;
71 int dataLen;
72 bool TagIsActive = false;
73 bool ReaderIsActive = false;
75 // Set up the demodulator for tag -> reader responses.
76 Demod14aInit(receivedResp, receivedRespPar);
78 // Set up the demodulator for the reader -> tag commands
79 Uart14aInit(receivedCmd, receivedCmdPar);
81 // Setup and start DMA.
82 if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) {
83 if (DBGLEVEL > 1)
84 Dbprintf("FpgaSetupSscDma failed. Exiting");
85 return;
88 tUart14a *uart = GetUart14a();
89 tDemod14a *demod = GetDemod14a();
91 // We won't start recording the frames that we acquire until we trigger;
92 // a good trigger condition to get started is probably when we see a
93 // response from the tag.
94 // triggered == false -- to wait first for card
95 bool triggered = !(param & 0x03);
97 uint32_t my_rsamples = 0;
99 // Current captured passwords counter
100 uint8_t auth_attempts = 0;
102 SpinDelay(50);
104 // loop and listen
105 while (!BUTTON_PRESS()) {
106 WDT_HIT();
107 LED_A_ON();
109 int register readBufDataP = data - dmaBuf;
110 int register dmaBufDataP = DMA_BUFFER_SIZE - AT91C_BASE_PDC_SSC->PDC_RCR;
111 if (readBufDataP <= dmaBufDataP)
112 dataLen = dmaBufDataP - readBufDataP;
113 else
114 dataLen = DMA_BUFFER_SIZE - readBufDataP + dmaBufDataP;
116 // test for length of buffer
117 if (dataLen > DMA_BUFFER_SIZE) { // TODO: Check if this works properly
118 Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
119 break;
121 if (dataLen < 1)
122 continue;
124 // primary buffer was stopped( <-- we lost data!
125 if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
126 AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
127 AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
128 // Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
130 // secondary buffer sets as primary, secondary buffer was stopped
131 if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
132 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
133 AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
136 LED_A_OFF();
138 // Need two samples to feed Miller and Manchester-Decoder
139 if (my_rsamples & 0x01) {
141 if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
142 uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
143 if (MillerDecoding(readerdata, (my_rsamples - 1) * 4)) {
144 LED_C_ON();
146 // check - if there is a short 7bit request from reader
147 if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7))
148 triggered = true;
150 if (triggered) {
151 if ((receivedCmd) &&
152 ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) {
153 if (DBGLEVEL > 1)
154 Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2],
155 receivedCmd[3], receivedCmd[4]);
157 // temporarily save the captured pwd in our array
158 memcpy(&capturedPwds[4 * auth_attempts], receivedCmd + 1, 4);
159 auth_attempts++;
162 if (!LogTrace(receivedCmd, uart->len, uart->startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
163 uart->endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, uart->parity, true))
164 break;
166 /* ready to receive another command. */
167 Uart14aReset();
168 /* reset the demod code, which might have been */
169 /* false-triggered by the commands from the reader. */
170 Demod14aReset();
171 LED_B_OFF();
173 ReaderIsActive = (uart->state != STATE_14A_UNSYNCD);
176 // no need to try decoding tag data if the reader is sending - and we cannot afford the time
177 if (!ReaderIsActive) {
178 uint8_t tagdata = (previous_data << 4) | (*data & 0x0F);
179 if (ManchesterDecoding(tagdata, 0, (my_rsamples - 1) * 4)) {
180 LED_B_ON();
182 if (!LogTrace(receivedResp, demod->len, demod->startTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
183 demod->endTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, demod->parity, false))
184 break;
186 if ((!triggered) && (param & 0x01))
187 triggered = true;
189 // ready to receive another response.
190 Demod14aReset();
191 // reset the Miller decoder including its (now outdated) input buffer
192 Uart14aReset();
193 // UartInit(receivedCmd, receivedCmdPar);
194 LED_C_OFF();
196 TagIsActive = (demod->state != DEMOD_14A_UNSYNCD);
200 previous_data = *data;
201 my_rsamples++;
202 data++;
203 if (data == dmaBuf + DMA_BUFFER_SIZE) {
204 data = dmaBuf;
206 } // end main loop
208 FpgaDisableSscDma();
209 set_tracing(false);
211 Dbprintf("Stopped sniffing");
213 SpinDelay(200);
215 // Write stuff to spiffs logfile
216 if (auth_attempts > 0) {
217 if (DBGLEVEL > 1)
218 Dbprintf("[!] Authentication attempts = %u", auth_attempts);
220 if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) {
221 rdv40_spiffs_write((char *)HF_BOG_LOGFILE, capturedPwds, 4 * auth_attempts, RDV40_SPIFFS_SAFETY_SAFE);
222 } else {
223 rdv40_spiffs_append((char *)HF_BOG_LOGFILE, capturedPwds, 4 * auth_attempts, RDV40_SPIFFS_SAFETY_SAFE);
227 if (DBGLEVEL > 1)
228 Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts);
230 SpinErr(LED_A, 200, 5);
231 SpinDelay(100);
234 void ModInfo(void) {
235 DbpString(" HF 14a sniff standalone with ULC/ULEV1/NTAG auth storing in flashmem - aka BogitoRun (Bogito)");
238 void RunMod(void) {
240 StandAloneMode();
242 Dbprintf(">> Bogiton 14a Sniff UL/UL-EV1/NTAG a.k.a BogitoRun Started <<");
243 Dbprintf("Starting to sniff");
245 // param:
246 // bit 0 - trigger from first card answer
247 // bit 1 - trigger from first reader 7-bit request
248 SniffAndStore(0);
249 LEDsoff();
250 SpinDelay(300);
251 Dbprintf("- [ End ] -> You can take shell back ...");
252 Dbprintf("- [ ! ] -> use 'script run data_read_pwd_mem_spiffs' to print passwords");