Skip to content

Commit d6cd65e

Browse files
committed
ota_update: Clean up SHA API
Many of these functions are internal, and we can reduce RAM by caching the binary value instead.
1 parent fc25eb2 commit d6cd65e

File tree

2 files changed

+42
-46
lines changed

2 files changed

+42
-46
lines changed

wled00/ota_update.cpp

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,18 @@ void markOTAvalid() {
273273
}
274274

275275
#if defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DISABLE_OTA)
276-
// Cache for bootloader SHA256 digest as hex string
277-
static String bootloaderSHA256HexCache = "";
278-
279-
// Calculate and cache the bootloader SHA256 digest as hex string
280-
void calculateBootloaderSHA256() {
281-
if (!bootloaderSHA256HexCache.isEmpty()) return;
276+
static bool bootloaderSHA256CacheValid = false;
277+
static uint8_t bootloaderSHA256Cache[32];
282278

279+
/**
280+
* Calculate and cache the bootloader SHA256 digest
281+
* Reads the bootloader from flash at offset 0x1000 and computes SHA256 hash
282+
*/
283+
static void calculateBootloaderSHA256() {
283284
// Bootloader is at fixed offset 0x1000 (4KB) and is typically 32KB
284285
const uint32_t bootloaderSize = 0x8000; // 32KB, typical bootloader size
285286

286287
// Calculate SHA256
287-
uint8_t sha256[32];
288288
mbedtls_sha256_context ctx;
289289
mbedtls_sha256_init(&ctx);
290290
mbedtls_sha256_starts(&ctx, 0); // 0 = SHA256 (not SHA224)
@@ -299,33 +299,50 @@ void calculateBootloaderSHA256() {
299299
}
300300
}
301301

302-
mbedtls_sha256_finish(&ctx, sha256);
302+
mbedtls_sha256_finish(&ctx, bootloaderSHA256Cache);
303303
mbedtls_sha256_free(&ctx);
304-
305-
// Convert to hex string and cache it
306-
char hex[65];
307-
for (int i = 0; i < 32; i++) {
308-
sprintf(hex + (i * 2), "%02x", sha256[i]);
309-
}
310-
hex[64] = '\0';
311-
bootloaderSHA256HexCache = String(hex);
304+
bootloaderSHA256CacheValid = true;
312305
}
313306

314307
// Get bootloader SHA256 as hex string
315308
String getBootloaderSHA256Hex() {
316-
calculateBootloaderSHA256();
317-
return bootloaderSHA256HexCache;
309+
if (!bootloaderSHA256CacheValid) {
310+
calculateBootloaderSHA256();
311+
}
312+
313+
// Convert to hex string
314+
String result;
315+
result.reserve(65);
316+
for (int i = 0; i < 32; i++) {
317+
char b1 = bootloaderSHA256Cache[i];
318+
char b2 = b1 >> 4;
319+
b1 &= 0x0F;
320+
b1 += '0'; b2 += '0';
321+
if (b1 > '9') b1 += 7;
322+
if (b2 > '9') b2 += 7;
323+
result.concat(b1);
324+
result.concat(b2);
325+
}
326+
return std::move(result);
318327
}
319328

320-
// Invalidate cached bootloader SHA256 (call after bootloader update)
321-
void invalidateBootloaderSHA256Cache() {
322-
bootloaderSHA256HexCache = "";
329+
/**
330+
* Invalidate cached bootloader SHA256 (call after bootloader update)
331+
* Forces recalculation on next call to calculateBootloaderSHA256 or getBootloaderSHA256Hex
332+
*/
333+
static void invalidateBootloaderSHA256Cache() {
334+
bootloaderSHA256CacheValid = false;
323335
}
324336

325-
// Verify complete buffered bootloader using ESP-IDF validation approach
326-
// This matches the key validation steps from esp_image_verify() in ESP-IDF
327-
// Returns the actual bootloader data pointer and length via the buffer and len parameters
328-
bool verifyBootloaderImage(const uint8_t* &buffer, size_t &len, String* bootloaderErrorMsg) {
337+
/**
338+
* Verify complete buffered bootloader using ESP-IDF validation approach
339+
* This matches the key validation steps from esp_image_verify() in ESP-IDF
340+
* @param buffer Reference to pointer to bootloader binary data (will be adjusted if offset detected)
341+
* @param len Reference to length of bootloader data (will be adjusted to actual size)
342+
* @param bootloaderErrorMsg Pointer to String to store error message (must not be null)
343+
* @return true if validation passed, false otherwise
344+
*/
345+
static bool verifyBootloaderImage(const uint8_t* &buffer, size_t &len, String* bootloaderErrorMsg) {
329346
size_t availableLen = len;
330347
if (!bootloaderErrorMsg) {
331348
DEBUG_PRINTLN(F("bootloaderErrorMsg is null"));

wled00/ota_update.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -58,34 +58,13 @@ void handleOTAData(AsyncWebServerRequest *request, size_t index, uint8_t *data,
5858
void markOTAvalid();
5959

6060
#if defined(ARDUINO_ARCH_ESP32) && !defined(WLED_DISABLE_OTA)
61-
/**
62-
* Calculate and cache the bootloader SHA256 digest
63-
* Reads the bootloader from flash at offset 0x1000 and computes SHA256 hash
64-
*/
65-
void calculateBootloaderSHA256();
6661

6762
/**
6863
* Get bootloader SHA256 as hex string
6964
* @return String containing 64-character hex representation of SHA256 hash
7065
*/
7166
String getBootloaderSHA256Hex();
7267

73-
/**
74-
* Invalidate cached bootloader SHA256 (call after bootloader update)
75-
* Forces recalculation on next call to calculateBootloaderSHA256 or getBootloaderSHA256Hex
76-
*/
77-
void invalidateBootloaderSHA256Cache();
78-
79-
/**
80-
* Verify complete buffered bootloader using ESP-IDF validation approach
81-
* This matches the key validation steps from esp_image_verify() in ESP-IDF
82-
* @param buffer Reference to pointer to bootloader binary data (will be adjusted if offset detected)
83-
* @param len Reference to length of bootloader data (will be adjusted to actual size)
84-
* @param bootloaderErrorMsg Pointer to String to store error message (must not be null)
85-
* @return true if validation passed, false otherwise
86-
*/
87-
bool verifyBootloaderImage(const uint8_t* &buffer, size_t &len, String* bootloaderErrorMsg);
88-
8968
/**
9069
* Create a bootloader OTA context object on an AsyncWebServerRequest
9170
* @param request Pointer to web request object

0 commit comments

Comments
 (0)