Просмотр исходного кода

Check FW version at start of ota for encrypted binary

Harshit Malpani 3 лет назад
Родитель
Сommit
cca208f71a

+ 6 - 0
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");

+ 30 - 0
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;
     }