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 = sizeof (uint32_t );
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