Skip to content

Commit a396196

Browse files
committed
Correctly offset when sigLen is present
1 parent 315bc77 commit a396196

File tree

1 file changed

+52
-33
lines changed

1 file changed

+52
-33
lines changed

cores/esp8266/Updater.cpp

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
#include <Arduino.h>
12
#include "Updater.h"
23
#include "eboot_command.h"
34
#include <esp8266_peri.h>
45
#include <PolledTimeout.h>
56
#include "StackThunk.h"
67

8+
#include <memory>
9+
710
//#define DEBUG_UPDATER Serial
811

912
#include <Updater_Signing.h>
@@ -224,71 +227,87 @@ bool UpdaterClass::end(bool evenIfRemaining){
224227
}
225228

226229
if (_verify) {
230+
// If expectedSigLen is non-zero, we expect the last four bytes of the buffer to
231+
// contain a matching length field, preceded by the bytes of the signature itself.
232+
// But if expectedSigLen is zero, we expect neither a signature nor a length field;
233+
static constexpr uint32_t sigSize = 4;
227234
const uint32_t expectedSigLen = _verify->length();
228-
// If expectedSigLen is non-zero, we expect the last four bytes of the buffer to
229-
// contain a matching length field, preceded by the bytes of the signature itself.
230-
// But if expectedSigLen is zero, we expect neither a signature nor a length field;
235+
const uint32_t sigLenAddr = _startAddress + _size - sigSize;
231236
uint32_t sigLen = 0;
232237

238+
#ifdef DEBUG_UPDATER
239+
DEBUG_UPDATER.printf_P(PSTR("[Updater] expected sigLen: %lu\n"), expectedSigLen);
240+
#endif
233241
if (expectedSigLen > 0) {
234-
ESP.flashRead(_startAddress + _size - sizeof(uint32_t), &sigLen, sizeof(uint32_t));
235-
}
242+
ESP.flashRead(sigLenAddr, &sigLen, sigSize);
236243
#ifdef DEBUG_UPDATER
237-
DEBUG_UPDATER.printf_P(PSTR("[Updater] sigLen: %d\n"), sigLen);
244+
DEBUG_UPDATER.printf_P(PSTR("[Updater] sigLen from flash: %lu\n"), sigLen);
238245
#endif
246+
}
247+
239248
if (sigLen != expectedSigLen) {
240249
_setError(UPDATE_ERROR_SIGN);
241250
_reset();
242251
return false;
243252
}
244253

245-
int binSize = _size;
254+
auto binSize = _size;
246255
if (expectedSigLen > 0) {
247-
_size -= (sigLen + sizeof(uint32_t) /* The siglen word */);
248-
}
249-
_hash->begin();
256+
if (binSize < (sigLen + sigSize)) {
257+
_setError(UPDATE_ERROR_SIGN);
258+
_reset();
259+
return false;
260+
}
261+
binSize -= (sigLen + sigSize);
250262
#ifdef DEBUG_UPDATER
251-
DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize);
263+
DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted size (without the signature and sigLen): %lu\n"), binSize);
252264
#endif
253-
// Calculate the MD5 and hash using proper size
254-
uint8_t buff[128] __attribute__((aligned(4)));
255-
for(int i = 0; i < binSize; i += sizeof(buff)) {
256-
ESP.flashRead(_startAddress + i, (uint32_t *)buff, sizeof(buff));
257-
size_t read = std::min((int)sizeof(buff), binSize - i);
258-
_hash->add(buff, read);
265+
}
266+
267+
// Calculate hash of the payload, 128 bytes at a time
268+
alignas(alignof(uint32_t)) uint8_t buff[128];
269+
270+
_hash->begin();
271+
for (uint32_t offset = 0; offset < binSize; offset += sizeof(buff)) {
272+
auto len = std::min(sizeof(buff), binSize - offset);
273+
ESP.flashRead(_startAddress + offset, reinterpret_cast<uint32_t *>(&buff[0]), len);
274+
_hash->add(buff, len);
259275
}
260276
_hash->end();
277+
261278
#ifdef DEBUG_UPDATER
262-
unsigned char *ret = (unsigned char *)_hash->hash();
263-
DEBUG_UPDATER.printf_P(PSTR("[Updater] Computed Hash:"));
264-
for (int i=0; i<_hash->len(); i++) DEBUG_UPDATER.printf(" %02x", ret[i]);
265-
DEBUG_UPDATER.printf("\n");
279+
auto debugByteArray = [](const char *name, const unsigned char *hash, int len) {
280+
DEBUG_UPDATER.printf_P("[Updater] %s:", name);
281+
for (int i = 0; i < len; ++i) {
282+
DEBUG_UPDATER.printf(" %02x", hash[i]);
283+
}
284+
DEBUG_UPDATER.printf("\n");
285+
};
286+
debugByteArray(PSTR("Computed Hash"),
287+
reinterpret_cast<const unsigned char *>(_hash->hash()),
288+
_hash->len());
266289
#endif
267290

268-
uint8_t *sig = nullptr; // Safe to free if we don't actually malloc
291+
std::unique_ptr<uint8_t[]> sig;
269292
if (expectedSigLen > 0) {
270-
sig = (uint8_t*)malloc(sigLen);
293+
const uint32_t sigAddr = _startAddress + binSize;
294+
sig.reset(new (std::nothrow) uint8_t[sigLen]);
271295
if (!sig) {
272296
_setError(UPDATE_ERROR_SIGN);
273297
_reset();
274298
return false;
275299
}
276-
ESP.flashRead(_startAddress + binSize, sig, sigLen);
300+
ESP.flashRead(sigAddr, sig.get(), sigLen);
277301
#ifdef DEBUG_UPDATER
278-
DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:"));
279-
for (size_t i=0; i<sigLen; i++) {
280-
DEBUG_UPDATER.printf(" %02x", sig[i]);
281-
}
282-
DEBUG_UPDATER.printf("\n");
302+
debugByteArray(PSTR("Received Signature"), sig.get(), sigLen);
283303
#endif
284304
}
285-
if (!_verify->verify(_hash, (void *)sig, sigLen)) {
286-
free(sig);
305+
if (!_verify->verify(_hash, sig.get(), sigLen)) {
287306
_setError(UPDATE_ERROR_SIGN);
288307
_reset();
289308
return false;
290309
}
291-
free(sig);
310+
292311
_size = binSize; // Adjust size to remove signature, not part of bin payload
293312

294313
#ifdef DEBUG_UPDATER
@@ -301,7 +320,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
301320
return false;
302321
}
303322
#ifdef DEBUG_UPDATER
304-
else DEBUG_UPDATER.printf_P(PSTR("MD5 Success: %s\n"), _target_md5.c_str());
323+
else DEBUG_UPDATER.printf_P(PSTR("[Updater] MD5 Success: %s\n"), _target_md5.c_str());
305324
#endif
306325
}
307326

0 commit comments

Comments
 (0)