diff --git a/main/config.c b/main/config.c index f09facc..b0aae3d 100644 --- a/main/config.c +++ b/main/config.c @@ -12,13 +12,13 @@ #include "nvs_flash.h" #include "nvs.h" #include "soc/gpio_num.h" +#include "mbedtls/sha256.h" #include static const char *TAG = "CONFIG"; #define NVS_NAMESPACE "led_ctrl" -#define CONFIG_MAGIC 0xDEADBEEF #define HARDCODED_CONFIG #ifdef HARDCODED_CONFIG @@ -37,30 +37,44 @@ static config_t current_config = { .led_count_strip_a = -1, .led_count_strip_b = -1, .pwm_pin = -1, - .localBtn_pin = -1, - .magic = CONFIG_MAGIC}; + .localBtn_pin = -1}; + +static void calculate_config_hash(const config_t *cfg, uint8_t *out_hash); // NVS Functions static esp_err_t load_config_from_nvs(void) { nvs_handle_t nvs_handle; - esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle); - if (err != ESP_OK) + size_t size = sizeof(config_t); + config_t tmp; + + for (uint8_t i = 0; i < 2U; i++) { - ESP_LOGW(TAG, "NVS not found, using defaults"); - return ESP_ERR_NOT_FOUND; + esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READONLY, &nvs_handle); + if (err != ESP_OK) + { + ESP_LOGW(TAG, "NVS not found, using defaults"); + config_reset_config(); + continue; + } + + err = nvs_get_blob(nvs_handle, "config", &tmp, &size); + nvs_close(nvs_handle); + + uint8_t calc_hash[CONFIG_HASH_LEN]; + calculate_config_hash(&tmp, calc_hash); + + if (memcmp(calc_hash, tmp.hash, CONFIG_HASH_LEN) != 0) + { + ESP_LOGW(TAG, "Invalid config in NVS, using defaults"); + config_reset_config(); + continue; + } + + // We found a valid config + break; } - - size_t required_size = sizeof(config_t); - err = nvs_get_blob(nvs_handle, "config", ¤t_config, &required_size); - nvs_close(nvs_handle); - - if (err != ESP_OK || current_config.magic != CONFIG_MAGIC) - { - ESP_LOGW(TAG, "Invalid config in NVS, using defaults"); - return ESP_ERR_INVALID_STATE; - } - + ESP_LOGI(TAG, "Loaded config from NVS"); ESP_LOGI(TAG, " Strip A: GPIO%d", current_config.led_pin_strip_a); ESP_LOGI(TAG, " Strip B: GPIO%d", current_config.led_pin_strip_b); @@ -74,6 +88,8 @@ static esp_err_t load_config_from_nvs(void) static esp_err_t save_config_to_nvs(void) { + calculate_config_hash(¤t_config, current_config.hash); + nvs_handle_t nvs_handle; esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs_handle); if (err != ESP_OK) @@ -81,7 +97,6 @@ static esp_err_t save_config_to_nvs(void) return err; } - current_config.magic = CONFIG_MAGIC; err = nvs_set_blob(nvs_handle, "config", ¤t_config, sizeof(config_t)); if (err == ESP_OK) { @@ -110,7 +125,6 @@ esp_err_t config_reset_config(void) current_config.led_count_strip_b = -1; current_config.pwm_pin = -1; current_config.localBtn_pin = -1; - current_config.magic = CONFIG_MAGIC; return save_config_to_nvs(); } @@ -148,7 +162,6 @@ esp_err_t config_init(void) current_config.led_count_strip_b = HARDCODED_CONFIG_LED_STRIP_B_COUNT; current_config.pwm_pin = HARDCODED_CONFIG_PWM_PIN; current_config.localBtn_pin = HARDCODED_CONFIG_LOCALBTN_PIN; - current_config.magic = CONFIG_MAGIC; save_config_to_nvs(); #endif @@ -160,3 +173,19 @@ esp_err_t config_init(void) return ESP_OK; } + +static void calculate_config_hash(const config_t *cfg, uint8_t *out_hash) +{ + mbedtls_sha256_context ctx; + + mbedtls_sha256_init(&ctx); + mbedtls_sha256_starts(&ctx, 0); // 0 = SHA-256, 1 = SHA-224 + + mbedtls_sha256_update( + &ctx, + (const unsigned char *)cfg, + offsetof(config_t, hash)); + + mbedtls_sha256_finish(&ctx, out_hash); + mbedtls_sha256_free(&ctx); +} \ No newline at end of file diff --git a/main/config.h b/main/config.h index 815b000..f5298e2 100644 --- a/main/config.h +++ b/main/config.h @@ -11,18 +11,19 @@ #include #include +#define CONFIG_HASH_LEN 32 // SHA256 /** * @brief Configuration structure stored in NVS */ typedef struct { - int8_t led_pin_strip_a; // GPIO pin for LED strip A (-1 = not configured) - int8_t led_pin_strip_b; // GPIO pin for LED strip B (-1 = not configured) - int8_t led_count_strip_a; // LED count for LED strip A (-1 = not configured) - int8_t led_count_strip_b; // LED count for LED strip B (-1 = not configured) - int8_t pwm_pin; // GPIO pin for PWM input (-1 = not configured) - int8_t localBtn_pin; // GPIO pin for local btn input (-1 = not configured) - uint32_t magic; // Magic number to validate config (0xDEADBEEF) //TODO: use sha256 + int8_t led_pin_strip_a; // GPIO pin for LED strip A (-1 = not configured) + int8_t led_pin_strip_b; // GPIO pin for LED strip B (-1 = not configured) + int8_t led_count_strip_a; // LED count for LED strip A (-1 = not configured) + int8_t led_count_strip_b; // LED count for LED strip B (-1 = not configured) + int8_t pwm_pin; // GPIO pin for PWM input (-1 = not configured) + int8_t localBtn_pin; // GPIO pin for local btn input (-1 = not configured) + uint8_t hash[CONFIG_HASH_LEN]; // SHA256 Hash of config } config_t; /**