Skip to content

Commit 8848bff

Browse files
authored
Merge pull request #228 from arduino-libraries/fix-portenta-h7-sha256-cs
Fix SHA256 calculation required for Portenta H7 OTA
2 parents dc38b80 + 6a4e8f4 commit 8848bff

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

src/ArduinoIoTCloudTCP.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,24 @@
3333
#include "tls/utility/CryptoUtil.h"
3434
#endif
3535

36+
#if defined(ARDUINO_PORTENTA_H7_M7)
37+
# include "tls/utility/SHA256.h"
38+
# include <stm32h7xx_hal_rtc_ex.h>
39+
#endif
40+
3641
#include "utility/ota/OTA.h"
3742
#include "utility/ota/FlashSHA256.h"
3843

3944
#include "cbor/CBOREncoder.h"
4045

46+
/******************************************************************************
47+
* EXTERN
48+
******************************************************************************/
49+
50+
#if defined(ARDUINO_PORTENTA_H7_M7)
51+
extern RTC_HandleTypeDef RTCHandle;
52+
#endif
53+
4154
/******************************************************************************
4255
GLOBAL CONSTANTS
4356
******************************************************************************/
@@ -113,6 +126,40 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
113126
#endif /* AVR */
114127

115128
#if OTA_ENABLED && !defined(__AVR__)
129+
#if defined(ARDUINO_PORTENTA_H7_M7)
130+
/* The length of the application can be retrieved the same way it was
131+
* communicated to the bootloader, that is by writing to the non-volatile
132+
* storage registers of the RTC.
133+
*/
134+
SHA256 sha256;
135+
uint32_t const app_start = 0x8040000;
136+
uint32_t const app_size = HAL_RTCEx_BKUPRead(&RTCHandle, RTC_BKP_DR3);
137+
138+
sha256.begin();
139+
uint32_t b = 0;
140+
uint32_t bytes_read = 0; for(uint32_t a = app_start;
141+
bytes_read < app_size;
142+
bytes_read += sizeof(b), a += sizeof(b))
143+
{
144+
/* Read the next chunk of memory. */
145+
memcpy(&b, reinterpret_cast<const void *>(a), sizeof(b));
146+
/* Feed it to SHA256. */
147+
sha256.update(reinterpret_cast<uint8_t *>(&b), sizeof(b));
148+
}
149+
/* Retrieve the final hash string. */
150+
uint8_t sha256_hash[SHA256::HASH_SIZE] = {0};
151+
sha256.finalize(sha256_hash);
152+
String sha256_str;
153+
std::for_each(sha256_hash,
154+
sha256_hash + SHA256::HASH_SIZE,
155+
[&sha256_str](uint8_t const elem)
156+
{
157+
char buf[4];
158+
snprintf(buf, 4, "%02X", elem);
159+
sha256_str += buf;
160+
});
161+
DEBUG_VERBOSE("SHA256: %d bytes (of %d) read", bytes_read, app_size);
162+
#else
116163
/* Calculate the SHA256 checksum over the firmware stored in the flash of the
117164
* MCU. Note: As we don't know the length per-se we read chunks of the flash
118165
* until we detect one containing only 0xFF (= flash erased). This only works
@@ -123,12 +170,10 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort)
123170
* The bootloader is excluded from the calculation and occupies flash address
124171
* range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte).
125172
*/
126-
#if defined(ARDUINO_PORTENTA_H7_M7)
127-
// TODO: check if we need to checksum the whole flash or just the first megabyte
128-
_ota_img_sha256 = FlashSHA256::calc(0x8040000, 0x200000 - 0x40000);
129-
#else
130-
_ota_img_sha256 = FlashSHA256::calc(0x2000, 0x40000 - 0x2000);
173+
String const sha256_str = FlashSHA256::calc(0x2000, 0x40000 - 0x2000);
131174
#endif
175+
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str());
176+
_ota_img_sha256 = sha256_str;
132177
#endif /* OTA_ENABLED */
133178

134179
#ifdef BOARD_HAS_OFFLOADED_ECCX08

src/utility/ota/FlashSHA256.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ String FlashSHA256::calc(uint32_t const start_addr, uint32_t const max_flash_siz
101101
});
102102
/* Do some debug printout. */
103103
DEBUG_VERBOSE("SHA256: %d bytes read", flash_addr);
104-
DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str());
105104
return sha256_str;
106105
}
107106

0 commit comments

Comments
 (0)