Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

app_update: Add esp_ota_write_raw function to write pre-encrypted data (IDFGH-5583) #7305

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 67 additions & 1 deletion components/app_update/esp_ota_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct ota_ops_entry_ {
uint32_t handle;
const esp_partition_t *part;
bool need_erase;
bool raw_write;
uint32_t wrote_size;
uint8_t partial_bytes;
WORD_ALIGNED_ATTR uint8_t partial_data[16];
Expand Down Expand Up @@ -250,6 +251,67 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
return ESP_ERR_INVALID_ARG;
}

esp_err_t esp_ota_write_raw(esp_ota_handle_t handle, const void *data, size_t size)
{
const uint8_t *data_bytes = (const uint8_t *)data;
esp_err_t ret;
ota_ops_entry_t *it;

if (!esp_flash_encryption_enabled()) {
ESP_LOGE(TAG, "Flash encryption is disabled");
return ESP_ERR_NOT_SUPPORTED;
}

if (data == NULL) {
ESP_LOGE(TAG, "write data is invalid");
return ESP_ERR_INVALID_ARG;
}

// find ota handle in linked list
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
if (it->handle == handle) {
if (it->need_erase) {
// must erase the partition before writing to it
uint32_t first_sector = it->wrote_size / SPI_FLASH_SEC_SIZE;
uint32_t last_sector = (it->wrote_size + size) / SPI_FLASH_SEC_SIZE;

ret = ESP_OK;
if ((it->wrote_size % SPI_FLASH_SEC_SIZE) == 0) {
ret = esp_partition_erase_range(it->part, it->wrote_size, ((last_sector - first_sector) + 1) * SPI_FLASH_SEC_SIZE);
} else if (first_sector != last_sector) {
ret = esp_partition_erase_range(it->part, (first_sector + 1) * SPI_FLASH_SEC_SIZE, (last_sector - first_sector) * SPI_FLASH_SEC_SIZE);
}
if (ret != ESP_OK) {
return ret;
}
}

ret = esp_partition_write_raw(it->part, it->wrote_size, data_bytes, size);
if (ret == ESP_OK) {
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0) {
uint8_t magic_byte;
ret = esp_partition_read(it->part, it->wrote_size, &magic_byte, 1);
if (ret != ESP_OK) {
return ret;
}

if (magic_byte != ESP_IMAGE_HEADER_MAGIC) {
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", magic_byte);
return ESP_ERR_OTA_VALIDATE_FAILED;
}
it->raw_write = true;
}
it->wrote_size += size;
}
return ret;
}
}

//if go to here ,means don't find the handle
ESP_LOGE(TAG,"not found the handle");
return ESP_ERR_INVALID_ARG;
}

esp_err_t esp_ota_write_with_offset(esp_ota_handle_t handle, const void *data, size_t size, uint32_t offset)
{
const uint8_t *data_bytes = (const uint8_t *)data;
Expand Down Expand Up @@ -329,7 +391,11 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)

if (it->partial_bytes > 0) {
/* Write out last 16 bytes, if necessary */
ret = esp_partition_write(it->part, it->wrote_size, it->partial_data, 16);
if (it->raw_write) {
ret = esp_partition_write_raw(it->part, it->wrote_size, it->partial_data, 16);
} else {
ret = esp_partition_write(it->part, it->wrote_size, it->partial_data, 16);
}
if (ret != ESP_OK) {
ret = ESP_ERR_INVALID_STATE;
goto cleanup;
Expand Down
20 changes: 20 additions & 0 deletions components/app_update/include/esp_ota_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,26 @@ esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp
*/
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);

/**
* @brief Write encrypted OTA update data to partition
*
* This function can be called multiple times as
* data is received during the OTA operation. Data is written
* sequentially to the partition.
*
* @param handle Handle obtained from esp_ota_begin
* @param data Data buffer to write
* @param size Size of data buffer in bytes.
*
* @return
* - ESP_OK: Data was written to flash successfully.
* - ESP_ERR_INVALID_ARG: handle is invalid.
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte.
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
* - ESP_ERR_OTA_SELECT_INFO_INVALID: OTA data partition has invalid contents
*/
esp_err_t esp_ota_write_raw(esp_ota_handle_t handle, const void* data, size_t size);

/**
* @brief Write OTA update data to partition
*
Expand Down