10000 Permit using the Updater _hash function, even if we don't have a sign… · esp8266/Arduino@f78c633 · GitHub
[go: up one dir, main page]

Skip to content

Commit f78c633

Browse files
authored
Permit using the Updater _hash function, even if we don't have a signature appended to the image (#8507)
The _hash and _verify functionality of the Updater class are pretty much entwined. But it might be useful to calculate the hash, even without a signature present in the image itself. This change permits that by allowing a zero-length signature. For reference, one possible use case is where the expected hash is provided separately to the uploaded image. Another is to provide generic post-upload validation of the image: the hash function permits a convenient way of inspecting the complete image against arbitrary conditions; this is particularly useful after HTTP client OTA updates. (It's fair that reading the whole image back out of flash is not very efficient, but that's not the concern of this PR.)
1 parent 520233f commit f78c633

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

cores/esp8266/Updater.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -223,19 +223,29 @@ bool UpdaterClass::end(bool evenIfRemaining){
223223
_size = progress();
224224
}
225225

226-
uint32_t sigLen = 0;
227226
if (_verify) {
228-
ESP.flashRead(_startAddress + _size - sizeof(uint32_t), &sigLen, sizeof(uint32_t));
227+
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;
231+
uint32_t sigLen = 0;
232+
233+
if (expectedSigLen > 0) {
234+
ESP.flashRead(_startAddress + _size - sizeof(uint32_t), &sigLen, sizeof(uint32_t));
235+
}
229236
#ifdef DEBUG_UPDATER
230237
DEBUG_UPDATER.printf_P(PSTR("[Updater] sigLen: %d\n"), sigLen);
231238
#endif
232-
if (sigLen != _verify->length()) {
239+
if (sigLen != expectedSigLen) {
233240
_setError(UPDATE_ERROR_SIGN);
234241
_reset();
235242
return false;
236243
}
237244

238-
int binSize = _size - sigLen - sizeof(uint32_t) /* The siglen word */;
245+
int binSize = _size;
246+
if (expectedSigLen > 0) {
247+
_size -= (sigLen + sizeof(uint32_t) /* The siglen word */);
248+
}
239249
_hash->begin();
240250
#ifdef DEBUG_UPDATER
241251
DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize);
@@ -254,20 +264,24 @@ bool UpdaterClass::end(bool evenIfRemaining){
254264
for (int i=0; i<_hash->len(); i++) DEBUG_UPDATER.printf(" %02x", ret[i]);
255265
DEBUG_UPDATER.printf("\n");
256266
#endif
257-
uint8_t *sig = (uint8_t*)malloc(sigLen);
258-
if (!sig) {
259-
_setError(UPDATE_ERROR_SIGN);
260-
_reset();
261-
return false;
262-
}
263-
ESP.flashRead(_startAddress + binSize, sig, sigLen);
267+
268+
uint8_t *sig = nullptr; // Safe to free if we don't actually malloc
269+
if (expectedSigLen > 0) {
270+
sig = (uint8_t*)malloc(sigLen);
271+
if (!sig) {
272+
_setError(UPDATE_ERROR_SIGN);
273+
_reset();
274+
return false;
275+
}
276+
ESP.flashRead(_startAddress + binSize, sig, sigLen);
264277
#ifdef DEBUG_UPDATER
265-
DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:"));
266-
for (size_t i=0; i<sigLen; i++) {
267-
DEBUG_UPDATER.printf(" %02x", sig[i]);
268-
}
269-
DEBUG_UPDATER.printf("\n");
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");
270283
#endif
284+
}
271285
if (!_verify->verify(_hash, (void *)sig, sigLen)) {
272286
free(sig);
273287
_setError(UPDATE_ERROR_SIGN);

0 commit comments

Comments
 (0)
0