|
23 | 23 |
|
24 | 24 | #ifdef HAS_TCP |
25 | 25 | #include <ArduinoIoTCloudTCP.h> |
| 26 | + |
26 | 27 | #ifdef BOARD_HAS_ECCX08 |
27 | 28 | #include "tls/BearSSLTrustAnchors.h" |
28 | 29 | #include "tls/utility/CryptoUtil.h" |
|
34 | 35 | #endif |
35 | 36 |
|
36 | 37 | #ifdef BOARD_HAS_OFFLOADED_ECCX08 |
37 | | -#include <ArduinoECCX08.h> |
38 | | -#include "tls/utility/CryptoUtil.h" |
39 | | -#endif |
40 | | - |
41 | | -#ifdef BOARD_STM32H7 |
42 | | -# include "tls/utility/SHA256.h" |
43 | | -# include <stm32h7xx_hal_rtc_ex.h> |
44 | | -# include <WiFi.h> |
45 | | -#endif |
46 | | - |
47 | | -#if defined (ARDUINO_ARCH_ESP32) && OTA_ENABLED |
48 | | -# include "tls/utility/SHA256.h" |
49 | | -#include "esp_spi_flash.h" |
50 | | -#include "esp_ota_ops.h" |
51 | | -#include "esp_image_format.h" |
52 | | -#endif |
53 | | - |
54 | | -#if defined (ARDUINO_NANO_RP2040_CONNECT) || \ |
55 | | - (defined (ARDUINO_ARCH_SAMD) && OTA_ENABLED) |
56 | | -#include "utility/ota/FlashSHA256.h" |
| 38 | + #include <ArduinoECCX08.h> |
| 39 | + #include "tls/utility/CryptoUtil.h" |
57 | 40 | #endif |
58 | 41 |
|
59 | 42 | #if OTA_ENABLED |
60 | | -#include "utility/ota/OTA.h" |
| 43 | + #include "utility/ota/OTA.h" |
61 | 44 | #endif |
62 | 45 |
|
63 | 46 | #include <algorithm> |
64 | 47 | #include "cbor/CBOREncoder.h" |
65 | | - |
66 | 48 | #include "utility/watchdog/Watchdog.h" |
67 | 49 |
|
68 | | -/****************************************************************************** |
69 | | - * EXTERN |
70 | | - ******************************************************************************/ |
71 | | - |
72 | | -#ifdef BOARD_STM32H7 |
73 | | -extern RTC_HandleTypeDef RTCHandle; |
74 | | -#endif |
75 | | - |
76 | 50 | /****************************************************************************** |
77 | 51 | LOCAL MODULE FUNCTIONS |
78 | 52 | ******************************************************************************/ |
@@ -164,100 +138,8 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress, |
164 | 138 | #endif /* AVR */ |
165 | 139 |
|
166 | 140 | #if OTA_ENABLED && !defined(__AVR__) |
167 | | -#if defined(BOARD_STM32H7) |
168 | | - /* The length of the application can be retrieved the same way it was |
169 | | - * communicated to the bootloader, that is by writing to the non-volatile |
170 | | - * storage registers of the RTC. |
171 | | - */ |
172 | | - SHA256 sha256; |
173 | | - uint32_t const app_start = 0x8040000; |
174 | | - uint32_t const app_size = HAL_RTCEx_BKUPRead(&RTCHandle, RTC_BKP_DR3); |
175 | | - |
176 | | - sha256.begin(); |
177 | | - uint32_t b = 0; |
178 | | - uint32_t bytes_read = 0; for(uint32_t a = app_start; |
179 | | - bytes_read < app_size; |
180 | | - bytes_read += sizeof(b), a += sizeof(b)) |
181 | | - { |
182 | | - /* Read the next chunk of memory. */ |
183 | | - memcpy(&b, reinterpret_cast<const void *>(a), sizeof(b)); |
184 | | - /* Feed it to SHA256. */ |
185 | | - sha256.update(reinterpret_cast<uint8_t *>(&b), sizeof(b)); |
186 | | - } |
187 | | - /* Retrieve the final hash string. */ |
188 | | - uint8_t sha256_hash[SHA256::HASH_SIZE] = {0}; |
189 | | - sha256.finalize(sha256_hash); |
190 | | - String sha256_str; |
191 | | - std::for_each(sha256_hash, |
192 | | - sha256_hash + SHA256::HASH_SIZE, |
193 | | - [&sha256_str](uint8_t const elem) |
194 | | - { |
195 | | - char buf[4]; |
196 | | - snprintf(buf, 4, "%02X", elem); |
197 | | - sha256_str += buf; |
198 | | - }); |
199 | | - DEBUG_VERBOSE("SHA256: %d bytes (of %d) read", bytes_read, app_size); |
200 | | -#elif defined(ARDUINO_ARCH_SAMD) |
201 | | - /* Calculate the SHA256 checksum over the firmware stored in the flash of the |
202 | | - * MCU. Note: As we don't know the length per-se we read chunks of the flash |
203 | | - * until we detect one containing only 0xFF (= flash erased). This only works |
204 | | - * for firmware updated via OTA and second stage bootloaders (SxU family) |
205 | | - * because only those erase the complete flash before performing an update. |
206 | | - * Since the SHA256 firmware image is only required for the cloud servers to |
207 | | - * perform a version check after the OTA update this is a acceptable trade off. |
208 | | - * The bootloader is excluded from the calculation and occupies flash address |
209 | | - * range 0 to 0x2000, total flash size of 0x40000 bytes (256 kByte). |
210 | | - */ |
211 | | - String const sha256_str = FlashSHA256::calc(0x2000, 0x40000 - 0x2000); |
212 | | -#elif defined(ARDUINO_NANO_RP2040_CONNECT) |
213 | | - /* The maximum size of a RP2040 OTA update image is 1 MByte (that is 1024 * |
214 | | - * 1024 bytes or 0x100'000 bytes). |
215 | | - */ |
216 | | - String const sha256_str = FlashSHA256::calc(XIP_BASE, 0x100000); |
217 | | -#elif defined(ARDUINO_ARCH_ESP32) |
218 | | - SHA256 sha256; |
219 | | - |
220 | | - uint32_t lengthLeft = ESP.getSketchSize(); |
221 | | - |
222 | | - const esp_partition_t *running = esp_ota_get_running_partition(); |
223 | | - if (!running) { |
224 | | - DEBUG_ERROR("Partition could not be found"); |
225 | | - } |
226 | | - const size_t bufSize = SPI_FLASH_SEC_SIZE; |
227 | | - std::unique_ptr<uint8_t[]> buf(new uint8_t[bufSize]); |
228 | | - uint32_t offset = 0; |
229 | | - if(!buf.get()) { |
230 | | - DEBUG_ERROR("Not enough memory to allocate buffer"); |
231 | | - } |
232 | | - |
233 | | - sha256.begin(); |
234 | | - while( lengthLeft > 0) { |
235 | | - size_t readBytes = (lengthLeft < bufSize) ? lengthLeft : bufSize; |
236 | | - if (!ESP.flashRead(running->address + offset, reinterpret_cast<uint32_t*>(buf.get()), (readBytes + 3) & ~3)) { |
237 | | - DEBUG_ERROR("Could not read buffer from flash"); |
238 | | - } |
239 | | - sha256.update(buf.get(), readBytes); |
240 | | - lengthLeft -= readBytes; |
241 | | - offset += readBytes; |
242 | | - } |
243 | | - /* Retrieve the final hash string. */ |
244 | | - uint8_t sha256_hash[SHA256::HASH_SIZE] = {0}; |
245 | | - sha256.finalize(sha256_hash); |
246 | | - String sha256_str; |
247 | | - std::for_each(sha256_hash, |
248 | | - sha256_hash + SHA256::HASH_SIZE, |
249 | | - [&sha256_str](uint8_t const elem) |
250 | | - { |
251 | | - char buf[4]; |
252 | | - snprintf(buf, 4, "%02X", elem); |
253 | | - sha256_str += buf; |
254 | | - }); |
255 | | - DEBUG_VERBOSE("SHA256: %d bytes (of %d) read", ESP.getSketchSize() - lengthLeft, ESP.getSketchSize()); |
256 | | -#else |
257 | | -# error "No method for SHA256 checksum calculation over application image defined for this architecture." |
258 | | -#endif |
259 | | - DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(sha256_str.c_str()), sha256_str.c_str()); |
260 | | - _ota_img_sha256 = sha256_str; |
| 141 | + _ota_img_sha256 = getOTAImageSHA256(); |
| 142 | + DEBUG_VERBOSE("SHA256: HASH(%d) = %s", strlen(_ota_img_sha256.c_str()), _ota_img_sha256.c_str()); |
261 | 143 | #endif /* OTA_ENABLED */ |
262 | 144 |
|
263 | 145 | #if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08) || defined(BOARD_HAS_SE050) |
@@ -902,6 +784,21 @@ void ArduinoIoTCloudTCP::onOTARequest() |
902 | 784 | _ota_error = esp32_onOTARequest(_ota_url.c_str()); |
903 | 785 | #endif |
904 | 786 | } |
| 787 | + |
| 788 | +String ArduinoIoTCloudTCP::getOTAImageSHA256() |
| 789 | +{ |
| 790 | +#if defined (ARDUINO_ARCH_SAMD) |
| 791 | + return samd_getOTAImageSHA256(); |
| 792 | +#elif defined (ARDUINO_NANO_RP2040_CONNECT) |
| 793 | + return rp2040_connect_getOTAImageSHA256(); |
| 794 | +#elif defined (BOARD_STM32H7) |
| 795 | + return portenta_h7_getOTAImageSHA256(); |
| 796 | +#elif defined (ARDUINO_ARCH_ESP32) |
| 797 | + return esp32_getOTAImageSHA256(); |
| 798 | +#else |
| 799 | + # error "No method for SHA256 checksum calculation over application image defined for this architecture." |
| 800 | +#endif |
| 801 | +} |
905 | 802 | #endif |
906 | 803 |
|
907 | 804 | void ArduinoIoTCloudTCP::updateThingTopics() |
|
0 commit comments