From e04c1eb3021cfc21e100aff6ee292088c21dabf9 Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Wed, 7 Jun 2023 15:39:53 +0530 Subject: [PATCH] ota: Enable the handling of encrypted OTA image Also, added the docs around OTA and sample usage in light example. --- components/esp_matter/esp_matter_ota.cpp | 9 ++++++ components/esp_matter/esp_matter_ota.h | 12 ++++++++ components/esp_matter/idf_component.yml | 5 ++++ connectedhomeip/connectedhomeip | 2 +- docs/en/developing.rst | 37 ++++++++++++++++++++++++ examples/light/CMakeLists.txt | 7 +++++ examples/light/main/app_main.cpp | 15 ++++++++++ 7 files changed, 86 insertions(+), 1 deletion(-) diff --git a/components/esp_matter/esp_matter_ota.cpp b/components/esp_matter/esp_matter_ota.cpp index 2eb16cd0d..e3120c350 100644 --- a/components/esp_matter/esp_matter_ota.cpp +++ b/components/esp_matter/esp_matter_ota.cpp @@ -79,3 +79,12 @@ void esp_matter_ota_requestor_start(void) gRequestorUser.Init(&gRequestorCore, &gImageProcessor); #endif } + +#if CONFIG_ENABLE_ENCRYPTED_OTA +esp_err_t esp_matter_ota_requestor_encrypted_init(const char *key, uint16_t size) +{ + VerifyOrReturnError(key != nullptr, ESP_ERR_INVALID_ARG); + VerifyOrReturnError(gImageProcessor.InitEncryptedOTA(chip::CharSpan{key, size}) == CHIP_NO_ERROR, ESP_ERR_INVALID_STATE); + return ESP_OK; +} +#endif // CONFIG_ENABLE_ENCRYPTED_OTA diff --git a/components/esp_matter/esp_matter_ota.h b/components/esp_matter/esp_matter_ota.h index 945dbb219..bbd7ba4c1 100644 --- a/components/esp_matter/esp_matter_ota.h +++ b/components/esp_matter/esp_matter_ota.h @@ -26,3 +26,15 @@ esp_err_t esp_matter_ota_requestor_init(void); * */ void esp_matter_ota_requestor_start(void); + +/** + * @brief This API initializes the handling of encrypted OTA image + * + * @param[in] key null terminated RSA-3072 key in PEM format + * @param[in] size Size of the key + * + * @return ESP_OK or success, appropriate error otherwise + */ +#if CONFIG_ENABLE_ENCRYPTED_OTA +esp_err_t esp_matter_ota_requestor_encrypted_init(const char *key, uint16_t size); +#endif // CONFIG_ENABLE_ENCRYPTED_OTA diff --git a/components/esp_matter/idf_component.yml b/components/esp_matter/idf_component.yml index 59f90810e..09ffa1415 100644 --- a/components/esp_matter/idf_component.yml +++ b/components/esp_matter/idf_component.yml @@ -4,3 +4,8 @@ dependencies: ## Required IDF version idf: version: ">=4.4.2" + + espressif/esp_encrypted_img: + version: "2.0.3" + rules: + - if: "idf_version >=4.4" diff --git a/connectedhomeip/connectedhomeip b/connectedhomeip/connectedhomeip index 2695c8d07..04b2fdfc6 160000 --- a/connectedhomeip/connectedhomeip +++ b/connectedhomeip/connectedhomeip @@ -1 +1 @@ -Subproject commit 2695c8d072984c3597831e66aed28164dcffc7d1 +Subproject commit 04b2fdfc6f7259116a50170b0d38dab9507e20d3 diff --git a/docs/en/developing.rst b/docs/en/developing.rst index 42b9704a5..ccc17b79b 100644 --- a/docs/en/developing.rst +++ b/docs/en/developing.rst @@ -1164,3 +1164,40 @@ Run the following command from host to commission the device. ./chip-tool pairing ble-wifi 1234 my_SSID my_PASSPHRASE my_PASSCODE my_DISCRIMINATOR --paa-trust-store-path /path/to/PAA-Certificates/ + +2.7 Matter OTA +-------------- + +- Enable the ``CONFIG_ENABLE_OTA_REQUESTOR`` option to enable Matter OTA Requestor functionality. + +Please follow the `guide `__ +in the connectedhomeip repository for generating a Matter OTA image and performing OTA. + +2.7.1 Encrypted Matter OTA +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The esp-matter SDK supports using a pre-encrypted application image for OTA upgrades. +Please follow the steps below to enable and use encrypted application images for OTA upgrades. + +- Enable the ``CONFIG_ENABLE_OTA_REQUESTOR`` and ``CONFIG_ENABLE_ENCRYPTED_OTA`` options +- The application code must make an API call to ``esp_matter_ota_requestor_encrypted_init()`` after calling + ``esp_matter::start()``. You can use the following code as a reference: + +:: + + #include + + { + const char *rsa_private_key; // Please set this to the buffer containing RSA 3072 private key in PEM format + uint16_t rsa_private_key_len; // Please set this to the length of RSA 3072 private key + + esp_err_t err = esp_matter_ota_requestor_encrypted_init(rsa_private_key, rsa_private_key_len); + } + + +- Please refer to the `guide `__ + in the connectedhomeip repository for instructions on how to generate a private key, encrypted OTA image, and Matter OTA image. + +NOTE: There are several ways to store the private key, such as hardcoding it in the firmware, embedding it as a text +file, or reading it from the NVS. We have demonstrated the use of the private key by embedding it as a text file in the +light example. diff --git a/examples/light/CMakeLists.txt b/examples/light/CMakeLists.txt index f6c7c3e82..b1407babb 100644 --- a/examples/light/CMakeLists.txt +++ b/examples/light/CMakeLists.txt @@ -43,6 +43,13 @@ set(EXTRA_COMPONENT_DIRS ${extra_components_dirs_append}) project(light) + +# WARNING: This is just an example for using key for decrypting the encrypted OTA image +# Please do not use it as is. +if(CONFIG_ENABLE_ENCRYPTED_OTA) + target_add_binary_data(light.elf "esp_image_encryption_key.pem" TEXT) +endif() + if(CONFIG_IDF_TARGET_ESP32C2) include(relinker) endif() diff --git a/examples/light/main/app_main.cpp b/examples/light/main/app_main.cpp index 64480a163..5f51f1699 100644 --- a/examples/light/main/app_main.cpp +++ b/examples/light/main/app_main.cpp @@ -29,6 +29,14 @@ using namespace chip::app::Clusters; constexpr auto k_timeout_seconds = 300; +#if CONFIG_ENABLE_ENCRYPTED_OTA +extern const char decryption_key_start[] asm("_binary_esp_image_encryption_key_pem_start"); +extern const char decryption_key_end[] asm("_binary_esp_image_encryption_key_pem_end"); + +static const char *s_decryption_key = decryption_key_start; +static const uint16_t s_decryption_key_len = decryption_key_end - decryption_key_start; +#endif // CONFIG_ENABLE_ENCRYPTED_OTA + static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg) { switch (event->Type) { @@ -163,6 +171,13 @@ extern "C" void app_main() /* Starting driver with default values */ app_driver_light_set_defaults(light_endpoint_id); +#if CONFIG_ENABLE_ENCRYPTED_OTA + err = esp_matter_ota_requestor_encrypted_init(s_decryption_key, s_decryption_key_len); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Failed to initialized the encrypted OTA, err: %d", err); + } +#endif // CONFIG_ENABLE_ENCRYPTED_OTA + #if CONFIG_ENABLE_CHIP_SHELL esp_matter::console::diagnostics_register_commands(); esp_matter::console::wifi_register_commands();