A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at records-reader 98 lines 2.9 kB view raw
1#include "ObfuscationUtils.h" 2 3#include <Logging.h> 4#include <base64.h> 5#include <esp_mac.h> 6#include <mbedtls/base64.h> 7 8#include <cstring> 9 10namespace obfuscation { 11 12namespace { 13constexpr size_t HW_KEY_LEN = 6; 14 15// Simple lazy init — no thread-safety concern on single-core ESP32-C3. 16const uint8_t* getHwKey() { 17 static uint8_t key[HW_KEY_LEN] = {}; 18 static bool initialized = false; 19 if (!initialized) { 20 esp_efuse_mac_get_default(key); 21 initialized = true; 22 } 23 return key; 24} 25} // namespace 26 27void xorTransform(std::string& data) { 28 const uint8_t* key = getHwKey(); 29 for (size_t i = 0; i < data.size(); i++) { 30 data[i] ^= key[i % HW_KEY_LEN]; 31 } 32} 33 34void xorTransform(std::string& data, const uint8_t* key, size_t keyLen) { 35 if (keyLen == 0 || key == nullptr) return; 36 for (size_t i = 0; i < data.size(); i++) { 37 data[i] ^= key[i % keyLen]; 38 } 39} 40 41String obfuscateToBase64(const std::string& plaintext) { 42 if (plaintext.empty()) return ""; 43 std::string temp = plaintext; 44 xorTransform(temp); 45 return base64::encode(reinterpret_cast<const uint8_t*>(temp.data()), temp.size()); 46} 47 48std::string deobfuscateFromBase64(const char* encoded, bool* ok) { 49 if (encoded == nullptr || encoded[0] == '\0') { 50 if (ok) *ok = false; 51 return ""; 52 } 53 if (ok) *ok = true; 54 size_t encodedLen = strlen(encoded); 55 // First call: get required output buffer size 56 size_t decodedLen = 0; 57 int ret = mbedtls_base64_decode(nullptr, 0, &decodedLen, reinterpret_cast<const unsigned char*>(encoded), encodedLen); 58 if (ret != 0 && ret != MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) { 59 LOG_ERR("OBF", "Base64 decode size query failed (ret=%d)", ret); 60 if (ok) *ok = false; 61 return ""; 62 } 63 std::string result(decodedLen, '\0'); 64 ret = mbedtls_base64_decode(reinterpret_cast<unsigned char*>(&result[0]), decodedLen, &decodedLen, 65 reinterpret_cast<const unsigned char*>(encoded), encodedLen); 66 if (ret != 0) { 67 LOG_ERR("OBF", "Base64 decode failed (ret=%d)", ret); 68 if (ok) *ok = false; 69 return ""; 70 } 71 result.resize(decodedLen); 72 xorTransform(result); 73 return result; 74} 75 76void selfTest() { 77 const char* testInputs[] = {"", "hello", "WiFi P@ssw0rd!", "a"}; 78 bool allPassed = true; 79 for (const char* input : testInputs) { 80 String encoded = obfuscateToBase64(std::string(input)); 81 std::string decoded = deobfuscateFromBase64(encoded.c_str()); 82 if (decoded != input) { 83 LOG_ERR("OBF", "FAIL: \"%s\" -> \"%s\" -> \"%s\"", input, encoded.c_str(), decoded.c_str()); 84 allPassed = false; 85 } 86 } 87 // Verify obfuscated form differs from plaintext 88 String enc = obfuscateToBase64("test123"); 89 if (enc == "test123") { 90 LOG_ERR("OBF", "FAIL: obfuscated output identical to plaintext"); 91 allPassed = false; 92 } 93 if (allPassed) { 94 LOG_DBG("OBF", "Obfuscation self-test PASSED"); 95 } 96} 97 98} // namespace obfuscation