In my previous blog I wrote about the ESP HomeKit SDK and then I realize I needed some distribution system of some kind. Then I found life-cycle-manager made by HomeACcessoryKid on git hub. This is exactly what I need!
The LifeCycle Manager (LCM) tracks software and firmware versions. Firmware is software, inclusive of programs or data, that has been permanently written onto read-only memory (ROM) or programmable read-only memory (PROM). This is a program that allows any simple repository based on ESP-Open-RTos on a ESP8266 to solve its life cycle tasks. The LifeCycle Manager enables you to:
- Assign a WiFi AccessPoint for internet connectivity
- Specify and install the user app without flashing over cable (once the LCM image is in)
- Update the user app over the air by using releases and versions on GitHub
The solution is dedicated to a particular set of repositories and devices, which I consider is worth solving.
- Many ESP8266 devices have only 1Mbyte of flash.
- Many people have no interest in setting up a software (web)server to solve their upgrade needs.
- Many repositories have no ram or flash available to combine the upgrade routines and the user routines.
- For repositories that will be applied by MANY people, a scalable software server is needed.
- Be able to setup WiFi securely while not depending on an electrical connection whenever WiFi needs setup.
In my opinion, for the target group of my blog, the typical solution doesn’t work and so LCM will handle it. Also it turns out that there are no out-of-the-box solutions of the typical case out there so we are fine with the limitations of LCM!
Having over the air firmware updates is very important to be able to close security holes and prevent others to introduce malicious code. The user app only requires a few simple lines of code so no increase in RAM usage or complexity and an overall smaller flash footprint. Through the use of cryptography throughout the life cycle manager, it is not possible for any outside party to squeeze in any malicious code nor to snoop the password of the WiFi Access Point.
The fact that it is hosted on GitHub means your code is protected by the https certificates from GitHub and that no matter how many devices are out there, it will scale. The code is publicly visible and can be audited at all times so that security is at its best. In this case we pre install the LCM code on the hardware thereby allowing the final user to select any relevant repository.
If you feel you need 100% control, you can fork this repository, create your own private key and do the life cycle of the LCM yourself. But since the code of LCM is public, by audit it is unlikely that malicious events will happen. It is up to you.
How it works
After installing LifeCycle Manager for the first time it will get the latest Software version from your GitHub. In this case Version X.
Main app(0) v.x
The user code Main app is running in boot slot 0 at Version X.
boot=slot1 baseURL=repo version=x
This represents that in sector 1 used by rboot, we will also store the following info
baseURL: everything is intended to be relative to https://github.com, so this info is the user/repo part
version: the version that this repo is currently running at.
After this we run the OTA code which will try to deposit in boot slot 0 the latest version (t) of the baseURL repo.
This represents an exponential hold-off to prevent excessive hammering on the GitHub servers. It resets at a power-cycle.
Download certificate signature: Certificate update? Download Certificates.
This is a file that contains the checksum of the sector containing three certificates/keys
- Public key of HomeACessoryKid that signs the certificate/key sector
- Root CA used by GitHub
- Root CA used by the DistributedContentProvider (Amazon in this case)
First, the file is intended to be downloaded with server certificate verification activated. If this fails, it is downloaded anyway without verification and server is marked as invalid. Once downloaded, the sha256 checksum of the active sector is compared to the checksum in the signature file. If equal, we move on. If not, we download the updated sector file to the standby sector.
From the sector containing up to date certificates the sha256 hash is signed by the private key of HomeACessoryKid. Using the available public key, the validity is verified
If in the previous steps the server is marked invalid, we return to the main app in boot slot 0 and we report by syslog to a server (to be determined) so we learn that GitHub has changed its certificate CA provider and HomeACessoryKid can issue a new certificate sector.
new OTA version? self-updater(0) update OTAapp➔1 checksum OK?
Now that the downloading from GitHub has been secured, we can trust whatever we download based on a checksum. We verify if there is an update of this OTA repo itself? If so, we use a self-updater (part of this repo) to ‘self update’. After this we have the latest OTA code.
OTA app(1) updates Main app➔0 checksum OK?
Using the base URL info and the version as stored in sector1, the latest binary is found and downloaded if needed. If the checksum does not work out, we return to the OTA app start point considering we cannot run the old code any more. But normally we boot the new code and the mission is done.
Note: that switching from boot=slot1 to boot=slot0 does not require a reflash
HomeACcessoryKid, life-cycle-manager (2019), Initial install, WiFi settings and over the air firmware upgrades for any esp-open-rtos repository on GitHub, https://github.com/HomeACcessoryKid/life-cycle-managerMaxim Kulkin, esp-wifi-config (2019), Library to bootstrap WiFi-enabled accessories WiFi config, https://github.com/maximkulkin/esp-wifi-config Paul Sokolovsky, esp-open-sdk (2019), Free and open (as much as possible) integrated SDK for ESP8266/ESP8285 chips, https://github.com/pfalcon/esp-open-sdk Espressif Systems, esptool (2019), ESP8266 and ESP32 serial bootloader utility, https://github.com/espressif/esptool