|
11 | 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | 12 | // See the License for the specific language governing permissions and |
13 | 13 | // limitations under the License. |
| 14 | +#include <string.h> |
14 | 15 | #include "esp_flash_partitions.h" |
15 | 16 | #include "esp_log.h" |
16 | 17 | #include "rom/spi_flash.h" |
| 18 | +#include "rom/md5_hash.h" |
| 19 | +#include "esp_flash_data_types.h" |
17 | 20 |
|
18 | 21 | static const char *TAG = "flash_parts"; |
19 | 22 |
|
20 | 23 | esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions) |
21 | 24 | { |
22 | | - int num_parts; |
23 | | - uint32_t chip_size = g_rom_flashchip.chip_size; |
24 | | - *num_partitions = 0; |
25 | | - |
26 | | - for(num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) { |
27 | | - const esp_partition_info_t *part = &partition_table[num_parts]; |
28 | | - |
29 | | - if (part->magic == 0xFFFF |
30 | | - && part->type == PART_TYPE_END |
31 | | - && part->subtype == PART_SUBTYPE_END) { |
32 | | - /* TODO: check md5 */ |
33 | | - ESP_LOGD(TAG, "partition table verified, %d entries", num_parts); |
34 | | - *num_partitions = num_parts; |
35 | | - return ESP_OK; |
36 | | - } |
| 25 | + int md5_found = 0; |
| 26 | + int num_parts; |
| 27 | + uint32_t chip_size = g_rom_flashchip.chip_size; |
| 28 | + *num_partitions = 0; |
37 | 29 |
|
38 | | - if (part->magic != ESP_PARTITION_MAGIC) { |
39 | | - if (log_errors) { |
40 | | - ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic); |
41 | | - } |
42 | | - return ESP_ERR_INVALID_STATE; |
43 | | - } |
| 30 | + for (num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) { |
| 31 | + const esp_partition_info_t *part = &partition_table[num_parts]; |
| 32 | + |
| 33 | + if (part->magic == ESP_PARTITION_MAGIC) { |
| 34 | + const esp_partition_pos_t *pos = &part->pos; |
| 35 | + if (pos->offset > chip_size || pos->offset + pos->size > chip_size) { |
| 36 | + if (log_errors) { |
| 37 | + ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x", |
| 38 | + num_parts, pos->offset, pos->size, chip_size); |
| 39 | + } |
| 40 | + return ESP_ERR_INVALID_SIZE; |
| 41 | + } |
| 42 | + } else if (part->magic == ESP_PARTITION_MAGIC_MD5) { |
| 43 | + if (md5_found) { |
| 44 | + if (log_errors) { |
| 45 | + ESP_LOGE(TAG, "Only one MD5 checksum is allowed"); |
| 46 | + } |
| 47 | + return ESP_ERR_INVALID_STATE; |
| 48 | + } |
44 | 49 |
|
45 | | - const esp_partition_pos_t *pos = &part->pos; |
46 | | - if (pos->offset > chip_size || pos->offset + pos->size > chip_size) { |
47 | | - if (log_errors) { |
48 | | - ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x", |
49 | | - num_parts, pos->offset, pos->size, chip_size); |
| 50 | + struct MD5Context context; |
| 51 | + unsigned char digest[16]; |
| 52 | + MD5Init(&context); |
| 53 | + MD5Update(&context, (unsigned char *) partition_table, num_parts * sizeof(esp_partition_info_t)); |
| 54 | + MD5Final(digest, &context); |
| 55 | + |
| 56 | + unsigned char *md5sum = ((unsigned char *) part) + 16; // skip the 2B magic number and the 14B fillup bytes |
| 57 | + |
| 58 | + if (memcmp(md5sum, digest, sizeof(digest)) != 0) { |
| 59 | + if (log_errors) { |
| 60 | + ESP_LOGE(TAG, "Incorrect MD5 checksum"); |
| 61 | + } |
| 62 | + return ESP_ERR_INVALID_STATE; |
| 63 | + } |
| 64 | + //MD5 checksum matches and we continue with the next interation in |
| 65 | + //order to detect the end of the partition table |
| 66 | + md5_found = 1; |
| 67 | + } else if (part->magic == 0xFFFF |
| 68 | + && part->type == PART_TYPE_END |
| 69 | + && part->subtype == PART_SUBTYPE_END) { |
| 70 | + ESP_LOGD(TAG, "partition table verified, %d entries", num_parts); |
| 71 | + *num_partitions = num_parts - md5_found; //do not count the partition where the MD5 checksum is held |
| 72 | + return ESP_OK; |
| 73 | + } else { |
| 74 | + if (log_errors) { |
| 75 | + ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic); |
| 76 | + } |
| 77 | + return ESP_ERR_INVALID_STATE; |
50 | 78 | } |
51 | | - return ESP_ERR_INVALID_SIZE; |
52 | 79 | } |
53 | | - } |
54 | 80 |
|
55 | | - if (log_errors) { |
56 | | - ESP_LOGE(TAG, "partition table has no terminating entry, not valid"); |
57 | | - } |
58 | | - return ESP_ERR_INVALID_STATE; |
| 81 | + if (log_errors) { |
| 82 | + ESP_LOGE(TAG, "partition table has no terminating entry, not valid"); |
| 83 | + } |
| 84 | + return ESP_ERR_INVALID_STATE; |
59 | 85 | } |
60 | 86 |
|
0 commit comments