1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2020 Dmitriy Loginoov
3 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // See LICENSE.txt for the text of the license.
16 //-----------------------------------------------------------------------------
17 // LF rswb - This mode can simulate ID from selected slot, read ID to
18 // selected slot, write from selected slot to T5555/T55x7 tag and store
19 // read ID to flash (only RDV4).
20 // Predefining it is not recommended because you can incidentally rewrite your MANDATORY tag data.
22 // To recall stored ID from flash execute:
23 // mem spifss dump o emdump p
25 // mem spifss dump o emdump f emdump
27 // hexdump emdump -e '5/1 "%02X" /0 "\n"'
29 // Mode list (switched by single click):
31 // 0 - READ Read source card ID and store it to current slot
32 // Will switch to SIM mode automatically.
34 // 1 - SIM Simulate read ID
36 // 2 - WRITE(CLONE) Write read ID to T55x7 card
37 // !!! Warning, card id WILL BE OVERWRITTEN
39 // 3 - BRUTE Brute upper or down from read card)
40 // You can PRESS SINGLE to exit brute mode OR
41 // PRESS DOUBLE to save bruted ID to current slot (will automatically switch to SIM mode) AND
42 // Also You can HOLD button to change brute speeds.
44 // Slots are switched by HOLD (LONG PRESS)
45 //-----------------------------------------------------------------------------
46 #include "standalone.h"
47 #include "proxmark3_arm.h"
49 #include "fpgaloader.h"
64 #define LF_CLOCK 64 // for 125kHz
65 #define LF_RWSB_T55XX_TYPE 1 // Tag type: 0 - T5555, 1-T55x7, 2-EM4x05
67 #define LF_RWSB_UNKNOWN_RESULT 0
68 #define LF_RWSB_BRUTE_STOPED 1
69 #define LF_RWSB_BRUTE_SAVED 2
72 #define LF_RWSB_MODE_READ 0
73 #define LF_RWSB_MODE_SIM 1
74 #define LF_RWSB_MODE_WRITE 2
75 #define LF_RWSB_MODE_BRUTE 3
77 // Predefined bruteforce speed
78 // avg: 1s, 1.2s, 1.5s, 2s
79 static int em4100rswb_bruteforceSpeedCurrent
= 1;
80 static int em4100rswb_bruteforceSpeed
[] = {10, 12, 14, 16};
82 // em4100rswb_low & em4100rswb_high - array for storage IDs. Its length must be equal.
83 // Predefined IDs must be stored in em4100rswb_low[].
84 // In em4100rswb_high[] must be nulls
85 static uint64_t em4100rswb_low
[] = {0, 0, 0, 0};
86 static uint32_t em4100rswb_high
[] = {0, 0, 0, 0};
87 static int em4100rswb_buflen
;
90 DbpString(" LF EM4100 read/sim/write/brute mode");
93 static uint64_t rev_quads(uint64_t bits
) {
95 for (int i
= 0; i
< 16; i
++) {
96 result
+= ((bits
>> (60 - 4 * i
)) & 0xf) << (4 * i
);
101 static void fill_buff(uint8_t bit
) {
102 uint8_t *bba
= BigBuf_get_addr();
103 memset(bba
+ em4100rswb_buflen
, bit
, LF_CLOCK
/ 2);
104 em4100rswb_buflen
+= (LF_CLOCK
/ 2);
105 memset(bba
+ em4100rswb_buflen
, bit
^ 1, LF_CLOCK
/ 2);
106 em4100rswb_buflen
+= (LF_CLOCK
/ 2);
109 static void construct_EM410x_emul(uint64_t id
) {
111 int binary
[4] = {0, 0, 0, 0};
112 int parity
[4] = {0, 0, 0, 0};
113 em4100rswb_buflen
= 0;
115 for (i
= 0; i
< 9; i
++)
118 for (i
= 0; i
< 10; i
++) {
119 for (j
= 3; j
>= 0; j
--, id
/= 2)
122 for (j
= 0; j
< 4; j
++)
123 fill_buff(binary
[j
]);
125 fill_buff(binary
[0] ^ binary
[1] ^ binary
[2] ^ binary
[3]);
126 for (j
= 0; j
< 4; j
++)
127 parity
[j
] ^= binary
[j
];
130 for (j
= 0; j
< 4; j
++)
131 fill_buff(parity
[j
]);
136 static void LED_Update(int mode
, int slot
) {
168 static void FlashLEDs(uint32_t speed
, uint8_t times
) {
169 for (int i
= 0; i
< times
* 2; i
++) {
179 static void SaveIDtoFlash(int addr
, uint64_t id
) {
181 char *filename
= "emdump";
182 rdv40_spiffs_mount();
183 for (int i
= 0; i
< 5; i
++) {
184 bt
[4 - i
] = (uint8_t)(id
>> 8 * i
& 0xff);
186 if (exists_in_spiffs(filename
) == false) {
187 rdv40_spiffs_write(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
189 rdv40_spiffs_append(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
194 static uint64_t PackEmID(uint64_t original
, int newCardNum
) {
195 uint64_t buf
= original
;
200 for (int i
= 1; i
<= 16; i
++) {
203 buf
|= (newCardNum
& 0xFFFF) << 1;
204 buf
|= oddparity32((buf
>> 1) & 0xFFF);
205 buf
|= (evenparity32((buf
>> 13) & 0xFFF)) << 25;
207 uint32_t cardnumNew
= (buf
>> 1) & 0xFFFF;
208 uint32_t fcNew
= (buf
>> 17) & 0xFF;
209 Dbprintf("[=] RECONSTRUCT TAG ID: %"PRIx64
" - FC: %u - Card: %u\n", buf
, fcNew
, cardnumNew
);
213 static void PrintFcAndCardNum(uint64_t lowData
) {
214 // Calculate Facility Code and Card Number from high and low
215 uint32_t fc
= (lowData
>> 17) & 0xFF;
216 uint32_t cardnum
= (lowData
>> 1) & 0xFFFF;
217 Dbprintf("[=] READ TAG ID: %"PRIx64
" - FC: %u - Card: %u", lowData
, fc
, cardnum
);
220 static int BruteEMTag(uint64_t originalCard
, int slot
) {
225 uint32_t cardnum
= (originalCard
>> 1) & 0xFFFF;
226 if (cardnum
> 32767) {
230 while (cardnum
> 1 && cardnum
< 65535) {
232 if (data_available()) break;
234 cardnum
= cardnum
+ direction
;
235 uint64_t currentCard
= PackEmID(originalCard
, cardnum
);
236 Dbprintf("[=] >> Simulating card id %"PRIx64
" <<", currentCard
);
237 construct_EM410x_emul(rev_quads(currentCard
));
238 SimulateTagLowFrequencyEx(em4100rswb_buflen
, 0, 1, em4100rswb_bruteforceSpeed
[em4100rswb_bruteforceSpeedCurrent
] * 10000);
240 int button_pressed
= BUTTON_CLICKED(1000);
241 if (button_pressed
== BUTTON_SINGLE_CLICK
) {
242 Dbprintf("[=] >> Exit bruteforce mode without saving. <<");
243 return LF_RWSB_BRUTE_STOPED
;
244 } else if (button_pressed
== BUTTON_DOUBLE_CLICK
) {
246 Dbprintf("[=] >> Saving bruteforced card to current slot <<");
247 em4100rswb_low
[slot
] = currentCard
;
249 SaveIDtoFlash(slot
, em4100rswb_low
[slot
]);
251 return LF_RWSB_BRUTE_SAVED
;
252 } else if (button_pressed
== BUTTON_HOLD
) {
254 WAIT_BUTTON_RELEASED();
255 em4100rswb_bruteforceSpeedCurrent
= (em4100rswb_bruteforceSpeedCurrent
+ 1) % speed_count
;
256 FlashLEDs(100, em4100rswb_bruteforceSpeedCurrent
+ 1);
257 Dbprintf("[=] >> Setting speed to %d (%d) <<", em4100rswb_bruteforceSpeedCurrent
, em4100rswb_bruteforceSpeed
[em4100rswb_bruteforceSpeedCurrent
]);
260 return LF_RWSB_BRUTE_STOPED
;
263 static int ExecuteMode(int mode
, int slot
) {
264 LED_Update(mode
, slot
);
268 //default first mode is simulate
269 case LF_RWSB_MODE_READ
:
270 Dbprintf("[=] >> Read mode started <<");
271 lf_em410x_watch(1, &em4100rswb_high
[slot
], &em4100rswb_low
[slot
], true);
272 LED_Update(mode
, slot
);
273 Dbprintf("[=] >> Tag found. Saving. <<");
275 PrintFcAndCardNum(em4100rswb_low
[slot
]);
277 SaveIDtoFlash(slot
, em4100rswb_low
[slot
]);
279 return LF_RWSB_UNKNOWN_RESULT
;
280 case LF_RWSB_MODE_SIM
:
281 Dbprintf("[=] >> Sim mode started <<");
282 construct_EM410x_emul(rev_quads(em4100rswb_low
[slot
]));
283 SimulateTagLowFrequency(em4100rswb_buflen
, 0, true);
284 return LF_RWSB_UNKNOWN_RESULT
;
285 case LF_RWSB_MODE_WRITE
:
286 Dbprintf("[!!] >> Write mode started <<");
287 copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE
289 , (uint32_t)(em4100rswb_low
[slot
] >> 32)
290 , (uint32_t)(em4100rswb_low
[slot
] & 0xffffffff)
294 return LF_RWSB_UNKNOWN_RESULT
;
295 case LF_RWSB_MODE_BRUTE
:
296 Dbprintf("[=] >> Bruteforce mode started <<");
297 return BruteEMTag(em4100rswb_low
[slot
], slot
);
299 return LF_RWSB_UNKNOWN_RESULT
;
302 static int SwitchMode(int mode
, int slot
) {
304 ExecuteMode(mode
, slot
);
306 if (mode
== LF_RWSB_MODE_READ
) {
307 //After read mode we need to switch to sim mode automatically
308 Dbprintf("[=] >> automatically switch to sim mode after read <<");
310 return SwitchMode(LF_RWSB_MODE_SIM
, slot
);
311 } else if (mode
== LF_RWSB_MODE_BRUTE
) {
312 //We have already have a click inside brute mode. Lets switch next mode
313 Dbprintf("[=] >> automatically switch to read mode after brute <<");
315 return SwitchMode(LF_RWSB_MODE_READ
, slot
);
322 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
323 Dbprintf("[=] >> LF EM4100 read/write/clone/brute started <<");
329 mode
= SwitchMode(mode
, slot
);
333 if (data_available()) break;
335 int button_pressed
= BUTTON_CLICKED(1000);
336 LED_Update(mode
, slot
);
338 //press button - switch mode
339 //hold button - switch slot
340 if (button_pressed
== BUTTON_SINGLE_CLICK
) {
341 Dbprintf("[=] >> Single click <<");
342 mode
= (mode
+ 1) % mode_count
;
345 mode
= SwitchMode(mode
, slot
);
346 } else if (button_pressed
== BUTTON_HOLD
) {
347 Dbprintf("[=] >> Button hold <<");
348 slot
= (slot
+ 1) % slots_count
;
352 //automatically switch to SIM mode on slot selection
353 mode
= LF_RWSB_MODE_SIM
;
354 mode
= SwitchMode(mode
, slot
);