diff --git a/components/esp_https_ota/src/esp_https_ota.c b/components/esp_https_ota/src/esp_https_ota.c index 6bd8ec0cc0..431a8628d3 100644 --- a/components/esp_https_ota/src/esp_https_ota.c +++ b/components/esp_https_ota/src/esp_https_ota.c @@ -382,6 +382,12 @@ static esp_err_t read_header(esp_https_ota_t *handle) esp_err_t esp_https_ota_get_img_desc(esp_https_ota_handle_t https_ota_handle, esp_app_desc_t *new_app_info) { +#if CONFIG_ESP_HTTPS_OTA_DECRYPT_CB + // This API is not supported in case firmware image is encrypted in nature. + // It is recommended to retrieve image description through decryption callback in application layer. + return ESP_ERR_NOT_SUPPORTED; +#endif + esp_https_ota_t *handle = (esp_https_ota_t *)https_ota_handle; if (handle == NULL || new_app_info == NULL) { ESP_LOGE(TAG, "esp_https_ota_read_img_desc: Invalid argument"); diff --git a/examples/system/ota/pre_encrypted_ota/main/pre_encrypted_ota.c b/examples/system/ota/pre_encrypted_ota/main/pre_encrypted_ota.c index 5cad8a6bbf..1ae72c11e8 100644 --- a/examples/system/ota/pre_encrypted_ota/main/pre_encrypted_ota.c +++ b/examples/system/ota/pre_encrypted_ota/main/pre_encrypted_ota.c @@ -39,6 +39,27 @@ extern const char rsa_private_pem_end[] asm("_binary_private_pem_end"); #define OTA_URL_SIZE 256 +static esp_err_t validate_image_header(esp_app_desc_t *new_app_info) +{ + if (new_app_info == NULL) { + return ESP_ERR_INVALID_ARG; + } + + const esp_partition_t *running = esp_ota_get_running_partition(); + esp_app_desc_t running_app_info; + if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) { + ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version); + } + +#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK + if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) { + ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update."); + return ESP_FAIL; + } +#endif + return ESP_OK; +} + static esp_err_t _decrypt_cb(decrypt_cb_arg_t *args, void *user_ctx) { if (args == NULL || user_ctx == NULL) { @@ -53,9 +74,18 @@ static esp_err_t _decrypt_cb(decrypt_cb_arg_t *args, void *user_ctx) if (err != ESP_OK && err != ESP_ERR_NOT_FINISHED) { return err; } + static bool is_image_verified = false; if (pargs.data_out_len > 0) { args->data_out = pargs.data_out; args->data_out_len = pargs.data_out_len; + if (!is_image_verified) { + is_image_verified = true; + const int app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t); + // It is unlikely to not have App Descriptor available in first iteration of decrypt callback. + assert(args->data_out_len >= app_desc_offset + sizeof(esp_app_desc_t)); + esp_app_desc_t *app_info = (esp_app_desc_t *) &args->data_out[app_desc_offset]; + return validate_image_header(app_info); + } } else { args->data_out_len = 0; }