Draft: draft-ietf-suit-manifest

Commentary: This changeset is incomplete , but has substantial changes already : Remove Dependency Components . Remove bstr wrappers from elements of SUIT - Common . Add reporting policy to support RATS . Refactor text encoding . Expand Introduction to explain commands . Add additional terminology . Use " Recipient " instead of device where possible . Add a structure overview section that describes the structure of SUIT metadata without going into encoding details . Cross - referenced with full descriptions . Clean up abstract machine definition where : arg was still used where params should have been used . Add an A / B image template . Remove component reference . Expand parameter descriptions . Remove the " creating conditional sequences " section , since it is now served by A / B image templates . Added many clarifying comments Added many xrefs Added clarifying terminology Some reorganisation of information : encoding information moved from conditions / directives to parameters Added clarification about minimizing signature verifications Added clarification of distinction between  and Directives Clarify some binary matches as asserts Clarify how multiple manifest processors interact Fix organisation of metadata structure Add description of delegation chains Add clarification of manifest authentication Add description of critical metadata Add definition of suit - text with components Add description of text field for representing version dependencies Add description of the dependency prefix , with reference to multiple manifest processors Update reporting policy Add suit - record metadata description Define parameter scope    parameter Clarify many parameters Add description of wait events Expand definition of Soft Failure Add detail about what conditions match against Add detail on scope of identifier ( UUID ) conditions Add a command to fetch with URI list Added design rationale for the Envelope NOTE : Some XREFs broken in appendices NOTE : Examples not updated yet .
This specification describes the format of a manifest.  A manifest is
a bundle of metadata about the firmware for an IoT device, where to
find the firmware, the devices to which it applies, and cryptographic
information protecting the manifest.  Firmware updates and trusted
boot both tend to use sequences of common operations, so the manifest
encodes those sequences of operations, rather than declaring the
metadata.
A firmware update mechanism is an essential security feature for IoT
devices to deal with vulnerabilities.  While the transport of
firmware images to the devices themselves is important there are
already various techniques available, such as the Lightweight
Machine-to-Machine (LwM2M) protocol offering device management of IoT
devices.  Equally important is the inclusion of meta-data about the
conveyed firmware image (in the form of a manifest) and the use of
end-to-end security protection to detect modifications and
(optionally) to make reverse engineering more difficult.  End-to-end
security allows the author, who builds the firmware image, to be sure
that no other party (including potential adversaries) can install
firmware updates on IoT devices without adequate privileges.  This
authorization process is ensured by the use of dedicated symmetric or
asymmetric keys installed on the IoT device: for use cases where only
integrity protection is required it is sufficient to install a trust
anchor on the IoT device.  For confidentiality protected firmware
images it is additionally required to install either one or multiple
symmetric or asymmetric keys on the IoT device.  Starting security
protection at the author is a risk mitigation technique so firmware
images and manifests can be stored on untrusted repositories; it also
reduces the scope of a compromise of any repository or intermediate
system to be no worse than a denial of service.
It is assumed that the reader is familiar with the high-level
firmware update architecture I-D.ietf-suit-architecture.
Most Update and Trusted Execution operations are composed of the same
small set of fundamental operations, such as copying a firmware image
from one place to another, checking that a firmware image is correct,
verifying that the specified firmware is the correct firmware for the
device, or unpacking a firmware.  By using these fundamental
operations in different orders and changing the parameters they use,
a great many use cases can be supported by the same encoding.  The
SUIT manifest uses this observation to heavily optimize update
metadata for consumption by constrained devices.
While the SUIT manifest is informed by and optimized for firmware
update use cases, there is nothing in the I-D.ietf-suit-information-
model that restricts its use to only firmware use cases.  Software
update and delivery of arbitrary data can equally be managed by SUIT-
based metadata.
This specification describes the format of a manifest.  A manifest is
a bundle of metadata about the firmware for an IoT device, where to
find the firmware, the devices to which it applies, and cryptographic
information protecting the manifest.  Firmware updates and secure
boot both tend to use sequences of common operations, so the manifest
encodes those sequences of operations, rather than declaring the
metadata.  The manifest also serves as a building block for secure
boot.
A firmware update mechanism is an essential security feature for IoT
devices to deal with vulnerabilities.  While the transport of
firmware images to the devices themselves is important there are
already various techniques available.  Equally important is the
inclusion of metadata about the conveyed firmware image (in the form
of a manifest) and the use of a security wrapper to provide end-to-
end security protection to detect modifications and (optionally) to
make reverse engineering more difficult.  End-to-end security allows
the author, who builds the firmware image, to be sure that no other
party (including potential adversaries) can install firmware updates
on IoT devices without adequate privileges.  For confidentiality
protected firmware images it is additionally required to encrypt the
firmware image.  Starting security protection at the author is a risk
mitigation technique so firmware images and manifests can be stored
on untrusted repositories; it also reduces the scope of a compromise
of any repository or intermediate system to be no worse than a denial
of service.
A manifest is a bundle of metadata about the firmware for an IoT
device, where to find the firmware, the devices to which it applies,
and cryptographic information protecting the manifest.
It is assumed that the reader is familiar with the high-level
firmware update architecture I-D.ietf-suit-architecture and the
threats, requirements, and user stories in I-D.ietf-suit-information-
model.
In the SUIT manifest specification, these operations are called
commands.  Commands are classed as either conditions or directives.
Conditions have no side-effects, while directives do have side-
effects.  Conceptually, a sequence of commands is like a script but
the used language is tailored to software updates and secure boot.
The available commands support simple steps, such as copying a
firmware image from one place to another, checking that a firmware
image is correct, verifying that the specified firmware is the
correct firmware for the device, or unpacking a firmware.  By using
these steps in different orders and changing the parameters they use,
a broad range of use cases can be supported.  The SUIT manifest uses
this observation to optimize metadata for consumption by constrained
devices.
While the SUIT manifest is informed by and optimized for firmware
update and secure boot use cases, there is nothing in the I-D.ietf-
suit-information-model that restricts its use to only those use
cases.  Other use cases include the management of trusted
applications in a Trusted Execution Environment (TEE), see I-D.ietf-
teep-architecture.
The following terminology is used throughout this document.
SUIT: Software Update for the Internet of Things, the IETF working
group for this standard.
SUIT: Software Update for the Internet of Things, also the IETF
working group for this standard.
Manifest: A piece of information that describes one or more
payloads, one or more resources, and the processors needed to
transform resources into payloads.
Recipient: The system, typically an IoT device, that receives a
manifest.
A/B images: Dividing a device's storage into two or more bootable
images, at different offsets, such that the active image can write
to the inactive image(s).
This specification covers four aspects of firmware update: the
background that has informed this specification, the behavior of a
device consuming a manifest, the process of creating a manifest, and
the structure of the manifest itself.
manifest-structure specifies the content of the manifest.
For information about firmware update in general and the background
of the suit manifest, see background.  To implement an updatable
device, see interpreter-behavior and manifest-structure.  To
implement a tool that generates updates, see creating-manifests and
manifest-structure.
This section describes the logistical challenges, device constraints,
use cases, and design principles that informed the structure of the
manifest.  For the security considerations of the manifest, see I-
D.ietf-suit-information-model.
Manifest: A manifest is a bundle of metadata about the firmware
for an IoT device, where to find the firmware, and the devices to
which it applies.
Envelope: A container with the manifest, an authentication wrapper
with cryptographic information protecting the manifest,
authorization information, and severed fields.
Recipient: The system, typically an IoT device, that receives and
processes a manifest.
Manifest Processor: A component of the Recipient that consumes
Manifests and executes the commands in the Manifest.
Component: An updatable logical block of the Firmware, Software,
configuration, or data of the Recipient.
Component Set: A group of interdependent Components that must be
updated simultaneously.
A/B images: Dividing a Recipient's storage into two or more
bootable images, at different offsets, such that the active image
can write to the inactive image(s).
Record: The result of a Command and any metadata about it.
Report: A list of Records.
Procedure: The process of invoking one or more sequences of
commands.
Update Procedure: A procedure that updates a Recipient by fetching
dependencies, software images, and installing them.
Boot Procedure: A procedure that boots a Recipient by verifying
dependencies and images, loading images, and invoking one or more
image.
Software: Instructions and data that allow a Recipient to perform
a useful function.
Firmware: Instructions and data that allow a Recipient to perform
a useful function.  Typically, changed infrequently, stored in
nonvolatile memory, and small enough to apply to RFC7228 Class 0-2
devices.
Image: Information that a Recipient uses to perform its function,
typically firmware/software, configuration, or resource data such
as text or images.  Also, a Payload, once installed is an Image.
Abort: The Manifest Processor immediately halts execution of the
current Procedure.  It creates a Record of an error condition.
metadata-structure specifies the content of the Envelope and the
Manifest.
To implement an updatable device, see interpreter-behavior and
metadata-structure.  To implement a tool that generates updates, see
creating-manifests and metadata-structure.
The IANA consideration section, see iana, provides instructions to
IANA to create several registries.  This section also provides the
CBOR labels for the structures defined in this document.
The complete CDDL description is provided in full-cddl, examples are
given in examples and a design rational is offered in design-
rationale.  Finally, implementation-matrix gives a summarize of the
mandatory-to-implement features of this specification.
Distributing firmware updates to diverse devices with diverse trust
anchors in a coordinated system presents unique challenges.  Devices
have a broad set of constraints, requiring different metadata to make
appropriate decisions.  There may be many actors in production IoT
systems, each of whom has some authority.  Distributing firmware in
such a multi-party environment presents additional challenges.  Each
party requires a different subset of data.  Some data may not be
accessible to all parties.  Multiple signatures may be required from
parties with different authorities.  This topic is covered in more
depth in I-D.ietf-suit-architecture.
Distributing firmware updates to diverse devices with diverse trust
anchors in a coordinated system presents unique challenges.  Devices
have a broad set of constraints, requiring different metadata to make
appropriate decisions.  There may be many actors in production IoT
systems, each of whom has some authority.  Distributing firmware in
such a multi-party environment presents additional challenges.  Each
party requires a different subset of data.  Some data may not be
accessible to all parties.  Multiple signatures may be required from
parties with different authorities.  This topic is covered in more
depth in I-D.ietf-suit-architecture.  The security aspects are
described in I-D.ietf-suit-information-model.
multiple processors may require coordinated update of all
applications.
mesh networks may require multicast distribution.
multiple microcontrollers may require coordinated update of all
applications.
extra information may need to be conveyed in the manifest in the
earlier stages of the device lifecycle before those data items are
stripped when the manifest is delivery to a constrained device.
The RECOMMENDED process is to verify the signature of the manifest
prior to parsing/executing any section of the manifest.  This guards
the parser against arbitrary input by unauthenticated third parties,
but it costs extra energy when a device receives an incompatible
manifest.
expects to receive many incompatible manifests.
expects to receive few manifests with failing signatures-for
example if it is behind a gateway that checks signatures.
has a power budget that makes signature verification undesirable.
Then, the device MAY choose to parse and execute only the SUIT_Common
section of the manifest prior to signature verification.  The
guidelines in creating-manifests require that the common section
contain the applicability checks, so this section is sufficient for
applicability verification.  The manifest parser MUST NOT execute any
command with side-effects outside the parser (for example, Run, Copy,
Swap, or Fetch commands) prior to authentication and any such command
MUST result in an error.
The manifest described in this document is intended to meet several
goals, as described below.
In order to provide flexible behavior to constrained devices, while
still allowing more powerful devices to use their full capabilities,
the SUIT manifest encodes the required behavior of a Recipient
device.  Behavior is encoded as a specialized byte code, contained in
a CBOR list.  This promotes a flat encoding, which simplifies the
parser.  The information encoded by this byte code closely matches
the operations that a device will perform, which promotes ease of
processing.  The core operations used by most update and trusted
execution operations are represented in the byte code.  The byte code
can be extended by registering new operations.
The specialized byte code approach gives benefits equivalent to those
provided by a scripting language or conventional byte code, with two
substantial differences.  First, the language is extremely high
level, consisting of only the operations that a device may perform
during update and trusted execution of a firmware image.  Second, the
language specifies linear behavior, without reverse branches.
Conditional processing is supported, and parallel and out-of-order
processing may be performed by sufficiently capable devices.
By structuring the data in this way, the manifest processor becomes a
very simple engine that uses a pull parser to interpret the manifest.
This pull parser invokes a series of command handlers that evaluate a
Condition or execute a Directive.  Most data is structured in a
highly regular pattern, which simplifies the parser.
The results of this allow a Recipient to implement a very small
parser for constrained applications.  If needed, such a parser also
allows the Recipient to perform complex updates with reduced
overhead.  Conditional execution of commands allows a simple device
to perform important decisions at validation-time.
Dependency handling is vastly simplified as well.  Dependencies
function like subroutines of the language.  When a manifest has a
dependency, it can invoke that dependency's commands and modify their
behavior by setting parameters.  Because some parameters come with
security implications, the dependencies also have a mechanism to
reject modifications to parameters on a fine-grained level.
Developing a robust permissions system works in this model too.  The
Recipient can use a simple ACL that is a table of Identities and
Component Identifier permissions to ensure that operations on
components fail unless they are permitted by the ACL.  This table can
be further refined with individual parameters and commands.
Capability reporting is similarly simplified.  A Recipient can report
the Commands, Parameters, Algorithms, and Component Identifiers that
it supports.  This is sufficiently precise for a manifest author to
create a manifest that the Recipient can accept.
The simplicity of design in the Recipient due to all of these
benefits allows even a highly constrained platform to use advanced
update capabilities.
This section describes the behavior of the manifest interpreter.
This section focuses primarily on interpreting commands in the
manifest.  However, there are several other important behaviors of
the interpreter: encoding version detection , rollback protection,
and authenticity verification are chief among these (see interpreter-
setup).
The Envelope (see ovr-envelope) contains Delegation Chains, the
Authentication Block, the Manifest, any Severable Elements, and
any Integrated Payloads or Dependencies.
Delegation Chains (see ovr-delegation) allow a Recipient to work
from one of its Trust Anchors to an authority of the
Authentication Block.
The Authentication Block (see ovr-auth) contains a list of
signatures or MACs of the manifest..
Critical metadata, such as sequence number.
Common metadata, including lists of dependencies and affected
components.
Command sequences, directing the Recipient how to install and
use the payload(s).
Integrity check values for severable fields.
Severable fields (see ovr-severable).
Integrated dependencies (see ovr-integrated).
Integrated payloads (see ovr-integrated).
The diagram below illustrates the hierarchy of the Envelope.
The SUIT Envelope is a container that encloses Delegation Chains, the
Authentication Block, the Manifest, any Severable Elements, and any
integrated payloads or dependencies.  The Envelope is used instead of
conventional cryptographic envelopes, such as COSE_Envelope because
it allows modular processing, severing of elements, and integrated
payloads in a way that would add substantial complexity with existing
solutions.  See design-rationale-envelope for a description of the
reasoning for this.
See envelope for more detail.
Delegation Chains allow a Recipient to validate intermediate Update
Authorities against long-term a Trust Anchor.  These are lists of
CWTs, where the first in the list is signed by a Trust Anchor.
See delegation-info for more detail.
The payload element in each of these COSE elements is a SUIT_Digest
SUIT_Digest.
See authentication-info for more detail.
The Manifest contains most metadata about one or more images.  The
Manifest is divided into Critical Metadata, Common Metadata, Command
Sequences, and Integrity Check Values.
See manifest-structure for more detail.
Some metadata needs to be accessed before the manifest is processed.
This metadata can be used to determine which the newest manifest is
and whether the structure version is supported.  It also MAY provide
a URI for obtaining a canonical copy of the manifest and Envelope.
See manifest-version, manifest-seqnr, manifest-reference-uri for more
detail.
Some metadata is used repeatedly and in more than one command
sequence.  In order to reduce the size of the manifest, this metadata
is collected into the Common section.  Common is composed of three
parts: a list of dependencies, a list of components referenced by the
manifest, and a command sequence to execute prior to each other
command sequence.  The common command sequence is typically used to
set commonly used values and perform compatibility checks.  The
common command sequence MUST NOT have any side-effects outside of
setting parameter values.
See manifest-common, SUIT_Dependency for more detail.
Command sequences provide the instructions that a Recipient requires
in order to install or use an image.  These sequences tell a device
to set parameter values, test system parameters, copy data from one
place to another, transform data, digest data, and run code.
Command sequences are broken up into three groups: Common Command
Sequence (see ovr-common), update commands, and secure boot commands.
Update Command Sequences are: Dependency Resolution, Payload Fetch,
and Payload Installation.  An Update Procedure is the complete set of
each Update Command Sequence, each preceded by the Common Command
Sequence.
Boot Command Sequences are: System Validation, Image Loading, and
Image Invocation.  A Boot Procedure is the complete set of each Boot
Command Sequence, each preceded by the Common Command Sequence.
Command Sequences are grouped into these sets to ensure that there is
common coordination between dependencies and dependents on when to
execute each command.
See manifest-commands for more detail.
To enable ovr-severable, there needs to be a mechanism to verify
integrity of any metadata outside the manifest.  Integrity Check
Values are used to verify the integrity of metadata that is not
contained in the manifest.  This MAY include Severable Command
Sequences, CoSWID, or Text data.  Integrated Dependencies and
Integrated Payloads are integrity-checked using Command Sequences, so
they do not have Integrity Check Values present in the Manifest.
See integrity-checks for more detail.
Text is typically a ovr-severable.  It contains all the text that
describes the update.  Because text is explicitly for human
consumption, it is all grouped together so that it can be Severed
easily.  The text section has space both for describing the manifest
as a whole and for describing each individual component.
See manifest-digest-text for more detail.
Severable Elements are elements of the ovr-envelope that have ovr-
integrity in the ovr-manifest.
A management system Severs the Text and CoSWID sections before
sending an Envelope to a constrained Recipient, which saves
Recipient bandwidth.
A Recipient Severs the Installation section after installing the
Update, which saves storage space.
See severable-fields for more detail.
When an update is delivered via a comparatively unconstrained
medium, such as a removable mass storage device, it may be
beneficial to bundle updates into single files.
When a manifest requires encryption, it must be referenced as a
dependency, so a trivial manifest may be used to enclose the
encrypted manifest.  The encrypted manifest may be contained in
the dependent manifest's envelope.
When a manifest transports a small payload, such as an encrypted
key, that payload may be placed in the manifest's envelope.
See composite-manifests, encrypted-manifests for more detail.
This section describes the behavior of the manifest interpreter and
focuses primarily on interpreting commands in the manifest.  However,
there are several other important behaviors of the interpreter:
encoding version detection, rollback protection, and authenticity
verification are chief among these.
Whenever the interpreter can choose between several manifests, it
MUST select the latest valid manifest, authentic manifest.
Whenever the interpreter can choose between several manifests, it
MUST select the latest valid, authentic manifest.
Payload not available (update interpreter).
Dependency not available (update interpreter).
Application crashed when executed (bootloader interpreter).
Watchdog timeout occurred (bootloader interpreter).
Dependency or Payload verification failed (bootloader
interpreter).
Payload not available.
Dependency not available.
Application crashed when executed.
Watchdog timeout occurred.
Dependency or Payload verification failed.
Missing component from a set.
Required parameter not supplied.
The RECOMMENDED process is to verify the signature of the manifest
prior to parsing/executing any section of the manifest.  This guards
the parser against arbitrary input by unauthenticated third parties,
but it costs extra energy when a Recipient receives an incompatible
manifest.
When validating authenticity of manifests, the interpreter MAY use an
ACL (see access-control-lists) to determine the extent of the rights
conferred by that authenticity.  Where a device supports only one
level of access, it MAY choose to skip signature verification of
dependencies, since they are referenced by digest.  Where a device
supports more than one trusted party, it MAY choose to defer the
verification of signatures of dependencies until the list of affected
components is known so that it can skip redundant signature
verifications.  For example, a dependency signed by the same author
as the dependent does not require a signature verification.
Similarly, if the signer of the dependent has full rights to the
device, according to the ACL, then no signature verification is
necessary on the dependency.
For each listed component, the interpreter MUST provide storage for
the supported interpreter-parameters.  If the interpreter does not
have sufficient temporary storage to process the parameters for all
components, it MAY process components serially for each command
sequence.  See serial-processing for more details.
For each listed component, the interpreter MUST provide storage for
the supported parameters.  If the interpreter does not have
sufficient temporary storage to process the parameters for all
components, it MAY process components serially for each command
sequence.  See serial-processing for more details.
Executing the same manifest on multiple devices MUST result in the
same system state.
The byte code that forms the bulk of the manifest is processed by an
interpreter.  This interpreter can be modeled as a simple abstract
machine.  This machine consists of several data storage locations
that are modified by commands.  Certain commands also affect the
machine's behavior.
Every command that modifies system state targets a specific
component.  Components are units of code or data that can be targeted
by an update.  They are identified by Component identifiers, arrays
of binary-strings-effectively a binary path.  Each component has a
corresponding set of configuration, Parameters.  Parameters are used
as the inputs to commands.
Some parameters are REQUIRED to implement.  These parameters allow a
device to perform core functions.
Image Digest.
Some parameters are RECOMMENDED to implement.  These parameters are
needed for most use-cases.
Image Size.
Other parameters are OPTIONAL to implement.  These parameters allow a
device to implement specific use-cases.
Strict Order.
Soft Failure.
Device ID.
Encryption Info.
Unpack Info.
Source Component.
URI List.
Custom Parameters.
Commands define the behavior of a device.  The commands are divided
into two groups: those that modify state (directives) and those that
perform tests (conditions).  There are also several Control Flow
operations.
Check Vendor Identifier (cvid).
Check Class Identifier (ccid).
Verify Image (cimg).
Set Current Component (setc).
Override Parameters (ovrp).
NOTE: on systems that support only a single component, Set Current
Component has no effect.
Set Current Dependency (setd).
Set Parameters (setp).
Process Dependency (pdep).
Run (run).
Fetch (getc).
Other commands are OPTIONAL to implement.  These commands allow a
device to implement specific use-cases.
Use Before (ubf).
Check Component Offset (cco).
Check Device Identifier (cdid).
Check Image Not Match (nimg).
Check Minimum Battery (minb).
Check Update Authorized (auth).
Check Version (cver).
Abort (abrt).
Try Each (try).
Copy (copy).
Swap (swap).
Wait For Event (wfe).
Run Sequence (srun) mandatory component set.
Run with Arguments (arun).
The following table describes the behavior of each command. "params"
represents the parameters for the current component or dependency.
Because each manifest has a list of components and a list of
components defined by its dependencies, it is possible for the
manifest processor to handle one component at a time, traversing the
manifest tree once for each listed component.  In this mode, the
interpreter ignores any commands executed while the component index
is not the current component.  This reduces the overall volatile
storage required to process the update so that the only limit on
number of components is the size of the manifest.  However, this
approach requires additional processing power.
Advanced devices may make use of the Strict Order parameter and
enable parallel processing of some segments, or it may reorder some
segments.  To perform parallel processing, once the Strict Order
parameter is set to False, the device may fork a process for each
command until the Strict Order parameter is returned to True or the
command sequence ends.  Then, it joins all forked processes before
continuing processing of commands.  To perform out-of-order
processing, a similar approach is used, except the device consumes
all commands after the Strict Order parameter is set to False, then
it sorts these commands into its preferred order, invokes them all,
then continues processing.
If a Recipient supports groups of interdependent components (a
Component Set), then it SHOULD require that all Components in the
Component Set are specified by one manifest and its dependencies.
This manifest is called the Root Manifest.
The guidelines in creating-manifests require that the common section
contains the applicability checks, so this section is sufficient for
applicability verification.  The parser MUST restrict acceptable
commands to: Conditions, Override Parameters, Set Parameters, Try-
Each, and Run Sequence ONLY.  The manifest parser MUST NOT execute
any command with side-effects outside the parser (for example, Run,
Copy, Swap, or Fetch commands) prior to authentication and any such
command MUST Abort.  The Common Sequence MUST be executed again in
its entirety after authenticity validation.
When executing Common prior to authenticity validation, the Manifest
Processor MUST evaluate the integrity of the manifest using the
SUIT_Digest present in the authentication block.
Alternatively, a Recipient MAY rely on network infrastructure to
filter inapplicable manifests.
Executing the same manifest on multiple Recipients MUST result in
the same system state.
The heart of the manifest is the list of commands, which are
processed by an interpreter.  This interpreter can be modeled as a
simple abstract machine.  This machine consists of several data
storage locations that are modified by commands.
There are two types of commands, namely those that modify state
(directives) and those that perform tests (conditions).  Parameters
are used as the inputs to commands.  Some directives offer control
flow operations.  Directives target a specific component or
dependency.  A dependency is another SUIT_Envelope that describes
additional components.  Dependencies are identified by digest, but
referenced in commands by Dependency Index, the index into the array
of Dependencies.  A component is a unit of code or data that can be
targeted by an update.  Components are identified by Component
Identifiers, i.e. arrays of binary strings, but referenced in
commands by Component Index, the index into the array of Component
Identifiers.
Conditions MUST NOT have any side-effects other than informing the
interpreter of success or failure.  The Interpreter does not Abort if
the Soft Failure flag is set when a Condition reports failure.
Directives MAY have side-effects in the parameter table, the
interpreter state, or the current component.  The Interpreter MUST
Abort if a Directive reports failure regardless of the Soft Failure
flag.
The following table describes the behavior of each command. "params"
represents the parameters for the current component or dependency.
Most commands operate on either a component or a dependency.  Setting
the Component Index clears the Dependency Index.  Setting the
Dependency Index clears the Component Index.
The interpreter MUST support a special case of Component Index if
more than two or more components are supported: setting Component
Index to True is allowed.  When a command is invoked and the
Component Index is True, the command MUST be invoked once for each
Component, in the order listed in the array of Component Identifiers.
The interpreter MUST support a special case of Dependency Index when
two or more dependencies are supported.  When a command is invoked
and the Dependency Index is True, the command MUST be invoked once
for each Dependency, in the order listed in the array of
Dependencies.
This is represented by the following pseudocode.
Try Each and Run Sequence are affected in the same way as other
commands: they are invoked once for each possible Component or
Dependency.  This means that the sequences that are arguments to Try
Each and Run Sequence are NOT invoked with Component Index = True or
Dependency Index = True.  They are only invoked with integer indices.
The interpreter loops over the whole sequence, setting the Component
Index or Dependency Index to each possible index in turn.
In highly constrained devices, where storage for parameters is
limited, the manifest processor MAY handle one component at a time,
traversing the manifest tree once for each listed component.  In this
mode, the interpreter ignores any commands executed while the
component index is not the current component.  This reduces the
overall volatile storage required to process the update so that the
only limit on number of components is the size of the manifest.
However, this approach requires additional processing power.
In order to operate in this mode, the manifest processor loops on
each section for every supported component, simply ignoring commands
when the current component is not selected.
When a serialized Manifest Processor encounters a component or
dependency index of True, it does not ignore any commands.  It
applies them to the current component or dependency on each
iteration.
Advanced Recipients MAY make use of the Strict Order parameter and
enable parallel processing of some Command Sequences, or it may
reorder some Command Sequences.  To perform parallel processing, once
the Strict Order parameter is set to False, the Recipient may fork a
process for each command until the Strict Order parameter is returned
to True or the Command Sequence ends.  Then, it joins all forked
processes before continuing processing of commands.  To perform out-
of-order processing, a similar approach is used, except the Recipient
consumes all commands after the Strict Order parameter is set to
False, then it sorts these commands into its preferred order, invokes
them all, then continues processing.
To perform more useful parallel operations, sequences of commands may
be collected in a suit-directive-run-sequence.  Then, each of these
sequences may be run in parallel.  Each sequence defaults to Strict
Order = True.  To isolate each sequence from each other sequence,
each sequence must declare a single target component.  Set Component
Index is not permitted inside this sequence.
To perform more useful parallel operations, sequences of commands may
be collected in a suit-directive-run-sequence.  Then, each of these
sequences may be run in parallel.  Each sequence defaults to Strict
Order = True.  To isolate each sequence from each other sequence,
each sequence MUST begin with a Set Component Index directive.  The
interpreter MUST track each Set Component Index directive, and cause
an Abort if more than one Set Component Index directive targets the
same Component Index.  When Strict Order = False, each suit-
directive-run-sequence MUST begin with a Set Component Index
directive.  Any further Set Component Index directives MUST cause an
Abort.  This allows the interpreter that forks suit-directive-run-
sequence processes to check that the first element is correct, then
fork a process to handle the remainder of the sequence.
Manifests are created using tools for constructing COSE structures,
calculating cryptographic values and compiling desired system state
into a sequence of operations required to achieve that state.  The
process of constructing COSE structures is covered in RFC8152 and the
calculation of cryptographic values is beyond the scope of this
document.
Compiling desired system state into a sequence of operations can be
accomplished in many ways, however several templates are provided
here to cover common use-cases.  Many of these templates can be
aggregated to produce more complex behavior.
NOTE: Digest should always be set using Override Parameters, since
this prevents a less-privileged dependent from replacing the digest.
When a manifest is constructed from a descriptive document, the
descriptive document SHOULD be included in the severable text
section.  This section MAY be pruned from the manifest prior to
distribution to a device.  The inclusion of text source material
enables several use-cases on unconstrained intermediate systems,
where small manifest size, low parser complexity, and pull parsing
are not required.
An unconstrained system that makes decisions based on the manifest
can use the source material instead so that it does not need to
execute the manifest.
An unconstrained system that presents data to a user can do so
according to typical usage patterns without first executing the
manifest, and can trust that information with the same level of
confidence as the manifest itself.
A verifier can be constructed to emulate execution the manifest and
compare the results of that execution to the source material,
providing a check that the manifest performs its stated objectives
and that the manifest does not exceed the capabilities of the target
device.
The compatibility check ensures that devices only install compatible
images.
All manifests MUST contain the compatibility check template, except
as outlined below.
If a device class has a unique trust anchor, and every element in its
trust chain is unique-different from every element in any other
device class, then it MAY include the compatibility check.
If a manifest includes a dependency that performs a compatibility
check, then the dependent manifest MAY include the compatibility
check.
The compatibility check template contains a data dependency: Vendor
Identifier and Class Identifier MUST be set prior to executing the
template.  One example of the full template is included below,
however Parameters may be set within a Try-Each block as well.  They
may also be inherited from a dependent manifest.
Check Vendor Identifier.
Check Class Identifier.
Directive Run.
Compression Info.
For any other section that the dependency has, the dependent MUST
invoke Process Dependency.
All elements in the outer map are wrapped in bstr.
The map indices in this encoding are reset to 1 for each map within
the structure.  This is to keep the indices as small as possible.
The goal is to keep the index objects to single bytes (CBOR positive
integers 1-23).
CDDL names are hyphenated and CDDL structures follow the convention
adopted in COSE RFC8152: SUIT_Structure_Name.
Because the manifest can be used by different actors at different
times, some parts of the manifest can be removed without affecting
later stages of the lifecycle.  This is called "Severing."  Severing
of information is achieved by separating that information from the
signed container so that removing it does not affect the signature.
This means that ensuring authenticity of severable parts of the
manifest is a requirement for the signed portion of the manifest.
Severing some parts makes it possible to discard parts of the
manifest that are no longer necessary.  This is important because it
allows the storage used by the manifest to be greatly reduced.  For
example, no text size limits are needed if text is removed from the
manifest prior to delivery to a constrained device.
Elements are made severable by removing them from the manifest,
encoding them in a bstr, and placing a SUIT_Digest of the bstr in the
manifest so that they can still be authenticated.  The SUIT_Digest
typically consumes 4 bytes more than the size of the raw digest,
therefore elements smaller than (Digest Bits)/8 + 4 SHOULD never be
severable.  Elements larger than (Digest Bits)/8 + 4 MAY be
severable, while elements that are much larger than (Digest Bits)/8 +
4 SHOULD be severable.
This object is a container for the other pieces of the manifest to
provide a common mechanism to find each of the parts.  All elements
of the envelope are contained in bstr objects.  Wherever the manifest
references an object in the envelope, the bstr is included in the
digest calculation.
The suit-authentication-wrapper contains a list of 1 or more
cryptographic authentication wrappers for the core part of the
manifest.  These are implemented as COSE_Mac_Tagged or
COSE_Sign_Tagged blocks.  Each of these blocks contains a SUIT_Digest
of the manifest.  This enables modular processing of the manifest.
The COSE_Mac_Tagged and COSE_Sign_Tagged blocks are described in RFC
8152 RFC8152 and are beyond the scope of this document.  The suit-
authentication-wrapper MUST come before any element in the
SUIT_Envelope, except for the OPTIONAL suit-delegation, regardless of
canonical encoding of CBOR.  All validators MUST reject any
SUIT_Envelope that begins with any element other than a suit-
authentication-wrapper or suit-delegation.
When a system has multiple security domains they MAY require
independent verification of authenticity or security policies.
Security domains may be divided by separation technology such as Arm
TrustZone, or Intel SGX.  Security domains may also be divided into
separate processors and memory spaces, with a communication interface
between them.
For example, an application processor may have an attached
communications module that contains a processor.  The communications
module may require metadata signed by a specific Trust Authority for
regulatory approval.  This may be a different Trust Authority than
the application processor.
When there are two or more security domains, a manifest processor MAY
be required in each.  The first manifest processor is the normal
manifest processor as described for the Recipient in Abstract
Machine.  The second manifest processor only executes sections when
the first manifest processor requests it.  An API interface is
provided from the second manifest processor to the first.  This
allows the first manifest processor to request a limited set of
operations from the second.  These operations are limited to: setting
parameters, inserting an Envelope, invoking a Manifest Command
Sequence.  The second manifest processor declares a prefix to the
first, which tells the first manifest processor when it should
delegate to the second.  These rules are enforced by underlying
separation of privilege infrastructure, such as TEEs, or physical
separation.
When the first manifest processor encounters a dependency prefix,
that informs the first manifest processor that it should provide the
second manifest processor with the corresponding dependency Envelope.
This is done when the dependency is fetched.  The second manifest
processor immediately verifies any authentication information in the
dependency Envelope.  When a parameter is set for any component that
matches the prefix, this parameter setting is passed to the second
manifest processor via an API.  As the first manifest processor works
through the Procedure (set of command sequences) it is executing,
each time it sees a Process Dependency command that is associated
with the prefix declared by the second manifest processor, it uses
the API to ask the second manifest processor to invoke that
dependency section instead.
Manifests are created using tools for constructing COSE structures,
calculating cryptographic values and compiling desired system state
into a sequence of operations required to achieve that state.  The
process of constructing COSE structures and the calculation of
cryptographic values is covered in RFC8152.
Compiling desired system state into a sequence of operations can be
accomplished in many ways.  Several templates are provided below to
cover common use-cases.  These templates can be combined to produce
more complex behavior.
The Author MUST ensure that all parameters consumed by a command are
set prior to invoking that command.  Where Component Index = True or
Dependency Index = True, this means that the parameters consumed by
each command MUST have been set for each Component or Dependency,
respectively.
This template performs a secure boot operation.
According to command-behavior, the Run directive applies to the
component referenced by the current Component Index.  Hence, the Set
Component Index directive has to be used to target a specific
component.
This template triggers the download of firmware.
The Fetch directive needs the URI parameter to be set to determine
where the image is retrieved from.  Additionally, the destination of
where the component shall be stored has to be configured.  The URI is
configured via the Set Parameters directive while the destination is
configured via the Set Component Index directive.
This template modifies the Firmware Download template and adds an
additional sequence.  The Firmware Download operations are moved from
the Payload Install sequence to the Payload Fetch sequence.
This template triggers the installation of a payload included in the
manifest envelope.  It is identical to firmware-download-template
except that it places an added restriction on the URI passed to the
Set Parameters directive.
An implementor MAY choose to place a payload in the envelope of a
manifest.  The payload envelope key MAY be a positive or negative
integer.  The payload envelope key MUST NOT be a value between 0 and
24 and it MUST NOT be used by any other envelope element in the
manifest.  The payload MUST be serialized in a bstr element.
The URI for a payload enclosed in this way MUST be expressed as a
fragment-only reference, as defined in RFC3986, Section 4.4.  The
fragment identifier is the stringified envelope key of the payload.
For example, an envelope that contains a payload a key 42 would use a
URI "#42", key -73 would use a URI "#-73".
This directive loads an firmware image from external storage.
As outlined in command-behavior, the Copy directive needs a source
and a destination to be configured.  The source is configured via
Component Index (with the Set Parameters directive) and the
destination is configured via the Set Component Index directive.
This template is similar to template-load-ext but additionally
performs decompression.  Hence, the only difference is in setting the
Compression Info parameter.
An implementor MAY choose to place a dependency's envelope in the
envelope of its dependent.  The dependent envelope key for the
dependency envelope MUST NOT be a value between 0 and 24 and it MUST
NOT be used by any other envelope element in the dependent manifest.
The URI for a dependency enclosed in this way MUST be expressed as a
fragment-only reference, as defined in RFC3986, Section 4.4.  The
fragment identifier is the stringified envelope key of the
dependency.  For example, an envelope that contains a dependency at
key 42 would use a URI "#42", key -73 would use a URI "#-73".
To use an encrypted manifest, create a plaintext dependent, and add
the encrypted manifest as a dependency.  The dependent can include
very little information.
A plaintext manifest and its encrypted dependency may also form a
composite-manifests.
The metadata for SUIT updates is composed of several primary
constituent parts: the Envelope, Delegation Chains, Authentication
Information, Manifest, and Severable Elements.
For a diagram of the metadata structure, see metadata-structure-
overview.
The map indices in the envelope encoding are reset to 1 for each map
within the structure.  This is to keep the indices as small as
possible.  The goal is to keep the index objects to single bytes
(CBOR positive integers 1-23).
The Envelope contains each of the other primary constituent parts of
the SUIT metadata.  It allows for modular processing of the manifest
by ordering components in the expected order of processing.
The Envelope is encoded as a CBOR Map. Each element of the Envelope
is enclosed in a bstr, which allows computation of a message digest
against known bounds.
The suit-delegation field MAY carry one or more CBOR Web Tokens
(CWTs) RFC8392, with RFC8747 cnf claims.  They can be used to perform
enhanced authorization decisions.  The CWTs are arranged into a list
of lists.  Each list starts with CWT authorized by a Trust Anchor,
and finishes with a key used to authenticate the Manifest (see
authentication-info).  This allows an Update Authority to delegate
from a long term Trust Anchor, down through intermediaries, to a
delegate without any out-of-band updates Trust Anchors.
A Recipient MAY choose to cache intermediaries and/or delegates.  If
an Update Distributor knows that a targeted Recipient has cached some
intermediaries or delegates, it MAY choose to strip any cached
intermediaries or delegates from the Delegation Chains in order to
reduce bandwidth and energy.
The suit-authentication-wrapper contains a list of one or more
cryptographic authentication wrappers for the Manifest.  These are
implemented as COSE_Mac_Tagged or COSE_Sign_Tagged blocks.  Each of
these blocks contains a SUIT_Digest of the Manifest.  This enables
modular processing of the manifest.  The COSE_Mac_Tagged and
COSE_Sign_Tagged blocks are described in RFC 8152 RFC8152.  The suit-
authentication-wrapper MUST come before any element in the
SUIT_Envelope, except for the OPTIONAL suit-delegation, regardless of
canonical encoding of CBOR.  All validators MUST reject any
SUIT_Envelope that begins with any element other than a suit-
authentication-wrapper or suit-delegation.
A SUIT_Envelope that has not had authentication information added
MUST still contain the suit-authentication-wrapper element, but the
content MUST be nil.
a plaintext manifest: SUIT_Manifest.
an encrypted manifest: both a SUIT_Encryption_Wrapper and the
ciphertext of a manifest.
When the envelope contains SUIT_Encryption_Wrapper, the suit-
authentication-wrapper MUST authenticate the plaintext of suit-
manifest-encrypted.  This ensures that the manifest can be stored
decrypted and that a recipient MAY convert the suit-manifest-
encrypted element to a suit-manifest element.
suit-manifest contains a SUIT_Manifest structure, which describes the
payload(s) to be installed and any dependencies on other manifests.
suit-manifest-encryption-info contains a SUIT_Encryption_Wrapper, a
COSE object that describes the information required to decrypt a
ciphertext manifest.
suit-manifest-encrypted contains a ciphertext manifest.
Each of suit-dependency-resolution, suit-payload-fetch, and suit-
payload-installation contain the severable contents of the
identically named portions of the manifest, described in secmanifest.
suit-text contains all the human-readable information that describes
any and all parts of the manifest, its payload(s) and its
resource(s).
suit-coswid contains a Concise Software Identifier.  This may be
discarded by the Recipient if not needed.
a reference for each of the severable blocks.
a list of actions that the Recipient should perform.
The following CDDL fragment defines the manifest.
Several fields in the Manifest can be either a CBOR structure or a
SUIT_Digest.  In each of these cases, the SUIT_Digest provides for a
severable field.  Severable fields are RECOMMENDED to implement.  In
particular, text SHOULD be severable, since most useful text elements
occupy more space than a SUIT_Digest, but are not needed by the
Recipient.  Because SUIT_Digest is a CBOR Array and each severable
element is a CBOR bstr, it is straight-forward for a Recipient to
determine whether an element is been severable.  The key used for a
severable element is the same in the SUIT_Manifest and in the
SUIT_Envelope so that a Recipient can easily identify the correct
data in the envelope.
The suit-manifest-version indicates the version of serialization used
to encode the manifest.  Version 1 is the version described in this
document. suit-manifest-version is REQUIRED.
The suit-manifest-sequence-number is a monotonically increasing anti-
rollback counter.  It also helps devices to determine which in a set
of manifests is the "root" manifest in a given update.  Each manifest
MUST have a sequence number higher than each of its dependencies.
Each Recipient MUST reject any manifest that has a sequence number
lower than its current sequence number.  It MAY be convenient to use
a UTC timestamp in seconds as the sequence number. suit-manifest-
sequence-number is REQUIRED.
suit-common encodes all the information that is shared between each
of the command sequences, including: suit-dependencies, suit-
components, suit-dependency-components, and suit-common-sequence.
suit-common is REQUIRED to implement.
In order to distinguish between components that are affected by the
current manifest and components that are affected by a dependency,
they are kept in separate lists.  Components affected by the current
manifest only list the component identifier.  Components affected by
a dependency include the component identifier and the index of the
dependency that defines the component.
suit-components is a list of SUIT_Component blocks that specify the
component identifiers that will be affected by the content of the
current manifest. suit-components is OPTIONAL, but at least one
manifest MUST contain a suit-components block.
suit-dependency-components is a list of SUIT_Component_Reference
blocks that specify component identifiers that will be affected by
the content of a dependency of the current manifest. suit-dependency-
components is OPTIONAL.
suit-common-sequence is a SUIT_Command_Sequence to execute prior to
executing any other command sequence.  Typical actions in suit-
common-sequence include setting expected device identity and image
digests when they are conditional (see secconditional for more
information on conditional sequences). suit-common-sequence is
RECOMMENDED.
suit-reference-uri is a text string that encodes a URI where a full
version of this manifest can be found.  This is convenient for
allowing management systems to show the severed elements of a
manifest when this URI is reported by a device after installation.
suit-dependency-resolution is a SUIT_Command_Sequence to execute in
order to perform dependency resolution.  Typical actions include
configuring URIs of dependency manifests, fetching dependency
manifests, and validating dependency manifests' contents. suit-
dependency-resolution is REQUIRED when suit-dependencies is present.
suit-payload-fetch is a SUIT_Command_Sequence to execute in order to
obtain a payload.  Some manifests may include these actions in the
suit-install section instead if they operate in a streaming
installation mode.  This is particularly relevant for constrained
devices without any temporary storage for staging the update. suit-
payload-fetch is OPTIONAL.
suit-install is a SUIT_Command_Sequence to execute in order to
install a payload.  Typical actions include verifying a payload
stored in temporary storage, copying a staged payload from temporary
storage, and unpacking a payload. suit-install is OPTIONAL.
suit-validate is a SUIT_Command_Sequence to execute in order to
validate that the result of applying the update is correct.  Typical
actions involve image validation and manifest validation. suit-
validate is REQUIRED.  If the manifest contains dependencies, one
process-dependency invocation per dependency or one process-
dependency invocation targeting all dependencies SHOULD be present in
validate.
suit-load is a SUIT_Command_Sequence to execute in order to prepare a
payload for execution.  Typical actions include copying an image from
permanent storage into RAM, optionally including actions such as
decryption or decompression. suit-load is OPTIONAL.
suit-run is a SUIT_Command_Sequence to execute in order to run an
image. suit-run typically contains a single instruction: either the
"run" directive for the bootable manifest or the "process
dependencies" directive for any dependents of the bootable manifest.
suit-run is OPTIONAL.  Only one manifest in an update may contain the
"run" directive.
suit-text is a digest that uniquely identifies the content of the
Text that is packaged in the SUIT_Envelope. text is OPTIONAL.
suit-coswid is a digest that uniquely identifies the content of the
concise-software-identifier that is packaged in the SUIT_Envelope.
coswid is OPTIONAL.
SUIT_Dependency specifies a manifest that describes a dependency of
the current manifest.
The following CDDL describes the SUIT_Dependency structure.
The suit-dependency-digest specifies the dependency manifest uniquely
by identifying a particular Manifest structure.  The digest is
calculated over the Manifest structure instead of the COSE
Sig_structure or Mac_structure.  This means that a digest may need to
be calculated more than once, however this is necessary to ensure
that removing a signature from a manifest does not break dependencies
due to missing signature elements.  This is also necessary to support
the trusted intermediary use case, where an intermediary re-signs the
Manifest, removing the original signature, potentially with a
different algorithm, or trading COSE_Sign for COSE_Mac.
The suit-dependency-prefix element contains a
SUIT_Component_Identifier.  This specifies the scope at which the
dependency operates.  This allows the dependency to be forwarded on
to a component that is capable of parsing its own manifests.  It also
allows one manifest to be deployed to multiple dependent devices
without those devices needing consistent component hierarchy.  This
element is OPTIONAL.
The SUIT_Component_Reference describes an image that is defined by
another manifest.  This is useful for overriding the behavior of
another manifest, for example by directing the recipient to look at a
different URI for the image or by changing the expected format, such
as when a gateway performs decryption on behalf of a constrained
device.  The following CDDL describes the SUIT_Component_Reference.
A SUIT_Envelope that has not had authentication information added
MUST still contain the suit-authentication-wrapper element, but the
content MUST be an empty list.
To use an encrypted manifest, it must be a dependency of a plaintext
manifest.  This allows fine-grained control of what information is
accessible to intermediate systems for the purposes of management,
while still preserving the confidentiality of the manifest contents.
This also means that a Recipient can process an encrypted manifest in
the same way as an encrypted payload, allowing code reuse.
A template for using an encrypted manifest is covered in template-
encrypted-manifest.
The CoSWID, Text section, or any Command Sequence of the Update
Procedure (Dependency Resolution, Image Fetch, Image Installation)
can be either a CBOR structure or a SUIT_Digest.  In each of these
cases, the SUIT_Digest provides for a severable field.  Severable
fields are RECOMMENDED to implement.  In particular, the human-
readable text SHOULD be severable, since most useful text elements
occupy more space than a SUIT_Digest, but are not needed by the
Recipient.  Because SUIT_Digest is a CBOR Array and each severable
element is a CBOR bstr, it is straight-forward for a Recipient to
determine whether an element has been severed.  The key used for a
severable element is the same in the SUIT_Manifest and in the
SUIT_Envelope so that a Recipient can easily identify the correct
data in the envelope.  See integrity-checks for more detail.
The suit-manifest-version indicates the version of serialization used
to encode the manifest.  Version 1 is the version described in this
document. suit-manifest-version is REQUIRED to implement.
The suit-manifest-sequence-number is a monotonically increasing anti-
rollback counter.  It also helps Recipients to determine which in a
set of manifests is the "root" manifest in a given update.  Each
manifest MUST have a sequence number higher than each of its
dependencies.  Each Recipient MUST reject any manifest that has a
sequence number lower than its current sequence number.  It MAY be
convenient to use a UTC timestamp in seconds as the sequence number.
suit-manifest-sequence-number is REQUIRED to implement.
suit-reference-uri is a text string that encodes a URI where a full
version of this manifest can be found.  This is convenient for
allowing management systems to show the severed elements of a
manifest when this URI is reported by a Recipient after installation.
Each SUIT_Component_Identifier => map entry contains a map of integer
=> text values.  All SUIT_Component_Identifiers present in suit-text
MUST also be present in manifest-common or the suit-common of a
dependency.
suit-text contains all the human-readable information that describes
any and all parts of the manifest, its payload(s) and its
resource(s).  The text section is typically severable, allowing
manifests to be distributed without the text, since end-nodes do not
require text.  The meaning of each field is described below.
The following table describes the text fields available in each map
identified by a SUIT_Component_Identifier.
suit-text is OPTIONAL to implement.
suit-text-version-required is used to represent a version-based
dependency on suit-parameter-version as described in suit-parameter-
version and suit-condition-version.  To describe a version
dependency, a Manifest Author should populate the suit-text map with
a SUIT_Component_Identifier key for the dependency component, and
place in the corresponding map a suit-text-version-required key with
a text expression that is representative of the version constraints
placed on the dependency.
For example, to express a dependency on a component "['x', 'y']",
where the version should be any v1.x later than v1.2.5, but not v2.0
or above, the author would add the following structure to the suit-
text element.  Note that this text is in cbor-diag notation.
suit-coswid contains a Concise Software Identifier.  This element
SHOULD be made severable so that it can be discarded by the Recipient
or an intermediary if it is not required by the Recipient.
suit-coswid is OPTIONAL to implement.
suit-common encodes all the information that is shared between each
of the command sequences, including: suit-dependencies, suit-
components, and suit-common-sequence. suit-common is REQUIRED to
implement.
suit-components is a list of suit-component-identifier blocks that
specify the component identifiers that will be affected by the
content of the current manifest. suit-components is REQUIRED to
implement; at least one manifest in a dependency tree MUST contain a
suit-components block.
suit-common-sequence is a SUIT_Command_Sequence to execute prior to
executing any other command sequence.  Typical actions in suit-
common-sequence include setting expected Recipient identity and image
digests when they are conditional (see suit-directive-try-each and
a-b-template for more information on conditional sequences). suit-
common-sequence is RECOMMENDED to implement.  It is REQUIRED if the
optimizations described in minimal-sigs will be used.  Whenever a
parameter or try-each is required by more than one Command Sequence,
suit-common-sequence results in a smaller encoding.
SUIT_Dependency specifies a manifest that describes a dependency of
the current manifest.  The Manifest is identified, however the
Recipient should expect an Envelope when it acquires the dependency.
This is because the Manifest is the one invariant element of the
Envelope, where other elements may change by countersigning, adding
authentication blocks, or severing elements.
The suit-dependency-digest specifies the dependency manifest uniquely
by identifying a particular Manifest structure.  This is identical to
the digest that would be present as the payload of any suit-
authentication-block in the dependency's Envelope.  The digest is
calculated over the Manifest structure instead of the COSE
Sig_structure or Mac_structure.  This is necessary to ensure that
removing a signature from a manifest does not break dependencies due
to missing signature elements.  This is also necessary to support the
trusted intermediary use case, where an intermediary re-signs the
Manifest, removing the original signature, potentially with a
different algorithm, or trading COSE_Sign for COSE_Mac.
The suit-dependency-prefix element contains a
SUIT_Component_Identifier (see suit-component-identifier).  This
specifies the scope at which the dependency operates.  This allows
the dependency to be forwarded on to a component that is capable of
parsing its own manifests.  It also allows one manifest to be
deployed to multiple dependent Recipients without those Recipients
needing consistent component hierarchy.  This element is OPTIONAL.
A dependency prefix can be used with a component identifier.  This
allows complex systems to understand where dependencies need to be
applied.  The dependency prefix can be used in one of two ways.  The
first simply prepends the prefix to all Component Identifiers in the
dependency.
A dependency prefix can also be used to indicate when a dependency
manifest needs to be processed by a secondary manifest processor, as
described in hierarchical-interpreters.
A Component Identifier can be trivial, such as the simple array
[h'00'].  It can also represent a filesystem path by encoding each
segment of the path as an element in the list.  For example, the path
"/usr/bin/env" would encode to ['usr','bin','env'].
This hierarchical construction allows a component identifier to
identify any part of a complex, multi-component system.
Dependency Resolution: suit-dependency-resolution is a
SUIT_Command_Sequence to execute in order to perform dependency
resolution.  Typical actions include configuring URIs of
dependency manifests, fetching dependency manifests, and
validating dependency manifests' contents. suit-dependency-
resolution is REQUIRED to implement and to use when suit-
dependencies is present.
Payload Fetch: suit-payload-fetch is a SUIT_Command_Sequence to
execute in order to obtain a payload.  Some manifests may include
these actions in the suit-install section instead if they operate
in a streaming installation mode.  This is particularly relevant
for constrained devices without any temporary storage for staging
the update. suit-payload-fetch is OPTIONAL to implement.
Payload Installation: suit-install is a SUIT_Command_Sequence to
execute in order to install a payload.  Typical actions include
verifying a payload stored in temporary storage, copying a staged
payload from temporary storage, and unpacking a payload. suit-
install is OPTIONAL to implement.
Image Validation: suit-validate is a SUIT_Command_Sequence to
execute in order to validate that the result of applying the
update is correct.  Typical actions involve image validation and
manifest validation. suit-validate is REQUIRED to implement.  If
the manifest contains dependencies, one process-dependency
invocation per dependency or one process-dependency invocation
targeting all dependencies SHOULD be present in validate.
Image Loading: suit-load is a SUIT_Command_Sequence to execute in
order to prepare a payload for execution.  Typical actions include
copying an image from permanent storage into RAM, optionally
including actions such as decryption or decompression. suit-load
is OPTIONAL to implement.
Run or Boot: suit-run is a SUIT_Command_Sequence to execute in
order to run an image. suit-run typically contains a single
instruction: either the "run" directive for the bootable manifest
or the "process dependencies" directive for any dependents of the
bootable manifest. suit-run is OPTIONAL to implement.  Only one
manifest in an update may contain the "run" directive.
Goals 1,2,3 form the Update Procedure.  Goals 4,5,6 form the Boot
Procedure.
Each Command Sequence follows exactly the same structure to ensure
that the parser is as simple as possible.
Each condition is a command code identifier, followed by a reporting-
policy.
Reporting policies provide a hint to the manifest processor of
whether or not to add the success or failure of a command to any
report that it generates.
To facilitate optional conditions, a special directive, suit-
directive-try-each, is provided.  It runs several new lists of
conditions/directives, one after another, that are contained as an
argument to the directive.  By default, it assumes that a failure of
a condition should not indicate a failure of the update/boot, but a
parameter is provided to override this behavior.  See suit-parameter-
soft-failure.
To facilitate construction of Reports that describe the success, or
failure of a given Procedure, each command is given a Reporting
Policy.  This is an integer bitfield that follows the command and
indicates what the Recipient should do with the Record of executing
the command.  The options are summarized in the table below.
Any or all of these policies may be enabled at once.
If the component index is set to True when a command is executed with
a non-zero reporting policy, then the Reporting Engine MUST receive
one Record for each Component, in the order expressed in the
Components list.  If the dependency index is set to True when a
command is executed with a non-zero reporting policy, then the
Reporting Engine MUST receive one Record for each Dependency, in the
order expressed in the Dependencies list.
SUIT does NOT REQUIRE a particular format of Records or Reports.
SUIT only defines hints to the Reporting engine for which Records it
should aggregate into the Report.
For example, a system using DICE certificates MAY use instances of
suit-send-sysinfo-success to construct its certificates.
An OPTIONAL Record format, SUIT_Record is defined in full-cddl.  It
is encoded as a map, with the following elements.
In Secure Boot operations, the Reporting engine MAY aggregate the
Records produced in a Procedure into the evidence used for an
attestation report.
Most parameters are scoped to a specific component.  This means that
setting a parameter for one component has no effect on the parameters
of any other component.  The only exceptions to this are two Manifest
Processor parameters: Strict Order and Soft Failure.
When executing a command sequence inside SUIT_Directive_Try_Each and
a condition failure occurs, the manifest processor aborts the
sequence.  If Soft Failure is True, it returns Success.  Otherwise,
it returns the original condition failure.
SUIT_Parameter_Soft_Failure is scoped to the enclosing
SUIT_Command_Sequence.  Its value is discarded when
SUIT_Command_Sequence terminates.
Compression Info defines any information that is required for a
device to perform decompression operations.  Typically, this includes
the algorithm identifier.
The following CDDL describes all SUIT_Parameters.
Each of these follows exactly the same structure to ensure that the
parser is as simple as possible.
Argument blocks are defined for each type of directive.
To facilitate optional conditions, a special directive is provided.
It runs several new lists of conditions/directives, one after
another, that are contained as an argument to the directive.  By
default, it assumes that a failure of a condition should not indicate
a failure of the update/boot, but a parameter is provided to override
this behavior.
Each condition MUST report a success code on completion.  If a
condition reports failure, then the current sequence of commands MUST
terminate.  If a condition requires additional information, this MUST
be specified in one or more parameters before the condition is
executed.  If a Recipient attempts to process a condition that
expects additional information and that information has not been set,
it MUST report a failure.  If a Recipient encounters an unknown
Condition Code, it MUST report a failure.
Positive Condition numbers are reserved for IANA registration.
Negative numbers are reserved for proprietary, application-specific
directives.
There are three identifier-based conditions: suit-condition-vendor-
identifier, suit-condition-class-identifier, and suit-condition-
device-identifier.  Each of these conditions match a RFC 4122 RFC4122
UUID that MUST have already been set as a parameter.  The installing
device MUST match the specified UUID in order to consider the
manifest valid.  These identifiers MAY be scoped by component.
Verify that the current component matches the digest parameter for
the current component.  The digest is verified against the digest
specified in the Component's parameters list.  If no digest is
specified, the condition fails. suit-condition-image-match is
REQUIRED to implement.
Verify that the current component does not match the supplied digest.
If no digest is specified, then the digest is compared against the
digest specified in the Component's parameters list.  If no digest is
specified, the condition fails. suit-condition-image-not-match is
OPTIONAL to implement.
Verify that the current time is BEFORE the specified time. suit-
condition-use-before is used to specify the last time at which an
update should be installed.  The recipient evaluates the current time
against the suit-parameter-use-before parameter, which must have
already been set as a parameter, encoded as a POSIX timestamp, that
is seconds after 1970-01-01 00:00:00.  Timestamp conditions MUST be
evaluated in 64 bits, regardless of encoded CBOR size. suit-
condition-use-before is OPTIONAL to implement.
suit-condition-minimum-battery provides a mechanism to test a
device's battery level before installing an update.  This condition
is for use in primary-cell applications, where the battery is only
ever discharged.  For batteries that are charged, suit-directive-wait
is more appropriate, since it defines a "wait" until the battery
level is sufficient to install the update. suit-condition-minimum-
battery is specified in mWh. suit-condition-minimum-battery is
OPTIONAL to implement.
Request Authorization from the application and fail if not
authorized.  This can allow a user to decline an update.  Argument is
an integer priority level.  Priorities are application defined. suit-
condition-update-authorized is OPTIONAL to implement.
Several conditions use identifiers to determine whether a manifest
matches a given Recipient or not.  These identifiers are defined to
be RFC 4122 RFC4122 UUIDs.  These UUIDs are not human-readable and
are therefore used for machine-based processing only.
A Recipient MAY match any number of UUIDs for vendor or class
identifier.  This may be relevant to physical or software modules.
For example, a Recipient that has an OS and one or more applications
might list one Vendor ID for the OS and one or more additional Vendor
IDs for the applications.  This Recipient might also have a Class ID
that must be matched for the OS and one or more Class IDs for the
applications.
Identifiers are used for compatibility checks.  They MUST NOT be used
as assertions of identity.  They are evaluated by identifier-
conditions.
A fingerprint computed over the component itself, encoded in the
SUIT_Digest structure.  The SUIT_Digest is wrapped in a bstr, as
required in secparameters.
The size of the firmware image in bytes.  This size is encoded as a
positive integer.
An expiry date for the use of the manifest encoded as a POSIX
timestamp; a positive integer.  Implementations that use this
parameter MUST use a 64-bit internal representation of the integer.
This parameter sets the offset in a component.  Some components
support multiple possible Slots (offsets into a storage area).  This
parameter describes the intended Slot to use, identified by its
offset into the component's storage area.  This offset MUST be
encoded as a positive integer.
Compression Info defines any information that is required for a
Recipient to perform decompression operations.  Typically, this
includes the algorithm identifier.  This document defines the use of
ZLIB RFC1950, Brotli RFC7932, and ZSTD I-D.kucherawy-rfc8478bis.
Additional compression formats can be registered through the IANA-
maintained registry.
SUIT_Unpack_Info defines the information required for a Recipient to
interpret a packed format.  This document defines the use of the
following binary encodings: Intel HEX HEX, Motorola S-record SREC,
Executable and Linkable Format (ELF) ELF, and Common Object File
Format (COFF) COFF.
Additional packing formats can be registered through the IANA-
maintained registry.
A URI from which to fetch a resource.
This parameter sets the source component to be used with either suit-
directive-copy or with suit-directive-swap.  The current Component,
as set by suit-directive-set-component-index defines the destination,
and suit-parameter-source-component defines the source.
This parameter contains an encoded set of arguments for suit-
directive-run.  The arguments MUST be provided as an implementation-
defined bstr.
This parameter sets the minimum battery level in mWh.  This parameter
is encoded as a positive integer.  Used with suit-condition-minimum-
battery.
This parameter sets the priority of the update.  This parameter is
encoded as an integer.  It is used along with suit-condition-update-
authorized [1] to ask an application for permission to initiate an
update.  This does not constitute a privilege inversion because an
explicit request for authorization has been provided by the Update
Authority in the form of the suit-condition-update-authorized
command.
Applications MAY define their own meanings for the update priority.
For example, critical reliability & vulnerability fixes MAY be given
negative numbers, while bug fixes MAY be given small positive
numbers, and feature additions MAY be given larger positive numbers,
which allows an application to make an informed decision about
whether and when to allow an update to proceed.
Indicates allowable versions for the specified component.  Allowable
versions can be specified, either with a list or with range matching.
This parameter is compared with version asserted by the current
component when suit-condition-version is invoked.  The current
component may assert the current version in many ways, including
storage in a parameter storage database, in a metadata object, or in
a known location within the component itself.
Many conditions use identifiers to determine whether a manifest
matches a given Recipient or not.  These identifiers are defined to
be RFC 4122 RFC4122 UUIDs.  These UUIDs are explicitly NOT human-
readable.  They are for machine-based matching only.
A device may match any number of UUIDs for vendor or class
identifier.  This may be relevant to physical or software modules.
For example, a device that has an OS and one or more applications
might list one Vendor ID for the OS and one or more additional Vendor
IDs for the applications.  This device might also have a Class ID
that must be matched for the OS and one or more Class IDs for the
applications.
When a Recipient executes a Directive, it MUST report a success code.
If the Directive reports failure, then the current Command Sequence
MUST terminate.
Set Component Index defines the component to which successive
directives and conditions will apply.  The supplied argument MUST be
either a boolean or an unsigned integer index into the concatenation
of suit-components and suit-dependency-components.  If the following
directives apply to ALL components, then the boolean value "True" is
used instead of an index.  True does not apply to dependency
components.  If the following directives apply to NO components, then
the boolean value "False" is used.  When suit-directive-set-
dependency-index is used, suit-directive-set-component-index = False
is implied.  When suit-directive-set-component-index is used, suit-
directive-set-dependency-index = False is implied.
The following CDDL describes the argument to suit-directive-set-
component-index.
The first integer represents the major number.  This indicates
breaking changes to the component.
The second integer represents the minor number.  This is typically
reserved for new features or large, non-breaking changes.
The third integer is the patch version.  This is typically
reserved for bug fixes.
The fourth integer is the build number.
Where Alpha (-3), Beta (-2), and Release Candidate (-1) are used,
they are inserted as a negative number between Minor and Patch
numbers.  This allows these releases to compare correctly with final
releases.  For example, Version 2.0, RC1 should be lower than Version
2.0.0 and higher than any Version 1.x.  By encoding RC as -1, this
works correctly: [2,0,-1,1] compares as lower than [2,0,0].
Similarly, beta (-2) is lower than RC and alpha (-3) is lower than
RC.
suit-directive-wait suit-directive-wait directs the manifest
processor to pause until a specified event occurs.  The suit-
parameter-wait-info encodes the parameters needed for the directive.
The exact implementation of the pause is implementation-defined.  For
example, this could be done by blocking on a semaphore, registering
an event handler and suspending the manifest processor, polling for a
notification, or aborting the update entirely, then restarting when a
notification is received.
suit-parameter-wait-info is encoded as a map of wait events.  When
ALL wait events are satisfied, the Manifest Processor continues.  The
wait events currently defined are described in the following table.
suit-wait-event-other-device-version reuses the encoding of suit-
parameter-version-match.  It is encoded as a sequence that contains
an implementation-defined bstr identifier for the other device, and a
list of one or more SUIT_Parameter_Version_Match.
Indicates a list of URIs from which to fetch a resource.  The URI
list is encoded as a list of tstr, in priority order.  The Recipient
should attempt to fetch the resource from each URI in turn, ruling
out each, in order, if the resource is inaccessible or it is
otherwise undesirable to fetch from that URI. suit-parameter-uri-list
is consumed by suit-directive-fetch-uri-list.
An implementation-defined set of arguments to suit-directive-fetch.
Arguments are encoded in a bstr.
See parallel-processing for behavioral description of Strict Order.
When executing a command sequence inside suit-directive-try-each or
suit-directive-run-sequence and a condition failure occurs, the
manifest processor aborts the sequence.  For suit-directive-try-each,
if Soft Failure is True, the next sequence in Try Each is invoked,
otherwise suit-directive-try-each fails with the condition failure
code.  In suit-directive-run-sequence, if Soft Failure is True the
suit-directive-run-sequence simply halts with no side-effects and the
Manifest Processor continues with the following command, otherwise,
the suit-directive-run-sequence fails with the condition failure
code.
suit-parameter-soft-failure is scoped to the enclosing
SUIT_Command_Sequence.  Its value is discarded when
SUIT_Command_Sequence terminates.  It MUST NOT be set outside of
suit-directive-try-each or suit-directive-run-sequence.
When suit-directive-try-each is invoked, Soft Failure defaults to
True.  An Update Author may choose to set Soft Failure to False if
they require a failed condition in a sequence to force an Abort.
When suit-directive-run-sequence is invoked, Soft Failure defaults to
False.  An Update Author may choose to make failures soft within a
suit-directive-run-sequence.
This parameter is an extension point for any proprietary, application
specific conditions and directives.
The abstract description of these conditions is defined in command-
behavior.
Conditions compare parameters against properties of the system.
These properties may be asserted in many different ways, including:
calculation on-demand, volatile definition in memory, static
definition within the manifest processor, storage in known location
within an image, storage within a key storage system, storage in One-
Time-Programmable memory, inclusion in mask ROM, or inclusion as a
register in hardware.  Some of these assertion methods are global in
scope, such as a hardware register, some are scoped to an individual
component, such as storage at a known location in an image, and some
assertion methods can be either global or component-scope, based on
implementation.
Each condition MUST report a result code on completion.  If a
condition reports failure, then the current sequence of commands MUST
terminate.  A subsequent command or command sequence MAY continue
executing if suit-parameter-soft-failure is set.  If a condition
requires additional information, this MUST be specified in one or
more parameters before the condition is executed.  If a Recipient
attempts to process a condition that expects additional information
and that information has not been set, it MUST report a failure.  If
a Recipient encounters an unknown condition, it MUST report a
failure.
Condition labels in the positive number range are reserved for IANA
registration while those in the negative range are custom conditions
reserved for proprietary use.  See iana for more details.
There are three identifier-based conditions: suit-condition-vendor-
identifier, suit-condition-class-identifier, and suit-condition-
device-identifier.  Each of these conditions match a RFC 4122 RFC4122
UUID that MUST have already been set as a parameter.  The installing
Recipient MUST match the specified UUID in order to consider the
manifest valid.  These identifiers are scoped by component in the
manifest.  The Recipient MAY treat them as scoped by component or as
global identifiers.
Each identifier condition compares the corresponding identifier
parameter to a parameter asserted to the Manifest Processor by the
Recipient.  Identifiers MUST be known to the Manifest Processor in
order to evaluate compatibility.
Globally-scoped identifiers MUST match, regardless of current
component index.  Component-scoped identifiers match only when the
current component index resolves to the component associated with the
component-scoped identifier.
Verify that the current component matches the suit-parameter-image-
digest for the current component.  The digest is verified against the
digest specified in the Component's parameters list.  If no digest is
specified, the condition fails. suit-condition-image-match is
REQUIRED to implement.
Verify that the current component does not match the suit-parameter-
image-digest.  If no digest is specified, the condition fails. suit-
condition-image-not-match is OPTIONAL to implement.
Verify that the current time is BEFORE the specified time. suit-
condition-use-before is used to specify the last time at which an
update should be installed.  The recipient evaluates the current time
against the suit-parameter-use-before, which must have already been
set as a parameter, encoded as a POSIX timestamp, that is seconds
after 1970-01-01 00:00:00.  Timestamp conditions MUST be evaluated in
64 bits, regardless of encoded CBOR size. suit-condition-use-before
is OPTIONAL to implement.
Verify that the offset of the current component matches the offset
set in suit-parameter-component-offset.  This condition allows a
manifest to select between several images to match a target offset.
suit-condition-minimum-battery provides a mechanism to test a
Recipient's battery level before installing an update.  This
condition is primarily for use in primary-cell applications, where
the battery is only ever discharged.  For batteries that are charged,
suit-directive-wait is more appropriate, since it defines a "wait"
until the battery level is sufficient to install the update. suit-
condition-minimum-battery is specified in mWh. suit-condition-
minimum-battery is OPTIONAL to implement. suit-condition-minimum-
battery consumes suit-parameter-minimum-battery.
Request Authorization from the application and fail if not
authorized.  This can allow a user to decline an update. suit-
parameter-update-priority provides an integer priority level that the
application can use to determine whether or not to authorize the
update.  Priorities are application defined. suit-condition-update-
authorized is OPTIONAL to implement.
The abstract description of these commands is defined in command-
behavior.
When a Recipient executes a Directive, it MUST report a result code.
If the Directive reports failure, then the current Command Sequence
MUST terminate.
Set Component Index defines the component to which successive
directives and conditions will apply.  The supplied argument MUST be
either a boolean or an unsigned integer index into suit-components.
If the following commands apply to ALL components, then the boolean
value "True" is used instead of an index.  If the following commands
apply to NO components, then the boolean value "False" is used.  When
suit-directive-set-dependency-index is used, suit-directive-set-
component-index = False is implied.  When suit-directive-set-
component-index is used, suit-directive-set-dependency-index = False
is implied.
If component index is set to True when a command is invoked, then the
command applies to all components, in the order they appear in suit-
common-components.  When the Manifest Processor invokes a command
while the component index is set to True, it must execute the command
once for each possible component index, ensuring that the command
receives the parameters corresponding to that component index.
Typical operations that require suit-directive-set-dependency-index
include setting a source URI, invoking "Fetch," or invoking "Process
Dependency" for an individual dependency.
The following CDDL describes the argument to suit-directive-set-
dependency-index.
The following CDDL describes the SUIT_Run_Sequence argument.
SUIT_Parameter_Soft_Failure defaults to False when suit-directive-
run-sequence begins.  Its value is discarded when suit-directive-run-
sequence terminates.
SUIT_Parameter_Soft_Failure is initialized to True at the beginning
of each sequence.  If one sequence aborts due to a condition failure,
the next is started.  If no sequence completes without condition
failure, then suit-directive-try-each returns an error.  If a
particular application calls for all sequences to fail and still
continue, then an empty sequence (nil) can be added to the Try Each
Argument.
If dependency index is set to True when a command is invoked, then
the command applies to all dependencies, in the order they appear in
suit-common-components.  When the Manifest Processor invokes a
command while the dependency index is set to True, it must execute
the command once for each possible dependency index, ensuring that
the command receives the parameters corresponding to that dependency
index.
Typical operations that require suit-directive-set-dependency-index
include setting a source URI or Encryption Information, invoking
"Fetch," or invoking "Process Dependency" for an individual
dependency.
suit-parameter-soft-failure is initialized to True at the beginning
of each sequence.  If one sequence aborts due to a condition failure,
the next is started.  If no sequence completes without condition
failure, then suit-directive-try-each returns an error.  If a
particular application calls for all sequences to fail and still
continue, then an empty sequence (nil) can be added to the Try Each
Argument.
The following CDDL describes the SUIT_Try_Each argument.
The argument to suit-directive-try-each is a list of
SUIT_Command_Sequence. suit-directive-try-each does not specify a
reporting policy.
The argument to suit-directive-process-dependency is defined in the
following CDDL.
The argument to suit-directive-set-parameters is defined in the
following CDDL.
N.B.: A directive code is reserved for an optimization: a way to set
a parameter to the contents of another parameter, optionally with
another component ID.
suit-directive-set-parameters does not specify a reporting policy.
The argument to suit-directive-override-parameters is defined in the
following CDDL.
suit-directive-override-parameters does not specify a reporting
policy.
suit-directive-fetch can target one or more manifests and one or more
payloads. suit-directive-fetch retrieves each component and each
manifest listed in component-index and manifest-index, respectively.
If component-index or manifest-index is True, instead of an integer,
then all current manifest components/manifests are fetched.  The
current manifest's dependent-components are not automatically
fetched.  In order to pre-fetch these, they MUST be specified in a
component-index integer.
suit-directive-fetch typically takes no arguments unless one is
needed to modify fetch behavior.  If an argument is needed, it must
be wrapped in a bstr.
suit-directive-fetch reads the URI or URI List parameter to find the
source of the fetch it performs.
suit-directive-fetch can target one or more manifests and one or more
payloads. suit-directive-fetch retrieves each component and each
manifest listed in component-index and dependency-index,
respectively.  If component-index or dependency-index is True,
instead of an integer, then all current manifest components/manifests
are fetched.  The current manifest's dependent-components are not
automatically fetched.  In order to pre-fetch these, they MUST be
specified in a component-index integer.
suit-directive-fetch typically takes no arguments unless one is
needed to modify fetch behavior.  If an argument is needed, it must
be wrapped in a bstr and set in suit-parameter-fetch-arguments.
suit-directive-fetch reads the URI parameter to find the source of
the fetch it performs.
The argument to suit-directive-fetch is defined in the following
CDDL.
suit-directive-fetch-uri-list uses the same semantics as suit-
directive-fetch, however it iterates over the suit-parameter-uri-list
to select a URI to fetch from.
suit-directive-copy reads its source from
SUIT_Parameter_Source_Component.
The argument to suit-directive-copy is defined in the following CDDL.
suit-directive-run directs the manifest processor to transfer
execution to the current Component Index.  When this is invoked, the
manifest processor MAY be unloaded and execution continues in the
Component Index.  Arguments provided to Run are forwarded to the
executable code located in Component Index, in an application-
specific way.  For example, this could form the Linux Kernel Command
Line if booting a Linux device.
suit-directive-copy reads its source from suit-parameter-source-
component.
suit-directive-run directs the manifest processor to transfer
execution to the current Component Index.  When this is invoked, the
manifest processor MAY be unloaded and execution continues in the
Component Index.  Arguments are provided to suit-directive-run
through suit-parameter-run-args and are forwarded to the executable
code located in Component Index in an application-specific way.  For
example, this could form the Linux Kernel Command Line if booting a
Linux device.
The argument to suit-directive-run is defined in the following CDDL.
The following CDDL defines the encoding of these events.
The SUIT_Text_Map contains all text descriptions needed for this
manifest.  The text section is typically severable, allowing
manifests to be distributed without the text, since end-nodes do not
require text.  The meaning of each field is described below.
suit-parameter-soft-failure defaults to False when suit-directive-
run-sequence begins.  Its value is discarded when suit-directive-run-
sequence terminates.
When the CoSWID, Text section, or any Command Sequence of the Update
Procedure is made severable, it is moved to the Envelope and replaced
with a SUIT_Digest.  The SUIT_Digest is computed over the entire bstr
enclosing the Manifest element that has been moved to the Envelope.
Each element that is made severable from the Manifest is placed in
the Envelope with an identical key, so that it matches the key of the
corresponding Integrity Check Value.
Each Integrity Check Value covers the corresponding Envelope Element
as described in severable-fields.
Because the manifest can be used by different actors at different
times, some parts of the manifest can be removed or "Severed" without
affecting later stages of the lifecycle.  Severing of information is
achieved by separating that information from the signed container so
that removing it does not affect the signature.  This means that
ensuring integrity of severable parts of the manifest is a
requirement for the signed portion of the manifest.  Severing some
parts makes it possible to discard parts of the manifest that are no
longer necessary.  This is important because it allows the storage
used by the manifest to be greatly reduced.  For example, no text
size limits are needed if text is removed from the manifest prior to
delivery to a constrained device.
Elements are made severable by removing them from the manifest,
encoding them in a bstr, and placing a SUIT_Digest of the bstr in the
manifest so that they can still be authenticated.  The SUIT_Digest
typically consumes 4 bytes more than the size of the raw digest,
therefore elements smaller than (Digest Bits)/8 + 4 SHOULD NOT be
severable.  Elements larger than (Digest Bits)/8 + 4 MAY be
severable, while elements that are much larger than (Digest Bits)/8 +
4 SHOULD be severable.
Because of this, all command sequences in the manifest are encoded in
a bstr so that there is a single code path needed for all command
sequences.
A second model requires an ACL to be presented to the device,
authenticated by a trusted party or stored on the device.  This ACL
grants access rights for specific component IDs or component ID
prefixes to the listed identities or identity groups.  Any identity
may verify an image digest, but fetching into or fetching from a
component ID requires approval from the ACL.
A third model allows a device to provide even more fine-grained
controls: The ACL lists the component ID or component ID prefix that
an identity may use, and also lists the commands that the identity
may use in combination with that component ID.
RFC 8152 RFC8152 provides containers for signature, MAC, and
encryption, but no basic digest container.  The container needed for
a digest requires a type identifier and a container for the raw
digest data.  Some forms of digest may require additional parameters.
These can be added following the digest.  This structure is described
by the following CDDL.
The algorithms listed are sufficient for verifying integrity of
Firmware Updates as of this writing, however this may change over
time.
For some use cases, it is important to provide a sequence that can
fail without terminating an update.  For example, a dual-image XIP
MCU may require an update that can be placed at one of two offsets.
This has two implications, first, the digest of each offset will be
different.  Second, the image fetched for each offset will have a
different URI.  Conditional sequences allow this to be resolved in a
simple way.
The following JSON representation of a manifest demonstrates how this
would be represented.  It assumes that the bootloader and manifest
processor take care of A/B switching and that the manifest is not
aware of this distinction.
In order to create a valid SUIT Manifest document the structure of
the corresponding CBOR message MUST adhere to the following CDDL data
definition.
The following examples demonstrate a small subset of the
functionality of the manifest.  However, despite this, even a simple
manifest processor can execute most of these manifests.
Each example uses SHA256 as the digest function.
Secure boot and compatibility check.
Simultaneous download and installation of payload.
Compatibility test, simultaneous download and installation, and
secure boot.
Compatibility test, simultaneous download and installation, load from
external storage, and secure boot.
Compatibility test, simultaneous download and installation, load and
decompress from external storage, and secure boot.
Compatibility test, download, installation, and secure boot.
Compatibility test, 2 images, simultaneous download and installation,
and secure boot.
IANA is requested to setup a registry group for SUIT elements.
This document is about a manifest format describing and protecting
firmware images and as such it is part of a larger solution for
offering a standardized way of delivering firmware updates to IoT
devices.  A more detailed discussion about security can be found in
the architecture document I-D.ietf-suit-architecture and in I-D.ietf-
suit-information-model.
A second model requires an ACL to be presented to the Recipient,
authenticated by a trusted party or stored on the Recipient.  This
ACL grants access rights for specific component IDs or component ID
prefixes to the listed identities or identity groups.  Any identity
may verify an image digest, but fetching into or fetching from a
component ID requires approval from the ACL.
A third model allows a Recipient to provide even more fine-grained
controls: The ACL lists the component ID or component ID prefix that
an identity may use, and also lists the commands that the identity
may use in combination with that component ID.
RFC 8152 RFC8152 provides containers for signature, MAC, and
encryption, but no basic digest container.  The container needed for
a digest requires a type identifier and a container for the raw
digest data.  Some forms of digest may require additional parameters.
These can be added following the digest.
The SUIT digest is a CBOR List containing two elements: a suit-
digest-algorithm-id and a bstr containing the bytes of the digest.
allocate a CBOR tag for the SUIT Envelope and another for the SUIT
Manifest.
IANA is requested to setup a registry for SUIT manifests.  Several
registries defined in the subsections below need to be created.
This document is about a manifest format describing and protecting
firmware images and as such it is part of a larger solution for
offering a standardized way of delivering firmware updates to IoT
devices.  A detailed security treatment can be found in the
architecture I-D.ietf-suit-architecture and in the information model
I-D.ietf-suit-information-model documents.