Internet-Draft | Secure Reporting of Update Status | July 2021 |
Moran | Expires 13 January 2022 | [Page] |
The Software Update for the Internet of Things (SUIT) manifest provides a way for many different update and boot workflows to be described by a common format. However, this does not provide a feedback mechanism for developers in the event that an update or boot fails.¶
This specification describes a lightweight feedback mechanism that allows a developer in possession of a manifest to reconstruct the decisions made and actions performed by a manifest processor.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 13 January 2022.¶
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.¶
A SUIT manifest processor can fail to install or boot an update for many reasons. Frequently, the error codes generated by such systems fail to provide developers with enough information to find root causes and produce corrective actions, resulting in extra effort to reproduce failures. Logging the results of each SUIT command can simplify this process.¶
While it is possible to report the results of SUIT commands through existing logging or attestation mechanisms, this comes with several drawbacks:¶
The CBOR objects defined in this document allow devices to:¶
This document provides a definition of a SUIT-specific logging container that may be used in a variety of scenarios.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Terms used in this specification include:¶
If the developer can be assumed to have a copy of the manifest, then they need little information to reconstruct what the manifest processor has done. They simply need any data that influences the control flow of the manifest. The manifest only supports the following control flow primitives:¶
Of these, only conditions change the behavior of the processor from the default, and then only when the condition fails.¶
Then, to reconstruct the flow of a manifest, all a developer needs is a list of metadata about failed conditions:¶
Most conditions compare a parameter to an actual value, so the "reason" is typically simply the actual value.¶
Since it is possible that a non-condition command may fail in an exceptional circumstance, this must be included as well. To accommodate for a failed command, the list of failed conditions is expanded to be a list of failed commands instead. In the case of a command failure, the failure reason is typically a numeric error code.¶
Reconstructing what a device has done in this way is compact, however it requires some reconstruction effort. This is an issue that can be solved by tooling.¶
suit-record = { suit-record-manifest-id => [* uint ], suit-record-manifest-section => int, suit-record-section-offset => uint, ( suit-record-component-index => uint // suit-record-dependency-index => uint ), suit-record-failure-reason => SUIT_Parameters / int, }¶
suit-record-manifest-id is used to identify which manifest contains the command that caused the record to be generated. The manifest id is a list of integers that form a walk of the manifest tree, starting at the root. An empty list indicates that the command was contained in the root manifest. If the list is not empty, the command was contained in one of the root manifest's dependencies, or nested even further below that.¶
For example, suppose that the root manifest has 3 dependencies and each of those dependencies has 2 dependencies of its own:¶
Root¶
A manifest-id of [1,0] would indicate that the current command was contained within Dependency B0. Similarly, a manifest-id of [2,1] would indicate Dependency C1¶
suit-record-manifest-section indicates which section of the manifest was active. This is used in addition to an offset so that the developer can index into severable sections in a predictable way. The value of this element is the value of the key that identified the section in the manifest.¶
suit-record-section-offset is the number of bytes into the current section at which the current command is located.¶
suit-record-component-index is the index of the component that was specified at the time that the report was generated. This field is necessary due to the availability of set-current-component values of True and a list of components. Both of these values cause the manifest processor to loop over commands using a series of component-ids , so the developer needs to know which was selected when the command executed.¶
suit-record-dependency-index is similar to suit-record-component-index but is used to identify the dependency that was active.¶
suit-record-failure-reason contains the reason for the command failure. For example, this could be the actual value of a SUIT_Digest or class identifier. This is encoded in a SUIT_Parameters block as defined in [I-D.ietf-suit-manifest]. If it is not a condition that has failed, but a directive, then the value of this element is an integer that represents an implementation-defined failure code.¶
Some metadata is common to all records, such as the root manifest: the manifest that is the entry-point for the manifest processor. This metadata is aggregated with a list of suit-records.¶
suit-report = { suit-report-manifest-digest => SUIT_Digest, ? suit-report-manifest-uri => tstr, ? suit-report-nonce => bstr, suit-report-records => [ *suit-record ] }¶
suit-report-manifest-digest provides a SUIT_Digest (as defined in [I-D.ietf-suit-manifest]) that is the characteristic digest of the Root manifest.¶
suit-report-manifest-uri provides the reference URI that was provided in the root manifest.¶
suit-report-nonce provides a container for freshness or replay protection information. This field MAY be omitted where the suit-report is authenticated within a container that provides freshness already. For example, attestation evidence typically contains a proof of freshness.¶
suit-report-records is a list of 0 or more SUIT Records. Because SUIT Records are only generated on failure, in simple cases this can be an empty list.¶
IANA is requested to allocate a CBOR tag for the SUIT Report.¶
The SUIT Report should either be carried over a secure transport, or signed, or both. Ideally, attestation should be used to prove that the report was generated by legitimate hardware.¶