Software Update Mechanism for Ostro™ OS🔗
Ostro OS based software can be deployed to a target device in two ways:
Full Disk Flashing
A new software image is built and installed, completely replacing what was previously present on the device. It can be useful for initializing a device with Ostro OS.
This is a component that Ostro OS borrows from Clear Linux* OS and consists of both a server and client component. The Software Update component is not tied to any specific platform or architecture, as long as the concept of rootfs/filesystem is supported.
The main concept behind the Software Update tool is that it doesn’t rely on the target device to perform the installation of packages, handle file conflicts, dependency and versioning check. Instead, all of this happens a priori, on a build server. And it happens only once, instead of trying to repeat the same operations on each device. All the device needs to do is to lookup a reference file (manifest) for the list of files it must acquire, should they not be present locally. The tool focuses on high level functionality (bundles), instead of individual packages. In detail, the Software Update functionality is comprised of a pair of tools:
Software Update Server
A back-end tool which generates the data stream for updates and bundles.
Software Update Client
A tool that resides on the device and uses the data stream produced by the Server.
The client needs an URL exposing the data stream. This requires setting up a web server (e.g., apache, nginx) pointing to the “www” directory generated by the SW Update Server. The SW Update server does not act as web server, it merely produces data that the manager of the update stream will have to expose through a separate tool.
Software Update Server🔗
The SW Update Server is a tool used to produce the stream of updates that, later on, a device can use to upgrade itself. The SW Update Server runs on the back-end machine(s) producing the build artefacts. For example, in the case of a large build infrastructure, it can run on a CI (Continuous Integration) server. For each build, the server generates information specific to that build (in software update lingo, the delta from version 0) and related to previous builds (deltas from a customizable number of previous versions).
The information produced by the server is then exposed as URL by a web server and used by the software update client running on supported devices.
Version 1.0 of Ostro OS can produce only deltas from version 0. This will be fixed in later releases, however the overhead introduced is fairly minimal, since it impacts only those files that change; instead of downloading a delta, they are downloaded in their entirety.
Software Update Client🔗
The client runs on the device and is responsible for downloading, verifying and applying the updates. It can also restore modified files to their pristine state as they were in the initial SW image.
The version of swupd client that ships with Ostro 1.0 does not support signature verification, therefore it is necessary to provide the swupd feed through a secure channel (https). Once this is addressed, unsecure channels will also be suitable; as long as the signature and integrity checks are satisfied, the software update client will treat them as trusted.
The software update mechanism supports the concept of bundles: groups of files that provide one functionality.
Ostro OS users coming from popular Linux distros are probably already familiar with the concept of package.
How is a bundle different from a package?
- A bundle has no dependency: it is self-contained. A bundle might also list files contained in other bundles, and that is permitted by design. The SW Update Server and client work together to handle such overlapping.
- As long as bundles come from the same SW Update stream, they cannot cause installation conflicts on the device, because they were obtained from the same rootfs. It is expected that conflicts were solved during the creation of the rootfs. The team managing the SW Update stream is responsible for vetting the rootfs used during the creation of bundles.
- Bundle creation implies that there is a starting rootfs that provides all the files the bundles will include. How this rootfs is created is irrelevant from the perspective of the SW Update Server tool creating the bundles. In Ostro OS, the rootfs is populated through the execution of bitbake recipes, but in Clear Linux this is done by installing .rpm packages. Compared to packages, bundles are a competing way to deliver files to the target device, however bundles can be inserted in an existing workflow that is based on packages, with minimal modifications.
Coming back to how bundles relate to each other: there is one special bundle, called “os-core”, which contains the minimum set of files needed to have a barebone working system.
All other bundles are optional and can be either deployed or removed by using the software update client program.
Ostro OS developers can also use bundles by packaging each application as its own separate bundle. This is discussed further in the Software Update: Building an Ostro™ OS Repository technical note.
SW Update vs. Security🔗
What follows is the description of the ideas behind SW Update Security, which parts are implemented, which parts are missing and how to mitigate the effects of the security gaps in the 1.0 release of Ostro OS.
In the SW Update design, the SW Update Server secures the update information by generating hashes (metadata) for each file (in a manifest). Then it signs the file containing the references to the hashes (signature of the manifest). Successively, the information about all the manifests available is then gathered in a meta-manifest, called “Manifest of Manifests” or MoM file. This file is signed as well.
The design allows for different signing keys, so that the more onerous work of signing all the individual manifests doesn’t need to involve any signing authority.
A signing authority is needed (or desirable) only for signing the MoM file. This is sufficient to the client for asserting the authenticity of the MoM and extend the trust also to the simple manifests and the files they refer to.
This solution is effective against online (Man in the Middle) attacks, however it doesn’t protect against offline attacks.
To defeat offline attacks, the chain of trust must continue uninterrupted from the BIOS boot, and this requires the Ostro OS EFI application to be signed with a key recognized by the EFI BIOS.
The BIOS must also be configured to load exclusively binary files that are signed with a known key.
Once the booting is secured, another feature (IMA) supports the extension of the chain of trust to the SW Update Client, which is then responsible of authenticating any update produced by the server.
State of the implementation for Ostro OS 1.0🔗
Ostro OS 1.0 doe not come with signed EFI binary files. Those who are in need of such feature must follow the standard EFI procedures for installing custom EFI keys (where needed), signing the bootable files and locking down the BIOS, to allow only signed boots.
Furthermore, the SW Update Client doesn’t support for now the verification of the signatures associated with manifests.
This limitation can be mitigated by limiting the SW Update stream to secure connections (HTTPS). In theory, non-secured connections would also work if the SW Update Client supported the verification of signatures.
At the moment, the signing key used for official Ostro OS builds is simply meant to exemplify the process. It is not meant to provide any additional level of security.
One interested in hardening the security of a self-generated image, must provide own keys, apply them to the various signing phases, install them to the BIOS and enable EFI-only boot. The update stream will have to flow only through HTTPS.
Once the limitations listed are overcome, any source will be equally safe even if it is plain HTTP.