1
+ #include < Arduino.h>
1
2
#include " Updater.h"
2
3
#include " eboot_command.h"
3
4
#include < esp8266_peri.h>
4
5
#include < PolledTimeout.h>
5
6
#include " StackThunk.h"
6
7
8
+ #include < memory>
9
+
7
10
// #define DEBUG_UPDATER Serial
8
11
9
12
#include < Updater_Signing.h>
@@ -224,71 +227,87 @@ bool UpdaterClass::end(bool evenIfRemaining){
224
227
}
225
228
226
229
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 );
227
234
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;
231
236
uint32_t sigLen = 0 ;
232
237
238
+ #ifdef DEBUG_UPDATER
239
+ DEBUG_UPDATER.printf_P (PSTR (" [Updater] expected sigLen: %lu\n " ), expectedSigLen);
240
+ #endif
233
241
if (expectedSigLen > 0 ) {
234
- ESP.flashRead (_startAddress + _size - sizeof (uint32_t ), &sigLen, sizeof (uint32_t ));
235
- }
242
+ ESP.flashRead (sigLenAddr, &sigLen, SigSize);
236
243
#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);
238
245
#endif
246
+ }
247
+
239
248
if (sigLen != expectedSigLen) {
240
249
_setError (UPDATE_ERROR_SIGN);
241
250
_reset ();
242
251
return false ;
243
252
}
244
253
245
- int binSize = _size;
254
+ auto binSize = _size;
246
255
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);
250
262
#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);
252
264
#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);
259
275
}
260
276
_hash->end ();
277
+
261
278
#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 ());
266
289
#endif
267
290
268
- uint8_t * sig = nullptr ; // Safe to free if we don't actually malloc
291
+ std::unique_ptr< uint8_t []> sig;
269
292
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]);
271
295
if (!sig) {
272
296
_setError (UPDATE_ERROR_SIGN);
273
297
_reset ();
274
298
return false ;
275
299
}
276
- ESP.flashRead (_startAddress + binSize , sig, sigLen);
300
+ ESP.flashRead (sigAddr , sig. get () , sigLen);
277
301
#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);
283
303
#endif
284
304
}
285
- if (!_verify->verify (_hash, (void *)sig, sigLen)) {
286
- free (sig);
305
+ if (!_verify->verify (_hash, sig.get (), sigLen)) {
287
306
_setError (UPDATE_ERROR_SIGN);
288
307
_reset ();
289
308
return false ;
290
309
}
291
- free (sig);
310
+
292
311
_size = binSize; // Adjust size to remove signature, not part of bin payload
293
312
294
313
#ifdef DEBUG_UPDATER
@@ -301,7 +320,7 @@ bool UpdaterClass::end(bool evenIfRemaining){
301
320
return false ;
302
321
}
303
322
#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 ());
305
324
#endif
306
325
}
307
326
0 commit comments