# TEE Over-the-Air Updates (OTA)

## Overview

The OTA update mechanism allows a device to update itself based on data received while the normal firmware is running (for example, over Wi-Fi or Bluetooth). While OTA updates for application images are extensively documented here, this section specifically details how OTA updates for the TEE image are securely managed.

TEE OTA requires configuring the partition table of the device with at least two TEE OTA app slot partitions (i.e., `tee_0` and `tee_1`) and a TEE OTA Data Partition (type `data` and subtype `tee_ota`).

> Sample flash partition layout with TEE and application OTA support

### TEE OTA Data Partition

An OTA data partition (type `data`, subtype `tee_ota`) for the TEE image must be included in the partition table of any project which uses the OTA functions. Note that the TEE app has its own OTA data partition, separate from that of the REE app.

For factory boot settings, the TEE OTA data partition should contain no data (all bytes erased to 0xFF). In this case, the second stage bootloader will boot the first available TEE OTA slot (usually `tee_0`). After the first OTA update, the TEE OTA data partition is updated to specify which OTA app slot partition should be booted next.

The TEE OTA data partition is two flash sectors (0x2000 bytes) in size, to prevent problems if there is a power failure while it is being written. Sectors are independently erased and written with matching data, and if they disagree a counter field is used to determine which sector was written more recently.

> ESP-TEE: OTA Data partition entry

## OTA Process: Boot-up Flow and Image Rollback

1. The new TEE application is successfully downloaded over the appropriate interface (Wi-Fi, Bluetooth, Ethernet, etc.). The REE app will download the TEE OTA update. Since it does not have permission to write to the TEE flash region directly, it will issue the appropriate service calls to write the new firmware to the flash.

2. The new firmware is written to the passive TEE partition and set as the bootable partition with the state `NEW`. This means that the application is new and should be monitored during its first boot. The system is then rebooted.

3. The bootloader will verify the magic and the CRC of the first sector in the `tee_otadata` partition. If invalid, the second sector will be used.

4. If the application state is `PENDING_VERIFY`, it will be overwritten to `INVALID`. The bootloader will not select any image marked as `INVALID` for booting.

5. If the application state is `NEW`, it will be overwritten to `PENDING_VERIFY`. This means that the application requires a confirmation to be considered as operable. If this does not happen and a reboot occurs, the state will be overwritten to `INVALID` and this application will no longer be able to boot, i.e., there will be a rollback to the previous working application.

6. The new TEE application starts executing, but it needs a self-test to confirm its operability. As we reach the point of entry of the non-secure app, we consider the rollback self-test to be successful. The application is then marked as valid (state `VALID`) and selected across further reboots if there are no updates to the device.

7. If the self-test fails - the device did not reach the non-secure app entry point as there was some issue with the TEE image. This is considered as a critical exception and the device will reboot.

> Note

> - Any partition flashed serially will be automatically marked as valid during its first boot.

> - If the first `tee_otadata` sector is valid but does not match with a valid second `tee_otadata` sector (or vice versa), it is the responsibility of the bootloader to make the `tee_otadata` sectors the same before handing control to TEE.

> - If Secure Boot is enabled, the bootloader will verify the TEE and the non-secure app.

TEE OTA process flow

## Application Example

The tee_secure_ota example demonstrates how to perform an Over-the-Air updates with HTTP/S for the TEE.

## API Reference

Note

To use the TEE OTA APIs in your project, ensure that the tee_ota_ops component is listed as a local dependency in the component manager manifest file idf_component.yml. Refer to the tee_secure_ota example for guidance.

### Header File

- components/esp_tee/subproject/components/tee_ota_ops/include/esp_tee_ota_ops.h

### Functions

esp_err_t esp_tee_ota_begin(void)

  Commence the TEE OTA update.

  This function does the following:

  - Initialize the internal TEE OTA state machine

  - Set the passive TEE partition as the destination for the new image and erase it

  Returns:

    - `ESP_OK` on success

    - `ESP_ERR_NOT_FOUND` in case the `tee_otadata` or the passive TEE partition is not found

    - `ESP_ERR_FLASH_OP_FAIL` in case erasing the passive TEE partition fails

esp_err_t esp_tee_ota_write(uint32_t rel_offset, const void *data, size_t size)

  Write TEE OTA update data to the partition. This function can be called multiple times as data is received during the OTA operation and can write data in non-contiguous manner.

  Parameters:

    - rel_offset -- Address offset at which the given data should be written at - relative to the start address of the passive TEE partition

    - data -- Data buffer to write

    - size -- Size of data buffer in bytes

  Returns:

    - `ESP_OK` on success

    - `ESP_ERR_INVALID_ARG` in case the `tee_otadata` or the passive TEE partition is not found

    - `ESP_ERR_INVALID_STATE` in case the TEE OTA state machine is in an invalid state

    - `ESP_ERR_FLASH_OP_FAIL` in case writing the new TEE image fails

    - `ESP_FAIL` for other errors

esp_err_t esp_tee_ota_end(void)

  Finish the TEE OTA update and validate newly written TEE image.

  Returns:

    - `ESP_OK` on success

    - `ESP_ERR_INVALID_STATE` in case the TEE OTA state machine is in an invalid state

    - `ESP_ERR_IMAGE_INVALID` in case the new TEE OTA image verification fails

    - `ESP_FAIL` for other errors

Was this page helpful?

- Thank you! We received your feedback.
- If you have any comments, fill in Espressif Documentation Feedback Form.

- We value your feedback.
- Let us know how we can improve this page by filling in Espressif Documentation Feedback Form.