From 85b3c5d91bd7fa8d1f3e2a412cd33e484c31cc26 Mon Sep 17 00:00:00 2001 From: Will Tatam Date: Tue, 18 Nov 2025 05:53:12 +0000 Subject: [PATCH] refactor to use a common sha1 function --- wled00/fcn_declare.h | 2 ++ wled00/json.cpp | 67 -------------------------------------------- wled00/util.cpp | 55 +++++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 68 deletions(-) diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 01c2c2ec..2346ee45 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -401,6 +401,8 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL int16_t extractModeDefaults(uint8_t mode, const char *segVar); void checkSettingsPIN(const char *pin); uint16_t crc16(const unsigned char* data_p, size_t length); +String computeSHA1(const String& input); +String getDeviceId(); uint16_t beatsin88_t(accum88 beats_per_minute_88, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0); uint16_t beatsin16_t(accum88 beats_per_minute, uint16_t lowest = 0, uint16_t highest = 65535, uint32_t timebase = 0, uint16_t phase_offset = 0); uint8_t beatsin8_t(accum88 beats_per_minute, uint8_t lowest = 0, uint8_t highest = 255, uint32_t timebase = 0, uint8_t phase_offset = 0); diff --git a/wled00/json.cpp b/wled00/json.cpp index 47bac547..08468df5 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -1,12 +1,5 @@ #include "wled.h" -// Include SHA1 libraries for device ID generation -#ifdef ESP8266 - #include -#endif -#ifdef ESP32 - #include "mbedtls/sha1.h" -#endif #define JSON_PATH_STATE 1 #define JSON_PATH_INFO 2 @@ -698,66 +691,6 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme } } -String getDeviceId() { - static String cachedDeviceId = ""; - if (cachedDeviceId.length() > 0) return cachedDeviceId; - - uint8_t mac[6]; - WiFi.macAddress(mac); - - #ifdef ESP8266 - // For ESP8266 we use the Hash.h library which is built into the ESP8266 Core - char macStr[18]; - sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - String macString = String(macStr) + "WLED"; // Salt with "WLED" - String firstHash = sha1(macString); - String secondHash = sha1(firstHash); - cachedDeviceId = firstHash + secondHash.substring(38); // Concatenate first hash + last 2 chars of second - return cachedDeviceId; - #endif - - #ifdef ESP32 - // For ESP32 we use the mbedtls library which is built into the ESP32 core - unsigned char shaResult[20]; // SHA1 produces a hash of 20 bytes (which is 40 HEX characters) - mbedtls_sha1_context ctx; - - // First hash: MAC address + "WLED" salt - mbedtls_sha1_init(&ctx); - mbedtls_sha1_starts_ret(&ctx); - mbedtls_sha1_update_ret(&ctx, mac, 6); - mbedtls_sha1_update_ret(&ctx, (const unsigned char*)"WLED", 4); - mbedtls_sha1_finish_ret(&ctx, shaResult); - mbedtls_sha1_free(&ctx); - - // Convert first hash to hexadecimal string - char firstHash[41]; - for (int i = 0; i < 20; i++) { - sprintf(&firstHash[i*2], "%02x", shaResult[i]); - } - - // Second hash: SHA1 of the first hash - unsigned char shaResult2[20]; - mbedtls_sha1_init(&ctx); - mbedtls_sha1_starts_ret(&ctx); - mbedtls_sha1_update_ret(&ctx, (const unsigned char*)firstHash, 40); - mbedtls_sha1_finish_ret(&ctx, shaResult2); - mbedtls_sha1_free(&ctx); - - // Convert second hash to hexadecimal string - char secondHash[41]; - for (int i = 0; i < 20; i++) { - sprintf(&secondHash[i*2], "%02x", shaResult2[i]); - } - - // Return first hash + last 2 chars of second hash - char result[43]; - sprintf(result, "%s%c%c", firstHash, secondHash[38], secondHash[39]); - cachedDeviceId = String(result); - return cachedDeviceId; - #endif - - return String(""); -} void serializeInfo(JsonObject root) { diff --git a/wled00/util.cpp b/wled00/util.cpp index 09769c96..1f6d47df 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -3,6 +3,7 @@ #include "const.h" #ifdef ESP8266 #include "user_interface.h" // for bootloop detection +#include // for SHA1 on ESP8266 #else #include #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) @@ -10,6 +11,7 @@ #elif ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(3, 3, 0) #include "soc/rtc.h" #endif +#include "mbedtls/sha1.h" // for SHA1 on ESP32 #endif @@ -1124,4 +1126,55 @@ uint8_t perlin8(uint16_t x, uint16_t y) { uint8_t perlin8(uint16_t x, uint16_t y, uint16_t z) { return (((perlin3D_raw((uint32_t)x << 8, (uint32_t)y << 8, (uint32_t)z << 8, true) * 2015) >> 10) + 33168) >> 8; //scale to 16 bit, offset, then scale to 8bit -} \ No newline at end of file +} + +// Platform-agnostic SHA1 computation from String input +String computeSHA1(const String& input) { + #ifdef ESP8266 + return sha1(input); // ESP8266 has built-in sha1() function + #else + // ESP32: Compute SHA1 hash using mbedtls + unsigned char shaResult[20]; // SHA1 produces 20 bytes + mbedtls_sha1_context ctx; + + mbedtls_sha1_init(&ctx); + mbedtls_sha1_starts_ret(&ctx); + mbedtls_sha1_update_ret(&ctx, (const unsigned char*)input.c_str(), input.length()); + mbedtls_sha1_finish_ret(&ctx, shaResult); + mbedtls_sha1_free(&ctx); + + // Convert to hexadecimal string + char hexString[41]; + for (int i = 0; i < 20; i++) { + sprintf(&hexString[i*2], "%02x", shaResult[i]); + } + hexString[40] = '\0'; + + return String(hexString); + #endif +} + +// Generate a device ID based on SHA1 hash of MAC address salted with "WLED" +// Returns: original SHA1 + last 2 chars of double-hashed SHA1 (42 chars total) +String getDeviceId() { + static String cachedDeviceId = ""; + if (cachedDeviceId.length() > 0) return cachedDeviceId; + + uint8_t mac[6]; + WiFi.macAddress(mac); + char macStr[18]; + sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + // First hash: MAC address + "WLED" salt + String macString = String(macStr) + "WLED"; + String firstHash = computeSHA1(macString); + + // Second hash: SHA1 of the first hash + String secondHash = computeSHA1(firstHash); + + // Concatenate first hash + last 2 chars of second hash + cachedDeviceId = firstHash + secondHash.substring(38); + + return cachedDeviceId; +} +