diff --git a/include/cyclic.h b/include/cyclic.h index 8c7319be..d40891af 100644 --- a/include/cyclic.h +++ b/include/cyclic.h @@ -10,6 +10,7 @@ #include "display.h" #include "sds011read.h" #include "sdcard.h" +#include "macsniff.h" extern Ticker cyclicTimer; diff --git a/include/macsniff.h b/include/macsniff.h index 175cba58..6bc346ef 100644 --- a/include/macsniff.h +++ b/include/macsniff.h @@ -14,7 +14,7 @@ #include "corona.h" #endif -uint16_t get_salt(void); +uint32_t renew_salt(void); uint64_t macConvert(uint8_t *paddr); esp_err_t macQueueInit(void); void mac_process(void *pvParameters); diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 88d618e5..82a88a24 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -97,7 +97,6 @@ void doHousekeeping() { "free heap = %d bytes)", ESP.getMinFreeHeap(), ESP.getFreeHeap()); reset_counters(); // clear macs container and reset all counters - get_salt(); // get new salt for salting hashes if (ESP.getMinFreeHeap() <= MEM_LOW) // check again do_reset(true); // memory leak, reset device @@ -108,7 +107,6 @@ void doHousekeeping() { if (ESP.getMinFreePsram() <= MEM_LOW) { ESP_LOGI(TAG, "PSRAM full, counter cleared"); reset_counters(); // clear macs container and reset all counters - get_salt(); // get new salt for salting hashes if (ESP.getMinFreePsram() <= MEM_LOW) // check again do_reset(true); // memory leak, reset device @@ -140,6 +138,7 @@ void reset_counters() { macs.clear(); // clear all macs container macs_wifi = 0; macs_ble = 0; + renew_salt(); // get new salt #ifdef HAS_DISPLAY dp_plotCurve(0, true); #endif diff --git a/src/macsniff.cpp b/src/macsniff.cpp index 3e5e8210..d47df342 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -9,10 +9,11 @@ static const char TAG[] = __FILE__; QueueHandle_t MacQueue; TaskHandle_t macProcessTask; -uint16_t salt = 0; +static uint32_t salt = renew_salt(); -uint16_t get_salt(void) { - salt = (uint16_t)random(65536); // get new 16bit random for salting hashes +uint32_t renew_salt(void) { + salt = esp_random(); + ESP_LOGV(TAG, "new salt = %04X", salt); return salt; } @@ -101,9 +102,6 @@ void IRAM_ATTR mac_add(uint8_t *paddr, int8_t rssi, snifftype_t sniff_type) { uint16_t mac_analyze(MacBuffer_t MacBuffer) { - if (salt == 0) // ensure we have salt (appears after radio is turned on) - return 0; - if ((cfg.rssilimit) && (MacBuffer.rssi < cfg.rssilimit)) { // rssi is negative value ESP_LOGI(TAG, "%s RSSI %d -> ignoring (limit: %d)", @@ -126,8 +124,7 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) { } }; - char buff[10]; // temporary buffer for printf - uint32_t *mac; // temporary buffer for shortened MAC + uint32_t *mac; // pointer to shortened 4 byte MAC // only last 3 MAC Address bytes are used for MAC address anonymization // but since it's uint32 we take 4 bytes to avoid 1st value to be 0. @@ -138,11 +135,15 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) { // and increment counter on display // https://en.wikipedia.org/wiki/MAC_Address_Anonymization - snprintf(buff, sizeof(buff), "%08X", - *mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC - // to 8 digit hex string - uint16_t hashedmac = hash(&buff[3], 5); // hash MAC 8 digit -> 5 digit - auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique + // reversed 4 byte MAC added to current salt + const uint32_t saltedmac = *mac + salt; + + // hashed 4 byte MAC + // to save RAM, we use only lower 2 bytes of hash, since collisions don't + // matter in our use case + const uint16_t hashedmac = hash((const char *)&saltedmac, 4); + + auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique bool added = newmac.second ? true : false; // true if hashed MAC is unique in container @@ -183,7 +184,8 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) { // Log scan result ESP_LOGV(TAG, - "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " + "%s %s RSSI %ddBi -> MAC %0x:%0x:%0x:%0x:%0x:%0x -> salted %04X" + " -> hashed %04X -> WiFi:%d " "BLTH:%d " #if (COUNT_ENS) "(CWA:%d)" @@ -191,7 +193,9 @@ uint16_t mac_analyze(MacBuffer_t MacBuffer) { "-> %d Bytes left", added ? "new " : "known", MacBuffer.sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", - MacBuffer.rssi, buff, hashedmac, macs_wifi, macs_ble, + MacBuffer.rssi, MacBuffer.mac[0], MacBuffer.mac[1], MacBuffer.mac[2], + MacBuffer.mac[3], MacBuffer.mac[4], MacBuffer.mac[5], saltedmac, + hashedmac, macs_wifi, macs_ble, #if (COUNT_ENS) cwa_report(), #endif diff --git a/src/main.cpp b/src/main.cpp index b5f69647..5d7bb62b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -428,7 +428,7 @@ void setup() { // initialize salt value using esp_random() called by random() in // arduino-esp32 core. Note: do this *after* wifi has started, since // function gets it's seed from RF noise - get_salt(); // get new 16bit for salting hashes + reset_counters(); // start state machine ESP_LOGI(TAG, "Starting Interrupt Handler..."); diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 9aad91ff..23116014 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -18,7 +18,6 @@ void set_reset(uint8_t val[]) { case 1: // reset MAC counter ESP_LOGI(TAG, "Remote command: reset MAC counter"); reset_counters(); // clear macs - get_salt(); // get new salt break; case 2: // reset device to factory settings ESP_LOGI(TAG, "Remote command: reset device to factory settings"); @@ -119,7 +118,6 @@ void set_countmode(uint8_t val[]) { return; } reset_counters(); // clear macs - get_salt(); // get new salt } void set_screensaver(uint8_t val[]) { diff --git a/src/senddata.cpp b/src/senddata.cpp index 6c10be82..df9c2411 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -115,7 +115,6 @@ void sendData() { // clear counter if not in cumulative counter mode if (cfg.countermode != 1) { reset_counters(); // clear macs container and reset all counters - get_salt(); // get new salt for salting hashes ESP_LOGI(TAG, "Counter cleared"); } #ifdef HAS_DISPLAY