1 //-----------------------------------------------------------------------------
3 // based on code by: Artyom Gnatyuk, 2020
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // LF rswb - This mode can simulate ID from selected slot, read ID to
10 // selected slot, write from selected slot to T5555/T55x7 tag and store
11 // readed ID to flash (only RDV4).
12 // Predefined its is not recomended because you can incedently rewrite your MANDATORY tag data.
14 // To recall stored ID from flash execute:
15 // mem spifss dump o emdump p
17 // mem spifss dump o emdump f emdump
19 // hexdump emdump -e '5/1 "%02X" /0 "\n"'
21 // Mode list (switched by single click):
23 // 0 - READ Read source card ID and store it to current slot
24 // Will switch to SIM mode automatically.
26 // 1 - SIM Simulate readed ID
28 // 2 - WRITE(CLONE) Write readed ID to T55x7 card
29 // !!! Warning, card id WILL BE OVERRWRITED
31 // 3 - BRUTE Brute upper or down from readed card)
32 // You can PRESS SINGLE to exit brute mode OR
33 // PRESS DOUBLE to save bruted ID to current slot (will automatically switch to SIM mode) AND
34 // Also You can HOLD button to change brute speeds.
36 // Slots are switched by HOLD (LONG PRESS)
37 //-----------------------------------------------------------------------------
38 #include "standalone.h"
39 #include "proxmark3_arm.h"
41 #include "fpgaloader.h"
56 #define LF_CLOCK 64 // for 125kHz
57 #define LF_RWSB_T55XX_TYPE 1 // Tag type: 0 - T5555, 1-T55x7
59 #define LF_RWSB_UNKNOWN_RESULT 0
60 #define LF_RWSB_BRUTE_STOPED 1
61 #define LF_RWSB_BRUTE_SAVED 2
64 #define LF_RWSB_MODE_READ 0
65 #define LF_RWSB_MODE_SIM 1
66 #define LF_RWSB_MODE_WRITE 2
67 #define LF_RWSB_MODE_BRUTE 3
69 // Predefined bruteforce speed
70 // avg: 1s, 1.2s, 1.5s, 2s
71 static int bruteforceSpeedCurrent
= 1;
72 static int bruteforceSpeed
[] = {10, 12, 14, 16};
74 // low & high - array for storage IDs. Its length must be equal.
75 // Predefined IDs must be stored in low[].
76 // In high[] must be nulls
77 static uint64_t low
[] = {0, 0, 0, 0};
78 static uint32_t high
[] = {0, 0, 0, 0};
82 DbpString(" LF EM4100 read/sim/write/brute mode");
85 static uint64_t rev_quads(uint64_t bits
) {
87 for (int i
= 0; i
< 16; i
++) {
88 result
+= ((bits
>> (60 - 4 * i
)) & 0xf) << (4 * i
);
93 static void fill_buff(uint8_t bit
) {
94 uint8_t *bba
= BigBuf_get_addr();
95 memset(bba
+ buflen
, bit
, LF_CLOCK
/ 2);
96 buflen
+= (LF_CLOCK
/ 2);
97 memset(bba
+ buflen
, bit
^ 1, LF_CLOCK
/ 2);
98 buflen
+= (LF_CLOCK
/ 2);
101 static void construct_EM410x_emul(uint64_t id
) {
103 int binary
[4] = {0, 0, 0, 0};
104 int parity
[4] = {0, 0, 0, 0};
107 for (i
= 0; i
< 9; i
++)
110 for (i
= 0; i
< 10; i
++) {
111 for (j
= 3; j
>= 0; j
--, id
/= 2)
114 for (j
= 0; j
< 4; j
++)
115 fill_buff(binary
[j
]);
117 fill_buff(binary
[0] ^ binary
[1] ^ binary
[2] ^ binary
[3]);
118 for (j
= 0; j
< 4; j
++)
119 parity
[j
] ^= binary
[j
];
122 for (j
= 0; j
< 4; j
++)
123 fill_buff(parity
[j
]);
128 static void LED_Update(int mode
, int slot
) {
160 static void FlashLEDs(uint32_t speed
, uint8_t times
) {
161 for (int i
= 0; i
< times
* 2; i
++) {
171 static void SaveIDtoFlash(int addr
, uint64_t id
) {
173 char *filename
= "emdump";
174 rdv40_spiffs_mount();
175 for (int i
= 0; i
< 5; i
++) {
176 bt
[4 - i
] = (uint8_t)(id
>> 8 * i
& 0xff);
178 if (exists_in_spiffs(filename
) == false) {
179 rdv40_spiffs_write(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
181 rdv40_spiffs_append(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
186 static uint64_t PackEmID(uint64_t original
, int newCardNum
) {
187 uint64_t buf
= original
;
192 for (int i
= 1; i
<= 16; i
++) {
195 buf
|= (newCardNum
& 0xFFFF) << 1;
196 buf
|= oddparity32((buf
>> 1) & 0xFFF);
197 buf
|= (evenparity32((buf
>> 13) & 0xFFF)) << 25;
199 uint32_t cardnumNew
= (buf
>> 1) & 0xFFFF;
200 uint32_t fcNew
= (buf
>> 17) & 0xFF;
201 Dbprintf("[=] RECONSTRUCT TAG ID: %"PRIx64
" - FC: %u - Card: %u\n", buf
, fcNew
, cardnumNew
);
205 static void PrintFcAndCardNum(uint64_t lowData
) {
206 // Calculate Facility Code and Card Number from high and low
207 uint32_t fc
= (lowData
>> 17) & 0xFF;
208 uint32_t cardnum
= (lowData
>> 1) & 0xFFFF;
209 Dbprintf("[=] READ TAG ID: %"PRIx64
" - FC: %u - Card: %u", lowData
, fc
, cardnum
);
212 static int BruteEMTag(uint64_t originalCard
, int slot
) {
217 uint32_t cardnum
= (originalCard
>> 1) & 0xFFFF;
218 if (cardnum
> 32767) {
222 while (cardnum
> 1 && cardnum
< 65535) {
224 if (data_available()) break;
226 cardnum
= cardnum
+ direction
;
227 uint64_t currentCard
= PackEmID(originalCard
, cardnum
);
228 Dbprintf("[=] >> Simulating card id %"PRIx64
" <<", currentCard
);
229 construct_EM410x_emul(rev_quads(currentCard
));
230 SimulateTagLowFrequencyEx(buflen
, 0, 1, bruteforceSpeed
[bruteforceSpeedCurrent
] * 10000);
232 int button_pressed
= BUTTON_CLICKED(1000);
233 if (button_pressed
== BUTTON_SINGLE_CLICK
) {
234 Dbprintf("[=] >> Exit bruteforce mode without saving. <<");
235 return LF_RWSB_BRUTE_STOPED
;
236 } else if (button_pressed
== BUTTON_DOUBLE_CLICK
) {
238 Dbprintf("[=] >> Saving bruteforced card to current slot <<");
239 low
[slot
] = currentCard
;
241 SaveIDtoFlash(slot
, low
[slot
]);
243 return LF_RWSB_BRUTE_SAVED
;
244 } else if (button_pressed
== BUTTON_HOLD
) {
246 WAIT_BUTTON_RELEASED();
247 bruteforceSpeedCurrent
= (bruteforceSpeedCurrent
+ 1) % speed_count
;
248 FlashLEDs(100, bruteforceSpeedCurrent
+ 1);
249 Dbprintf("[=] >> Setting speed to %d (%d) <<", bruteforceSpeedCurrent
, bruteforceSpeed
[bruteforceSpeedCurrent
]);
252 return LF_RWSB_BRUTE_STOPED
;
255 static int ExecuteMode(int mode
, int slot
) {
256 LED_Update(mode
, slot
);
260 //default first mode is simulate
261 case LF_RWSB_MODE_READ
:
262 Dbprintf("[=] >> Read mode started <<");
263 lf_em410x_watch(1, &high
[slot
], &low
[slot
]);
264 LED_Update(mode
, slot
);
265 Dbprintf("[=] >> Tag found. Saving. <<");
267 PrintFcAndCardNum(low
[slot
]);
269 SaveIDtoFlash(slot
, low
[slot
]);
271 return LF_RWSB_UNKNOWN_RESULT
;
272 case LF_RWSB_MODE_SIM
:
273 Dbprintf("[=] >> Sim mode started <<");
274 construct_EM410x_emul(rev_quads(low
[slot
]));
275 SimulateTagLowFrequency(buflen
, 0, true);
276 return LF_RWSB_UNKNOWN_RESULT
;
277 case LF_RWSB_MODE_WRITE
:
278 Dbprintf("[!!] >> Write mode started <<");
279 copy_em410x_to_t55xx(LF_RWSB_T55XX_TYPE
, LF_CLOCK
, (uint32_t)(low
[slot
] >> 32), (uint32_t)(low
[slot
] & 0xffffffff));
280 return LF_RWSB_UNKNOWN_RESULT
;
281 case LF_RWSB_MODE_BRUTE
:
282 Dbprintf("[=] >> Bruteforce mode started <<");
283 return BruteEMTag(low
[slot
], slot
);
285 return LF_RWSB_UNKNOWN_RESULT
;
288 static int SwitchMode(int mode
, int slot
) {
290 ExecuteMode(mode
, slot
);
292 if (mode
== LF_RWSB_MODE_READ
) {
293 //After read mode we need to switch to sim mode automatically
294 Dbprintf("[=] >> automatically switch to sim mode after read <<");
296 return SwitchMode(LF_RWSB_MODE_SIM
, slot
);
297 } else if (mode
== LF_RWSB_MODE_BRUTE
) {
298 //We have already have a click inside brute mode. Lets switch next mode
299 Dbprintf("[=] >> automatically switch to read mode after brute <<");
301 return SwitchMode(LF_RWSB_MODE_READ
, slot
);
308 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
309 Dbprintf("[=] >> LF EM4100 read/write/clone/brute started <<");
315 mode
= SwitchMode(mode
, slot
);
319 if (data_available()) break;
321 int button_pressed
= BUTTON_CLICKED(1000);
322 LED_Update(mode
, slot
);
324 //press button - switch mode
325 //hold button - switch slot
326 if (button_pressed
== BUTTON_SINGLE_CLICK
) {
327 Dbprintf("[=] >> Single click <<");
328 mode
= (mode
+ 1) % mode_count
;
331 mode
= SwitchMode(mode
, slot
);
332 } else if (button_pressed
== BUTTON_HOLD
) {
333 Dbprintf("[=] >> Button hold <<");
334 slot
= (slot
+ 1) % slots_count
;
338 //automatically switch to SIM mode on slot selection
339 mode
= LF_RWSB_MODE_SIM
;
340 mode
= SwitchMode(mode
, slot
);