void bootloader_sha256_finish(bootloader_sha256_handle_t handle, uint8_t *digest) { assert(handle != NULL); if (digest == NULL) { return; // We'd free resources here, but there are none to free } uint32_t data_words = words_hashed; // Pad to a 55 byte long block loaded in the engine // (leaving 1 byte 0x80 plus variable padding plus 8 bytes of length, // to fill a 64 byte block.) int block_bytes = (words_hashed % BLOCK_WORDS) * 4; int pad_bytes = 55 - block_bytes; if (pad_bytes < 0) { pad_bytes += 64; } static const uint8_t padding[64] = { 0x80, 0, }; pad_bytes += 5; // 1 byte for 0x80 plus first 4 bytes of the 64-bit length assert(pad_bytes % 4 == 0); // should be, as (block_bytes % 4 == 0) bootloader_sha256_data(handle, padding, pad_bytes); assert(words_hashed % BLOCK_WORDS == 60/4); // 32-bits left in block // Calculate 32-bit length for final 32 bits of data uint32_t bit_count = __builtin_bswap32( data_words * 32 ); bootloader_sha256_data(handle, &bit_count, sizeof(bit_count)); assert(words_hashed % BLOCK_WORDS == 0); while(REG_READ(SHA_256_BUSY_REG) == 1) { } REG_WRITE(SHA_256_LOAD_REG, 1); while(REG_READ(SHA_256_BUSY_REG) == 1) { } uint32_t *digest_words = (uint32_t *)digest; uint32_t *sha_text_reg = (uint32_t *)(SHA_TEXT_BASE); for (int i = 0; i < DIGEST_WORDS; i++) { digest_words[i] = __builtin_bswap32(sha_text_reg[i]); } asm volatile ("memw"); }
esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t size, int type, uint8_t *out_sha_256) { if (out_sha_256 == NULL || size == 0) { return ESP_ERR_INVALID_ARG; } if (type == PART_TYPE_APP) { const esp_partition_pos_t partition_pos = { .offset = address, .size = size, }; esp_image_metadata_t data; // Function esp_image_verify() verifies and fills the structure data. // here important to get: image_digest, image_len, hash_appended. if (esp_image_verify(ESP_IMAGE_VERIFY_SILENT, &partition_pos, &data) != ESP_OK) { return ESP_ERR_IMAGE_INVALID; } if (data.image.hash_appended) { memcpy(out_sha_256, data.image_digest, ESP_PARTITION_HASH_LEN); return ESP_OK; } // If image doesn't have a appended hash then hash calculates for entire image. size = data.image_len; } // If image is type by data then hash is calculated for entire image. const void *partition_bin = bootloader_mmap(address, size); if (partition_bin == NULL) { ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", address, size); return ESP_FAIL; } bootloader_sha256_handle_t sha_handle = bootloader_sha256_start(); if (sha_handle == NULL) { bootloader_munmap(partition_bin); return ESP_ERR_NO_MEM; } bootloader_sha256_data(sha_handle, partition_bin, size); bootloader_sha256_finish(sha_handle, out_sha_256); bootloader_munmap(partition_bin); return ESP_OK; }