esp_image_format.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #include <string.h>
  14. #include <sys/param.h>
  15. #include <esp32/rom/rtc.h>
  16. #include <soc/cpu.h>
  17. #include <bootloader_utility.h>
  18. #include <esp_secure_boot.h>
  19. #include <esp_log.h>
  20. #include <esp_spi_flash.h>
  21. #include <bootloader_flash.h>
  22. #include <bootloader_random.h>
  23. #include <bootloader_sha.h>
  24. #include "bootloader_util.h"
  25. #include "bootloader_common.h"
  26. /* Checking signatures as part of verifying images is necessary:
  27. - Always if secure boot is enabled
  28. - Differently in bootloader and/or app, depending on kconfig
  29. */
  30. #ifdef BOOTLOADER_BUILD
  31. #ifdef CONFIG_SECURE_SIGNED_ON_BOOT
  32. #define SECURE_BOOT_CHECK_SIGNATURE
  33. #endif
  34. #else /* !BOOTLOADER_BUILD */
  35. #ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
  36. #define SECURE_BOOT_CHECK_SIGNATURE
  37. #endif
  38. #endif
  39. static const char *TAG = "esp_image";
  40. #define HASH_LEN ESP_IMAGE_HASH_LEN
  41. #define SIXTEEN_MB 0x1000000
  42. #define ESP_ROM_CHECKSUM_INITIAL 0xEF
  43. /* Headroom to ensure between stack SP (at time of checking) and data loaded from flash */
  44. #define STACK_LOAD_HEADROOM 32768
  45. /* Mmap source address mask */
  46. #define MMAP_ALIGNED_MASK 0x0000FFFF
  47. #ifdef BOOTLOADER_BUILD
  48. /* 64 bits of random data to obfuscate loaded RAM with, until verification is complete
  49. (Means loaded code isn't executable until after the secure boot check.)
  50. */
  51. static uint32_t ram_obfs_value[2];
  52. /* Range of IRAM used by the loader, defined in ld script */
  53. extern int _loader_text_start;
  54. extern int _loader_text_end;
  55. #endif
  56. /* Return true if load_addr is an address the bootloader should load into */
  57. static bool should_load(uint32_t load_addr);
  58. /* Return true if load_addr is an address the bootloader should map via flash cache */
  59. static bool should_map(uint32_t load_addr);
  60. /* Load or verify a segment */
  61. static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
  62. /* split segment and verify if data_len is too long */
  63. static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum);
  64. /* Verify the main image header */
  65. static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent);
  66. /* Verify a segment header */
  67. static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent);
  68. /* Log-and-fail macro for use in esp_image_load */
  69. #define FAIL_LOAD(...) do { \
  70. if (!silent) { \
  71. ESP_LOGE(TAG, __VA_ARGS__); \
  72. } \
  73. goto err; \
  74. } \
  75. while(0)
  76. static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data);
  77. static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
  78. static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data);
  79. static esp_err_t image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
  80. {
  81. #ifdef BOOTLOADER_BUILD
  82. bool do_load = (mode == ESP_IMAGE_LOAD);
  83. #else
  84. bool do_load = false; // Can't load the image in app mode
  85. #endif
  86. bool silent = (mode == ESP_IMAGE_VERIFY_SILENT);
  87. esp_err_t err = ESP_OK;
  88. // checksum the image a word at a time. This shaves 30-40ms per MB of image size
  89. uint32_t checksum_word = ESP_ROM_CHECKSUM_INITIAL;
  90. bootloader_sha256_handle_t sha_handle = NULL;
  91. if (data == NULL || part == NULL) {
  92. return ESP_ERR_INVALID_ARG;
  93. }
  94. if (part->size > SIXTEEN_MB) {
  95. err = ESP_ERR_INVALID_ARG;
  96. FAIL_LOAD("partition size 0x%x invalid, larger than 16MB", part->size);
  97. }
  98. bzero(data, sizeof(esp_image_metadata_t));
  99. data->start_addr = part->offset;
  100. ESP_LOGD(TAG, "reading image header @ 0x%x", data->start_addr);
  101. err = bootloader_flash_read(data->start_addr, &data->image, sizeof(esp_image_header_t), true);
  102. if (err != ESP_OK) {
  103. goto err;
  104. }
  105. // Calculate SHA-256 of image if secure boot is on, or if image has a hash appended
  106. #ifdef SECURE_BOOT_CHECK_SIGNATURE
  107. if (1) {
  108. #else
  109. if (data->image.hash_appended) {
  110. #endif
  111. sha_handle = bootloader_sha256_start();
  112. if (sha_handle == NULL) {
  113. return ESP_ERR_NO_MEM;
  114. }
  115. bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t));
  116. }
  117. ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x",
  118. data->image.magic,
  119. data->image.segment_count,
  120. data->image.spi_mode,
  121. data->image.spi_size,
  122. data->image.entry_addr);
  123. err = verify_image_header(data->start_addr, &data->image, silent);
  124. if (err != ESP_OK) {
  125. goto err;
  126. }
  127. if (data->image.segment_count > ESP_IMAGE_MAX_SEGMENTS) {
  128. FAIL_LOAD("image at 0x%x segment count %d exceeds max %d",
  129. data->start_addr, data->image.segment_count, ESP_IMAGE_MAX_SEGMENTS);
  130. }
  131. uint32_t next_addr = data->start_addr + sizeof(esp_image_header_t);
  132. for(int i = 0; i < data->image.segment_count; i++) {
  133. esp_image_segment_header_t *header = &data->segments[i];
  134. ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
  135. err = process_segment(i, next_addr, header, silent, do_load, sha_handle, &checksum_word);
  136. if (err != ESP_OK) {
  137. goto err;
  138. }
  139. next_addr += sizeof(esp_image_segment_header_t);
  140. data->segment_data[i] = next_addr;
  141. next_addr += header->data_len;
  142. }
  143. // Segments all loaded, verify length
  144. uint32_t end_addr = next_addr;
  145. if (end_addr < data->start_addr) {
  146. FAIL_LOAD("image offset has wrapped");
  147. }
  148. data->image_len = end_addr - data->start_addr;
  149. ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr);
  150. if (!esp_cpu_in_ocd_debug_mode()) {
  151. err = verify_checksum(sha_handle, checksum_word, data);
  152. if (err != ESP_OK) {
  153. goto err;
  154. }
  155. }
  156. if (data->image_len > part->size) {
  157. FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size);
  158. }
  159. bool is_bootloader = (data->start_addr == ESP_BOOTLOADER_OFFSET);
  160. /* For secure boot, we don't verify signature on bootloaders.
  161. For non-secure boot, we don't verify any SHA-256 hash appended to the bootloader because esptool.py may have
  162. rewritten the header - rely on esptool.py having verified the bootloader at flashing time, instead.
  163. */
  164. if (!is_bootloader) {
  165. #ifdef SECURE_BOOT_CHECK_SIGNATURE
  166. // secure boot images have a signature appended
  167. err = verify_secure_boot_signature(sha_handle, data);
  168. #else
  169. // No secure boot, but SHA-256 can be appended for basic corruption detection
  170. if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) {
  171. err = verify_simple_hash(sha_handle, data);
  172. }
  173. #endif // SECURE_BOOT_CHECK_SIGNATURE
  174. } else { // is_bootloader
  175. // bootloader may still have a sha256 digest handle open
  176. if (sha_handle != NULL) {
  177. bootloader_sha256_finish(sha_handle, NULL);
  178. }
  179. }
  180. if (data->image.hash_appended) {
  181. const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
  182. if (hash == NULL) {
  183. err = ESP_FAIL;
  184. goto err;
  185. }
  186. memcpy(data->image_digest, hash, HASH_LEN);
  187. bootloader_munmap(hash);
  188. }
  189. sha_handle = NULL;
  190. if (err != ESP_OK) {
  191. goto err;
  192. }
  193. #ifdef BOOTLOADER_BUILD
  194. if (do_load) { // Need to deobfuscate RAM
  195. for (int i = 0; i < data->image.segment_count; i++) {
  196. uint32_t load_addr = data->segments[i].load_addr;
  197. if (should_load(load_addr)) {
  198. uint32_t *loaded = (uint32_t *)load_addr;
  199. for (int j = 0; j < data->segments[i].data_len/sizeof(uint32_t); j++) {
  200. loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1];
  201. }
  202. }
  203. }
  204. }
  205. #endif
  206. // Success!
  207. return ESP_OK;
  208. err:
  209. if (err == ESP_OK) {
  210. err = ESP_ERR_IMAGE_INVALID;
  211. }
  212. if (sha_handle != NULL) {
  213. // Need to finish the hash process to free the handle
  214. bootloader_sha256_finish(sha_handle, NULL);
  215. }
  216. // Prevent invalid/incomplete data leaking out
  217. bzero(data, sizeof(esp_image_metadata_t));
  218. return err;
  219. }
  220. esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
  221. {
  222. #ifdef BOOTLOADER_BUILD
  223. return image_load(ESP_IMAGE_LOAD, part, data);
  224. #else
  225. return ESP_FAIL;
  226. #endif
  227. }
  228. esp_err_t esp_image_verify(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data)
  229. {
  230. return image_load(mode, part, data);
  231. }
  232. static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t *image, bool silent)
  233. {
  234. esp_err_t err = ESP_OK;
  235. if (image->magic != ESP_IMAGE_HEADER_MAGIC) {
  236. if (!silent) {
  237. ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
  238. }
  239. err = ESP_ERR_IMAGE_INVALID;
  240. }
  241. if (bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION) != ESP_OK) {
  242. err = ESP_ERR_IMAGE_INVALID;
  243. }
  244. if (!silent) {
  245. if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
  246. ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
  247. }
  248. if (image->spi_speed > ESP_IMAGE_SPI_SPEED_80M) {
  249. ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image->spi_speed);
  250. }
  251. if (image->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) {
  252. ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image->spi_size);
  253. }
  254. }
  255. return err;
  256. }
  257. static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segment_header_t *header, bool silent, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
  258. {
  259. esp_err_t err;
  260. /* read segment header */
  261. err = bootloader_flash_read(flash_addr, header, sizeof(esp_image_segment_header_t), true);
  262. if (err != ESP_OK) {
  263. ESP_LOGE(TAG, "bootloader_flash_read failed at 0x%08x", flash_addr);
  264. return err;
  265. }
  266. if (sha_handle != NULL) {
  267. bootloader_sha256_data(sha_handle, header, sizeof(esp_image_segment_header_t));
  268. }
  269. intptr_t load_addr = header->load_addr;
  270. uint32_t data_len = header->data_len;
  271. uint32_t data_addr = flash_addr + sizeof(esp_image_segment_header_t);
  272. ESP_LOGV(TAG, "segment data length 0x%x data starts 0x%x", data_len, data_addr);
  273. err = verify_segment_header(index, header, data_addr, silent);
  274. if (err != ESP_OK) {
  275. return err;
  276. }
  277. if (data_len % 4 != 0) {
  278. FAIL_LOAD("unaligned segment length 0x%x", data_len);
  279. }
  280. bool is_mapping = should_map(load_addr);
  281. do_load = do_load && should_load(load_addr);
  282. if (!silent) {
  283. ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s",
  284. index, data_addr, load_addr,
  285. data_len, data_len,
  286. (do_load)?"load":(is_mapping)?"map":"");
  287. }
  288. #ifdef BOOTLOADER_BUILD
  289. /* Before loading segment, check it doesn't clobber bootloader RAM. */
  290. if (do_load) {
  291. const intptr_t load_end = load_addr + data_len;
  292. if (load_end <= (intptr_t) SOC_DIRAM_DRAM_HIGH) {
  293. /* Writing to DRAM */
  294. intptr_t sp = (intptr_t)get_sp();
  295. if (load_end > sp - STACK_LOAD_HEADROOM) {
  296. /* Bootloader .data/.rodata/.bss is above the stack, so this
  297. * also checks that we aren't overwriting these segments.
  298. *
  299. * TODO: This assumes specific arrangement of sections we have
  300. * in the ESP32. Rewrite this in a generic way to support other
  301. * layouts.
  302. */
  303. ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x limit 0x%08x)",
  304. index, load_end, sp, sp - STACK_LOAD_HEADROOM);
  305. return ESP_ERR_IMAGE_INVALID;
  306. }
  307. } else {
  308. /* Writing to IRAM */
  309. const intptr_t loader_iram_start = (intptr_t) &_loader_text_start;
  310. const intptr_t loader_iram_end = (intptr_t) &_loader_text_end;
  311. if (bootloader_util_regions_overlap(loader_iram_start, loader_iram_end,
  312. load_addr, load_end)) {
  313. ESP_LOGE(TAG, "Segment %d (0x%08x-0x%08x) overlaps bootloader IRAM (0x%08x-0x%08x)",
  314. index, load_addr, load_end, loader_iram_start, loader_iram_end);
  315. return ESP_ERR_IMAGE_INVALID;
  316. }
  317. }
  318. }
  319. #endif // BOOTLOADER_BUILD
  320. uint32_t free_page_count = bootloader_mmap_get_free_pages();
  321. ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
  322. int32_t data_len_remain = data_len;
  323. while (data_len_remain > 0) {
  324. uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
  325. /* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
  326. data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
  327. err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
  328. if (err != ESP_OK) {
  329. return err;
  330. }
  331. data_addr += data_len;
  332. data_len_remain -= data_len;
  333. }
  334. return ESP_OK;
  335. err:
  336. if (err == ESP_OK) {
  337. err = ESP_ERR_IMAGE_INVALID;
  338. }
  339. return err;
  340. }
  341. static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, uint32_t data_len, bool do_load, bootloader_sha256_handle_t sha_handle, uint32_t *checksum)
  342. {
  343. const uint32_t *data = (const uint32_t *)bootloader_mmap(data_addr, data_len);
  344. if(!data) {
  345. ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed",
  346. data_addr, data_len);
  347. return ESP_FAIL;
  348. }
  349. #ifdef BOOTLOADER_BUILD
  350. // Set up the obfuscation value to use for loading
  351. while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) {
  352. bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value));
  353. }
  354. uint32_t *dest = (uint32_t *)load_addr;
  355. #endif
  356. const uint32_t *src = data;
  357. for (int i = 0; i < data_len; i += 4) {
  358. int w_i = i/4; // Word index
  359. uint32_t w = src[w_i];
  360. *checksum ^= w;
  361. #ifdef BOOTLOADER_BUILD
  362. if (do_load) {
  363. dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]);
  364. }
  365. #endif
  366. // SHA_CHUNK determined experimentally as the optimum size
  367. // to call bootloader_sha256_data() with. This is a bit
  368. // counter-intuitive, but it's ~3ms better than using the
  369. // SHA256 block size.
  370. const size_t SHA_CHUNK = 1024;
  371. if (sha_handle != NULL && i % SHA_CHUNK == 0) {
  372. bootloader_sha256_data(sha_handle, &src[w_i],
  373. MIN(SHA_CHUNK, data_len - i));
  374. }
  375. }
  376. bootloader_munmap(data);
  377. return ESP_OK;
  378. }
  379. static esp_err_t verify_segment_header(int index, const esp_image_segment_header_t *segment, uint32_t segment_data_offs, bool silent)
  380. {
  381. if ((segment->data_len & 3) != 0
  382. || segment->data_len >= SIXTEEN_MB) {
  383. if (!silent) {
  384. ESP_LOGE(TAG, "invalid segment length 0x%x", segment->data_len);
  385. }
  386. return ESP_ERR_IMAGE_INVALID;
  387. }
  388. uint32_t load_addr = segment->load_addr;
  389. bool map_segment = should_map(load_addr);
  390. /* Check that flash cache mapped segment aligns correctly from flash to its mapped address,
  391. relative to the 64KB page mapping size.
  392. */
  393. ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x",
  394. index, map_segment, segment_data_offs, load_addr);
  395. if (map_segment
  396. && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
  397. if (!silent) {
  398. ESP_LOGE(TAG, "Segment %d load address 0x%08x, doesn't match data 0x%08x",
  399. index, load_addr, segment_data_offs);
  400. }
  401. return ESP_ERR_IMAGE_INVALID;
  402. }
  403. return ESP_OK;
  404. }
  405. static bool should_map(uint32_t load_addr)
  406. {
  407. return (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH)
  408. || (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH);
  409. }
  410. static bool should_load(uint32_t load_addr)
  411. {
  412. /* Reload the RTC memory segments whenever a non-deepsleep reset
  413. is occurring */
  414. bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
  415. if (should_map(load_addr)) {
  416. return false;
  417. }
  418. if (load_addr < 0x10000000) {
  419. // Reserved for non-loaded addresses.
  420. // Current reserved values are
  421. // 0x0 (padding block)
  422. // 0x4 (unused, but reserved for an MD5 block)
  423. return false;
  424. }
  425. if (!load_rtc_memory) {
  426. if (load_addr >= SOC_RTC_IRAM_LOW && load_addr < SOC_RTC_IRAM_HIGH) {
  427. ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
  428. return false;
  429. }
  430. if (load_addr >= SOC_RTC_DRAM_LOW && load_addr < SOC_RTC_DRAM_HIGH) {
  431. ESP_LOGD(TAG, "Skipping RTC fast memory segment at 0x%08x\n", load_addr);
  432. return false;
  433. }
  434. if (load_addr >= SOC_RTC_DATA_LOW && load_addr < SOC_RTC_DATA_HIGH) {
  435. ESP_LOGD(TAG, "Skipping RTC slow memory segment at 0x%08x\n", load_addr);
  436. return false;
  437. }
  438. }
  439. return true;
  440. }
  441. esp_err_t esp_image_verify_bootloader(uint32_t *length)
  442. {
  443. esp_image_metadata_t data;
  444. esp_err_t err = esp_image_verify_bootloader_data(&data);
  445. if (length != NULL) {
  446. *length = (err == ESP_OK) ? data.image_len : 0;
  447. }
  448. return err;
  449. }
  450. esp_err_t esp_image_verify_bootloader_data(esp_image_metadata_t *data)
  451. {
  452. if (data == NULL) {
  453. return ESP_ERR_INVALID_ARG;
  454. }
  455. const esp_partition_pos_t bootloader_part = {
  456. .offset = ESP_BOOTLOADER_OFFSET,
  457. .size = ESP_PARTITION_TABLE_OFFSET - ESP_BOOTLOADER_OFFSET,
  458. };
  459. return esp_image_verify(ESP_IMAGE_VERIFY,
  460. &bootloader_part,
  461. data);
  462. }
  463. static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data)
  464. {
  465. uint32_t unpadded_length = data->image_len;
  466. uint32_t length = unpadded_length + 1; // Add a byte for the checksum
  467. length = (length + 15) & ~15; // Pad to next full 16 byte block
  468. // Verify checksum
  469. uint8_t buf[16];
  470. esp_err_t err = bootloader_flash_read(data->start_addr + unpadded_length, buf, length - unpadded_length, true);
  471. uint8_t calc = buf[length - unpadded_length - 1];
  472. uint8_t checksum = (checksum_word >> 24)
  473. ^ (checksum_word >> 16)
  474. ^ (checksum_word >> 8)
  475. ^ (checksum_word >> 0);
  476. if (err != ESP_OK || checksum != calc) {
  477. ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc);
  478. return ESP_ERR_IMAGE_INVALID;
  479. }
  480. if (sha_handle != NULL) {
  481. bootloader_sha256_data(sha_handle, buf, length - unpadded_length);
  482. }
  483. if (data->image.hash_appended) {
  484. // Account for the hash in the total image length
  485. length += HASH_LEN;
  486. }
  487. data->image_len = length;
  488. return ESP_OK;
  489. }
  490. static void debug_log_hash(const uint8_t *image_hash, const char *caption);
  491. static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
  492. {
  493. uint8_t image_hash[HASH_LEN] = { 0 };
  494. ESP_LOGI(TAG, "Verifying image signature...");
  495. // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash
  496. // appended to the image for corruption detection
  497. if (data->image.hash_appended) {
  498. const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
  499. bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN);
  500. bootloader_munmap(simple_hash);
  501. }
  502. bootloader_sha256_finish(sha_handle, image_hash);
  503. // Log the hash for debugging
  504. debug_log_hash(image_hash, "Calculated secure boot hash");
  505. // Use hash to verify signature block
  506. const esp_secure_boot_sig_block_t *sig_block = bootloader_mmap(data->start_addr + data->image_len, sizeof(esp_secure_boot_sig_block_t));
  507. esp_err_t err = esp_secure_boot_verify_signature_block(sig_block, image_hash);
  508. bootloader_munmap(sig_block);
  509. if (err != ESP_OK) {
  510. ESP_LOGE(TAG, "Secure boot signature verification failed");
  511. // Go back and check if the simple hash matches or not (we're off the fast path so we can re-hash the whole image now)
  512. ESP_LOGI(TAG, "Calculating simple hash to check for corruption...");
  513. const void *whole_image = bootloader_mmap(data->start_addr, data->image_len - HASH_LEN);
  514. if (whole_image != NULL) {
  515. sha_handle = bootloader_sha256_start();
  516. bootloader_sha256_data(sha_handle, whole_image, data->image_len - HASH_LEN);
  517. bootloader_munmap(whole_image);
  518. if (verify_simple_hash(sha_handle, data) != ESP_OK) {
  519. ESP_LOGW(TAG, "image corrupted on flash");
  520. } else {
  521. ESP_LOGW(TAG, "image valid, signature bad");
  522. }
  523. }
  524. return ESP_ERR_IMAGE_INVALID;
  525. }
  526. return ESP_OK;
  527. }
  528. static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data)
  529. {
  530. uint8_t image_hash[HASH_LEN] = { 0 };
  531. bootloader_sha256_finish(sha_handle, image_hash);
  532. // Log the hash for debugging
  533. debug_log_hash(image_hash, "Calculated hash");
  534. // Simple hash for verification only
  535. const void *hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN);
  536. if (memcmp(hash, image_hash, HASH_LEN) != 0) {
  537. ESP_LOGE(TAG, "Image hash failed - image is corrupt");
  538. debug_log_hash(hash, "Expected hash");
  539. bootloader_munmap(hash);
  540. return ESP_ERR_IMAGE_INVALID;
  541. }
  542. bootloader_munmap(hash);
  543. return ESP_OK;
  544. }
  545. // Log a hash as a hex string
  546. static void debug_log_hash(const uint8_t *image_hash, const char *label)
  547. {
  548. #if BOOT_LOG_LEVEL >= LOG_LEVEL_DEBUG
  549. char hash_print[HASH_LEN * 2 + 1];
  550. hash_print[HASH_LEN * 2] = 0;
  551. bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN);
  552. ESP_LOGD(TAG, "%s: %s", label, hash_print);
  553. #endif
  554. }