Draft: draft-ietf-suit-manifest

Commentary: Extensive review posted here : Other changes not directly related to this review : Remove suit - record due to new draft in SUIT . Add tags for SUIT manifest and envelope
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.
This specification describes the format of a manifest.  A manifest is
a bundle of metadata about code/data obtained by a recipient (chiefly
the firmware for an IoT device), where to find the that code/data,
the devices to which it applies, and cryptographic information
protecting the manifest.  Software updates and Trusted Invocation
both tend to use sequences of common operations, so the manifest
encodes those sequences of operations, rather than declaring the
metadata.
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.
the Firmware Author to reason about releasing a firmware.
the Network Operator to reason about compatibility of a firmware.
the Device Operator to reason about the impact of a firmware.
the Plant Manager to reason about timing and acceptance of
firmware updates.
the device to reason about the authority & authenticity of a
firmware prior to installation.
the device to reason about the applicability of a firmware.
the device to reason about the installation of a firmware.
the device to reason about the authenticity & encoding of a
firmware at boot.
a Firmware Author to reason about releasing a firmware.
a Network Operator to reason about compatibility of a firmware.
a Device Operator to reason about the impact of a firmware.
a Plant Manager to reason about timing and acceptance of firmware
updates.
a device to reason about the authority & authenticity of a
firmware prior to installation.
a device to reason about the applicability of a firmware.
a device to reason about the installation of a firmware.
a device to reason about the authenticity & encoding of a firmware
at boot.
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.
In this document, 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 Trusted Invocation.
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.
While the SUIT manifest is informed by and optimized for firmware
update and Trusted Invocation 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 (TAs) in a Trusted Execution Environment (TEE), as
discussed in I-D.ietf-teep-architecture.
Envelope: A container with the manifest, an authentication wrapper
with cryptographic information protecting the manifest,
authorization information, and severed fields.
Envelope: A container with the manifest, an authentication wrapper
with cryptographic information protecting the manifest,
authorization information, and severable elements (see: TBD).
Trusted Execution: A process by which a system ensures that only
trusted code is executed, for example secure boot.
Trusted Invocation: A process by which a system ensures that only
trusted code is executed, for example secure boot or launching a
Trusted Application.
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.
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.
Update Procedure: A procedure that updates a Recipient by fetching
dependencies and images, and installing them.
Invocation Procedure: A procedure in which a Recipient verifies
dependencies and images, loading images, and invokes one or more
image.
Firmware: Software that is typically changed infrequently, stored
in nonvolatile memory, and small enough to apply to RFC7228 Class
0-2 devices.
Abort: The Manifest Processor immediately halts execution of the
current Procedure.  It creates a Record of an error condition.
Abort: An event in which the Manifest Processor immediately halts
execution of the current Procedure.  It creates a Record of an
error condition.
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.
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 delivered to a constrained device.
If verification and running is implemented in a bootloader, then the
bootloader MUST also verify the signature of the manifest and the
applicability of the manifest in order to implement secure boot
workflows.  The bootloader may add its own authentication, e.g. a
MAC, to the manifest in order to prevent further verifications.
If verification and running is implemented in a bootloader, then the
bootloader MUST also verify the signature of the manifest and the
applicability of the manifest in order to implement secure boot
workflows.  The bootloader may add its own authentication, e.g. a
Message Authentication Code (MAC), to the manifest in order to
prevent further verifications.
Integrity check values for severable fields.
Severable fields (see ovr-severable).
Integrity check values for severable elements.
Severable elements (see ovr-severable).
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.
Delegation Chains allow a Recipient to establish a chain of trust
from a Trust Anchor to the signer of a manifest by validating
delegation claims.  Each delegation claim is a RFC8392 CBOR Web
Tokens (CWTs).  The first claim in each list is signed by a Trust
Anchor.  Each subsequent claim in a list is signed by the public key
claimed in the preceding list element.  The last element in each list
claims a public key that can be used to verify a signature in the
Authentication Block (ovr-auth).
The payload element in each of these COSE elements is a SUIT_Digest
SUIT_Digest.
Each of these objects is used in detached payload mode.  The payload
is the bstr-wrapped SUIT_Digest.
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 needs to be accessed before the manifest is processed.
This metadata can be used to determine which manifest is newest 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, and manifest-reference-uri for
more detail.
See manifest-common, SUIT_Dependency for more detail.
See manifest-common, and SUIT_Dependency for more detail.
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.
Invocation Command Sequences are: System Validation, Image Loading,
and Image Invocation.  A Invocation Procedure is the complete set of
each Invocation Command Sequence, each preceded by the Common Command
Sequence.
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.
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.
Severable Elements are elements of the ovr-envelope that have ovr-
integrity in the ovr-manifest.
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, Concise Software Identifiers (I-D.ietf-sacm-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.
Text is typically a Severable Element (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.
Severable Elements are elements of the Envelope (ovr-envelope) that
have Integrity Check Values (ovr-integrity) in the Manifest (ovr-
manifest).
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, authentic manifest.
If the latest valid, authentic manifest fails, it MAY select the
next latest valid, authentic manifest.
This section describes the behavior of the manifest processor and
focuses primarily on interpreting commands in the manifest.  However,
there are several other important behaviors of the manifest
processor: encoding version detection, rollback protection, and
authenticity verification are chief among these.
Whenever the manifest processor can choose between several
manifests, it MUST select the latest valid, authentic manifest.
If the latest valid, authentic manifest fails, it MAY select the
next latest valid, authentic manifest, according to application-
specific policy.
Unsupported component ID encountered.
Unsupported Component Identifier encountered.
Following these initial tests, the interpreter clears all parameter
storage.  This ensures that the interpreter begins without any leaked
data.
Selecting an older manifest in the event of failure of the latest
valid manifest is a robustness mechanism that is necessary for
supporting the requirements in I-D.ietf-suit-architecture, section
Trusted Execution Environments MAY require a failure to invoke a new
installation, rather than a rollback approach.  See I-D.ietf-suit-
information-model, Section 4.2.1 for more discussion on the security
considerations that apply to rollback.
Following these initial tests, the manifest processor clears all
parameter storage.  This ensures that the manifest processor begins
without any leaked data.
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.
When validating authenticity of manifests, the manifest processor 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.
Once a valid, authentic manifest has been selected, the interpreter
MUST examine the component list and verify that its maximum number of
components is not exceeded and that each listed component ID is
supported.
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.
The interpreter SHOULD check that the common section contains at
least one vendor ID check and at least one class ID check.
If the manifest contains more than one component, each command
sequence MUST begin with a Set Current Component command.
Once a valid, authentic manifest has been selected, the manifest
processor MUST examine the component list and verify that its maximum
number of components is not exceeded and that each listed component
is supported.
For each listed component, the manifest processor MUST provide
storage for the supported parameters.  If the manifest processor 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.
The manifest processor SHOULD check that the common sequence contains
at least Check Vendor Identifier command and at least one Check Class
Identifier command.
Because the common sequence contains Check Vendor Identifier and
Check Class Identifier command(s), no custom commands are permitted
in the common sequence.  This ensures that any custom commands are
only executed by devices that understand them.
If the manifest contains more than one component and/or dependency,
each command sequence MUST begin with a Set Component Index or Set
Dependency Index command.
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.
specify a digest and a payload for every Component in the
Component Set.
The single dependent manifest is sometimes called a 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.
The guidelines in Creating Manifests (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 and the following
directives: 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.
Executing a secure boot MUST either result in an error, or a
booted system.
Executing a Trusted Invocation MUST either result in an error, or
an invoked image.
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.
The heart of the manifest is the list of commands, which are
processed by a Manifest Processor-a form of interpreter.  This
Manifest Processor 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.
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, but referenced in commands by Component Index; Component
Identifiers are arrays of binary strings and a Component Index is an
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 (suit-parameter-soft-failure) is set when a
Condition reports failure.
As a result, Set Component Index is described as current :=
components[arg].  The actual operation performed for Set Component
Index is described by the following pseudocode, however, because of
the definition of current (above), these are semantically equivalent.
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.
Integers MUST always be supported by Set Component Index and Set
Dependency Index.  Arrays of integers MUST be supported by Set
Component Index and Set Dependency Index if the Recipient supports 3
or more components or 3 or more dependencies, respectively.  True
MUST be supported by Set Component Index and Set Dependency Index if
the Recipient supports 2 or more components or 2 or more
dependencies, respectively.  Each of these operates on the list of
components or list of dependencies declared in the manifest.
Integer indices are the default case as described in the previous
section.  An array of integers represents a list of the components
(Set Component Index) or a list of dependencies (Set Dependency
Index) to which each subsequent command applies.  The value True
replaces the list of component indices or dependency indices with the
full list of components or the full list of dependencies,
respectively, as defined in the manifest.
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, nor are they invoked with array indices.
They are only invoked with integer indices.  The interpreter loops
over the whole sequence, setting the Component Index or Dependency
Index to each index in turn.
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.
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 issue
each or every command concurrently until the Strict Order parameter
is returned to True or the Command Sequence ends.  Then, it waits for
all issued commands to complete 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 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.
To perform more useful parallel operations, a manifest author may
collect sequences of commands in a Run Sequence command.  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 or Set
Dependency Index directive with the following exception: when the
index is either True or an array of indices, the Set Component Index
or Set Dependency Index is implied.  Any further Set Component Index
directives MUST cause an Abort.  This allows the interpreter that
issues Run Sequence commands to check that the first element is
correct, then issue the sequence to a parallel execution context to
handle the remainder of the sequence.
If the specified dependency does not contain the current section,
Process Dependency succeeds immediately.
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 a system has multiple security domains, each domain might
require independent verification of authenticity or security
policies.  Security domains might be divided by separation technology
such as Arm TrustZone, Intel SGX, or another TEE technology.
Security domains might 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 might 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 (see I-D.ietf-teep-
architecture), a manifest processor might be required in each.  The
first manifest processor is the normal manifest processor as
described for the Recipient in command-behavior.  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.
This mechanism ensures that the two or more manifest processors do
not need to trust each other, except in a very limited case.  When
parameter setting across security domains is used, it must be very
carefully considered.  Only parameters that do not have an effect on
security properties should be allowed.  The dependency manifest MAY
control which parameters are allowed to be set by using the Override
Parameters directive.  The second manifest processor MAY also control
which parameters may be set by the first manifest processor by means
of an ACL that lists the allowed parameters.  For example, a URI may
be set by a dependent without a substantial impact on the security
properties of the manifest.
NOTE: On systems that support only a single component, Set Current
Component has no effect and can be omitted.
This section details a set of templates for creating manifests.
These templates explain which parameters, commands, and orders of
commands are necessary to achieve a stated goal.
NOTE: On systems that support only a single component and no
dependencies, Set Component Index has no effect and can be omitted.
The goal of the compatibility check template ensure that Recipients
only install compatible images.
This template performs a secure boot operation.
The goal of the Trusted Invocation template is to ensure that only
authorized code is invoked; such as in Secure Boot or when a Trusted
Application is loaded into a TEE.
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 goal of the Component Download template is to acquire and store
an image.
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.
Optionally, the Set Parameters directive in the install sequence MAY
also contain Encryption Info (see suit-parameter-encryption-info),
Compression Info (see suit-parameter-compression-info), or Unpack
Info (see suit-parameter-unpack-info) to perform simultaneous
download and decryption, decompression, or unpacking, respectively.
The goal of the Install template is to use an image already stored in
an identified component to copy into a second component.
This template is typically used with the Component Download template,
however a modification to that template is required: the Component
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 goal of the Install and Transform template is to use an image
already stored in an identified component to decompress, decrypt, or
unpack at time of installation.
This template is typically used with the Component Download template,
however a modification to that template is required: all Component
Download operations are moved from the common sequence and the
install sequence to the fetch sequence.  The Component Download
template targets a download component identifier, while the Install
and Transform template uses an install component identifier.  In-
place unpacking, decompression, and decryption is complex and
vulnerable to power failure.  Therefore, these identifiers SHOULD be
different; in-place installation SHOULD NOT be used without
establishing guarantees of robustness to power failure.
The goal of the Integrated Payload template is to install a payload
that is included in the manifest envelope.  It is identical to the
Component Download template (firmware-download-template) except that
it places an added restriction on the URI passed to the Set
Parameters directive.
An implementer 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.
This directive loads an firmware image from external storage.
The goal of the Load from Nonvolatile Storage template is to load an
image from a non-volatile component into a volatile component, for
example loading a firmware image from external Flash into RAM.
The goal of the Load & Decompress from Nonvolatile Storage template
is to load an image from a non-volatile component into a volatile
component, decompressing on-the-fly, for example loading a firmware
image from external Flash into RAM.
This template can be modified for decryption or unpacking by adding
Decryption Info or Unpack Info to the Set Parameters directive.
The goal of the Dependency template is to obtain, verify, and process
a dependency manifest as appropriate.
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.
An implementer 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.
To use an encrypted manifest, create a plaintext dependent, and add
the encrypted manifest as a dependency.  The dependent can include
very little information.
The goal of the Encrypted Manifest template is to fetch and decrypt a
manifest so that it can be used as a dependency.  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.
A plaintext manifest and its encrypted dependency may also form a
composite manifest (composite-manifests).
The goal of the A/B Image Template is to acquire, validate, and
invoke one of two images, based on a test.
If Trusted Invocation (template-secure-boot) is used, only the run
sequence is added to this template, since the common sequence is
populated by this template.
NOTE: Any test can be used to select between images, Check Offset
Condition is used in this template because it is a typical test for
execute-in-place devices.
Wherever enumerations are used, they are started at 1.  This allows
detection of several common software errors that are caused by
uninitialised variables.  Positive numbers in enumerations are
reserved for IANA registration.  Negative numbers are used to
identify application-specific implementations.
Wherever enumerations are used, they are started at 1.  This allows
detection of several common software errors that are caused by
uninitialized variables.  Positive numbers in enumerations are
reserved for IANA registration.  Negative numbers are used to
identify application-specific values, as described in iana.
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.
The suit-delegation element 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 a 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 provisioning of Trust Anchors or
intermediary keys.
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 an empty list.
The suit-authentication-wrapper contains a list containing a
SUIT_Digest and 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 a list containing only the SUIT_Digest.
A signing application MUST verify the suit-manifest element against
the SUIT_Digest prior to signing.
A template for using an encrypted manifest is covered in template-
encrypted-manifest.
A template for using an encrypted manifest is covered in Encrypted
Manifest Template (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 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 element.  Severable
elements 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-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.
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.  For
convenience, an implementer MAY use a UTC timestamp in seconds as the
sequence number. suit-manifest-sequence-number is REQUIRED to
implement.
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.
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 suit-common (manifest-common) or the suit-
common of a dependency.
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-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 free text expression that is representative of the version
constraints placed on the dependency.  This text SHOULD be expressive
enough that a device operator can be expected to understand the
dependency.  This is a free text field and there are no specific
formatting rules.
By way of example only, 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 (CoSWID) as
defined in I-D.ietf-sacm-coswid.  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 typically requires no processing by the Recipient.
However all Recipients MUST NOT fail if a suit-coswid is present.
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.
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 command is required by more than one Command
Sequence, placing that parameter or commamd in 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, but 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-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.
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 for
Recipients to implement.
A component is a unit of code or data that can be targeted by an
update.  To facilitate composite devices, components are identified
by a list of CBOR byte strings, which allows construction of
hierarchical component structures.  A dependency MAY declare a prefix
to the components defined in the dependency manifest.  Components are
identified by Component Identifiers, but referenced in commands by
Component Index; Component Identifiers are arrays of binary strings
and a Component Index is an index into the array of Component
Identifiers.
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 condition is a command code identifier, followed by a reporting-
policy.
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 invocable manifest
or the "process dependencies" directive for any dependents of the
invocable manifest. suit-run is OPTIONAL to implement.
Goals 1,2,3 form the Update Procedure.  Goals 4,5,6 form the
Invocation Procedure.
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.
Many conditions and directives apply to a given component, and these
generally grouped together.  Therefore, a special command to set the
current component index is provided with a matching command to set
the current dependency index.  This index is a numeric index into the
component ID tables defined at the beginning of the document.  For
the purpose of setting the index, the two component ID tables are
considered to be concatenated together.
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.
Reporting policies provide a hint to the manifest processor of
whether to add the success or failure of a command to any report that
it generates.
Many conditions and directives apply to a given component, and these
generally grouped together.  Therefore, a special command to set the
current component index is provided with a matching command to set
the current dependency index.  This index is a numeric index into the
Component Identifier tables defined at the beginning of the manifest.
For the purpose of setting the index, the two Component Identifier
tables are considered to be concatenated together.
To facilitate optional conditions, a special directive, suit-
directive-try-each (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/invocation, but a parameter is provided to override
this behavior.  See suit-parameter-soft-failure (suit-parameter-soft-
failure).
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.
At the completion of each command, a Manifest Processor MAY forward
information about the command to a Reporting Engine, which is
responsible for reporting boot or update status to a third party.
The Reporting Engine is entirely implementation-defined, the
reporting policy simply facilitates the Reporting Engine's interface
to the SUIT Manifest Processor.
Together, these elements are called a Record.  A group of Records is
a Report.
If the component index is set to True or an array 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 or the component index array.  If the dependency
index is set to True or an array 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 or the component index array, respectively.
This specification does not define a particular format of Records or
Reports.  This specification only defines hints to the Reporting
Engine for which Records it should aggregate into the Report.  The
Reporting Engine MAY choose to ignore these hints and apply its own
policy instead.
When used in a Invocation Procedure, the report MAY form the basis of
an attestation report.  When used in an Update Process, the report
MAY form the basis for one or more log entries.
Identifiers are used for compatibility checks.  They MUST NOT be used
as assertions of identity.  They are evaluated by identifier-
conditions.
Identifiers are used for compatibility checks.  They MUST NOT be used
as assertions of identity.  They are evaluated by identifier
conditions (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.
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.
Private Enterprise Numbers are encoded as a relative OID, according
to the definition in I-D.ietf-cbor-tags-oid.  All PENs are relative
to the IANA PEN: 1.3.6.1.4.1.
A fingerprint computed over the component itself, encoded in the
SUIT_Digest SUIT_Digest structure.  The SUIT_Digest is wrapped in a
bstr, as required in secparameters.
An expiry date for the use of the manifest encoded as the positive
integer number of seconds since 1970-01-01.  Implementations that use
this parameter MUST use a 64-bit internal representation of the
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_Compression_Info defines any information that is required for a
Recipient to perform decompression operations.  SUIT_Compression_Info
is a map containing this data.  The only element defined for the map
in this specification is the suit-compression-algorithm.  This
document defines the following suit-compression-algorithm's: ZLIB
RFC1950, Brotli RFC7932, and ZSTD I-D.kucherawy-rfc8478bis.
Additional suit-compression-algorithm's can be registered through the
IANA-maintained registry.  If such a format requires more data than
an algorithm identifier, one or more new elements MUST be introduced
by specifying an element for SUIT_Compression_Info-extensions.
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.
A URI from which to fetch a resource, encoded as a text string.  CBOR
Tag 32 is not used because the meaning of the text string is
unambiguous in this context.
This parameter sets the source component to be used with either suit-
directive-copy (suit-directive-copy) or with suit-directive-swap
(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 (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 (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 (suit-condition-update-authorized) 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.
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.
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 (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.
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.
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.
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.
Indicates a list of URIs from which to fetch a resource.  The URI
list is encoded as a list of text string, in priority order.  CBOR
Tag 32 is not used because the meaning of the text string is
unambiguous in this context.  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 (suit-directive-fetch-uri-list).
An implementation-defined set of arguments to suit-directive-fetch
(suit-directive-fetch).  Arguments are encoded in a bstr.
The Strict Order Parameter allows a manifest to govern when
directives can be executed out-of-order.  This allows for systems
that have a sensitivity to order of updates to choose the order in
which they are executed.  It also allows for more advanced systems to
parallelize their handling of updates.  Strict Order defaults to
True.  It MAY be set to False when the order of operations does not
matter.  When arriving at the end of a command sequence, ALL commands
MUST have completed, regardless of the state of
SUIT_Parameter_Strict_Order.  If SUIT_Parameter_Strict_Order is
returned to True, ALL preceding commands MUST complete before the
next command is executed.
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.
The Strict Order Parameter allows a manifest to govern when
directives can be executed out-of-order.  This allows for systems
that have a sensitivity to order of updates to choose the order in
which they are executed.  It also allows for more advanced systems to
parallelize their handling of updates.  Strict Order defaults to
True.  It MAY be set to False when the order of operations does not
matter.  When arriving at the end of a command sequence, ALL commands
MUST have completed, regardless of the state of
SUIT_Parameter_Strict_Order.  SUIT_Process_Dependency must preserve
and restore the state of SUIT_Parameter_Strict_Order.  If
SUIT_Parameter_Strict_Order is returned to True, ALL preceding
commands MUST complete before the next command is executed.
When executing a command sequence inside suit-directive-try-each
(suit-directive-try-each) or suit-directive-run-sequence (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.
This parameter is an extension point for any proprietary, application
specific conditions and directives.
This parameter is an extension point for any proprietary, application
specific conditions and directives.  It MUST NOT be used in the
common sequence.  This effectively scopes each custom command to a
particular Vendor Identifier/Class Identifier pair.
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.
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 (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 definition by the author of a manifest
processor.  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.
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.  Each component MAY match more than one identifier.  Care
is needed to ensure that manifests correctly identify their targets
using these conditions.  Using only a generic class ID for a device-
specific firmware could result in matching devices that are not
compatible.
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.
Verify that the current component matches the suit-parameter-image-
digest (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 (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 parameter (suit-parameter-use-
before), which must have already been set as a parameter, encoded as
seconds after 1970-01-01 00:00:00 UTC.  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 (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.
SUIT_Condition_Custom describes any proprietary, application specific
condition.  This is encoded as a negative integer, chosen by the
firmware developer.  If additional information must be provided to
the condition, it should be encoded in a custom parameter (a nint) as
described in secparameters.  SUIT_Condition_Custom is OPTIONAL to
implement.
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 (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 (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.
Unconditionally fail.  This operation is typically used in
conjunction with suit-directive-try-each (suit-directive-try-each).
suit-condition-custom describes any proprietary, application specific
condition.  This is encoded as a negative integer, chosen by the
firmware developer.  If additional information must be provided to
the condition, it should be encoded in a custom parameter (a nint) as
described in secparameters.  SUIT_Condition_Custom is OPTIONAL to
implement.
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.
When a Recipient executes a Directive, it MUST report a result code.
If the Directive reports failure, then the current Command Sequence
MUST be terminated.
If the following commands apply to ONE component, an unsigned integer
index into the component list is used.  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 more than
one, but not all components, then an array of unsigned integer
indices into the component list is used.  See index-true for more
details.
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.
Set Dependency Index defines the manifest to which successive
directives and conditions will apply.  The supplied argument MUST be
either a boolean or an unsigned integer index into the dependencies.
If the following directives apply to ALL dependencies, then the
boolean value "True" is used instead of an index.  If the following
directives apply to NO dependencies, then the boolean value "False"
is used.  When suit-directive-set-component-index is used, suit-
directive-set-dependency-index = False is implied.  When suit-
directive-set-dependency-index is used, suit-directive-set-component-
index = False is implied.
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.
Set Dependency Index defines the manifest to which successive
directives and conditions will apply.  The supplied argument MUST be
either a boolean or an unsigned integer index into the dependencies,
or an array of unsigned integer indices into the list of
dependencies.  If the following directives apply to ALL dependencies,
then the boolean value "True" is used instead of an index.  If the
following directives apply to NO dependencies, then the boolean value
"False" is used.  When suit-directive-set-component-index is used,
suit-directive-set-dependency-index = False is implied.  When suit-
directive-set-dependency-index is used, suit-directive-set-component-
index = False is implied.
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, the Manifest
Processor MUST execute the command once for each possible dependency
index, ensuring that the command receives the parameters
corresponding to that dependency index.  If the dependency index is
set to an array of unsigned integers, then the Manifest Processor
MUST execute the command once for each listed dependency index,
ensuring that the command receives the parameters corresponding to
that dependency index.
See index-true for more details.
Unconditionally fail.  This operation is typically used in
conjunction with suit-directive-try-each.
This command runs several SUIT_Command_Sequence, one after another,
in a strict order.  Use this command to implement a "try/catch-try/
catch" sequence.  Manifest processors MAY implement this command.
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.
This command runs several SUIT_Command_Sequence instances, one after
another, in a strict order.  Use this command to implement a "try/
catch-try/catch" sequence.  Manifest processors MAY implement this
command.
suit-parameter-soft-failure (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 the current dependency is False, this directive has no effect.  If
the current dependency is True, then this directive applies to all
dependencies.  If the current section is "common," this directive
MUST have no effect.
If the current dependency is False, this directive has no effect.  If
the current dependency is True, then this directive applies to all
dependencies.  If the current section is "common," then the command
sequence MUST be terminated with an error.
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 instructs the manifest processor to obtain one or
more payloads, as specified by the component index. suit-directive-
copy retrieves each component listed in component-index,
respectively.  If component-index is True, instead of an integer,
then all current manifest components are copied.  The current
manifest's dependent-components are not automatically copied.  In
order to copy these, they MUST be specified in a component-index
integer.
suit-directive-fetch-uri-list uses the same semantics as suit-
directive-fetch (suit-directive-fetch), except that it iterates over
the URI List (suit-parameter-uri-list) to select a URI to fetch from.
suit-directive-copy instructs the manifest processor to obtain one or
more payloads, as specified by the component index.  As described in
index-true component index may be a single integer, a list of
integers, or True. suit-directive-copy retrieves each component
specified by the current component-index, respectively.  The current
manifest's dependent-components are not automatically copied.  In
order to copy these, they MUST be specified in a component-index
integer.
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.
suit-directive-copy reads its source from suit-parameter-source-
component (suit-parameter-source-component).
If either the source component parameter or the source component
itself is absent, this command fails.
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-arguments (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.
suit-parameter-soft-failure defaults to False when suit-directive-
run-sequence begins.  Its value is discarded when suit-directive-run-
sequence terminates.
suit-directive-swap instructs the manifest processor to move the
source to the destination and the destination to the source
simultaneously.  Swap has nearly identical semantics to suit-
directive-copy except that suit-directive-swap replaces the source
with the current contents of the destination in an application-
defined way.  If SUIT_Parameter_Compression_Info or
SUIT_Parameter_Encryption_Info are present, they MUST be handled in a
symmetric way, so that the source is decompressed into the
destination and the destination is compressed into the source.  The
source is decrypted into the destination and the destination is
encrypted into the source. suit-directive-swap is OPTIONAL to
implement.
suit-parameter-soft-failure (suit-parameter-soft-failure) defaults to
False when suit-directive-run-sequence begins.  Its value is
discarded when suit-directive-run-sequence terminates.
suit-directive-swap instructs the manifest processor to move the
source to the destination and the destination to the source
simultaneously.  Swap has nearly identical semantics to suit-
directive-copy except that suit-directive-swap replaces the source
with the current contents of the destination in an application-
defined way.  As with suit-directive-copy, if the source component is
missing, this command fails.
If SUIT_Parameter_Compression_Info or SUIT_Parameter_Encryption_Info
are present, they MUST be handled in a symmetric way, so that the
source is decompressed into the destination and the destination is
compressed into the source.  The source is decrypted into the
destination and the destination is encrypted into the source. suit-
directive-swap is OPTIONAL to implement.
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.
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.  The keys for the envelope elements have the same
values as the keys for the manifest elements.
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.
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
Identifier prefixes to the listed identities or identity groups.  Any
identity can verify an image digest, but fetching into or fetching
from a Component Identifier requires approval from the ACL.
A third model allows a Recipient to provide even more fine-grained
controls: The ACL lists the Component Identifier or Component
Identifier prefix that an identity can use, and also lists the
commands and parameters that the identity can use in combination with
that Component Identifier.
allocate a CBOR tag for the SUIT Envelope and another for the SUIT
Manifest.
allocate CBOR tag 48 in the CBOR Tags registry for the SUIT
Envelope.
allocate CBOR tag 480 in the CBOR Tags registry for the SUIT
Manifest.
allocate media type application/suit-envelope in the Media Types
registry.
setup several registries as described below.
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.