├── OTA.ino ├── PM3WiFi.ino ├── SPI.ino ├── WiFi.ino └── Proxmark3.ino /OTA.ino: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | bool ota_active = false; 5 | 6 | void ota_setup() 7 | { 8 | ArduinoOTA.setHostname("ProxmarkWifi"); 9 | 10 | ArduinoOTA.onStart([]() { 11 | ota_active = true; 12 | }); 13 | ArduinoOTA.onEnd([]() { 14 | ota_active = false; 15 | }); 16 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 17 | }); 18 | ArduinoOTA.onError([](ota_error_t error) { 19 | Serial.printf("Error[%u]: ", error); 20 | if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); 21 | else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); 22 | else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); 23 | else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); 24 | else if (error == OTA_END_ERROR) Serial.println("End Failed"); 25 | }); 26 | 27 | ArduinoOTA.begin(); 28 | } 29 | 30 | bool ota_loop() 31 | { 32 | return false; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /PM3WiFi.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SPI Slave Demo Sketch 3 | Connect the SPI Master device to the following pins on the esp8266: 4 | 5 | GPIO NodeMCU Name | Uno 6 | =================================== 7 | 15 D8 SS | D10 8 | 13 D7 MOSI | D11 9 | 12 D6 MISO | D12 10 | 14 D5 SCK | D13 11 | 12 | Note: If the ESP is booting at a moment when the SPI Master has the Select line HIGH (deselected) 13 | the ESP8266 WILL FAIL to boot! 14 | See SPISlave_SafeMaster example for possible workaround 15 | */ 16 | 17 | #include "SPISlave.h" 18 | 19 | 20 | void setup() { 21 | Serial.begin(115200); 22 | Serial.setDebugOutput(true); 23 | 24 | Serial.printf("\n\n\n"); 25 | 26 | Serial.printf("[i] SDK: '%s'\n", ESP.getSdkVersion()); 27 | Serial.printf("[i] CPU Speed: %d MHz\n", ESP.getCpuFreqMHz()); 28 | Serial.printf("[i] Flash Mode: %08X\n", ESP.getFlashChipMode()); 29 | Serial.printf("[i] Flash Size: %08X\n", ESP.getFlashChipSize()); 30 | Serial.printf("[i] Flash Speed: %d MHz\n", ESP.getFlashChipSpeed() / 1000000); 31 | Serial.printf("\n"); 32 | Serial.printf("[i] Starting\n"); 33 | 34 | Serial.printf("[i] Setup WiFi\n"); 35 | wifi_setup(); 36 | Serial.printf("[i] Setup OTA\n"); 37 | ota_setup(); 38 | Serial.printf("[i] Setup SPI\n"); 39 | spi_setup(); 40 | 41 | Serial.println("Setup done"); 42 | } 43 | 44 | uint32_t main_loop = 0; 45 | 46 | void loop() 47 | { 48 | bool hasWork = false; 49 | 50 | hasWork |= wifi_loop(); 51 | hasWork |= ota_loop(); 52 | hasWork |= spi_loop(); 53 | 54 | if(!hasWork) 55 | { 56 | delay(10); 57 | } 58 | 59 | if(main_loop++ > 1000) 60 | { 61 | Serial.println("still alive"); 62 | main_loop = 0; 63 | pm3_check_version(); 64 | } 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /SPI.ino: -------------------------------------------------------------------------------- 1 | 2 | uint32_t spi_recv_pos = 0; 3 | uint32_t spi_recv_len = 0; 4 | uint32_t spi_send_pos = 0; 5 | uint32_t spi_send_len = 0; 6 | 7 | uint32_t spi_recv_buf_align[(512+16 + 16)/4]; 8 | uint8_t *spi_recv_buf = (uint8_t*)spi_recv_buf_align; 9 | uint32_t spi_send_buf_align[(512+16 + 16)/4]; 10 | uint8_t *spi_send_buf = (uint8_t*)spi_send_buf_align; 11 | 12 | bool have_recv_data = false; 13 | bool have_send_data = false; 14 | 15 | void spi_setup() 16 | { 17 | SPISlave.onData([](uint8_t * data, size_t len) { 18 | 19 | if(spi_recv_pos + len > sizeof(spi_recv_buf_align)) 20 | { 21 | Serial.printf("[E] Receive buffer overflow\n"); 22 | } 23 | else 24 | { 25 | memcpy(&spi_recv_buf[spi_recv_pos], data, len); 26 | } 27 | spi_recv_pos += len; 28 | SPISlave.setStatus(spi_recv_pos); 29 | 30 | if(spi_recv_pos >= spi_recv_len && spi_recv_pos > 0) 31 | { 32 | have_recv_data = true; 33 | } 34 | }); 35 | 36 | SPISlave.onDataSent([]() { 37 | spi_send_pos += 32; 38 | 39 | if(spi_send_pos >= spi_send_len) 40 | { 41 | spi_send_pos = 0; 42 | spi_send_len = 0; 43 | SPISlave.setStatus(0); 44 | } 45 | else 46 | { 47 | SPISlave.setData(&spi_send_buf[spi_send_pos], spi_send_len - spi_send_pos); 48 | SPISlave.setStatus(0xE000 | (spi_send_len - spi_send_pos)); 49 | } 50 | }); 51 | 52 | SPISlave.onStatus([](uint32_t data) { 53 | if((data >> 12) == 0x0E) 54 | { 55 | spi_recv_len = data & 0x0FFF; 56 | spi_recv_pos = 0; 57 | SPISlave.setStatus(spi_recv_pos); 58 | } 59 | else 60 | { 61 | Serial.printf("Status: 0x%08X\n", data); 62 | } 63 | }); 64 | 65 | SPISlave.onStatusSent([]() { 66 | }); 67 | 68 | SPISlave.begin(); 69 | 70 | // bugfix according to https://www.esp8266.com/viewtopic.php?f=32&t=10579&start=12 71 | SPI1C2 |= 1 << SPIC2MISODM_S; 72 | 73 | SPISlave.setStatus(0); 74 | 75 | } 76 | 77 | void spi_send(uint8_t *buf, uint32_t len) 78 | { 79 | Serial.printf("[SPI] Sending %d byte\n", len); 80 | spi_send_pos = 0; 81 | spi_send_len = len; 82 | memcpy(spi_send_buf, buf, len); 83 | SPISlave.setData(spi_send_buf, spi_send_len); 84 | SPISlave.setStatus(0xE000 | spi_send_len); 85 | } 86 | 87 | bool spi_loop() 88 | { 89 | if(have_recv_data) 90 | { 91 | have_recv_data = false; 92 | pm3_parse(spi_recv_buf); 93 | } 94 | 95 | return false; 96 | } 97 | 98 | 99 | -------------------------------------------------------------------------------- /WiFi.ino: -------------------------------------------------------------------------------- 1 | 2 | const char *ssid = "XXX"; 3 | const char *password = "XXX"; 4 | bool connecting = false; 5 | 6 | 7 | void wifi_setup() 8 | { 9 | Serial.printf("[WiFi] Connecting...\n"); 10 | WiFi.begin(ssid, password); 11 | connecting = true; 12 | } 13 | 14 | bool wifi_loop(void) 15 | { 16 | int status = WiFi.status(); 17 | int curTime = millis(); 18 | static int nextTime = 0; 19 | static int stateCounter = 0; 20 | 21 | if(nextTime > curTime) 22 | { 23 | return false; 24 | } 25 | 26 | /* standard refresh time */ 27 | nextTime = curTime + 100; 28 | 29 | switch(status) 30 | { 31 | case WL_CONNECTED: 32 | if(connecting) 33 | { 34 | connecting = false; 35 | Serial.print("[WiFi] Connected, IP address: "); 36 | Serial.println(WiFi.localIP()); 37 | } 38 | break; 39 | 40 | case WL_CONNECTION_LOST: 41 | Serial.printf("[WiFi] Connection lost\n"); 42 | connecting = false; 43 | WiFi.disconnect(); 44 | WiFi.mode(WIFI_OFF); 45 | nextTime = curTime + 500; 46 | break; 47 | 48 | case WL_CONNECT_FAILED: 49 | Serial.printf("[WiFi] Connection failed\n"); 50 | connecting = false; 51 | WiFi.disconnect(); 52 | WiFi.mode(WIFI_OFF); 53 | nextTime = curTime + 1000; 54 | break; 55 | 56 | case WL_NO_SSID_AVAIL: 57 | Serial.printf("[WiFi] No SSID\n"); 58 | connecting = false; 59 | WiFi.disconnect(); 60 | WiFi.mode(WIFI_OFF); 61 | nextTime = curTime + 2000; 62 | break; 63 | 64 | case WL_SCAN_COMPLETED: 65 | Serial.printf("[WiFi] Scan completed\n"); 66 | connecting = false; 67 | WiFi.disconnect(); 68 | WiFi.mode(WIFI_OFF); 69 | break; 70 | 71 | case WL_DISCONNECTED: 72 | if(!connecting) 73 | { 74 | Serial.printf("[WiFi] Disconnected\n"); 75 | connecting = false; 76 | WiFi.disconnect(); 77 | WiFi.mode(WIFI_OFF); 78 | break; 79 | } 80 | else 81 | { 82 | if(++stateCounter > 50) 83 | { 84 | Serial.printf("[WiFi] Timeout, aborting\n"); 85 | connecting = false; 86 | WiFi.disconnect(); 87 | WiFi.mode(WIFI_OFF); 88 | } 89 | } 90 | 91 | case WL_IDLE_STATUS: 92 | if(!connecting) 93 | { 94 | connecting = true; 95 | Serial.printf("[WiFi] Idle, connecting to %s\n", ssid); 96 | WiFi.mode(WIFI_STA); 97 | WiFi.begin(ssid, password); 98 | stateCounter = 0; 99 | break; 100 | } 101 | 102 | case WL_NO_SHIELD: 103 | if(!connecting) 104 | { 105 | connecting = true; 106 | Serial.printf("[WiFi] Disabled (%d), connecting to %s\n", status, ssid); 107 | WiFi.mode(WIFI_STA); 108 | WiFi.begin(ssid, password); 109 | stateCounter = 0; 110 | break; 111 | } 112 | } 113 | 114 | return false; 115 | } 116 | 117 | -------------------------------------------------------------------------------- /Proxmark3.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | // For the bootloader 4 | #define CMD_DEVICE_INFO 0x0000 5 | #define CMD_SETUP_WRITE 0x0001 6 | #define CMD_FINISH_WRITE 0x0003 7 | #define CMD_HARDWARE_RESET 0x0004 8 | #define CMD_START_FLASH 0x0005 9 | #define CMD_NACK 0x00fe 10 | #define CMD_ACK 0x00ff 11 | 12 | // For general mucking around 13 | #define CMD_DEBUG_PRINT_STRING 0x0100 14 | #define CMD_DEBUG_PRINT_INTEGERS 0x0101 15 | #define CMD_DEBUG_PRINT_BYTES 0x0102 16 | #define CMD_LCD_RESET 0x0103 17 | #define CMD_LCD 0x0104 18 | #define CMD_BUFF_CLEAR 0x0105 19 | #define CMD_READ_MEM 0x0106 20 | #define CMD_VERSION 0x0107 21 | #define CMD_STATUS 0x0108 22 | #define CMD_PING 0x0109 23 | 24 | 25 | // controlling the ADC input multiplexer 26 | #define CMD_SET_ADC_MUX 0x020F 27 | 28 | // RDV40, Smart card operations 29 | #define CMD_SMART_RAW 0x0140 30 | #define CMD_SMART_UPGRADE 0x0141 31 | #define CMD_SMART_UPLOAD 0x0142 32 | #define CMD_SMART_ATR 0x0143 33 | // CMD_SMART_SETBAUD is unused for now 34 | #define CMD_SMART_SETBAUD 0x0144 35 | #define CMD_SMART_SETCLOCK 0x0145 36 | 37 | // For low-frequency tags 38 | #define CMD_READ_TI_TYPE 0x0202 39 | #define CMD_WRITE_TI_TYPE 0x0203 40 | #define CMD_DOWNLOADED_RAW_BITS_TI_TYPE 0x0204 41 | #define CMD_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0205 42 | #define CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K 0x0206 43 | #define CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K 0x0207 44 | #define CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K 0x0208 45 | #define CMD_DOWNLOADED_SIM_SAMPLES_125K 0x0209 46 | #define CMD_SIMULATE_TAG_125K 0x020A 47 | #define CMD_HID_DEMOD_FSK 0x020B 48 | #define CMD_HID_SIM_TAG 0x020C 49 | #define CMD_SET_LF_DIVISOR 0x020D 50 | #define CMD_LF_SIMULATE_BIDIR 0x020E 51 | #define CMD_HID_CLONE_TAG 0x0210 52 | #define CMD_EM410X_WRITE_TAG 0x0211 53 | #define CMD_INDALA_CLONE_TAG 0x0212 54 | // for 224 bits UID 55 | #define CMD_INDALA_CLONE_TAG_L 0x0213 56 | #define CMD_T55XX_READ_BLOCK 0x0214 57 | #define CMD_T55XX_WRITE_BLOCK 0x0215 58 | #define CMD_T55XX_RESET_READ 0x0216 59 | #define CMD_PCF7931_READ 0x0217 60 | #define CMD_PCF7931_WRITE 0x0222 61 | #define CMD_PCF7931_BRUTEFORCE 0x0227 62 | #define CMD_EM4X_READ_WORD 0x0218 63 | #define CMD_EM4X_WRITE_WORD 0x0219 64 | #define CMD_IO_DEMOD_FSK 0x021A 65 | #define CMD_IO_CLONE_TAG 0x021B 66 | #define CMD_EM410X_DEMOD 0x021c 67 | // Sampling configuration for LF reader/snooper 68 | #define CMD_SET_LF_SAMPLING_CONFIG 0x021d 69 | #define CMD_FSK_SIM_TAG 0x021E 70 | #define CMD_ASK_SIM_TAG 0x021F 71 | #define CMD_PSK_SIM_TAG 0x0220 72 | #define CMD_AWID_DEMOD_FSK 0x0221 73 | #define CMD_VIKING_CLONE_TAG 0x0223 74 | #define CMD_T55XX_WAKEUP 0x0224 75 | #define CMD_COTAG 0x0225 76 | #define CMD_PARADOX_CLONE_TAG 0x0226 77 | #define CMD_EM4X_PROTECT 0x0228 78 | 79 | // For the 13.56 MHz tags 80 | #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 81 | #define CMD_READ_SRI512_TAG 0x0303 82 | #define CMD_READ_SRIX4K_TAG 0x0304 83 | #define CMD_ISO_14443B_COMMAND 0x0305 84 | #define CMD_READER_ISO_15693 0x0310 85 | #define CMD_SIMTAG_ISO_15693 0x0311 86 | #define CMD_SNOOP_ISO_15693 0x0312 87 | #define CMD_ISO_15693_COMMAND 0x0313 88 | #define CMD_ISO_15693_COMMAND_DONE 0x0314 89 | #define CMD_ISO_15693_FIND_AFI 0x0315 90 | #define CMD_ISO_15693_DEBUG 0x0316 91 | #define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317 92 | #define CMD_CSETUID_ISO_15693 0x0318 93 | #define CMD_ISO_15693_SLIX_L_DISABLE_PRIVACY 0x0319 94 | 95 | // For Hitag2 transponders 96 | #define CMD_SNOOP_HITAG 0x0370 97 | #define CMD_SIMULATE_HITAG 0x0371 98 | #define CMD_READER_HITAG 0x0372 99 | #define CMD_SIMULATE_HITAG_S 0x0368 100 | #define CMD_TEST_HITAGS_TRACES 0x0367 101 | #define CMD_READ_HITAG_S 0x0373 102 | #define CMD_READ_HITAG_S_BLK 0x0374 103 | #define CMD_WR_HITAG_S 0x0375 104 | #define CMD_EMU_HITAG_S 0x0376 105 | 106 | #define CMD_SIMULATE_TAG_ISO_14443B 0x0381 107 | #define CMD_SNOOP_ISO_14443B 0x0382 108 | #define CMD_SNOOP_ISO_14443a 0x0383 109 | #define CMD_SIMULATE_TAG_ISO_14443a 0x0384 110 | #define CMD_READER_ISO_14443a 0x0385 111 | #define CMD_SIMULATE_TAG_LEGIC_RF 0x0387 112 | #define CMD_READER_LEGIC_RF 0x0388 113 | #define CMD_WRITER_LEGIC_RF 0x0389 114 | #define CMD_EPA_PACE_COLLECT_NONCE 0x038A 115 | #define CMD_EPA_PACE_REPLAY 0x038B 116 | 117 | #define CMD_ICLASS_CLONE 0x0390 118 | #define CMD_ICLASS_DUMP 0x0391 119 | #define CMD_SNOOP_ICLASS 0x0392 120 | #define CMD_SIMULATE_TAG_ICLASS 0x0393 121 | #define CMD_READER_ICLASS 0x0394 122 | #define CMD_ICLASS_READBLOCK 0x0396 123 | #define CMD_ICLASS_WRITEBLOCK 0x0397 124 | #define CMD_ICLASS_EML_MEMSET 0x0398 125 | #define CMD_ICLASS_CHECK 0x0399 126 | #define CMD_ICLASS_READCHECK 0x039A 127 | 128 | // For measurements of the antenna tuning 129 | #define CMD_MEASURE_ANTENNA_TUNING 0x0400 130 | #define CMD_MEASURE_ANTENNA_TUNING_HF 0x0401 131 | #define CMD_MEASURED_ANTENNA_TUNING 0x0410 132 | #define CMD_LISTEN_READER_FIELD 0x0420 133 | 134 | // For direct FPGA control 135 | #define CMD_FPGA_MAJOR_MODE_OFF 0x0500 136 | 137 | // For mifare commands 138 | #define CMD_MIFARE_SET_DBGMODE 0x0600 139 | #define CMD_MIFARE_EML_MEMCLR 0x0601 140 | #define CMD_MIFARE_EML_MEMSET 0x0602 141 | #define CMD_MIFARE_EML_MEMGET 0x0603 142 | #define CMD_MIFARE_EML_CARDLOAD 0x0604 143 | 144 | // magic chinese card commands 145 | #define CMD_MIFARE_CSETBLOCK 0x0605 146 | #define CMD_MIFARE_CGETBLOCK 0x0606 147 | #define CMD_MIFARE_CIDENT 0x0607 148 | #define CMD_MIFARE_CWIPE 0x0608 149 | 150 | #define CMD_SIMULATE_MIFARE_CARD 0x0610 151 | 152 | #define CMD_READER_MIFARE 0x0611 153 | #define CMD_MIFARE_NESTED 0x0612 154 | #define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613 155 | 156 | #define CMD_MIFARE_READBL 0x0620 157 | #define CMD_MIFARE_READSC 0x0621 158 | #define CMD_MIFARE_WRITEBL 0x0622 159 | #define CMD_MIFARE_CHKKEYS 0x0623 160 | #define CMD_MIFARE_PERSONALIZE_UID 0x0624 161 | #define CMD_MIFARE_SNIFFER 0x0630 162 | 163 | //ultralightC 164 | #define CMD_MIFAREU_READBL 0x0720 165 | #define CMD_MIFAREU_READCARD 0x0721 166 | #define CMD_MIFAREU_WRITEBL 0x0722 167 | #define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 168 | #define CMD_MIFAREUC_AUTH 0x0724 169 | //0x0725 and 0x0726 no longer used 170 | #define CMD_MIFAREUC_SETPWD 0x0727 171 | 172 | 173 | // mifare desfire 174 | #define CMD_MIFARE_DESFIRE_READBL 0x0728 175 | #define CMD_MIFARE_DESFIRE_WRITEBL 0x0729 176 | #define CMD_MIFARE_DESFIRE_AUTH1 0x072a 177 | #define CMD_MIFARE_DESFIRE_AUTH2 0x072b 178 | #define CMD_MIFARE_DES_READER 0x072c 179 | #define CMD_MIFARE_DESFIRE_INFO 0x072d 180 | #define CMD_MIFARE_DESFIRE 0x072e 181 | 182 | #define CMD_HF_SNIFFER 0x0800 183 | #define CMD_HF_PLOT 0x0801 184 | 185 | #define CMD_VARIABLE_SIZE_FLAG 0x8000 186 | #define CMD_UNKNOWN 0xFFFF 187 | 188 | 189 | #define USB_CMD_DATA_SIZE 512 190 | 191 | typedef struct { 192 | uint64_t cmd; 193 | uint64_t arg[3]; 194 | union { 195 | uint8_t asBytes[USB_CMD_DATA_SIZE]; 196 | uint32_t asDwords[USB_CMD_DATA_SIZE/4]; 197 | } d; 198 | } UsbCommand; 199 | 200 | 201 | typedef struct { 202 | uint16_t cmd; 203 | uint16_t datalen; 204 | uint32_t arg[3]; 205 | union { 206 | uint8_t asBytes[USB_CMD_DATA_SIZE]; 207 | uint32_t asDwords[USB_CMD_DATA_SIZE/4]; 208 | } d; 209 | } UsbResponse; 210 | 211 | void pm3_parse(uint8_t *buf) 212 | { 213 | UsbResponse *res = (UsbResponse*)buf; 214 | 215 | bool varLen = (res->cmd & 0x8000) != 0; 216 | uint32_t cmd = res->cmd & 0x7FFF; 217 | 218 | switch(cmd) 219 | { 220 | case CMD_ACK: 221 | res->d.asBytes[res->datalen] = 0; 222 | Serial.printf("[PM3] Debug: '%s'\n", res->d.asBytes); 223 | break; 224 | 225 | case CMD_DEBUG_PRINT_STRING: 226 | res->d.asBytes[res->datalen] = 0; 227 | Serial.printf("[PM3] Debug: '%s'\n", res->d.asBytes); 228 | break; 229 | 230 | case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: 231 | break; 232 | 233 | default: 234 | Serial.printf("[PM3] Response CMD 0x%04X\n", res->cmd); 235 | Serial.printf("[PM3] Response LEN 0x%04X\n", res->datalen); 236 | Serial.printf("[PM3] Response arg 0x%08X 0x%08X 0x%08X\n", res->arg[0], res->arg[1], res->arg[2]); 237 | break; 238 | } 239 | } 240 | 241 | void pm3_check_version() 242 | { 243 | UsbCommand cmd; 244 | 245 | cmd.cmd = CMD_VERSION; 246 | cmd.arg[0] = 0; 247 | cmd.arg[1] = 0; 248 | cmd.arg[2] = 0; 249 | 250 | spi_send((uint8_t*)&cmd, sizeof(cmd)); 251 | } 252 | 253 | void pm3_check_status() 254 | { 255 | UsbCommand cmd; 256 | 257 | cmd.cmd = CMD_STATUS; 258 | cmd.arg[0] = 0; 259 | cmd.arg[1] = 0; 260 | cmd.arg[2] = 0; 261 | 262 | spi_send((uint8_t*)&cmd, sizeof(cmd)); 263 | } 264 | 265 | 266 | 267 | --------------------------------------------------------------------------------