1 //-----------------------------------------------------------------------------
2 // Artyom Gnatyuk, 2020
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // LF rwc - This mode can simulate ID from selected slot, read ID to
9 // selected slot, write from selected slot to T5555 tag and store
10 // readed ID to flash (only RDV4). Also you can set predefined IDs
12 // To recall stored ID from flash execute:
13 // mem spifss dump o emdump p
15 // mem spifss dump o emdump f emdump
17 // hexdump emdump -e '5/1 "%02X" /0 "\n"'
18 //-----------------------------------------------------------------------------
19 #include "standalone.h"
20 #include "proxmark3_arm.h"
22 #include "fpgaloader.h"
30 #include "commonutil.h"
36 #define MAX_IND 16 // 4 LEDs - 2^4 combinations
37 #define LF_CLOCK 64 // for 125kHz
39 // low & high - array for storage IDs. Its length must be equal.
40 // Predefined IDs must be stored in low[].
41 // In high[] must be nulls
42 static uint64_t low
[] = {0x565AF781C7, 0x540053E4E2, 0x1234567890, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
43 static uint32_t high
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
44 static uint8_t slots_count
;
48 DbpString(" LF EM4100 read/write/clone mode");
51 static uint64_t rev_quads(uint64_t bits
) {
53 for (int i
= 0; i
< 16; i
++) {
54 result
+= ((bits
>> (60 - 4 * i
)) & 0xf) << (4 * i
);
59 static void fill_buff(uint8_t bit
) {
60 uint8_t *bba
= BigBuf_get_addr();
61 memset(bba
+ buflen
, bit
, LF_CLOCK
/ 2);
62 buflen
+= (LF_CLOCK
/ 2);
63 memset(bba
+ buflen
, bit
^ 1, LF_CLOCK
/ 2);
64 buflen
+= (LF_CLOCK
/ 2);
67 static void construct_EM410x_emul(uint64_t id
) {
70 int binary
[4] = {0, 0, 0, 0};
71 int parity
[4] = {0, 0, 0, 0};
74 for (i
= 0; i
< 9; i
++)
77 for (i
= 0; i
< 10; i
++) {
78 for (j
= 3; j
>= 0; j
--, id
/= 2)
81 for (j
= 0; j
< 4; j
++)
84 fill_buff(binary
[0] ^ binary
[1] ^ binary
[2] ^ binary
[3]);
85 for (j
= 0; j
< 4; j
++)
86 parity
[j
] ^= binary
[j
];
89 for (j
= 0; j
< 4; j
++)
95 static void led_slot(int i
) {
97 if (slots_count
> 4) {
98 LED(i
% MAX_IND
, 0); //binary indication, usefully for slots_count > 4
100 LED(1 << i
, 0); //simple indication for slots_count <=4
104 static void flash_leds(uint32_t speed
, uint8_t times
) {
105 for (uint16_t i
= 0; i
< times
* 2; i
++) {
115 static void SaveIDtoFlash(int addr
, uint64_t id
) {
117 const char *filename
= "emdump";
118 rdv40_spiffs_mount();
119 for (int i
= 0; i
< 5; i
++) {
120 bt
[4 - i
] = (uint8_t)(id
>> 8 * i
& 0xff);
122 if (exists_in_spiffs(filename
) == false) {
123 rdv40_spiffs_write(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
125 rdv40_spiffs_append(filename
, &bt
[0], 5, RDV40_SPIFFS_SAFETY_NORMAL
);
132 FpgaDownloadAndGo(FPGA_BITSTREAM_LF
);
133 Dbprintf("[=] >> LF EM4100 read/write/clone started <<");
136 //state 0 - select slot
137 // 1 - read tag to selected slot,
138 // 2 - simulate tag from selected slot
139 // 3 - write to T5555 tag
141 slots_count
= ARRAYLEN(low
);
147 if (data_available()) break;
149 int button_pressed
= BUTTON_HELD(1000);
155 if (button_pressed
== BUTTON_HOLD
) {
156 // Long press - switch to simulate mode
160 } else if (button_pressed
== BUTTON_SINGLE_CLICK
) {
161 // Click - switch to next slot
162 selected
= (selected
+ 1) % slots_count
;
168 if (button_pressed
== BUTTON_HOLD
) {
169 // Long press - switch to read mode
173 } else if (button_pressed
== BUTTON_SINGLE_CLICK
) {
174 // Click - exit to select mode
175 lf_em410x_watch(1, &high
[selected
], &low
[selected
]);
178 SaveIDtoFlash(selected
, low
[selected
]);
185 if (button_pressed
== BUTTON_HOLD
) {
186 // Long press - switch to read mode
190 } else if (button_pressed
== BUTTON_SINGLE_CLICK
) {
191 // Click - start simulating. Click again to exit from simulate mode
194 construct_EM410x_emul(rev_quads(low
[selected
]));
197 SimulateTagLowFrequency(buflen
, 0, true);
199 state
= 0; // Switch to select mode
204 if (button_pressed
== BUTTON_HOLD
) {
205 // Long press - switch to select mode
209 } else if (button_pressed
== BUTTON_SINGLE_CLICK
) {
210 // Click - write ID to tag
211 copy_em410x_to_t55xx(0, LF_CLOCK
, (uint32_t)(low
[selected
] >> 32), (uint32_t)(low
[selected
] & 0xffffffff));
213 state
= 0; // Switch to select mode