From e0f61af7099a99c82e859c34dbba96ab8df838ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 8 Sep 2020 18:24:10 +0200 Subject: [PATCH] Issue #18: Protect safety memory heder with CRC --- .../reflow-controller/safety/safety-memory.h | 2 +- stm-firmware/safety/safety-memory.c | 29 ++++++++++++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/stm-firmware/include/reflow-controller/safety/safety-memory.h b/stm-firmware/include/reflow-controller/safety/safety-memory.h index 303d8ca..e28f3fc 100644 --- a/stm-firmware/include/reflow-controller/safety/safety-memory.h +++ b/stm-firmware/include/reflow-controller/safety/safety-memory.h @@ -55,7 +55,7 @@ struct safety_memory_header { uint32_t config_overrides_len; /**< @brief Length of override entries in words */ uint32_t err_memory_offset; /**< @brief Offset of the error memory */ uint32_t err_memory_end; /**< @brief End of the error memory. This points to the word after the error memory, containing the CRC of the whole backup RAM. */ - uint32_t magic_i; /**< @brief Invers Magic. Set to the bitwise inverse of @ref SAFETY_MEMORY_MAGIC */ + uint32_t crc; /**< @brief CRC of the header */ }; struct safety_memory_boot_status { diff --git a/stm-firmware/safety/safety-memory.c b/stm-firmware/safety/safety-memory.c index 4076c73..c0ab3a6 100644 --- a/stm-firmware/safety/safety-memory.c +++ b/stm-firmware/safety/safety-memory.c @@ -76,13 +76,21 @@ static enum safety_memory_state safety_memory_get_header(struct safety_memory_he if (res) return SAFETY_MEMORY_INIT_CORRUPTED; - /* Check magics */ - if (header->magic != SAFETY_MEMORY_MAGIC || header->magic_i != (uint32_t)(~SAFETY_MEMORY_MAGIC)) { - /* Magics invalid */ + /* Check magic */ + if (header->magic != SAFETY_MEMORY_MAGIC) { + /* Magic invalid */ ret = SAFETY_MEMORY_INIT_FRESH; goto return_val; } + /* Check the header crc */ + crc_unit_reset(); + crc_unit_input_array((uint32_t *)header, wordsize_of(struct safety_memory_header)); + if (crc_unit_get_crc() != 0UL) { + ret = SAFETY_MEMORY_INIT_CORRUPTED; + goto return_val; + } + res = 0; if (header->boot_status_offset < wordsize_of(struct safety_memory_header)) res++; @@ -106,8 +114,14 @@ return_val: return ret; } -static void safety_memory_write_header(const struct safety_memory_header *header) +static void safety_memory_write_and_patch_header(struct safety_memory_header *header) { + /* Patch the CRC */ + crc_unit_reset(); + crc_unit_input_array((uint32_t *)header, wordsize_of(struct safety_memory_header) - 1U); + header->crc = crc_unit_get_crc(); + + /* Write to memory */ backup_ram_write_data(0UL, (uint32_t *)header, wordsize_of(*header)); } @@ -121,10 +135,9 @@ static void safety_memory_write_new_header(void) header.err_memory_offset = header.config_overrides_offset + SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT; header.err_memory_end = header.err_memory_offset; header.magic = SAFETY_MEMORY_MAGIC; - header.magic_i = ~SAFETY_MEMORY_MAGIC; backup_ram_wipe(); - safety_memory_write_header(&header); + safety_memory_write_and_patch_header(&header); } static int safety_memory_check_crc() @@ -399,7 +412,7 @@ int safety_memory_insert_error_entry(struct error_memory_entry *entry) /* Still fits in memory */ backup_ram_write_data(header.err_memory_end, &input_data, 1UL); header.err_memory_end++; - safety_memory_write_header(&header); + safety_memory_write_and_patch_header(&header); safety_memory_gen_crc(); ret = 0; } @@ -435,7 +448,7 @@ int safety_memory_insert_error_entry(struct error_memory_entry *entry) if ((addr + 1) < backup_ram_get_size_in_words()) { backup_ram_write_data(addr, &input_data, 1UL); header.err_memory_end++; - safety_memory_write_header(&header); + safety_memory_write_and_patch_header(&header); } else { ret = -3; goto return_value;