|
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