A large scale over-the-air firmware update system, in general, comprises these 4 components:
- A firmware repository and server application (the server) hosted in the cloud and accessible via internet protocols.
- A firmware update firmware library (the client) running on devices to be updated.
- A communication protocol known by client and server to access and transfer firmware binary data from server to client.
- A firmware update binary packaging system; includes preparation and encryption of firmware update files in such a way that the client firmware running on the device can safely, securely and correctly receive and apply a valid firmware image.
Components 2 & 4 are provided by the FM_Deploy Module in our IoT Firmware Core product and is ready to go to work with a variety of application-specific schemes.
Component 1 (the server) is customer and application-specific.
Component 3 (the client-server communication protocol) is dependent on the customer's choice of component 1.
The IoT Firmware Core can support various client-server communication protocols to move firmware from cloud to device. For example:
- HTTP GET requests to an HTTP server, over TCP
- CoAP GET requests to a CoAP server, over UDP
- MQTT subscribe, over TCP
- Custom protocol over TCP/UDP
All of these protocols can be implemented with their own (secure) authentication schemes. For example:
- HTTP has the "BASIC" authentication mode; the server issues a challenge; the client issues the response (the password). https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication. This is not secure; for secure authentication, the transport must be secured with TLS.
- CoAP has no authentication scheme built-in. It uses transport layer secure authentication with DTLS and pre-shared keys. More on a CoAP firmware update system here.
- MQTT uses a client ID and password issued by the MQTT service provider (e.g. Losant). This is not secure; for secure authentication the transport layer must be secured with TLS.
- A custom protocol uses a password/pre-shared key issued by the server provider. In the simplest form, a single key is used to grant access to a particular service; only when the connecting client transmits the correct password/key will the server respond to any request. All clients use this key to access the firmware update service. In addition to the key, the client sends the offset in bytes of the firmware that it requests; as well as additional meta data such as product ID (PID). This is not secure; for secure authentication to the service, the transport layer must be secured with DTLS/TLS.
The custom protocol can use client request messages of this form:
// | TOKEN | PID | OFFSET |
// 4 1 4
The Token is a 4 byte secret known only to the devices and the server. When the server receives the request with the correct token, it proceeds to decode the PID and OFFSET. It then finds the correct firmware image according to PID and slices it into a byte array consisting of bytes [OFFSET, size]. It then serves up the firmware image by sending the bytes to the client.
For TCP transports, the server can send the whole byte array to the socket and the transport will take care of getting it all to the client. The client will receive chunks of this firmware image as they are passed along by the TCP stack (chunk size is typically a function of stack buffer or firmware update library constraints - whichever is smaller). The firmware update library on the client built into the IoT Firmware Core is designed to handle these chunks and will place them into the correct location in flash and verify it before it is applied and the device reboots to it.
The TLS security layer is a key part of a secure firmware update system.
TLS requires no pre-shared keys to operate. The secure session is setup automatically with an algorithm such that both sides of the link receive a secret encryption/decryption key that is generated for that session only. No one in the middle can find this key. This is the confidentiality portion of TLS and can be used to safely send "cleartext" authentication tokens used in any of the protocols described above.
TLS can additionally offer its own authentication feature, and this is quite important because while the link can be secured, it could be that the server on the other end is not who you think it is, and will then receive your cleartext authentication token and then turn around and use it against you. To prevent this kind of attack, most TLS implementations will also authenticate the server. To do that, the TLS client will receive a certificate from the server signed by some recognized authority (could be a regular CA - certificate authority, could be your own private certificate provider). It will then check the signature against a LOCAL COPY of the CA's certificate stored on the device. You must pre-load such server-authentication certificates onto all devices. For example, a common CA is VeriSign. You would then download VeriSign's public certificate from their website, convert it to DER form (a binary X.509 form popular with embedded TLS stacks), then flash it onto the device (or embed it in the firmware image). If the server's certificate was also signed by VeriSign, then your device will only connect to servers that are who they are ACCORDING TO VERISIGN (whom you trust). You can also spin your own certificate-based security system if you can manage the certificates you generate properly (you are your own CA).
The IoT Firmware Core implements a robust, secure firmware update client library and a build-time firmware update binary generation system that works with the client library. The IoT Firmware Core is a complete firmware system in-a-box, and with a single command-line fm release, your application is built, linked and all manufacturing and deployment products are automatically generated: the combined firmware image with bootloader and application(s), and the secure firmware update binary.