idnits 2.17.1 draft-ietf-suit-manifest-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** There are 62 instances of too long lines in the document, the longest one being 22 characters in excess of 72. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document seems to contain a disclaimer for pre-RFC5378 work, but was first submitted on or after 10 November 2008. The disclaimer is usually necessary only for documents that revise or obsolete older RFCs, and that take significant amounts of text from those RFCs. If you can contact all authors of the source material and they are willing to grant the BCP78 rights to the IETF Trust, you can and should remove the disclaimer. Otherwise, the disclaimer is needed and you can ignore this comment. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (October 28, 2019) is 1642 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '1' on line 3415 -- Looks like a reference, but probably isn't: '2' on line 3417 -- Looks like a reference, but probably isn't: '3' on line 3419 == Missing Reference: '-1' is mentioned on line 1220, but not defined == Missing Reference: '-2' is mentioned on line 1222, but not defined == Missing Reference: '-3' is mentioned on line 1226, but not defined -- Looks like a reference, but probably isn't: '4' on line 1226 == Unused Reference: 'RFC6920' is defined on line 3408, but no explicit reference was found in the text ** Obsolete normative reference: RFC 8152 (Obsoleted by RFC 9052, RFC 9053) Summary: 2 errors (**), 0 flaws (~~), 6 warnings (==), 5 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 SUIT B. Moran 3 Internet-Draft H. Tschofenig 4 Intended status: Informational Arm Limited 5 Expires: April 30, 2020 H. Birkholz 6 Fraunhofer SIT 7 October 28, 2019 9 SUIT CBOR manifest serialisation format 10 draft-ietf-suit-manifest-01 12 Abstract 14 This specification describes the format of a manifest. A manifest is 15 a bundle of metadata about the firmware for an IoT device, where to 16 find the firmware, the devices to which it applies, and cryptographic 17 information protecting the manifest. 19 Status of This Memo 21 This Internet-Draft is submitted in full conformance with the 22 provisions of BCP 78 and BCP 79. 24 Internet-Drafts are working documents of the Internet Engineering 25 Task Force (IETF). Note that other groups may also distribute 26 working documents as Internet-Drafts. The list of current Internet- 27 Drafts is at https://datatracker.ietf.org/drafts/current/. 29 Internet-Drafts are draft documents valid for a maximum of six months 30 and may be updated, replaced, or obsoleted by other documents at any 31 time. It is inappropriate to use Internet-Drafts as reference 32 material or to cite them other than as "work in progress." 34 This Internet-Draft will expire on April 30, 2020. 36 Copyright Notice 38 Copyright (c) 2019 IETF Trust and the persons identified as the 39 document authors. All rights reserved. 41 This document is subject to BCP 78 and the IETF Trust's Legal 42 Provisions Relating to IETF Documents 43 (https://trustee.ietf.org/license-info) in effect on the date of 44 publication of this document. Please review these documents 45 carefully, as they describe your rights and restrictions with respect 46 to this document. Code Components extracted from this document must 47 include Simplified BSD License text as described in Section 4.e of 48 the Trust Legal Provisions and are provided without warranty as 49 described in the Simplified BSD License. 51 This document may contain material from IETF Documents or IETF 52 Contributions published or made publicly available before November 53 10, 2008. The person(s) controlling the copyright in some of this 54 material may not have granted the IETF Trust the right to allow 55 modifications of such material outside the IETF Standards Process. 56 Without obtaining an adequate license from the person(s) controlling 57 the copyright in such materials, this document may not be modified 58 outside the IETF Standards Process, and derivative works of it may 59 not be created outside the IETF Standards Process, except to format 60 it for publication as an RFC or to translate it into languages other 61 than English. 63 Table of Contents 65 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 66 2. Conventions and Terminology . . . . . . . . . . . . . . . . . 4 67 3. Distributing firmware . . . . . . . . . . . . . . . . . . . . 5 68 4. Workflow of a device applying a firmware update . . . . . . . 5 69 5. SUIT manifest goals . . . . . . . . . . . . . . . . . . . . . 6 70 6. SUIT manifest design overview . . . . . . . . . . . . . . . . 7 71 6.1. Manifest Design Evaluation . . . . . . . . . . . . . . . 8 72 6.2. Severable Elements . . . . . . . . . . . . . . . . . . . 9 73 6.3. Conventions . . . . . . . . . . . . . . . . . . . . . . . 9 74 6.4. Payloads . . . . . . . . . . . . . . . . . . . . . . . . 9 75 7. Manifest Structure . . . . . . . . . . . . . . . . . . . . . 10 76 7.1. Outer wrapper . . . . . . . . . . . . . . . . . . . . . . 11 77 7.2. Manifest . . . . . . . . . . . . . . . . . . . . . . . . 13 78 7.3. SUIT_Dependency . . . . . . . . . . . . . . . . . . . . . 16 79 7.4. SUIT_Component_Reference . . . . . . . . . . . . . . . . 17 80 7.5. Manifest Parameters . . . . . . . . . . . . . . . . . . . 17 81 7.5.1. SUIT_Parameter_Strict_Order . . . . . . . . . . . . . 19 82 7.5.2. SUIT_Parameter_Coerce_Condition_Failure . . . . . . . 20 83 7.6. SUIT_Parameter_Encryption_Info . . . . . . . . . . . . . 20 84 7.7. SUIT_Parameter_Compression_Info . . . . . . . . . . . . . 20 85 7.8. SUIT_Parameter_Unpack_Info . . . . . . . . . . . . . . . 20 86 7.9. SUIT_Parameters CDDL . . . . . . . . . . . . . . . . . . 21 87 7.10. SUIT_Command_Sequence . . . . . . . . . . . . . . . . . . 22 88 7.11. SUIT_Condition . . . . . . . . . . . . . . . . . . . . . 24 89 7.11.1. Identifier Conditions . . . . . . . . . . . . . . . 25 90 7.11.2. suit-condition-image-match . . . . . . . . . . . . . 25 91 7.11.3. suit-condition-image-not-match . . . . . . . . . . . 25 92 7.11.4. suit-condition-use-before . . . . . . . . . . . . . 25 93 7.11.5. suit-condition-minimum-battery . . . . . . . . . . . 25 94 7.11.6. suit-condition-update-authorised . . . . . . . . . . 26 95 7.11.7. suit-condition-version . . . . . . . . . . . . . . . 26 96 7.11.8. SUIT_Condition_Custom . . . . . . . . . . . . . . . 27 97 7.11.9. Identifiers . . . . . . . . . . . . . . . . . . . . 27 98 7.11.10. SUIT_Condition CDDL . . . . . . . . . . . . . . . . 29 99 7.12. SUIT_Directive . . . . . . . . . . . . . . . . . . . . . 29 100 7.12.1. suit-directive-set-component-index . . . . . . . . . 30 101 7.12.2. suit-directive-set-dependency-index . . . . . . . . 31 102 7.12.3. suit-directive-abort . . . . . . . . . . . . . . . . 31 103 7.12.4. suit-directive-run-sequence . . . . . . . . . . . . 31 104 7.12.5. suit-directive-try-each . . . . . . . . . . . . . . 32 105 7.12.6. suit-directive-process-dependency . . . . . . . . . 32 106 7.12.7. suit-directive-set-parameters . . . . . . . . . . . 33 107 7.12.8. suit-directive-override-parameters . . . . . . . . . 33 108 7.12.9. suit-directive-fetch . . . . . . . . . . . . . . . . 34 109 7.12.10. suit-directive-copy . . . . . . . . . . . . . . . . 34 110 7.12.11. suit-directive-swap . . . . . . . . . . . . . . . . 35 111 7.12.12. suit-directive-run . . . . . . . . . . . . . . . . . 35 112 7.12.13. suit-directive-wait . . . . . . . . . . . . . . . . 36 113 7.12.14. SUIT_Directive CDDL . . . . . . . . . . . . . . . . 37 114 8. Dependency processing . . . . . . . . . . . . . . . . . . . . 39 115 9. Access Control Lists . . . . . . . . . . . . . . . . . . . . 40 116 10. SUIT digest container . . . . . . . . . . . . . . . . . . . . 40 117 11. Creating conditional sequences . . . . . . . . . . . . . . . 41 118 12. Full CDDL . . . . . . . . . . . . . . . . . . . . . . . . . . 43 119 13. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 49 120 13.1. Example 0: . . . . . . . . . . . . . . . . . . . . . . . 50 121 13.2. Example 1: . . . . . . . . . . . . . . . . . . . . . . . 52 122 13.3. Example 2: . . . . . . . . . . . . . . . . . . . . . . . 54 123 13.4. Example 3: . . . . . . . . . . . . . . . . . . . . . . . 57 124 13.5. Example 4: . . . . . . . . . . . . . . . . . . . . . . . 61 125 13.6. Example 5: . . . . . . . . . . . . . . . . . . . . . . . 65 126 13.7. Example 6: . . . . . . . . . . . . . . . . . . . . . . . 69 127 14. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 73 128 15. Security Considerations . . . . . . . . . . . . . . . . . . . 73 129 16. Mailing List Information . . . . . . . . . . . . . . . . . . 74 130 17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 74 131 18. References . . . . . . . . . . . . . . . . . . . . . . . . . 74 132 18.1. Normative References . . . . . . . . . . . . . . . . . . 74 133 18.2. Informative References . . . . . . . . . . . . . . . . . 75 134 18.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 75 135 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 76 137 1. Introduction 139 A firmware update mechanism is an essential security feature for IoT 140 devices to deal with vulnerabilities. While the transport of 141 firmware images to the devices themselves is important there are 142 already various techniques available, such as the Lightweight 143 Machine-to-Machine (LwM2M) protocol offering device management of IoT 144 devices. Equally important is the inclusion of meta-data about the 145 conveyed firmware image (in the form of a manifest) and the use of 146 end-to-end security protection to detect modifications and 147 (optionally) to make reverse engineering more difficult. End-to-end 148 security allows the author, who builds the firmware image, to be sure 149 that no other party (including potential adversaries) can install 150 firmware updates on IoT devices without adequate privileges. This 151 authorization process is ensured by the use of dedicated symmetric or 152 asymmetric keys installed on the IoT device: for use cases where only 153 integrity protection is required it is sufficient to install a trust 154 anchor on the IoT device. For confidentiality protected firmware 155 images it is additionally required to install either one or multiple 156 symmetric or asymmetric keys on the IoT device. Starting security 157 protection at the author is a risk mitigation technique so firmware 158 images and manifests can be stored on untrusted respositories; it 159 also reduces the scope of a compromise of any repository or 160 intermediate system to be no worse than a denial of service. 162 It is assumed that the reader is familiar with the high-level 163 firmware update architecture [Architecture]. 165 The SUIT manifest is heavily optimised for consumption by constrained 166 devices. This means that it is not constructed as a conventional 167 descriptive document. Instead, of describing what an update IS, it 168 describes what a recipient should DO. 170 While the SUIT manifest is informed by and optimised for firmware 171 update use cases, there is nothing in the [Information] that 172 restricts its use to only firmware use cases. Software update and 173 delivery of arbitrary data can equally be managed by SUIT-based 174 metadata. 176 2. Conventions and Terminology 178 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 179 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 180 "OPTIONAL" in this document are to be interpreted as described in 181 BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all 182 capitals, as shown here. 184 - SUIT: Sofware Update for the Internet of Things, the IETF working 185 group for this standard. 187 - Payload: A piece of information to be delivered. Typically 188 Firmware for the purposes of SUIT. 190 - Resource: A piece of information that is used to construct a 191 payload. 193 - Manifest: A piece of information that describes one or more 194 payloads, one or more resources, and the processors needed to 195 transform resources into payloads. 197 - Update: One or more manifests that describe one or more payloads. 199 - Update Authority: The owner of a cryptographic key used to sign 200 updates, trusted by recipient devices. 202 - Recipient: The system, typically an IoT device, that receives a 203 manifest. 205 - Condition: A test for a property of the Recipient or its 206 components. 208 - Directive: An action for the Recipient to perform. 210 - Command: A Condition or a Directive. 212 - Trusted Execution: A process by which a system ensures that only 213 trusted code is executed, for example secure boot. 215 3. Distributing firmware 217 Distributing firmware in a multi-party environment is a difficult 218 operation. Each party requires a different subset of data. Some 219 data may not be accessible to all parties. Multiple signatures may 220 be required from parties with different authorities. This topic is 221 covered in more depth in [Architecture]. 223 4. Workflow of a device applying a firmware update 225 The manifest is designed to work with a pull parser, where each 226 section of the manifest is used in sequence. The expected workflow 227 for a device installing an update can be broken down into 5 steps: 229 1. Verify the signature of the manifest 231 2. Verify the applicability of the manifest 233 3. Resolve dependencies 235 4. Fetch payload(s) 237 5. Install payload(s) 239 When installation is complete, similar information can be used for 240 validating and running images in a further three steps: 242 1. Verify image(s) 244 2. Load image(s) 246 3. Run image(s) 248 When multiple manifests are used for an update, each manifest's steps 249 occur in a lockstep fashion; all manifests have dependency resolution 250 performed before any manifest performs a payload fetch, etc. 252 5. SUIT manifest goals 254 The manifest described in this document is intended to meet several 255 goals, as described below. 257 1. Meet the requirements defined in [Information]. 259 2. Simple to parse on a constrained node 261 3. Simple to process on a constrained node 263 4. Compact encoding 265 5. Comprehensible by an intermediate system 267 6. Expressive enough to enable advanced use cases on advanced nodes 269 7. Extensible 271 The SUIT manifest can be used for a variety of purposes throughout 272 its lifecycle. The manifest allows: 274 1. the Firmware Author to reason about releasing a firmware. 276 2. the Network Operator to reason about compatibility of a firmware. 278 3. the Device Operator to reason about the impact of a firmware. 280 4. the Device Operator to manage distribution of firmware to 281 devices. 283 5. the Plant Manager to reason about timing and acceptance of 284 firmware updates. 286 6. the device to reason about the authority & authenticity of a 287 firmware prior to installation. 289 7. the device to reason about the applicability of a firmware. 291 8. the device to reason about the installation of a firmware. 293 9. the device to reason about the authenticity & encoding of a 294 firmware at boot. 296 Each of these uses happens at a different stage of the manifest 297 lifecycle, so each has different requirements. 299 6. SUIT manifest design overview 301 In order to provide flexible behaviour to constrained devices, while 302 still allowing more powerful devices to use their full capabilities, 303 the SUIT manifest encodes the required behaviour of a Recipient 304 device. Behaviour is encoded as a specialised byte code, contained 305 in a CBOR list. This promotes a flat encoding, which simplifies the 306 parser. The information encoded by this byte code closely matches 307 the operations that a device will perform, which promotes ease of 308 processing. The core operations used by most update and trusted 309 execution operations are represented in the byte code. The byte code 310 can be extended by registering new operations. 312 The specialised byte code approach gives benefits equivalent to those 313 provided by a scripting language or conventional byte code, with two 314 substantial differences. First, the language is extremely high 315 level, consisting of only the operations that a device may perform 316 during update and trusted execution of a firmware image. Second, the 317 language specifies behaviours in a linearised form, without reverse 318 branches. Conditional processing is supported, and parallel and out- 319 of-order processing may be performed by sufficiently capable devices. 321 By structuring the data in this way, the manifest processor becomes a 322 very simple engine that uses a pull parser to interpret the manifest. 323 This pull parser invokes a series of command handlers that evaluate a 324 Condition or execute a Directive. Most data is structured in a 325 highly regular pattern, which simplifies the parser. 327 The results of this allow a Recipient to implement a very small 328 parser for constrained applications. If needed, such a parser also 329 allows the Recipient to perform complex updates with reduced 330 overhead. Conditional execution of commands allows a simple device 331 to perform important decisions at validation-time. 333 Dependency handling is vastly simplified as well. Dependencies 334 function like subroutines of the language. When a manifest has a 335 dependency, it can invoke that dependency's commands and modify their 336 behaviour by setting parameters. Because some parameters come with 337 security implications, the dependencies also have a mechanism to 338 reject modifications to parameters on a fine-grained level. 340 Developing a robust permissions system works in this model too. The 341 Recipient can use a simple ACL that is a table of Identities and 342 Component Identifier permissions to ensure that only manifests 343 authenticated by the appropriate identity have access to operate on a 344 component. 346 Capability reporting is similarly simplified. A Recipient can report 347 the Commands, Parameters, Algorithms, and Component Identifiers that 348 it supports. This is sufficiently precise for a manifest author to 349 create a manifest that the Recipient can accept. 351 The simplicity of design in the Recipient due to all of these 352 benefits allows even a highly constrained platform to use advanced 353 update capabilities. 355 6.1. Manifest Design Evaluation 357 To evaluate this design, it is compared to the goals stated above. 359 Goal evaluation: 361 1. Each command and condition is anchored to a manifest information 362 element in [Information] 364 2. The use of a byte code encourages flat encoding and reduces 365 nesting depth. This promotes a simple encoding. 367 3. The encoded information closely matches the operations that a 368 device will perform, making the format easy to process. 370 4. Encoding efficiency exceeds 50% when compared to raw data. 372 5. Tooling will be required to reason about the manifest. 374 6. The core operations used by most update and trusted execution 375 operations are represented in the byte code. The use cases 376 listed in [Information] are enabled. 378 7. Registration of new standard byte code identifiers enables 379 extension in a comprehensible way. 381 The manifest described by this document meets the stated goals. 382 Meeting goal 5-comprehensible by intermediate systems-will require 383 additional tooling or a division of metadata. 385 6.2. Severable Elements 387 Because the manifest can be used by different actors at different 388 times, some parts of the manifest can be removed without affecting 389 later stages of the lifecycle. This is called "Severing." Severing 390 of information is achieved by separating that information from the 391 signed container so that removing it does not affect the signature. 392 This means that ensuring authenticity of severable parts of the 393 manifest is a requirement for the signed portion of the manifest. 394 Severing some parts makes it possible to discard parts of the 395 manifest that are no longer necessary. This is important because it 396 allows the storage used by the manifest to be greatly reduced. For 397 example, no text size limits are needed if text is removed from the 398 manifest prior to delivery to a constrained device. 400 Elements are made severable by removing them from the manifest, 401 encoding them in a bstr, and placing a SUIT_Digest of the bstr in the 402 manifest so that they can still be authenticated. The SUIT_Digest 403 typically consumes 4 bytes more than the size of the raw digest, 404 therefore elements smaller than (Digest Bits)/8 + 4 SHOULD never be 405 severable. Elements larger than (Digest Bits)/8 + 4 MAY be 406 severable, while elements that are much larger than (Digest Bits)/8 + 407 4 SHOULD be severable. 409 6.3. Conventions 411 The map indices in this encoding are reset to 1 for each map within 412 the structure. This is to keep the indices as small as possible. 413 The goal is to keep the index objects to single bytes (CBOR positive 414 integers 1-23). 416 Wherever enumerations are used, they are started at 1. This allows 417 detection of several common software errors that are caused by 418 uninitialised variables. Positive numbers in enumerations are 419 reserved for IANA registration. Negative numbers are used to 420 identify application-specific implementations. 422 CDDL names are hyphenated and CDDL structures follow the convention 423 adopted in COSE [RFC8152]: SUIT_Structure_Name. 425 6.4. Payloads 427 Payloads can take many forms, for example, binary, hex, s-record, 428 elf, binary diff, PEM certificate, CBOR Web Token, serialised 429 configuration. These payloads fall into two broad categories: those 430 that require installation-time unpacking and those that do not. 431 Binary, PEM certificate, and CBOR Web Token do not require 432 installation-time unpacking. Hex, s-record, and serialised 433 configuration require installation-time unpacking. Elf may or may 434 not require unpacking depending on the target. 436 Some payloads cannot be directly converted to a writable binary 437 stream. Hex, s-record, and elf may contain gaps and they have no 438 guarantee of monotonic increase of address, which makes pre- 439 processing them into a binary stream difficult on constrained 440 platforms. Serialised configuration may be unpacked into a 441 configuration database, which makes it impossible to preprocess into 442 a binary stream, suitable for direct writing. 444 Where a specialised unpacking algorithm is needed, a digest is not 445 always calculable over an installed payload. For example, an elf, 446 s-record or hex file may contain gaps that can contain any data, 447 while not changing whether or not an installed payload is valid. 448 Serialised configuration may update only some device data rather than 449 all of it. This means that the digest cannot always be calculated 450 over an installed payload when a specialised installer is used. 452 This presents two problems for the manifest: first, it must indicate 453 that a specialised installer is needed and, second, it cannot provide 454 a hash of the payload that is checkable after installation. These 455 two problems are resolved in two ways: 457 1. Payloads that need a specialised installer must indicate this in 458 suit-payload-info-unpack. 460 2. Payloads that need specialised verification must indicate this in 461 the SUIT_Parameter_Image_Digest by indicating a SUIT_Digest 462 algorithm that correctly validates their information. 464 7. Manifest Structure 466 The manifest is divided into several sections in a hierarchy as 467 follows: 469 1. The outer wrapper 471 1. The authentication wrapper 473 2. The manifest 475 1. Critical Information 477 2. Information shared by all command sequences 479 1. List of dependencies 480 2. List of payloads 482 3. List of payloads in dependencies 484 4. Common list of conditions, directives 486 3. Dependency resolution Reference or list of conditions, 487 directives 489 4. Payload fetch Reference or list of conditions, 490 directives 492 5. Installation Reference or list of conditions, directives 494 6. Verification conditions/directives 496 7. Load conditions/directives 498 8. Run conditions/directives 500 9. Text / Reference 502 10. COSWID / Reference 504 3. Dependency resolution conditions/directives 506 4. Payload fetch conditions/directives 508 5. Installation conditions/directives 510 6. Text 512 7. COSWID / Reference 514 8. Intermediate Certificate(s) / CWTs 516 9. Inline Payload(s) 518 7.1. Outer wrapper 520 This object is a container for the other pieces of the manifest to 521 provide a common mechanism to find each of the parts. All elements 522 of the outer wrapper are contained in bstr objects. Wherever the 523 manifest references an object in the outer wrapper, the bstr is 524 included in the digest calculation. 526 The CDDL that describes the wrapper is below 528 SUIT_Outer_Wrapper = { 529 suit-authentication-wrapper => bstr .cbor 530 SUIT_Authentication_Wrapper / nil, 531 $SUIT_Manifest_Wrapped, 532 ? suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 533 ? suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 534 ? suit-install => bstr .cbor SUIT_Command_Sequence, 535 ? suit-text-external => bstr .cbor SUIT_Text_Info, 536 ? suit-coswid-external => bstr .cbor COSWID 537 } 539 SUIT_Authentication_Wrapper = [ + (COSE_Mac_Tagged / COSE_Sign_Tagged / 540 COSE_Mac0_Tagged / COSE_Sign1_Tagged)] 541 SUIT_Encryption_Wrapper = COSE_Encrypt_Tagged / COSE_Encrypt0_Tagged 543 SUIT_Manifest_Wrapped //= (suit-manifest => bstr .cbor SUIT_Manifest) 544 SUIT_Manifest_Wrapped //= ( 545 suit-manifest-encryption-info => bstr .cbor SUIT_Encryption_Wrapper, 546 suit-manifest-encrypted => bstr 547 ) 549 All elements of the outer wrapper must be wrapped in a bstr to 550 minimize the complexity of the code that evaluates the cryptographic 551 integrity of the element and to ensure correct serialisation for 552 integrity and authenticity checks. 554 The suit-authentication-wrapper contains a list of 1 or more 555 cryptographic authentication wrappers for the core part of the 556 manifest. These are implemented as COSE_Mac_Tagged or 557 COSE_Sign_Tagged blocks. The Manifest is authenticated by these 558 blocks in "detached payload" mode. The COSE_Mac_Tagged and 559 COSE_Sign_Tagged blocks are described in RFC 8152 [RFC8152] and are 560 beyond the scope of this document. The suit-authentication-wrapper 561 MUST come first in the SUIT_Outer_Wrapper, regardless of canonical 562 encoding of CBOR. All validators MUST reject any SUIT_Outer_Wrapper 563 that begins with any element other than a suit-authentication- 564 wrapper. 566 A manifest that has not had authentication information added MUST 567 still contain the suit-authentication-wrapper element, but the 568 content MUST be nil. 570 The outer wrapper MUST contain only one of 572 - a plaintext manifest: SUIT_Manifest 574 - an encrypted manifest: both a SUIT_Encryption_Wrapper and the 575 ciphertext of a manifest. 577 When the outer wrapper contains SUIT_Encryption_Wrapper, the suit- 578 authentication-wrapper MUST authenticate the plaintext of suit- 579 manifest-encrypted. 581 suit-manifest contains a SUIT_Manifest structure, which describes the 582 payload(s) to be installed and any dependencies on other manifests. 584 suit-manifest-encryption-info contains a SUIT_Encryption_Wrapper, a 585 COSE object that describes the information required to decrypt a 586 ciphertext manifest. 588 suit-manifest-encrypted contains a ciphertext manifest. 590 Each of suit-dependency-resolution, suit-payload-fetch, and suit- 591 payload-installation contain the severable contents of the 592 identically named portions of the manifest, described in Section 7.2. 594 suit-text contains all the human-readable information that describes 595 any and all parts of the manifest, its payload(s) and its 596 resource(s). 598 suit-coswid contains a Concise Software Identifier. This may be 599 discarded by the recipient if not needed. 601 7.2. Manifest 603 The manifest describes the critical metadata for the referenced 604 payload(s). In addition, it contains: 606 1. a version number for the manifest structure itself 608 2. a sequence number 610 3. a list of dependencies 612 4. a list of components affected 614 5. a list of components affected by dependencies 616 6. a reference for each of the severable blocks. 618 7. a list of actions that the recipient should perform. 620 The following CDDL fragment defines the manifest. 622 SUIT_Manifest = { 623 suit-manifest-version => 1, 624 suit-manifest-sequence-number => uint, 625 suit-common => bstr .cbor SUIT_Common, 626 ? suit-dependency-resolution => Digest / bstr .cbor SUIT_Command_Sequence, 627 ? suit-payload-fetch => Digest / bstr .cbor SUIT_Command_Sequence, 628 ? suit-install => Digest / bstr .cbor SUIT_Command_Sequence 629 ? suit-validate => bstr .cbor SUIT_Command_Sequence 630 ? suit-load => bstr .cbor SUIT_Command_Sequence 631 ? suit-run => bstr .cbor SUIT_Command_Sequence 632 ? suit-text-info => Digest / bstr .cbor SUIT_Text_Map 633 ? suit-coswid => Digest / bstr .cbor COSWID 634 } 636 SUIT_Common = { 637 ? suit-dependencies => bstr .cbor [ + SUIT_Dependency ], 638 ? suit-components => bstr .cbor [ + SUIT_Component_Identifier ], 639 ? suit-dependency-components => bstr .cbor [ + SUIT_Component_Reference ], 640 ? suit-common-sequence => bstr .cbor SUIT_Command_Sequence, 641 } 643 Several fields in the Manifest can be either a CBOR structure or a 644 SUIT_Digest. In each of these cases, the SUIT_Digest provides for a 645 severable field. Severable fields are RECOMMENDED to implement. In 646 particular, text SHOULD be severable, since most useful text elements 647 occupy more space than a SUIT_Digest, but are not needed by recipient 648 devices. Because SUIT_Digest is a CBOR Array and each severable 649 element is a CBOR bstr, it is straight-forward for a recipient to 650 determine whether an element is been severable. The key used for a 651 severable element is the same in the SUIT_Manifest and in the 652 SUIT_Outer_Wrapper so that a recipient can easily identify the 653 correct data in the outer wrapper. 655 The suit-manifest-version indicates the version of serialisation used 656 to encode the manifest. Version 1 is the version described in this 657 document. suit-manifest-version is REQUIRED. 659 The suit-manifest-sequence-number is a monotonically increasing anti- 660 rollback counter. It also helps devices to determine which in a set 661 of manifests is the "root" manifest in a given update. Each manifest 662 MUST have a sequence number higher than each of its dependencies. 663 Each recipient MUST reject any manifest that has a sequence number 664 lower than its current sequence number. It MAY be convenient to use 665 a UTC timestamp in seconds as the sequence number. suit-manifest- 666 sequence-number is REQUIRED. 668 suit-common encodes all the information that is shared between each 669 of the command sequences, including: suit-dependencies, suit- 670 components, suit-dependency-components, and suit-common-sequence. 671 suit-common is REQUIRED to implement. 673 suit-dependencies is a list of SUIT_Dependency blocks that specify 674 manifests that must be present before the current manifest can be 675 processed. suit-dependencies is OPTIONAL to implement. 677 In order to distinguish between components that are affected by the 678 current manifest and components that are affected by a dependency, 679 they are kept in separate lists. Components affected by the current 680 manifest only list the component identifier. Components affected by 681 a dependency include the component identifier and the index of the 682 dependency that defines the component. 684 suit-components is a list of SUIT_Component blocks that specify the 685 component identifiers that will be affected by the content of the 686 current manifest. suit-components is OPTIONAL, but at least one 687 manifest MUST contain a suit-components block. 689 suit-dependency-components is a list of SUIT_Component_Reference 690 blocks that specify component identifiers that will be affected by 691 the content of a dependency of the current manifest. suit-dependency- 692 components is OPTIONAL. 694 suit-common-sequence is a SUIT_Command_Sequence to execute prior to 695 executing any other command sequence. Typical actions in suit- 696 common-sequence include setting expected device identity and image 697 digests when they are conditional (see Section 11 for more 698 information on conditional sequences). suit-common-sequence is 699 RECOMMENDED. 701 suit-dependency-resolution is a SUIT_Command_Sequence to execute in 702 order to perform dependency resolution. Typical actions include 703 configuring URIs of dependency manifests, fetching dependency 704 manifests, and validating dependency manifests' contents. suit- 705 dependency-resolution is REQUIRED when suit-dependencies is present. 707 suit-payload-fetch is a SUIT_Command_Sequence to execute in order to 708 obtain a payload. Some manifests may include these actions in the 709 suit-install section instead if they operate in a streaming 710 installation mode. This is particularly relevant for constrained 711 devices without any temporary storage for staging the update. suit- 712 payload-fetch is OPTIONAL. 714 suit-install is a SUIT_Command_Sequence to execute in order to 715 install a payload. Typical actions include verifying a payload 716 stored in temporary storage, copying a staged payload from temporary 717 storage, and unpacking a payload. suit-install is OPTIONAL. 719 suit-validate is a SUIT_Command_Sequence to execute in order to 720 validate that the result of applying the update is correct. Typical 721 actions involve image validation and manifest validation. suit- 722 validate is REQUIRED. If the manifest contains dependencies, one 723 process-dependency invocation per dependency or one process- 724 dependency invocation targeting all dependencies SHOULD be present in 725 validate. 727 suit-load is a SUIT_Command_Sequence to execute in order to prepare a 728 payload for execution. Typical actions include copying an image from 729 permanent storage into RAM, optionally including actions such as 730 decryption or decompression. suit-load is OPTIONAL. 732 suit-run is a SUIT_Command_Sequence to execute in order to run an 733 image. suit-run typically contains a single instruction: either the 734 "run" directive for the bootable manifest or the "process 735 dependencies" directive for any dependents of the bootable manifest. 736 suit-run is OPTIONAL. Only one manifest in an update may contain the 737 "run" directive. 739 suit-text-info is a digest that uniquely identifies the content of 740 the Text that is packaged in the OuterWrapper. text is OPTIONAL. 742 suit-coswid is a digest that uniquely identifies the content of the 743 concise-software-identifier that is packaged in the OuterWrapper. 744 coswid is OPTIONAL. 746 7.3. SUIT_Dependency 748 SUIT_Dependency specifies a manifest that describes a dependency of 749 the current manifest. 751 The following CDDL describes the SUIT_Dependency structure. 753 SUIT_Dependency = { 754 suit-dependency-digest => SUIT_Digest, 755 ? suit-dependency-prefix => SUIT_Component_Identifier, 756 } 758 The suit-dependency-digest specifies the dependency manifest uniquely 759 by identifying a particular Manifest structure. The digest is 760 calculated over the Manifest structure instead of the COSE 761 Sig_structure or Mac_structure. This means that a digest may need to 762 be calculated more than once, however this is necessary to ensure 763 that removing a signature from a manifest does not break dependencies 764 due to missing signature elements. This is also necessary to support 765 the trusted intermediary use case, where an intermediary re-signs the 766 Manifest, removing the original signature, potentially with a 767 different algorithm, or trading COSE_Sign for COSE_Mac. 769 The suit-dependency-prefix element contains a 770 SUIT_Component_Identifier. This specifies the scope at which the 771 dependency operates. This allows the dependency to be forwarded on 772 to a component that is capable of parsing its own manifests. It also 773 allows one manifest to be deployed to multiple dependent devices 774 without those devices needing consistent component hierarchy. This 775 element is OPTIONAL. 777 7.4. SUIT_Component_Reference 779 The SUIT_Component_Reference describes an image that is defined by 780 another manifest. This is useful for overriding the behaviour of 781 another manifest, for example by directing the recipient to look at a 782 different URI for the image or by changing the expected format, such 783 as when a gateway performs decryption on behalf of a constrained 784 device. The following CDDL describes the SUIT_Component_Reference. 786 SUIT_Component_Reference = { 787 suit-component-identifier => SUIT_Component_Identifier, 788 suit-component-dependency-index => uint 789 } 791 7.5. Manifest Parameters 793 Many conditions and directives require additional information. That 794 information is contained within parameters that can be set in a 795 consistent way. Parameters MUST only be: 797 1. Integers 798 2. Byte strings 799 3. Booleans 801 This allows reduction of manifest size and replacement of parameters 802 from one manifest to the next. Byte strings MAY contain CBOR-encoded 803 objects. 805 The defined manifest parameters are described below. 807 +--------+-------+------+---------------+----------+----------------+ 808 | Parame | CBOR | Defa | Scope | Name | Description | 809 | ter | Type | ult | | | | 810 | Code | | | | | | 811 +--------+-------+------+---------------+----------+----------------+ 812 | 1 | boole | True | Global | Strict | Requires that | 813 | | an | | | Order | the manifest | 814 | | | | | | is processed | 815 | | | | | | in a strictly | 816 | | | | | | linear | 817 | | | | | | fashion. Set | 818 | | | | | | to 0 to enable | 819 | | | | | | parallel | 820 | | | | | | handling of | 821 | | | | | | manifest | 822 | | | | | | directives. | 823 | | | | | | | 824 | 2 | boole | Fals | Command | Coerce C | Coerces the | 825 | | an | e | Segment | ondition | success code | 826 | | | | | Failure | of a command | 827 | | | | | | segment to | 828 | | | | | | success even | 829 | | | | | | when aborted | 830 | | | | | | due to a | 831 | | | | | | condition | 832 | | | | | | failure. | 833 | | | | | | | 834 | 3 | bstr | nil | Component/Glo | Vendor | A RFC4122 UUID | 835 | | | | bal | ID | representing | 836 | | | | | | the vendor of | 837 | | | | | | the device or | 838 | | | | | | component | 839 | | | | | | | 840 | 4 | bstr | nil | Component/Glo | Class ID | A RFC4122 UUID | 841 | | | | bal | | representing | 842 | | | | | | the class of | 843 | | | | | | the device or | 844 | | | | | | component | 845 | | | | | | | 846 | 5 | bstr | nil | Component/Glo | Device | A RFC4122 UUID | 847 | | | | bal | ID | representing | 848 | | | | | | the device or | 849 | | | | | | component | 850 | | | | | | | 851 | 6 | bstr | nil | Component/Dep | URI | A URI from | 852 | | | | endency | | which to fetch | 853 | | | | | | a resource | 854 | | | | | | | 855 | 7 | bstr | nil | Component/Dep | Encrypti | A COSE object | 856 | | | | endency | on Info | defining the | 857 | | | | | | encryption | 858 | | | | | | mode of a | 859 | | | | | | resource | 860 | | | | | | | 861 | 8 | bstr | nil | Component | Compress | A SUIT_Compres | 862 | | | | | ion Info | sion_Info | 863 | | | | | | object | 864 | | | | | | | 865 | 9 | bstr | nil | Component | Unpack | A SUIT_Unpack_ | 866 | | | | | Info | Info object | 867 | | | | | | | 868 | 10 | uint | nil | Component | Source C | A Component | 869 | | | | | omponent | Index | 870 | | | | | | | 871 | 11 | bstr | nil | Component/Dep | Image | A SUIT_Digest | 872 | | | | endency | Digest | | 873 | | | | | | | 874 | 12 | bstr | nil | Component/Dep | Image | Integer size | 875 | | | | endency | Size | | 876 | | | | | | | 877 | 24 | bstr | nil | Component/Dep | URI List | A CBOR encoded | 878 | | | | endency | | list of ranked | 879 | | | | | | URIs | 880 | | | | | | | 881 | 25 | boole | Fals | Component/Dep | URI List | A CBOR encoded | 882 | | an | e | endency | Append | list of ranked | 883 | | | | | | URIs | 884 | | | | | | | 885 | nint | int/b | nil | Custom | Custom P | Application- | 886 | | str | | | arameter | defined | 887 | | | | | | parameter | 888 +--------+-------+------+---------------+----------+----------------+ 890 CBOR-encoded object parameters are still wrapped in a bstr. This is 891 because it allows a parser that is aggregating parameters to 892 reference the object with a single pointer and traverse it without 893 understanding the contents. This is important for modularisation and 894 division of responsibility within a pull parser. The same 895 consideration does not apply to Conditions and Directives because 896 those elements are invoked with their arguments immediately 898 7.5.1. SUIT_Parameter_Strict_Order 900 The Strict Order Parameter allows a manifest to govern when 901 directives can be executed out-of-order. This allows for systems 902 that have a sensitivity to order of updates to choose the order in 903 which they are executed. It also allows for more advanced systems to 904 parallelise their handling of updates. Strict Order defaults to 905 True. It MAY be set to False when the order of operations does not 906 matter. When arriving at the end of a command sequence, ALL commands 907 MUST have completed, regardless of the state of 908 SUIT_Parameter_Strict_Order. If SUIT_Parameter_Strict_Order is 909 returned to True, ALL preceding commands MUST complete before the 910 next command is executed. 912 7.5.2. SUIT_Parameter_Coerce_Condition_Failure 914 When executing a command sequence inside SUIT_Run_Sequence and a 915 condition failure occurs, the manifest processor aborts the sequence. 916 If Coerce Condition Failure is True, it returns Success. Otherwise, 917 it returns the original condition failure. 918 SUIT_Parameter_Coerce_Condition_Failure is scoped to the enclosing 919 SUIT_Directive_Run_Sequence. Its value is discarded when 920 SUIT_Directive_Run_Sequence terminates. 922 7.6. SUIT_Parameter_Encryption_Info 924 Encryption Info defines the mechanism that Fetch or Copy should use 925 to decrypt the data they transfer. SUIT_Parameter_Encryption_Info is 926 encoded as a COSE_Encrypt_Tagged or a COSE_Encrypt0_Tagged, wrapped 927 in a bstr 929 7.7. SUIT_Parameter_Compression_Info 931 Compression Info defines any information that is required for a 932 device to perform decompression operations. Typically, this includes 933 the algorithm identifier. 935 SUIT_Parameter_Compression_Info is defined by the following CDDL: 937 SUIT_Compression_Info = { 938 suit-compression-algorithm => SUIT_Compression_Algorithms 939 ? suit-compression-parameters => bstr 940 } 942 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 943 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 944 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 945 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 946 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 948 7.8. SUIT_Parameter_Unpack_Info 950 SUIT_Unpack_Info defines the information required for a device to 951 interpret a packed format, such as elf, hex, or binary diff. 952 SUIT_Unpack_Info is defined by the following CDDL: 954 SUIT_Unpack_Info = { 955 suit-unpack-algorithm => SUIT_Unpack_Algorithms 956 ? suit-unpack-parameters => bstr 957 } 959 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 960 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 961 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 963 7.9. SUIT_Parameters CDDL 965 The following CDDL describes all SUIT_Parameters. 967 SUIT_Parameters //= (suit-parameter-strict-order => bool) 968 SUIT_Parameters //= (suit-parameter-coerce-condition-failure => bool) 969 SUIT_Parameters //= (suit-parameter-vendor-id => bstr) 970 SUIT_Parameters //= (suit-parameter-class-id => bstr) 971 SUIT_Parameters //= (suit-parameter-device-id => bstr) 972 SUIT_Parameters //= (suit-parameter-uri => bstr) 973 SUIT_Parameters //= (suit-parameter-encryption-info => bstr .cbor SUIT_Encryption_Info) 974 SUIT_Parameters //= (suit-parameter-compression-info => bstr .cbor SUIT_Compression_Info) 975 SUIT_Parameters //= (suit-parameter-unpack-info => bstr .cbor SUIT_Unpack_Info) 976 SUIT_Parameters //= (suit-parameter-source-component => bstr .cbor SUIT_Component_Identifier) 977 SUIT_Parameters //= (suit-parameter-image-digest => bstr .cbor SUIT_Digest) 978 SUIT_Parameters //= (suit-parameter-image-size => uint) 979 SUIT_Parameters //= (suit-parameter-uri-list => bstr .cbor SUIT_URI_List) 980 SUIT_Parameters //= (suit-parameter_custom => int/bool/bstr) 982 SUIT_URI_List = [ + [priority: int, uri: tstr] ] 984 SUIT_Encryption_Info= COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 985 SUIT_Compression_Info = { 986 suit-compression-algorithm => SUIT_Compression_Algorithms 987 ? suit-compression-parameters => bstr 988 } 990 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 991 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 992 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_deflate 993 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_LZ4 994 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 996 SUIT_Unpack_Info = { 997 suit-unpack-algorithm => SUIT_Unpack_Algorithms 998 ? suit-unpack-parameters => bstr 999 } 1001 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Delta 1002 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Hex 1003 SUIT_Unpack_Algorithms //= SUIT_Unpack_Algorithm_Elf 1005 7.10. SUIT_Command_Sequence 1007 A SUIT_Command_Sequence defines a series of actions that the 1008 recipient MUST take to accomplish a particular goal. These goals are 1009 defined in the manifest and include: 1011 1. Dependency Resolution 1013 2. Payload Fetch 1014 3. Payload Installation 1016 4. Image Validation 1018 5. Image Loading 1020 6. Run or Boot 1022 Each of these follows exactly the same structure to ensure that the 1023 parser is as simple as possible. 1025 Lists of commands are constructed from two kinds of element: 1027 1. Conditions that MUST be true-any failure is treated as a failure 1028 of the update/load/boot 1030 2. Directives that MUST be executed. 1032 The lists of commands are logically structured into sequences of zero 1033 or more conditions followed by zero or more directives. The 1034 *logical* structure is described by the following CDDL: 1036 Command_Sequence = { 1037 conditions => [ * Condition], 1038 directives => [ * Directive] 1039 } 1041 This introduces significant complexity in the parser, however, so the 1042 structure is flattened to make parsing simpler: 1044 SUIT_Command_Sequence = [ + (SUIT_Condition/SUIT_Directive) ] 1046 Each condition and directive is composed of: 1048 1. A command code identifier 1050 2. An argument block 1052 Argument blocks are defined for each type of command. 1054 Many conditions and directives apply to a given component, and these 1055 generally grouped together. Therefore, a special command to set the 1056 current component index is provided with a matching command to set 1057 the current dependency index. This index is a numeric index into the 1058 component ID tables defined at the beginning of the document. For 1059 the purpose of setting the index, the two component ID tables are 1060 considered to be concatenated together. 1062 To facilitate optional conditions, a special directive is provided. 1063 It runs several new lists of conditions/directives, one after 1064 another, that are contained as an argument to the directive. By 1065 default, it assumes that a failure of a condition should not indicate 1066 a failure of the update/boot, but a parameter is provided to override 1067 this behaviour. 1069 7.11. SUIT_Condition 1071 Conditions are used to define mandatory properties of a system in 1072 order for an update to be applied. They can be pre-conditions or 1073 post-conditons of any directive or series of directives, depending on 1074 where they are placed in the list. Conditions include: 1076 +----------------+-------------------+----------------------------+ 1077 | Condition Code | Condition Name | Argument Type | 1078 +----------------+-------------------+----------------------------+ 1079 | 1 | Vendor Identifier | nil | 1080 | | | | 1081 | 2 | Class Identifier | nil | 1082 | | | | 1083 | 3 | Image Match | nil | 1084 | | | | 1085 | 4 | Use Before | Unsigned Integer timestamp | 1086 | | | | 1087 | 5 | Component Offset | Unsigned Integer | 1088 | | | | 1089 | 24 | Device Identifier | nil | 1090 | | | | 1091 | 25 | Image Not Match | nil | 1092 | | | | 1093 | 26 | Minimum Battery | Unsigned Integer | 1094 | | | | 1095 | 27 | Update Authorised | Integer | 1096 | | | | 1097 | 28 | Version | List of Integers | 1098 | | | | 1099 | nint | Custom Condition | bstr | 1100 +----------------+-------------------+----------------------------+ 1102 Each condition MUST report a success code on completion. If a 1103 condition reports failure, then the current sequence of commands MUST 1104 terminate. If a recipient encounters an unknown Condition Code, it 1105 MUST report a failure. 1107 Positive Condition numbers are reserved for IANA registration. 1108 Negative numbers are reserved for proprietary, application-specific 1109 directives. 1111 7.11.1. Identifier Conditions 1113 There are three identifier-based conditions: suit-condition-vendor- 1114 identifier, suit-condition-class-identifier, and suit-condition- 1115 device-identifier. Each of these conditions match a RFC 4122 1116 [RFC4122] UUID that MUST have already been set as a parameter. The 1117 installing device MUST match the specified UUID in order to consider 1118 the manifest valid. These identifiers MAY be scoped by component. 1120 The recipient uses the ID parameter that has already been set using 1121 the Set Parameters directive. If no ID has been set, this condition 1122 fails. suit-condition-class-identifier and suit-condition-vendor- 1123 identifier are REQUIRED to implement. suit-condition-device- 1124 identifier is OPTIONAL to implement. 1126 7.11.2. suit-condition-image-match 1128 Verify that the current component matches the digest parameter for 1129 the current component. The digest is verified against the digest 1130 specified in the Component's parameters list. If no digest is 1131 specified, the condition fails. suit-condition-image-match is 1132 REQUIRED to implement. 1134 7.11.3. suit-condition-image-not-match 1136 Verify that the current component does not match the supplied digest. 1137 If no digest is specified, then the digest is compared against the 1138 digest specified in the Components list. If no digest is specified 1139 and the component is not present in the Components list, the 1140 condition fails. suit-condition-image-not-match is OPTIONAL to 1141 implement. 1143 7.11.4. suit-condition-use-before 1145 Verify that the current time is BEFORE the specified time. suit- 1146 condition-use-before is used to specify the last time at which an 1147 update should be installed. One argument is required, encoded as a 1148 POSIX timestamp, that is seconds after 1970-01-01 00:00:00. 1149 Timestamp conditions MUST be evaluated in 64 bits, regardless of 1150 encoded CBOR size. suit-condition-use-before is OPTIONAL to 1151 implement. 1153 7.11.5. suit-condition-minimum-battery 1155 suit-condition-minimum-battery provides a mechanism to test a 1156 device's battery level before installing an update. This condition 1157 is for use in primary-cell applications, where the battery is only 1158 ever discharged. For batteries that are charged, suit-directive-wait 1159 is more appropriate, since it defines a "wait" until the battery 1160 level is sufficient to install the update. suit-condition-minimum- 1161 battery is specified in mWh. suit-condition-minimum-battery is 1162 OPTIONAL to implement. 1164 7.11.6. suit-condition-update-authorised 1166 Request Authorisation from the application and fail if not 1167 authorised. This can allow a user to decline an update. Argument is 1168 an integer priority level. Priorities are application defined. suit- 1169 condition-update-authorised is OPTIONAL to implement. 1171 7.11.7. suit-condition-version 1173 suit-condition-version allows comparing versions of firmware. 1174 Verifying image digests is preferred to version checks because 1175 digests are more precise. The image can be compared as: 1177 - Greater 1179 - Greater or Equal 1181 - Equal 1183 - Lesser or Equal 1185 - Lesser 1187 Versions are encoded as a CBOR list of integers. Comparisons are 1188 done on each integer in sequence. Comparison stops after all 1189 integers in the list defined by the manifest have been consumed OR 1190 after a non-equal match has occured. For example, if the manifest 1191 defines a comparison, "Equal [1]", then this will match all version 1192 sequences starting with 1. If a manifest defines both "Greater or 1193 Equal [1,0]" and "Lesser [1,10]", then it will match versions 1.0.x 1194 up to, but not including 1.10. 1196 The following CDDL describes SUIT_Condition_Version_Argument 1198 SUIT_Condition_Version_Argument = [ 1199 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1200 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1201 ] 1202 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater 1203 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Greater_Equal 1204 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Equal 1205 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser_Equal 1206 SUIT_Condition_Version_Comparison_Types /= SUIT_Condition_Version_Comparison_Lesser 1207 SUIT_Condition_Version_Comparison_Greater = 1 1208 SUIT_Condition_Version_Comparison_Greater_Equal = 2 1209 SUIT_Condition_Version_Comparison_Equal = 3 1210 SUIT_Condition_Version_Comparison_Lesser_Equal = 4 1211 SUIT_Condition_Version_Comparison_Lesser = 5 1213 SUIT_Condition_Version_Comparison_Value = [+int] 1215 While the exact encoding of versions is application-defined, semantic 1216 versions map conveniently. For example, 1218 - 1.2.3 = [1,2,3] 1220 - 1.2-rc3 = [1,2,-1,3] 1222 - 1.2-beta = [1,2,-2] 1224 - 1.2-alpha = [1,2,-3] 1226 - 1.2-alpha4 = [1,2,-3,4] 1228 suit-condition-version is OPTIONAL to implement. 1230 7.11.8. SUIT_Condition_Custom 1232 SUIT_Condition_Custom describes any proprietary, application specific 1233 condition. This is encoded as a negative integer, chosen by the 1234 firmware developer, and a bstr that encodes the parameters passed to 1235 the system that evaluates the condition matching that integer. 1236 SUIT_Condition_Custom is OPTIONAL to implement. 1238 7.11.9. Identifiers 1240 Many conditions use identifiers to determine whether a manifest 1241 matches a given recipient or not. These identifiers are defined to 1242 be RFC 4122 [RFC4122] UUIDs. These UUIDs are explicitly NOT human- 1243 readable. They are for machine-based matching only. 1245 A device may match any number of UUIDs for vendor or class 1246 identifier. This may be relevant to physical or software modules. 1247 For example, a device that has an OS and one or more applications 1248 might list one Vendor ID for the OS and one or more additional Vendor 1249 IDs for the applications. This device might also have a Class ID 1250 that must be matched for the OS and one or more Class IDs for the 1251 applications. 1253 A more complete example: A device has the following physical 1254 components: 1. A host MCU 2. A WiFi module 1256 This same device has three software modules: 1. An operating system 1257 2. A WiFi module interface driver 3. An application 1259 Suppose that the WiFi module's firmware has a proprietary update 1260 mechanism and doesn't support manifest processing. This device can 1261 report four class IDs: 1263 1. hardware model/revision 1265 2. OS 1267 3. WiFi module model/revision 1269 4. Application 1271 This allows the OS, WiFi module, and application to be updated 1272 independently. To combat possible incompatibilities, the OS class ID 1273 can be changed each time the OS has a change to its API. 1275 This approach allows a vendor to target, for example, all devices 1276 with a particular WiFi module with an update, which is a very 1277 powerful mechanism, particularly when used for security updates. 1279 7.11.9.1. Creating UUIDs: 1281 UUIDs MUST be created according to RFC 4122 [RFC4122]. UUIDs SHOULD 1282 use versions 3, 4, or 5, as described in RFC4122. Versions 1 and 2 1283 do not provide a tangible benefit over version 4 for this 1284 application. 1286 The RECOMMENDED method to create a vendor ID is: Vendor ID = 1287 UUID5(DNS_PREFIX, vendor domain name) 1289 The RECOMMENDED method to create a class ID is: Class ID = 1290 UUID5(Vendor ID, Class-Specific-Information) 1291 Class-specific information is composed of a variety of data, for 1292 example: 1294 - Model number 1296 - Hardware revision 1298 - Bootloader version (for immutable bootloaders) 1300 7.11.10. SUIT_Condition CDDL 1302 The following CDDL describes SUIT_Condition: 1304 SUIT_Condition //= (suit-condition-vendor-identifier, nil) 1305 SUIT_Condition //= (suit-condition-class-identifier, nil) 1306 SUIT_Condition //= (suit-condition-device-identifier, nil) 1307 SUIT_Condition //= (suit-condition-image-match, nil) 1308 SUIT_Condition //= (suit-condition-image-not-match, nil) 1309 SUIT_Condition //= (suit-condition-use-before, uint) 1310 SUIT_Condition //= (suit-condition-minimum-battery, uint) 1311 SUIT_Condition //= (suit-condition-update-authorised, int) 1312 SUIT_Condition //= (suit-condition-version, SUIT_Condition_Version_Argument) 1313 SUIT_Condition //= (suit-condition-component-offset, uint) 1314 SUIT_Condition //= (suit-condition-custom, bstr) 1316 SUIT_Condition_Version_Argument = [ 1317 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 1318 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 1319 ] 1320 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater 1321 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater-equal 1322 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-equal 1323 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser-equal 1324 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser 1326 SUIT_Condition_Version_Comparison_Value = [+int] 1328 7.12. SUIT_Directive 1330 Directives are used to define the behaviour of the recipient. 1331 Directives include: 1333 +----------------+----------------------+ 1334 | Directive Code | Directive Name | 1335 +----------------+----------------------+ 1336 | 12 | Set Component Index | 1337 | | | 1338 | 13 | Set Dependency Index | 1339 | | | 1340 | 14 | Abort | 1341 | | | 1342 | 15 | Try Each | 1343 | | | 1344 | 16 | Reserved | 1345 | | | 1346 | 17 | Reserved | 1347 | | | 1348 | 18 | Process Dependency | 1349 | | | 1350 | 19 | Set Parameters | 1351 | | | 1352 | 20 | Override Parameters | 1353 | | | 1354 | 21 | Fetch | 1355 | | | 1356 | 22 | Copy | 1357 | | | 1358 | 23 | Run | 1359 | | | 1360 | 29 | Wait | 1361 | | | 1362 | 30 | Run Sequence | 1363 | | | 1364 | 31 | Run with Arguments | 1365 | | | 1366 | 32 | Swap | 1367 +----------------+----------------------+ 1369 When a Recipient executes a Directive, it MUST report a success code. 1370 If the Directive reports failure, then the current Command Sequence 1371 MUST terminate. 1373 7.12.1. suit-directive-set-component-index 1375 Set Component Index defines the component to which successive 1376 directives and conditions will apply. The supplied argument MUST be 1377 either a boolean or an unsigned integer index into the concatenation 1378 of suit-components and suit-dependency-components. If the following 1379 directives apply to ALL components, then the boolean value "True" is 1380 used instead of an index. True does not apply to dependency 1381 components. If the following directives apply to NO components, then 1382 the boolean value "False" is used. When suit-directive-set- 1383 dependency-index is used, suit-directive-set-component-index = False 1384 is implied. When suit-directive-set-component-index is used, suit- 1385 directive-set-dependency-index = False is implied. 1387 The following CDDL describes the argument to suit-directive-set- 1388 component-index. 1390 SUIT_Directive_Set_Component_Index_Argument = uint/bool 1392 7.12.2. suit-directive-set-dependency-index 1394 Set Dependency Index defines the manifest to which successive 1395 directives and conditions will apply. The supplied argument MUST be 1396 either a boolean or an unsigned integer index into the dependencies. 1397 If the following directives apply to ALL dependencies, then the 1398 boolean value "True" is used instead of an index. If the following 1399 directives apply to NO dependencies, then the boolean value "False" 1400 is used. When suit-directive-set-component-index is used, suit- 1401 directive-set-dependency-index = False is implied. When suit- 1402 directive-set-dependency-index is used, suit-directive-set-component- 1403 index = False is implied. 1405 Typical operations that require suit-directive-set-dependency-index 1406 include setting a source URI, invoking "Fetch," or invoking "Process 1407 Dependency" for an individual dependency. 1409 The following CDDL describes the argument to suit-directive-set- 1410 dependency-index. 1412 SUIT_Directive_Set_Manifest_Index_Argument = uint/bool 1414 7.12.3. suit-directive-abort 1416 Unconditionally fail. This operation is typically used in 1417 conjunction with suit-directive-try-each. 1419 7.12.4. suit-directive-run-sequence 1421 To enable conditional commands, and to allow several strictly ordered 1422 sequences to be executed out-of-order, suit-directive-run-sequence 1423 allows the manifest processor to execute its argument as a 1424 SUIT_Command_Sequence. The argument must be wrapped in a bstr. 1426 When a sequence is executed, any failure of a condition causes 1427 immediate termination of the sequence. 1429 The following CDDL describes the SUIT_Run_Sequence argument. 1431 SUIT_Directive_Run_Sequence_Argument = bstr .cbor SUIT_Command_Sequence 1433 When suit-directive-run-sequence completes, it forwards the last 1434 status code that occurred in the sequence. If the Coerce on 1435 Condition Failure parameter is true, then suit-directive-run-sequence 1436 only fails when a directive in the argument sequence fails. 1438 SUIT_Parameter_Coerce_Condition_Failure defaults to False when suit- 1439 directive-run-sequence begins. Its value is discarded when suit- 1440 directive-run-sequence terminates. 1442 7.12.5. suit-directive-try-each 1444 This command runs several suit-directive-run-sequence one after 1445 another, in a strict order. Use this command to implement a "try/ 1446 catch-try/catch" sequence. Manifest processors MAY implement this 1447 command. 1449 SUIT_Parameter_Coerce_Condition_Failure is initialised to True at the 1450 beginning of each sequence. If one sequence aborts due to a 1451 condition failure, the next is started. If no sequence completes 1452 without condition failure, then suit-directive-try-each returns an 1453 error. If a particular application calls for all sequences to fail 1454 and still continue, then an empty sequence (nil) can be added to the 1455 Try Each Argument. 1457 The following CDDL describes the SUIT_Try_Each argument. 1459 SUIT_Directive_Try_Each_Argument = [ 1460 + bstr .cbor SUIT_Command_Sequence, 1461 nil / bstr .cbor SUIT_Command_Sequence 1462 ] 1464 7.12.6. suit-directive-process-dependency 1466 Execute the commands in the common section of the current dependency, 1467 followed by the commands in the equivalent section of the current 1468 dependency. For example, if the current section is "fetch payload," 1469 this will execute "common" in the current dependency, then "fetch 1470 payload" in the current dependency. Once this is complete, the 1471 command following suit-directive-process-dependency will be 1472 processed. 1474 If the current dependency is False, this directive has no effect. If 1475 the current dependency is True, then this directive applies to all 1476 dependencies. If the current section is "common," this directive 1477 MUST have no effect. 1479 When SUIT_Process_Dependency completes, it forwards the last status 1480 code that occurred in the dependency. 1482 The argument to suit-directive-process-dependency is defined in the 1483 following CDDL. 1485 SUIT_Directive_Process_Dependency_Argument = nil 1487 7.12.7. suit-directive-set-parameters 1489 suit-directive-set-parameters allows the manifest to configure 1490 behaviour of future directives by changing parameters that are read 1491 by those directives. When dependencies are used, suit-directive-set- 1492 parameters also allows a manifest to modify the behaviour of its 1493 dependencies. 1495 Available parameters are defined in Section 7.5. 1497 If a parameter is already set, suit-directive-set-parameters will 1498 skip setting the parameter to its argument. This provides the core 1499 of the override mechanism, allowing dependent manifests to change the 1500 behaviour of a manifest. 1502 The argument to suit-directive-set-parameters is defined in the 1503 following CDDL. 1505 SUIT_Directive_Set_Parameters_Argument = {+ SUIT_Parameters} 1507 N.B.: A directive code is reserved for an optimisation: a way to set 1508 a parameter to the contents of another parameter, optionally with 1509 another component ID. 1511 7.12.8. suit-directive-override-parameters 1513 suit-directive-override-parameters replaces any listed parameters 1514 that are already set with the values that are provided in its 1515 argument. This allows a manifest to prevent replacement of critical 1516 parameters. 1518 Available parameters are defined in Section 7.5. 1520 The argument to suit-directive-override-parameters is defined in the 1521 following CDDL. 1523 SUIT_Directive_Override_Parameters_Argument = {+ SUIT_Parameters} 1525 7.12.9. suit-directive-fetch 1527 suit-directive-fetch instructs the manifest processor to obtain one 1528 or more manifests or payloads, as specified by the manifest index and 1529 component index, respectively. 1531 suit-directive-fetch can target one or more manifests and one or more 1532 payloads. suit-directive-fetch retrieves each component and each 1533 manifest listed in component-index and manifest-index, respectively. 1534 If component-index or manifest-index is True, instead of an integer, 1535 then all current manifest components/manifests are fetched. The 1536 current manifest's dependent-components are not automatically 1537 fetched. In order to pre-fetch these, they MUST be specified in a 1538 component-index integer. 1540 suit-directive-fetch typically takes no arguments unless one is 1541 needed to modify fetch behaviour. If an argument is needed, it must 1542 be wrapped in a bstr. 1544 suit-directive-fetch reads the URI or URI List parameter to find the 1545 source of the fetch it performs. 1547 The behaviour of suit-directive-fetch can be modified by setting one 1548 or more of SUIT_Parameter_Encryption_Info, 1549 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 1550 three parameters each activate and configure a processing step that 1551 can be applied to the data that is transferred during suit-directive- 1552 fetch. 1554 The argument to suit-directive-fetch is defined in the following 1555 CDDL. 1557 SUIT_Directive_Fetch_Argument = nil/bstr 1559 7.12.10. suit-directive-copy 1561 suit-directive-copy instructs the manifest processor to obtain one or 1562 more payloads, as specified by the component index. suit-directive- 1563 copy retrieves each component listed in component-index, 1564 respectively. If component-index is True, instead of an integer, 1565 then all current manifest components are copied. The current 1566 manifest's dependent-components are not automatically copied. In 1567 order to copy these, they MUST be specified in a component-index 1568 integer. 1570 The behaviour of suit-directive-copy can be modified by setting one 1571 or more of SUIT_Parameter_Encryption_Info, 1572 SUIT_Parameter_Compression_Info, SUIT_Parameter_Unpack_Info. These 1573 three parameters each activate and configure a processing step that 1574 can be applied to the data that is transferred during suit-directive- 1575 copy. 1577 *N.B.* Fetch and Copy are very similar. Merging them into one 1578 command may be appropriate. 1580 suit-directive-copy reads its source from 1581 SUIT_Parameter_Source_Component. 1583 The argument to suit-directive-copy is defined in the following CDDL. 1585 SUIT_Directive_Copy_Argument = nil 1587 7.12.11. suit-directive-swap 1589 suit-directive-swap instructs the manifest processor to move the 1590 source to the destination and the destination to the source 1591 simultaneously. Swap has nearly identical semantics to suit- 1592 directive-copy except that suit-directive-swap replaces the source 1593 with the current contents of the destination in an application- 1594 defined way. If SUIT_Parameter_Compression_Info or 1595 SUIT_Parameter_Encryption_Info are present, they must be handled in a 1596 symmetric way, so that the source is decompressed into the 1597 destination and the destination is compressed into the source. The 1598 source is decrypted into the destination and the destination is 1599 encrypted into the source. suit-directive-swap is OPTIONAL to 1600 implement. 1602 7.12.12. suit-directive-run 1604 suit-directive-run directs the manifest processor to transfer 1605 execution to the current Component Index. When this is invoked, the 1606 manifest processor MAY be unloaded and execution continues in the 1607 Component Index. Arguments provided to Run are forwarded to the 1608 executable code located in Component Index, in an application- 1609 specific way. For example, this could form the Linux Kernel Command 1610 Line if booting a linux device. 1612 If the executable code at Component Index is constructed in such a 1613 way that it does not unload the manifest processor, then the manifest 1614 processor may resume execution after the executable completes. This 1615 allows the manifest processor to invoke suitable helpers and to 1616 verify them with image conditions. 1618 The argument to suit-directive-run is defined in the following CDDL. 1620 SUIT_Directive_Run_Argument = nil/bstr 1622 7.12.13. suit-directive-wait 1624 suit-directive-wait directs the manifest processor to pause until a 1625 specified event occurs. Some possible events include: 1627 1. Authorisation 1629 2. External Power 1631 3. Network availability 1633 4. Other Device Firmware Version 1635 5. Time 1637 6. Time of Day 1639 7. Day of Week 1641 The following CDDL defines the encoding of these events. 1643 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 1644 SUIT_Wait_Events //= (suit-wait-event-power => int) 1645 SUIT_Wait_Events //= (suit-wait-event-network => int) 1646 SUIT_Wait_Events //= (suit-wait-event-other-device-version 1647 => SUIT_Wait_Event_Argument_Other_Device_Version) 1648 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 1649 SUIT_Wait_Events //= (suit-wait-event-time-of-day 1650 => uint); Time of Day (seconds since 00:00:00) 1651 SUIT_Wait_Events //= (suit-wait-event-day-of-week 1652 => uint); Days since Sunday 1654 SUIT_Wait_Event_Argument_Authorisation = int ; priority 1655 SUIT_Wait_Event_Argument_Power = int ; Power Level 1656 SUIT_Wait_Event_Argument_Network = int ; Network State 1657 SUIT_Wait_Event_Argument_Other_Device_Version = [ 1658 other-device: bstr, 1659 other-device-version: [+int] 1660 ] 1661 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 1662 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 1663 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 1664 7.12.14. SUIT_Directive CDDL 1666 The following CDDL describes SUIT_Directive: 1668 SUIT_Directive //= (suit-directive-set-component-index, uint/bool) 1669 SUIT_Directive //= (suit-directive-set-dependency-index, uint/bool) 1670 SUIT_Directive //= (suit-directive-run-sequence, 1671 bstr .cbor SUIT_Command_Sequence) 1672 SUIT_Directive //= (suit-directive-try-each, 1673 SUIT_Directive_Try_Each_Argument) 1674 SUIT_Directive //= (suit-directive-process-dependency, nil) 1675 SUIT_Directive //= (suit-directive-set-parameters, 1676 {+ SUIT_Parameters}) 1677 SUIT_Directive //= (suit-directive-override-parameters, 1678 {+ SUIT_Parameters}) 1679 SUIT_Directive //= (suit-directive-fetch, nil) 1680 SUIT_Directive //= (suit-directive-copy, nil) 1681 SUIT_Directive //= (suit-directive-run, nil) 1682 SUIT_Directive //= (suit-directive-wait, 1683 { + SUIT_Wait_Events }) 1684 SUIT_Directive //= (suit-directive-run-with-arguments, bstr) 1686 SUIT_Directive_Try_Each_Argument = [ 1687 + bstr .cbor SUIT_Command_Sequence, 1688 nil / bstr .cbor SUIT_Command_Sequence 1689 ] 1691 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 1692 SUIT_Wait_Events //= (suit-wait-event-power => int) 1693 SUIT_Wait_Events //= (suit-wait-event-network => int) 1694 SUIT_Wait_Events //= (suit-wait-event-other-device-version 1695 => SUIT_Wait_Event_Argument_Other_Device_Version) 1696 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 1697 SUIT_Wait_Events //= (suit-wait-event-time-of-day 1698 => uint); Time of Day (seconds since 00:00:00) 1699 SUIT_Wait_Events //= (suit-wait-event-day-of-week 1700 => uint); Days since Sunday 1702 SUIT_Wait_Event_Argument_Authorisation = int ; priority 1703 SUIT_Wait_Event_Argument_Power = int ; Power Level 1704 SUIT_Wait_Event_Argument_Network = int ; Network State 1705 SUIT_Wait_Event_Argument_Other_Device_Version = [ 1706 other-device: bstr, 1707 other-device-version: [+int] 1708 ] 1709 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 1710 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 1711 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 1712 8. Dependency processing 1714 Dependencies need careful handling on constrained systems. A 1715 dependency tree that is too deep can cause recursive handling to 1716 overflow stack space. Systems that parse all dependencies into an 1717 object tree can easily fill up available memory. Too many 1718 dependencies can overrun available storage space. 1720 The dependency handling system in this document is designed to 1721 address as many of these problems as possible. 1723 Dependencies MAY be addressed in one of three ways: 1725 1. Iterate by component 1727 2. Iterate by manifest 1729 3. Out-of-order 1731 Because each manifest has a list of components and a list of 1732 components defined by its dependencies, it is possible for the 1733 manifest processor to handle one component at a time, traversing the 1734 manifest tree once for each listed component. This, however consumes 1735 significant processing power. 1737 Alternatively, it is possible for a device with sufficient memory to 1738 accumulate all parameters for all listed component IDs. This will 1739 naturally consume more memory, but it allows the device to process 1740 the manifests in a single pass. 1742 It is expected that the simplest and most power sensitive devices 1743 will use option 2, with a fixed maximum number of components. 1745 Advanced devices may make use of the Strict Order parameter and 1746 enable parallel processing of some segments, or it may reorder some 1747 segments. To perform parallel processing, once the Strict Order 1748 parameter is set to False, the device may fork a process for each 1749 command until the Strict Order parameter is returned to True or the 1750 command sequence ends. Then, it joins all forked processes before 1751 continuing processing of commands. To perform out-of-order 1752 processing, a similar approach is used, except the device consumes 1753 all commands after the Strict Order parameter is set to False, then 1754 it sorts these commands into its preferred order, invokes them all, 1755 then continues processing. 1757 9. Access Control Lists 1759 To manage permissions in the manifest, there are three models that 1760 can be used. 1762 First, the simplest model requires that all manifests are 1763 authenticated by a single trusted key. This mode has the advantage 1764 that only a root manifest needs to be authenticated, since all of its 1765 dependencies have digests included in the root manifest. 1767 This simplest model can be extended by adding key delegation without 1768 much increase in complexity. 1770 A second model requires an ACL to be presented to the device, 1771 authenticated by a trusted party or stored on the device. This ACL 1772 grants access rights for specific component IDs or component ID 1773 prefixes to the listed identities or identity groups. Any identity 1774 may verify an image digest, but fetching into or fetching from a 1775 component ID requires approval from the ACL. 1777 A third model allows a device to provide even more fine-grained 1778 controls: The ACL lists the component ID or component ID prefix that 1779 an identity may use, and also lists the commands that the identity 1780 may use in combination with that component ID. 1782 10. SUIT digest container 1784 RFC 8152 [RFC8152] provides containers for signature, MAC, and 1785 encryption, but no basic digest container. The container needed for 1786 a digest requires a type identifier and a container for the raw 1787 digest data. Some forms of digest may require additional parameters. 1788 These can be added following the digest. This structure is described 1789 by the following CDDL. 1791 The algorithms listed are sufficient for verifying integrity of 1792 Firmware Updates as of this writing, however this may change over 1793 time. 1795 SUIT_Digest = [ 1796 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 1797 suit-digest-bytes : bytes, 1798 ? suit-digest-parameters : any 1799 ] 1801 digest-algorithm-ids /= algorithm-id-sha224 1802 digest-algorithm-ids /= algorithm-id-sha256 1803 digest-algorithm-ids /= algorithm-id-sha384 1804 digest-algorithm-ids /= algorithm-id-sha512 1805 digest-algorithm-ids /= algorithm-id-sha3-224 1806 digest-algorithm-ids /= algorithm-id-sha3-256 1807 digest-algorithm-ids /= algorithm-id-sha3-384 1808 digest-algorithm-ids /= algorithm-id-sha3-512 1810 algorithm-id-sha224 = 1 1811 algorithm-id-sha256 = 2 1812 algorithm-id-sha384 = 3 1813 algorithm-id-sha512 = 4 1814 algorithm-id-sha3-224 = 5 1815 algorithm-id-sha3-256 = 6 1816 algorithm-id-sha3-384 = 7 1817 algorithm-id-sha3-512 = 8 1819 11. Creating conditional sequences 1821 For some use cases, it is important to provide a sequence that can 1822 fail without terminating an update. For example, a dual-image XIP 1823 MCU may require an update that can be placed at one of two offsets. 1824 This has two implications, first, the digest of each offset will be 1825 different. Second, the image fetched for each offset will have a 1826 different URI. Conditional sequences allow this to be resolved in a 1827 simple way. 1829 The following JSON representation of a manifest demonstrates how this 1830 would be represented. It assumes that the bootloader and manifest 1831 processor take care of A/B switching and that the manifest is not 1832 aware of this distinction. 1834 { 1835 "structure-version" : 1, 1836 "sequence-number" : 7, 1837 "common" :{ 1838 "components" : [ 1839 [b'0'] 1840 ], 1841 "common-sequence" : [ 1842 { 1843 "directive-set-var" : { 1844 "size": 32567 1845 }, 1846 }, 1847 { 1848 "try-each" : [ 1849 [ 1850 {"condition-component-offset" : ""}, 1851 { 1852 "directive-set-var": { 1853 "digest" : "" 1854 } 1855 } 1856 ], 1857 [ 1858 {"condition-component-offset" : ""}, 1859 { 1860 "directive-set-var": { 1861 "digest" : "" 1862 } 1863 } 1864 ], 1865 [{ "abort" : null }] 1866 ] 1867 } 1868 ] 1869 } 1870 "fetch" : [ 1871 { 1872 "try-each" : [ 1873 [ 1874 {"condition-component-offset" : ""}, 1875 { 1876 "directive-set-var": { 1877 "uri" : "" 1878 } 1879 } 1880 ], 1881 [ 1882 {"condition-component-offset" : ""}, 1883 { 1884 "directive-set-var": { 1885 "uri" : "" 1886 } 1887 } 1888 ], 1889 [{ "directive-abort" : null }] 1890 ] 1892 }, 1893 "fetch" : null 1894 ] 1895 } 1897 12. Full CDDL 1899 In order to create a valid SUIT Manifest document the structure of 1900 the corresponding CBOR message MUST adhere to the following CDDL data 1901 definition. 1903 SUIT_Outer_Wrapper = { 1904 suit-authentication-wrapper => bstr .cbor SUIT_Authentication_Wrapper / nil, 1905 $$SUIT_Manifest_Wrapped, 1906 suit-dependency-resolution => bstr .cbor SUIT_Command_Sequence, 1907 suit-payload-fetch => bstr .cbor SUIT_Command_Sequence, 1908 suit-install => bstr .cbor SUIT_Command_Sequence, 1909 suit-text => bstr .cbor SUIT_Text_Map, 1910 suit-coswid => bstr .cbor concise-software-identity 1911 } 1913 SUIT_Authentication_Wrapper = [ + ( 1914 COSE_Mac_Tagged / 1915 COSE_Sign_Tagged / 1916 COSE_Mac0_Tagged / 1917 COSE_Sign1_Tagged) 1918 ] 1920 SUIT_Encryption_Wrapper = COSE_Encrypt_Tagged / COSE_Encrypt0_Tagged 1922 $$SUIT_Manifest_Wrapped //= (suit-manifest => bstr .cbor SUIT_Manifest) 1923 $$SUIT_Manifest_Wrapped //= ( 1924 suit-manifest-encryption-info => bstr .cbor SUIT_Encryption_Wrapper, 1925 suit-manifest-encrypted => bstr 1926 ) 1928 COSE_Mac_Tagged = any 1929 COSE_Sign_Tagged = any 1930 COSE_Mac0_Tagged = any 1931 COSE_Sign1_Tagged = any 1932 COSE_Encrypt_Tagged = any 1933 COSE_Encrypt0_Tagged = any 1935 SUIT_Digest = [ 1936 suit-digest-algorithm-id : $suit-digest-algorithm-ids, 1937 suit-digest-bytes : bytes, 1938 ? suit-digest-parameters : any 1939 ] 1940 ; Named Information Hash Algorithm Identifiers 1941 suit-digest-algorithm-ids /= algorithm-id-sha224 1942 suit-digest-algorithm-ids /= algorithm-id-sha256 1943 suit-digest-algorithm-ids /= algorithm-id-sha384 1944 suit-digest-algorithm-ids /= algorithm-id-sha512 1945 suit-digest-algorithm-ids /= algorithm-id-sha3-224 1946 suit-digest-algorithm-ids /= algorithm-id-sha3-256 1947 suit-digest-algorithm-ids /= algorithm-id-sha3-384 1948 suit-digest-algorithm-ids /= algorithm-id-sha3-512 1950 SUIT_Manifest = { 1951 suit-manifest-version => 1, 1952 suit-manifest-sequence-number => uint, 1953 ? suit-common => bstr .cbor SUIT_Common, 1954 ? suit-dependency-resolution => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 1955 ? suit-payload-fetch => SUIT_Digest / bstr .cbor SUIT_Command_Sequence, 1956 ? suit-install => SUIT_Digest / bstr .cbor SUIT_Command_Sequence 1957 ? suit-validate => bstr .cbor SUIT_Command_Sequence 1958 ? suit-load => bstr .cbor SUIT_Command_Sequence 1959 ? suit-run => bstr .cbor SUIT_Command_Sequence 1960 ? suit-text => SUIT_Digest / bstr .cbor SUIT_Text_Map 1961 ? suit-coswid => SUIT_Digest / bstr .cbor concise-software-identity 1962 } 1964 SUIT_Common = { 1965 ? suit-dependencies => bstr .cbor SUIT_Dependencies, 1966 ? suit-components => bstr .cbor SUIT_Components, 1967 ? suit-dependency-components => bstr .cbor SUIT_Component_References, 1968 ? suit-common-sequence => bstr .cbor SUIT_Command_Sequence, 1969 } 1971 SUIT_Dependencies = [ + SUIT_Dependency ] 1972 SUIT_Components = [ + SUIT_Component_Identifier ] 1973 SUIT_Component_References = [ + SUIT_Component_Reference ] 1975 concise-software-identity = any 1977 SUIT_Dependency = { 1978 suit-dependency-digest => SUIT_Digest, 1979 suit-dependency-prefix => SUIT_Component_Identifier, 1980 } 1982 SUIT_Component_Identifier = [* bstr] 1984 SUIT_Component_Reference = { 1985 suit-component-identifier => SUIT_Component_Identifier, 1986 suit-component-dependency-index => uint 1988 } 1990 SUIT_Command_Sequence = [ + (SUIT_Condition // SUIT_Directive // SUIT_Command_Custom) ] 1992 SUIT_Command_Custom = (nint, bstr) 1993 SUIT_Condition //= (suit-condition-vendor-identifier, nil) 1994 SUIT_Condition //= (suit-condition-class-identifier, nil) 1995 SUIT_Condition //= (suit-condition-device-identifier, nil) 1996 SUIT_Condition //= (suit-condition-image-match, nil) 1997 SUIT_Condition //= (suit-condition-image-not-match, nil) 1998 SUIT_Condition //= (suit-condition-use-before, uint) 1999 SUIT_Condition //= (suit-condition-minimum-battery, uint) 2000 SUIT_Condition //= (suit-condition-update-authorised, int) 2001 SUIT_Condition //= (suit-condition-version, SUIT_Condition_Version_Argument) 2002 SUIT_Condition //= (suit-condition-component-offset, uint) 2003 SUIT_Condition //= (suit-condition-custom, bstr) 2005 RFC4122_UUID = bstr .size 16 2007 SUIT_Condition_Version_Argument = [ 2008 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Types, 2009 suit-condition-version-comparison: SUIT_Condition_Version_Comparison_Value 2010 ] 2011 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater 2012 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-greater-equal 2013 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-equal 2014 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser-equal 2015 SUIT_Condition_Version_Comparison_Types /= suit-condition-version-comparison-lesser 2017 suit-condition-version-comparison-greater = 1 2018 suit-condition-version-comparison-greater-equal = 2 2019 suit-condition-version-comparison-equal = 3 2020 suit-condition-version-comparison-lesser-equal = 4 2021 suit-condition-version-comparison-lesser = 5 2023 SUIT_Condition_Version_Comparison_Value = [+int] 2025 SUIT_Directive //= (suit-directive-set-component-index, uint/bool) 2026 SUIT_Directive //= (suit-directive-set-dependency-index, uint/bool) 2027 SUIT_Directive //= (suit-directive-run-sequence, bstr .cbor SUIT_Command_Sequence) 2028 SUIT_Directive //= (suit-directive-try-each, SUIT_Directive_Try_Each_Argument) 2029 SUIT_Directive //= (suit-directive-process-dependency, nil) 2030 SUIT_Directive //= (suit-directive-set-parameters, {+ SUIT_Parameters}) 2031 SUIT_Directive //= (suit-directive-override-parameters, {+ SUIT_Parameters}) 2032 SUIT_Directive //= (suit-directive-fetch, nil) 2033 SUIT_Directive //= (suit-directive-copy, nil) 2034 SUIT_Directive //= (suit-directive-swap, nil) 2035 SUIT_Directive //= (suit-directive-run, nil) 2036 SUIT_Directive //= (suit-directive-wait, { + SUIT_Wait_Events }) 2037 SUIT_Directive //= (suit-directive-run-with-arguments, bstr) 2039 SUIT_Directive_Try_Each_Argument = [ 2040 + bstr .cbor SUIT_Command_Sequence, 2041 nil / bstr .cbor SUIT_Command_Sequence 2042 ] 2044 SUIT_Wait_Events //= (suit-wait-event-authorisation => int) 2045 SUIT_Wait_Events //= (suit-wait-event-power => int) 2046 SUIT_Wait_Events //= (suit-wait-event-network => int) 2047 SUIT_Wait_Events //= (suit-wait-event-other-device-version 2048 => SUIT_Wait_Event_Argument_Other_Device_Version) 2049 SUIT_Wait_Events //= (suit-wait-event-time => uint); Timestamp 2050 SUIT_Wait_Events //= (suit-wait-event-time-of-day 2051 => uint); Time of Day (seconds since 00:00:00) 2052 SUIT_Wait_Events //= (suit-wait-event-day-of-week 2053 => uint); Days since Sunday 2055 SUIT_Wait_Event_Argument_Authorisation = int ; priority 2056 SUIT_Wait_Event_Argument_Power = int ; Power Level 2057 SUIT_Wait_Event_Argument_Network = int ; Network State 2058 SUIT_Wait_Event_Argument_Other_Device_Version = [ 2059 other-device: bstr, 2060 other-device-version: [+int] 2061 ] 2062 SUIT_Wait_Event_Argument_Time = uint ; Timestamp 2063 SUIT_Wait_Event_Argument_Time_Of_Day = uint ; Time of Day (seconds since 00:00:00) 2064 SUIT_Wait_Event_Argument_Day_Of_Week = uint ; Days since Sunday 2066 SUIT_Parameters //= (suit-parameter-strict-order => bool) 2067 SUIT_Parameters //= (suit-parameter-coerce-condition-failure => bool) 2068 SUIT_Parameters //= (suit-parameter-vendor-id => bstr) 2069 SUIT_Parameters //= (suit-parameter-class-id => bstr) 2070 SUIT_Parameters //= (suit-parameter-device-id => bstr) 2071 SUIT_Parameters //= (suit-parameter-uri => bstr) 2072 SUIT_Parameters //= (suit-parameter-encryption-info => bstr .cbor SUIT_Encryption_Info) 2073 SUIT_Parameters //= (suit-parameter-compression-info => bstr .cbor SUIT_Compression_Info) 2074 SUIT_Parameters //= (suit-parameter-unpack-info => bstr .cbor SUIT_Unpack_Info) 2075 SUIT_Parameters //= (suit-parameter-source-component => bstr .cbor SUIT_Component_Identifier) 2076 SUIT_Parameters //= (suit-parameter-image-digest => bstr .cbor SUIT_Digest) 2077 SUIT_Parameters //= (suit-parameter-image-size => uint) 2078 SUIT_Parameters //= (suit-parameter-uri-list => bstr .cbor SUIT_Component_URI_List) 2079 SUIT_Parameters //= (suit-parameter-custom => int/bool/bstr) 2081 SUIT_Component_URI_List = [ + [priority: int, uri: tstr] ] 2082 SUIT_Priority_Parameter_List = [ + [priority: int, parameters: { + SUIT_Parameters }] ] 2084 SUIT_Encryption_Info = COSE_Encrypt_Tagged/COSE_Encrypt0_Tagged 2085 SUIT_Compression_Info = { 2086 suit-compression-algorithm => SUIT_Compression_Algorithms 2087 ? suit-compression-parameters => bstr 2088 } 2090 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_gzip 2091 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_bzip2 2092 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lz4 2093 SUIT_Compression_Algorithms /= SUIT_Compression_Algorithm_lzma 2095 SUIT_Compression_Algorithm_gzip = 1 2096 SUIT_Compression_Algorithm_bzip2 = 2 2097 SUIT_Compression_Algorithm_deflate = 3 2098 SUIT_Compression_Algorithm_lz4 = 4 2099 SUIT_Compression_Algorithm_lzma = 7 2101 SUIT_Unpack_Info = { 2102 suit-unpack-algorithm => SUIT_Unpack_Algorithms 2103 ? suit-unpack-parameters => bstr 2104 } 2106 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Delta 2107 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Hex 2108 SUIT_Unpack_Algorithms /= SUIT_Unpack_Algorithm_Elf 2110 SUIT_Unpack_Algorithm_Delta = 1 2111 SUIT_Unpack_Algorithm_Hex = 2 2112 SUIT_Unpack_Algorithm_Elf = 3 2114 SUIT_Text_Map = {int => tstr} 2116 suit-authentication-wrapper = 1 2117 suit-manifest = 2 2119 suit-manifest-encryption-info = 3 2120 suit-manifest-encrypted = 4 2122 suit-manifest-version = 1 2123 suit-manifest-sequence-number = 2 2124 suit-common = 3 2125 suit-dependency-resolution = 7 2126 suit-payload-fetch = 8 2127 suit-install = 9 2128 suit-validate = 10 2129 suit-load = 11 2130 suit-run = 12 2131 suit-text = 13 2132 suit-coswid = 14 2134 suit-dependencies = 1 2135 suit-components = 2 2136 suit-dependency-components = 3 2137 suit-common-sequence = 4 2139 suit-dependency-digest = 1 2140 suit-dependency-prefix = 2 2142 suit-component-identifier = 1 2143 suit-component-dependency-index = 2 2145 suit-command-custom = nint 2147 suit-condition-vendor-identifier = 1 2148 suit-condition-class-identifier = 2 2149 suit-condition-image-match = 3 2150 suit-condition-use-before = 4 2151 suit-condition-component-offset = 5 2152 suit-condition-custom = 6 2154 suit-condition-device-identifier = 24 2155 suit-condition-image-not-match = 25 2156 suit-condition-minimum-battery = 26 2157 suit-condition-update-authorised = 27 2158 suit-condition-version = 28 2160 suit-directive-set-component-index = 12 2161 suit-directive-set-dependency-index = 13 2162 suit-directive-abort = 14 2163 suit-directive-try-each = 15 2164 suit-directive-do-each = 16 ; TBD 2165 suit-directive-map-filter = 17 ; TBD 2166 suit-directive-process-dependency = 18 2167 suit-directive-set-parameters = 19 2168 suit-directive-override-parameters = 20 2169 suit-directive-fetch = 21 2170 suit-directive-copy = 22 2171 suit-directive-run = 23 2173 suit-directive-wait = 29 2174 suit-directive-run-sequence = 30 2175 suit-directive-run-with-arguments = 31 2176 suit-directive-swap = 32 2177 suit-wait-event-argument-authorisation = 1 2178 suit-wait-event-power = 2 2179 suit-wait-event-network = 3 2180 suit-wait-event-other-device-version = 4 2181 suit-wait-event-time = 5 2182 suit-wait-event-time-of-day = 6 2183 suit-wait-event-day-of-week = 7 2184 suit-wait-event-authorisation = 8 2186 suit-parameter-strict-order = 1 2187 suit-parameter-coerce-condition-failure = 2 2188 suit-parameter-vendor-id = 3 2189 suit-parameter-class-id = 4 2190 suit-parameter-device-id = 5 2191 suit-parameter-uri = 6 2192 suit-parameter-encryption-info = 7 2193 suit-parameter-compression-info = 8 2194 suit-parameter-unpack-info = 9 2195 suit-parameter-source-component = 10 2196 suit-parameter-image-digest = 11 2197 suit-parameter-image-size = 12 2199 suit-parameter-uri-list = 24 2200 suit-parameter-uri-list-append = 25 2201 suit-parameter-prioritised-parameters = 26 2203 suit-parameter-custom = nint 2205 suit-compression-algorithm = 1 2206 suit-compression-parameters = 2 2208 suit-unpack-algorithm = 1 2209 suit-unpack-parameters = 2 2211 13. Examples 2213 The following examples demonstrate a small subset of the 2214 functionality of the manifest. However, despite this, even a simple 2215 manifest processor can execute most of these manifests. 2217 None of these examples include authentication. This is provided via 2218 RFC 8152 [RFC8152], and is omitted for clarity. 2220 13.1. Example 0: 2222 Secure boot only. 2224 The following JSON shows the intended behaviour of the manifest. 2226 { 2227 "structure-version": 1, 2228 "sequence-number": 1, 2229 "run-image": [ 2230 { "directive-set-component": 0 }, 2231 { "condition-image": null }, 2232 { "directive-run": null } 2233 ], 2234 "common": { 2235 "common-sequence": [ 2236 { 2237 "directive-set-var": { 2238 "digest": "00112233445566778899aabbccddeeff" 2239 "0123456789abcdeffedcba9876543210", 2240 "size": 34768 2241 } 2242 } 2243 ], 2244 "components": [ 2245 [ 2246 "Flash", 2247 78848 2248 ] 2249 ] 2250 } 2251 } 2253 Converted into the SUIT manifest, this produces: 2255 { 2256 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658405e5f' 2257 h'b84f9e9729a4d74096ad485921e842b4e320cc3fa177' 2258 h'8c2807377e1969e42449b3261109d273df4b3ceb9a61' 2259 h'06a46f0a7938de9a8441ab515b82463b39ee', 2260 / manifest / 2 : h'a40101020103583ea2024c818245466c6173684300340104' 2261 h'582c8213a20b8202582000112233445566778899aabbccdd' 2262 h'eeff0123456789abcdeffedcba98765432100c1987d00c47' 2263 h'860c0003f617f6' \ 2264 { 2265 / structure-version / 1 : 1, 2266 / sequence-number / 2 : 1, 2267 / common / 3 : h'a2024c818245466c6173684300340104582c8213a20b82' 2268 h'02582000112233445566778899aabbccddeeff01234567' 2269 h'89abcdeffedcba98765432100c1987d0' \ { 2270 / components / 2 : h'818245466c61736843003401' \ 2271 [ 2272 [h'466c617368', h'003401'], 2273 ], 2274 / common-sequence / 4 : h'8213a20b820258200011223344556677' 2275 h'8899aabbccddeeff0123456789abcdef' 2276 h'fedcba98765432100c1987d0' \ [ 2277 / set-vars / 19, { 2278 / digest / 11 : [ 2, 2279 h'00112233445566778899aabbccddeeff0123456789ab' 2280 h'cdeffedcba9876543210' ], 2281 / size / 12 : 34768, 2282 }, 2283 ], 2284 }, 2285 / run-image / 12 : h'860c0003f617f6' \ [ 2286 / set-component-index / 12, 0, 2287 / condition-image / 3, None, 2288 / run / 23, None, 2289 ], 2290 } 2291 } 2293 Total size of outer wrapper without COSE authentication object: 85 2295 Outer: 2297 a201f602584fa40101020103583ea2024c818245466c6173684300340104582c8213a20b 2298 8202582000112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210 2299 0c1987d00c47860c0003f617f6 2301 Total size of outer wrapper with COSE authentication object: 170 2302 Signed Outer: 2304 a2015854d28443a10126a1044874657374206b6579f658405e5fb84f9e9729a4d74096ad 2305 485921e842b4e320cc3fa1778c2807377e1969e42449b3261109d273df4b3ceb9a6106a4 2306 6f0a7938de9a8441ab515b82463b39ee02584fa40101020103583ea2024c818245466c61 2307 73684300340104582c8213a20b8202582000112233445566778899aabbccddeeff012345 2308 6789abcdeffedcba98765432100c1987d00c47860c0003f617f6 2310 13.2. Example 1: 2312 Simultaneous download and installation of payload. 2314 The following JSON shows the intended behaviour of the manifest. 2316 { 2317 "structure-version": 1, 2318 "sequence-number": 2, 2319 "apply-image": [ 2320 { "directive-set-component": 0 }, 2321 { 2322 "directive-set-var": { 2323 "uri": "http://example.com/file.bin" 2324 } 2325 }, 2326 { "directive-fetch": null } 2327 ], 2328 "common": { 2329 "common-sequence": [ 2330 { 2331 "directive-set-var": { 2332 "digest": "00112233445566778899aabbccddeeff" 2333 "0123456789abcdeffedcba9876543210", 2334 "size": 34768 2335 } 2336 } 2337 ], 2338 "components": [ 2339 [ 2340 "Flash", 2341 78848 2342 ] 2343 ] 2344 } 2345 } 2347 Converted into the SUIT manifest, this produces: 2349 { 2350 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658403d4e' 2351 h'9ff1ca8803a81ae1e2b13df28c527a4d6975e860035e' 2352 h'e9a88576b5e6f2bf12f33017e88157bcff58d712e7f8' 2353 h'010821ae0f82f78eb681b61697345e655cf4', 2354 / manifest / 2 : h'a40101020203583ea2024c818245466c6173684300340104' 2355 h'582c8213a20b8202582000112233445566778899aabbccdd' 2356 h'eeff0123456789abcdeffedcba98765432100c1987d00958' 2357 h'25860c0013a106781b687474703a2f2f6578616d706c652e' 2358 h'636f6d2f66696c652e62696e15f6' \ 2359 { 2360 / structure-version / 1 : 1, 2361 / sequence-number / 2 : 2, 2362 / common / 3 : h'a2024c818245466c6173684300340104582c8213a20b82' 2363 h'02582000112233445566778899aabbccddeeff01234567' 2364 h'89abcdeffedcba98765432100c1987d0' \ { 2365 / components / 2 : h'818245466c61736843003401' \ 2366 [ 2367 [h'466c617368', h'003401'], 2368 ], 2369 / common-sequence / 4 : h'8213a20b820258200011223344556677' 2370 h'8899aabbccddeeff0123456789abcdef' 2371 h'fedcba98765432100c1987d0' \ [ 2372 / set-vars / 19, { 2373 / digest / 11 : [ 2, 2374 h'00112233445566778899aabbccddeeff0123456789ab' 2375 h'cdeffedcba9876543210' ], 2376 / size / 12 : 34768, 2377 }, 2378 ], 2379 }, 2380 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 2381 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 2382 / set-component-index / 12, 0, 2383 / set-vars / 19, { 2384 / uri / 6 : http://example.com/file.bin, 2385 }, 2386 / fetch / 21, None, 2387 ], 2388 } 2389 } 2391 Total size of outer wrapper without COSE authentication object: 116 2393 Outer: 2395 a201f602586ea40101020203583ea2024c818245466c6173684300340104582c8213a20b 2396 8202582000112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210 2397 0c1987d0095825860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f6669 2398 6c652e62696e15f6 2400 Total size of outer wrapper with COSE authentication object: 201 2402 Signed Outer: 2404 a2015854d28443a10126a1044874657374206b6579f658403d4e9ff1ca8803a81ae1e2b1 2405 3df28c527a4d6975e860035ee9a88576b5e6f2bf12f33017e88157bcff58d712e7f80108 2406 21ae0f82f78eb681b61697345e655cf402586ea40101020203583ea2024c818245466c61 2407 73684300340104582c8213a20b8202582000112233445566778899aabbccddeeff012345 2408 6789abcdeffedcba98765432100c1987d0095825860c0013a106781b687474703a2f2f65 2409 78616d706c652e636f6d2f66696c652e62696e15f6 2411 13.3. Example 2: 2413 Compatibility test, simultaneous download and installation, and 2414 secure boot. 2416 The following JSON shows the intended behaviour of the manifest. 2418 { 2419 "structure-version": 1, 2420 "sequence-number": 3, 2421 "common": { 2422 "common-sequence": [ 2423 { 2424 "directive-set-var": { 2425 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 2426 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45", 2427 "digest": "00112233445566778899aabbccddeeff" 2428 "0123456789abcdeffedcba9876543210", 2429 "size": 34768 2430 } 2431 }, 2432 { "condition-vendor-id": null }, 2433 { "condition-class-id": null } 2434 ], 2435 "components": [ 2436 [ 2437 "Flash", 2438 78848 2439 ] 2440 ] 2441 }, 2442 "apply-image": [ 2443 { "directive-set-component": 0 }, 2444 { 2445 "directive-set-var": { 2446 "uri": "http://example.com/file.bin" 2447 } 2448 }, 2449 { "directive-fetch": null } 2450 ], 2451 "run-image": [ 2452 { "directive-set-component": 0 }, 2453 { "condition-image": null }, 2454 { "directive-run": null } 2455 ] 2456 } 2458 Converted into the SUIT manifest, this produces: 2460 { 2461 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840e637' 2462 h'5a57596cb4a35a90a30b4099bccf7e2352a9829bf7bb' 2463 h'1b56cfc0e713955be4fd360e366c94e32dfc344695b1' 2464 h'20b2c59732b2e3f079fc2693c5a459d9ce44', 2465 / manifest / 2 : h'a501010203035866a2024c818245466c6173684300340104' 2466 h'58548613a40350fa6b4a53d5ad5fdfbe9de663e4d41ffe04' 2467 h'501492af1425695e48bf429b2d51f2ab450b820258200011' 2468 h'2233445566778899aabbccddeeff0123456789abcdeffedc' 2469 h'ba98765432100c1987d001f602f6095825860c0013a10678' 2470 h'1b687474703a2f2f6578616d706c652e636f6d2f66696c65' 2471 h'2e62696e15f60c47860c0003f617f6' \ 2472 { 2473 / structure-version / 1 : 1, 2474 / sequence-number / 2 : 3, 2475 / common / 3 : h'a2024c818245466c617368430034010458548613a40350' 2476 h'fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425' 2477 h'695e48bf429b2d51f2ab450b8202582000112233445566' 2478 h'778899aabbccddeeff0123456789abcdeffedcba987654' 2479 h'32100c1987d001f602f6' \ { 2480 / components / 2 : h'818245466c61736843003401' \ 2481 [ 2482 [h'466c617368', h'003401'], 2483 ], 2484 / common-sequence / 4 : h'8613a40350fa6b4a53d5ad5fdfbe9de6' 2485 h'63e4d41ffe04501492af1425695e48bf' 2486 h'429b2d51f2ab450b8202582000112233' 2487 h'445566778899aabbccddeeff01234567' 2488 h'89abcdeffedcba98765432100c1987d0' 2489 h'01f602f6' \ [ 2490 / set-vars / 19, { 2491 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 2492 h'fe', 2493 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 2494 / digest / 11 : [ 2, 2495 h'00112233445566778899aabbccddeeff0123456789ab' 2496 h'cdeffedcba9876543210' ], 2497 / size / 12 : 34768, 2498 }, 2499 / condition-vendor-id / 1, None, 2500 / condition-class-id / 2, None, 2501 ], 2502 }, 2503 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 2504 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 2505 / set-component-index / 12, 0, 2506 / set-vars / 19, { 2507 / uri / 6 : http://example.com/file.bin, 2508 }, 2509 / fetch / 21, None, 2510 ], 2511 / run-image / 12 : h'860c0003f617f6' \ [ 2512 / set-component-index / 12, 0, 2513 / condition-image / 3, None, 2514 / run / 23, None, 2515 ], 2516 } 2517 } 2519 Total size of outer wrapper without COSE authentication object: 165 2521 Outer: 2523 a201f602589fa501010203035866a2024c818245466c617368430034010458548613a403 2524 50fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab450b 2525 8202582000112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210 2526 0c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e636f 2527 6d2f66696c652e62696e15f60c47860c0003f617f6 2529 Total size of outer wrapper with COSE authentication object: 250 2531 Signed Outer: 2533 a2015854d28443a10126a1044874657374206b6579f65840e6375a57596cb4a35a90a30b 2534 4099bccf7e2352a9829bf7bb1b56cfc0e713955be4fd360e366c94e32dfc344695b120b2 2535 c59732b2e3f079fc2693c5a459d9ce4402589fa501010203035866a2024c818245466c61 2536 7368430034010458548613a40350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af14 2537 25695e48bf429b2d51f2ab450b8202582000112233445566778899aabbccddeeff012345 2538 6789abcdeffedcba98765432100c1987d001f602f6095825860c0013a106781b68747470 2539 3a2f2f6578616d706c652e636f6d2f66696c652e62696e15f60c47860c0003f617f6 2541 13.4. Example 3: 2543 Compatibility test, simultaneous download and installation, load from 2544 external storage, and secure boot. 2546 The following JSON shows the intended behaviour of the manifest. 2548 { 2549 "structure-version": 1, 2550 "sequence-number": 4, 2551 "common": { 2552 "common-sequence": [ 2553 { 2554 "directive-set-var": { 2555 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 2556 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 2557 } 2558 }, 2559 { "directive-set-component": 0 }, 2560 { 2561 "directive-set-var": { 2562 "digest": "00112233445566778899aabbccddeeff" 2563 "0123456789abcdeffedcba9876543210", 2564 "size": 34768 2565 } 2566 }, 2567 { "directive-set-component": 1 }, 2568 { 2569 "directive-set-var": { 2570 "digest": "00112233445566778899aabbccddeeff" 2571 "0123456789abcdeffedcba9876543210", 2572 "size": 34768 2573 } 2574 }, 2575 { "condition-vendor-id": null }, 2576 { "condition-class-id": null } 2577 ], 2578 "components": [ 2579 [ 2580 "Flash", 2581 78848 2582 ], 2583 [ 2584 "RAM", 2585 1024 2586 ] 2587 ] 2588 }, 2589 "apply-image": [ 2590 { "directive-set-component": 0 }, 2591 { 2592 "directive-set-var": { 2593 "uri": "http://example.com/file.bin" 2594 } 2595 }, 2596 { "directive-fetch": null } 2597 ], 2598 "run-image": [ 2599 { "directive-set-component": 0 }, 2600 { "condition-image": null }, 2601 { "directive-set-component": 1 }, 2602 { 2603 "directive-set-var": { 2604 "source-index": 0 2605 } 2606 }, 2607 { "directive-fetch": null }, 2608 { "condition-image": null }, 2609 { "directive-run": null } 2611 ] 2612 } 2614 Converted into the SUIT manifest, this produces: 2616 { 2617 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840ef4b' 2618 h'399c55131a51bebafb46da6e6b79c59417fdefea7b87' 2619 h'e4234bf8f978094e3092c8506d8a912fbacaec5ba365' 2620 h'24ae0e4bb1aa14197e4d0afe10ba47e29e5a', 2621 / manifest / 2 : h'a50101020403589fa20254828245466c6173684300340182' 2622 h'4352414d4200040458858e13a20350fa6b4a53d5ad5fdfbe' 2623 h'9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab' 2624 h'450c0013a20b8202582000112233445566778899aabbccdd' 2625 h'eeff0123456789abcdeffedcba98765432100c1987d00c01' 2626 h'13a20b8202582000112233445566778899aabbccddeeff01' 2627 h'23456789abcdeffedcba98765432100c1987d001f602f609' 2628 h'5825860c0013a106781b687474703a2f2f6578616d706c65' 2629 h'2e636f6d2f66696c652e62696e15f60c518e0c0003f60c01' 2630 h'13a10a0015f603f617f6' \ 2631 { 2632 / structure-version / 1 : 1, 2633 / sequence-number / 2 : 4, 2634 / common / 3 : h'a20254828245466c61736843003401824352414d420004' 2635 h'0458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d41f' 2636 h'fe04501492af1425695e48bf429b2d51f2ab450c0013a2' 2637 h'0b8202582000112233445566778899aabbccddeeff0123' 2638 h'456789abcdeffedcba98765432100c1987d00c0113a20b' 2639 h'8202582000112233445566778899aabbccddeeff012345' 2640 h'6789abcdeffedcba98765432100c1987d001f602f6' \ { 2641 / components / 2 : h'828245466c61736843003401824352414d4200' 2642 h'04' \ 2643 [ 2644 [h'466c617368', h'003401'], 2645 [h'52414d', h'0004'], 2646 ], 2647 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 2648 h'63e4d41ffe04501492af1425695e48bf' 2649 h'429b2d51f2ab450c0013a20b82025820' 2650 h'00112233445566778899aabbccddeeff' 2651 h'0123456789abcdeffedcba9876543210' 2652 h'0c1987d00c0113a20b82025820001122' 2653 h'33445566778899aabbccddeeff012345' 2654 h'6789abcdeffedcba98765432100c1987' 2655 h'd001f602f6' \ [ 2656 / set-vars / 19, { 2657 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 2658 h'fe', 2660 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 2661 }, 2662 / set-component-index / 12, 0, 2663 / set-vars / 19, { 2664 / digest / 11 : [ 2, 2665 h'00112233445566778899aabbccddeeff0123456789ab' 2666 h'cdeffedcba9876543210' ], 2667 / size / 12 : 34768, 2668 }, 2669 / set-component-index / 12, 1, 2670 / set-vars / 19, { 2671 / digest / 11 : [ 2, 2672 h'00112233445566778899aabbccddeeff0123456789ab' 2673 h'cdeffedcba9876543210' ], 2674 / size / 12 : 34768, 2675 }, 2676 / condition-vendor-id / 1, None, 2677 / condition-class-id / 2, None, 2678 ], 2679 }, 2680 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 2681 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 2682 / set-component-index / 12, 0, 2683 / set-vars / 19, { 2684 / uri / 6 : http://example.com/file.bin, 2685 }, 2686 / fetch / 21, None, 2687 ], 2688 / run-image / 12 : h'8e0c0003f60c0113a10a0015f603f617f6' \ [ 2689 / set-component-index / 12, 0, 2690 / condition-image / 3, None, 2691 / set-component-index / 12, 1, 2692 / set-vars / 19, { 2693 / source-component / 10 : 0, 2694 }, 2695 / fetch / 21, None, 2696 / condition-image / 3, None, 2697 / run / 23, None, 2698 ], 2699 } 2700 } 2702 Total size of outer wrapper without COSE authentication object: 232 2704 Outer: 2706 a201f60258e2a50101020403589fa20254828245466c61736843003401824352414d4200 2707 040458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf 2708 429b2d51f2ab450c0013a20b8202582000112233445566778899aabbccddeeff01234567 2709 89abcdeffedcba98765432100c1987d00c0113a20b8202582000112233445566778899aa 2710 bbccddeeff0123456789abcdeffedcba98765432100c1987d001f602f6095825860c0013 2711 a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696e15f60c518e 2712 0c0003f60c0113a10a0015f603f617f6 2714 Total size of outer wrapper with COSE authentication object: 317 2716 Signed Outer: 2718 a2015854d28443a10126a1044874657374206b6579f65840ef4b399c55131a51bebafb46 2719 da6e6b79c59417fdefea7b87e4234bf8f978094e3092c8506d8a912fbacaec5ba36524ae 2720 0e4bb1aa14197e4d0afe10ba47e29e5a0258e2a50101020403589fa20254828245466c61 2721 736843003401824352414d4200040458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d4 2722 1ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b8202582000112233445566 2723 778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113a20b8202 2724 582000112233445566778899aabbccddeeff0123456789abcdeffedcba98765432100c19 2725 87d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f 2726 66696c652e62696e15f60c518e0c0003f60c0113a10a0015f603f617f6 2728 13.5. Example 4: 2730 Compatibility test, simultaneous download and installation, load and 2731 decompress from external storage, and secure boot. 2733 The following JSON shows the intended behaviour of the manifest. 2735 { 2736 "structure-version": 1, 2737 "sequence-number": 5, 2738 "common": { 2739 "common-sequence": [ 2740 { 2741 "directive-set-var": { 2742 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 2743 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 2744 } 2745 }, 2746 { "directive-set-component": 0 }, 2747 { 2748 "directive-set-var": { 2749 "digest": "00112233445566778899aabbccddeeff" 2750 "0123456789abcdeffedcba9876543210", 2751 "size": 34768 2752 } 2753 }, 2754 { "directive-set-component": 1 }, 2755 { 2756 "directive-set-var": { 2757 "digest": "0123456789abcdeffedcba9876543210" 2758 "00112233445566778899aabbccddeeff", 2759 "size": 34768 2760 } 2761 }, 2762 { "condition-vendor-id": null }, 2763 { "condition-class-id": null } 2764 ], 2765 "components": [ 2766 [ 2767 "Flash", 2768 78848 2769 ], 2770 [ 2771 "RAM", 2772 1024 2773 ] 2774 ] 2775 }, 2776 "apply-image": [ 2777 { "directive-set-component": 0 }, 2778 { 2779 "directive-set-var": { 2780 "uri": "http://example.com/file.bin" 2781 } 2782 }, 2783 { "directive-fetch": null } 2784 ], 2785 "load-image": [ 2786 { "directive-set-component": 0 }, 2787 { "condition-image": null }, 2788 { "directive-set-component": 1 }, 2789 { 2790 "directive-set-var": { 2791 "source-index": 0, 2792 "compression-info": { 2793 "algorithm": "gzip" 2794 } 2795 } 2796 }, 2797 { "directive-copy": null } 2798 ], 2799 "run-image": [ 2800 { "condition-image": null }, 2801 { "directive-run": null } 2803 ] 2804 } 2806 Converted into the SUIT manifest, this produces: 2808 { 2809 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840e90d' 2810 h'ab6e502bad8132adf86b4d78defaebac64fa6c6b2882' 2811 h'd12b36f492b14ce75819ed3524de4d66ddfd5e1d80a5' 2812 h'984004c1ac9b003b2da32589583a93c541dd', 2813 / manifest / 2 : h'a60101020503589fa20254828245466c6173684300340182' 2814 h'4352414d4200040458858e13a20350fa6b4a53d5ad5fdfbe' 2815 h'9de663e4d41ffe04501492af1425695e48bf429b2d51f2ab' 2816 h'450c0013a20b8202582000112233445566778899aabbccdd' 2817 h'eeff0123456789abcdeffedcba98765432100c1987d00c01' 2818 h'13a20b820258200123456789abcdeffedcba987654321000' 2819 h'112233445566778899aabbccddeeff0c1987d001f602f609' 2820 h'5825860c0013a106781b687474703a2f2f6578616d706c65' 2821 h'2e636f6d2f66696c652e62696e15f60b528a0c0003f60c01' 2822 h'13a20843a101010a0016f60c458403f617f6' \ 2823 { 2824 / structure-version / 1 : 1, 2825 / sequence-number / 2 : 5, 2826 / common / 3 : h'a20254828245466c61736843003401824352414d420004' 2827 h'0458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d41f' 2828 h'fe04501492af1425695e48bf429b2d51f2ab450c0013a2' 2829 h'0b8202582000112233445566778899aabbccddeeff0123' 2830 h'456789abcdeffedcba98765432100c1987d00c0113a20b' 2831 h'820258200123456789abcdeffedcba9876543210001122' 2832 h'33445566778899aabbccddeeff0c1987d001f602f6' \ { 2833 / components / 2 : h'828245466c61736843003401824352414d4200' 2834 h'04' \ 2835 [ 2836 [h'466c617368', h'003401'], 2837 [h'52414d', h'0004'], 2838 ], 2839 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 2840 h'63e4d41ffe04501492af1425695e48bf' 2841 h'429b2d51f2ab450c0013a20b82025820' 2842 h'00112233445566778899aabbccddeeff' 2843 h'0123456789abcdeffedcba9876543210' 2844 h'0c1987d00c0113a20b82025820012345' 2845 h'6789abcdeffedcba9876543210001122' 2846 h'33445566778899aabbccddeeff0c1987' 2847 h'd001f602f6' \ [ 2848 / set-vars / 19, { 2849 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 2850 h'fe', 2852 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 2853 }, 2854 / set-component-index / 12, 0, 2855 / set-vars / 19, { 2856 / digest / 11 : [ 2, 2857 h'00112233445566778899aabbccddeeff0123456789ab' 2858 h'cdeffedcba9876543210' ] 2859 / size / 12 : 34768 2860 }, 2861 / set-component-index / 12, 1, 2862 / set-vars / 19, { 2863 / digest / 11 : [ 2, 2864 h'0123456789abcdeffedcba9876543210001122334455' 2865 h'66778899aabbccddeeff' ], 2866 / size / 12 : 34768, 2867 }, 2868 / condition-vendor-id / 1, None, 2869 / condition-class-id / 2, None, 2870 ], 2871 }, 2872 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 2873 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 2874 / set-component-index / 12, 0, 2875 / set-vars / 19, { 2876 / uri / 6 : http://example.com/file.bin, 2877 }, 2878 / fetch / 21, None, 2879 ], 2880 / load-image / 11 : h'8a0c0003f60c0113a20843a101010a0016f6' \ [ 2881 / set-component-index / 12, 0, 2882 / condition-image / 3, None, 2883 / set-component-index / 12, 1, 2884 / set-vars / 19, { 2885 / compression-info / 8 : h'a10101', 2886 / source-component / 10 : 0, 2887 }, 2888 / copy / 22, None, 2889 ], 2890 / run-image / 12 : h'8403f617f6' \ [ 2891 / condition-image / 3, None, 2892 / run / 23, None, 2893 ], 2894 } 2895 } 2897 Total size of outer wrapper without COSE authentication object: 240 2899 Outer: 2901 a201f60258eaa60101020503589fa20254828245466c61736843003401824352414d4200 2902 040458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425695e48bf 2903 429b2d51f2ab450c0013a20b8202582000112233445566778899aabbccddeeff01234567 2904 89abcdeffedcba98765432100c1987d00c0113a20b820258200123456789abcdeffedcba 2905 987654321000112233445566778899aabbccddeeff0c1987d001f602f6095825860c0013 2906 a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696e15f60b528a 2907 0c0003f60c0113a20843a101010a0016f60c458403f617f6 2909 Total size of outer wrapper with COSE authentication object: 325 2911 Signed Outer: 2913 a2015854d28443a10126a1044874657374206b6579f65840e90dab6e502bad8132adf86b 2914 4d78defaebac64fa6c6b2882d12b36f492b14ce75819ed3524de4d66ddfd5e1d80a59840 2915 04c1ac9b003b2da32589583a93c541dd0258eaa60101020503589fa20254828245466c61 2916 736843003401824352414d4200040458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d4 2917 1ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b8202582000112233445566 2918 778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113a20b8202 2919 58200123456789abcdeffedcba987654321000112233445566778899aabbccddeeff0c19 2920 87d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e636f6d2f 2921 66696c652e62696e15f60b528a0c0003f60c0113a20843a101010a0016f60c458403f617 2922 f6 2924 13.6. Example 5: 2926 Compatibility test, download, installation, and secure boot. 2928 The following JSON shows the intended behaviour of the manifest. 2930 { 2931 "structure-version": 1, 2932 "sequence-number": 6, 2933 "common": { 2934 "common-sequence": [ 2935 { 2936 "directive-set-var": { 2937 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 2938 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 2939 } 2940 }, 2941 { "directive-set-component": 0 }, 2942 { 2943 "directive-set-var": { 2944 "digest": "00112233445566778899aabbccddeeff" 2945 "0123456789abcdeffedcba9876543210", 2946 "size": 34768 2947 } 2948 }, 2949 { "directive-set-component": 1 }, 2950 { 2951 "directive-set-var": { 2952 "digest": "0123456789abcdeffedcba9876543210" 2953 "00112233445566778899aabbccddeeff", 2954 "size": 34768 2955 } 2956 }, 2957 { "condition-vendor-id": null }, 2958 { "condition-class-id": null } 2959 ], 2960 "components": [ 2961 [ 2962 "ext-Flash", 2963 78848 2964 ], 2965 [ 2966 "Flash", 2967 1024 2968 ] 2969 ] 2970 }, 2971 "apply-image": [ 2972 { "directive-set-component": 0 }, 2973 { 2974 "directive-set-var": { 2975 "uri": "http://example.com/file.bin" 2976 } 2977 }, 2978 { "directive-fetch": null } 2979 ], 2980 "load-image": [ 2981 { "directive-set-component": 1 }, 2982 { "condition-not-image": null }, 2983 { "directive-set-component": 0 }, 2984 { "condition-image": null }, 2985 { "directive-set-component": 1 }, 2986 { 2987 "directive-set-var": { 2988 "source-index": 0 2989 } 2990 }, 2991 { "directive-fetch": null } 2992 ], 2993 "run-image": [ 2994 { "directive-set-component": 1 }, 2995 { "condition-image": null }, 2996 { "directive-run": null } 2998 ] 2999 } 3001 Converted into the SUIT manifest, this produces: 3003 { 3004 / auth object / 1 : h'd28443a10126a1044874657374206b6579f658402282' 3005 h'c1e7770b1806afb0cf78e74003af39166b9db14b0a7c' 3006 h'172d18598c8be16e3cec48770fb8471675a5b3bab05a' 3007 h'22e370a03320a7346f252f9629c3417ed153', 3008 / manifest / 2 : h'a6010102060358a2a202578282467b1b4595ab2143003401' 3009 h'8245466c6173684200040458858e13a20350fa6b4a53d5ad' 3010 h'5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d' 3011 h'51f2ab450c0013a20b8202582000112233445566778899aa' 3012 h'bbccddeeff0123456789abcdeffedcba98765432100c1987' 3013 h'd00c0113a20b820258200123456789abcdeffedcba987654' 3014 h'321000112233445566778899aabbccddeeff0c1987d001f6' 3015 h'02f6095825860c0013a106781b687474703a2f2f6578616d' 3016 h'706c652e636f6d2f66696c652e62696e15f60b528e0c0118' 3017 h'19f60c0003f60c0113a10a0015f60c47860c0103f617f6' \ 3018 { 3019 / structure-version / 1 : 1, 3020 / sequence-number / 2 : 6, 3021 / common / 3 : h'a202578282467b1b4595ab21430034018245466c617368' 3022 h'4200040458858e13a20350fa6b4a53d5ad5fdfbe9de663' 3023 h'e4d41ffe04501492af1425695e48bf429b2d51f2ab450c' 3024 h'0013a20b8202582000112233445566778899aabbccddee' 3025 h'ff0123456789abcdeffedcba98765432100c1987d00c01' 3026 h'13a20b820258200123456789abcdeffedcba9876543210' 3027 h'00112233445566778899aabbccddeeff0c1987d001f602' 3028 h'f6' \ { 3029 / components / 2 : h'8282467b1b4595ab21430034018245466c6173' 3030 h'68420004' \ 3031 [ 3032 [h'7b1b4595ab21', h'003401'], 3033 [h'466c617368', h'0004'], 3034 ], 3035 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3036 h'63e4d41ffe04501492af1425695e48bf' 3037 h'429b2d51f2ab450c0013a20b82025820' 3038 h'00112233445566778899aabbccddeeff' 3039 h'0123456789abcdeffedcba9876543210' 3040 h'0c1987d00c0113a20b82025820012345' 3041 h'6789abcdeffedcba9876543210001122' 3042 h'33445566778899aabbccddeeff0c1987' 3043 h'd001f602f6' \ [ 3044 / set-vars / 19, { 3045 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3046 h'fe', 3047 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3048 }, 3049 / set-component-index / 12, 0, 3050 / set-vars / 19, { 3051 / digest / 11 : [ 2, 3052 h'00112233445566778899aabbccddeeff0123456789ab' 3053 h'cdeffedcba9876543210' ], 3054 / size / 12 : 34768, 3055 }, 3056 / set-component-index / 12, 1, 3057 / set-vars / 19, { 3058 / digest / 11 : [ 2, 3059 h'0123456789abcdeffedcba9876543210001122334455' 3060 h'66778899aabbccddeeff' ], 3061 / size / 12 : 34768, 3062 }, 3063 / condition-vendor-id / 1, None, 3064 / condition-class-id / 2, None, 3065 ], 3066 }, 3067 / apply-image / 9 : h'860c0013a106781b687474703a2f2f6578616d70' 3068 h'6c652e636f6d2f66696c652e62696e15f6' \ [ 3069 / set-component-index / 12, 0, 3070 / set-vars / 19, { 3071 / uri / 6 : http://example.com/file.bin, 3072 }, 3073 / fetch / 21, None, 3074 ], 3075 / load-image / 11 : h'8e0c011819f60c0003f60c0113a10a0015f6' \ [ 3076 / set-component-index / 12, 1, 3077 / condition-not-image / 25, None, 3078 / set-component-index / 12, 0, 3079 / condition-image / 3, None, 3080 / set-component-index / 12, 1, 3081 / set-vars / 19, { 3082 / source-component / 10 : 0, 3083 }, 3084 / fetch / 21, None, 3085 ], 3086 / run-image / 12 : h'860c0103f617f6' \ [ 3087 / set-component-index / 12, 1, 3088 / condition-image / 3, None, 3089 / run / 23, None, 3090 ], 3091 } 3092 } 3093 Total size of outer wrapper without COSE authentication object: 245 3095 Outer: 3097 a201f60258efa6010102060358a2a202578282467b1b4595ab21430034018245466c6173 3098 684200040458858e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af142569 3099 5e48bf429b2d51f2ab450c0013a20b8202582000112233445566778899aabbccddeeff01 3100 23456789abcdeffedcba98765432100c1987d00c0113a20b820258200123456789abcdef 3101 fedcba987654321000112233445566778899aabbccddeeff0c1987d001f602f609582586 3102 0c0013a106781b687474703a2f2f6578616d706c652e636f6d2f66696c652e62696e15f6 3103 0b528e0c011819f60c0003f60c0113a10a0015f60c47860c0103f617f6 3105 Total size of outer wrapper with COSE authentication object: 330 3107 Signed Outer: 3109 a2015854d28443a10126a1044874657374206b6579f658402282c1e7770b1806afb0cf78 3110 e74003af39166b9db14b0a7c172d18598c8be16e3cec48770fb8471675a5b3bab05a22e3 3111 70a03320a7346f252f9629c3417ed1530258efa6010102060358a2a202578282467b1b45 3112 95ab21430034018245466c6173684200040458858e13a20350fa6b4a53d5ad5fdfbe9de6 3113 63e4d41ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b8202582000112233 3114 445566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113a2 3115 0b820258200123456789abcdeffedcba987654321000112233445566778899aabbccddee 3116 ff0c1987d001f602f6095825860c0013a106781b687474703a2f2f6578616d706c652e63 3117 6f6d2f66696c652e62696e15f60b528e0c011819f60c0003f60c0113a10a0015f60c4786 3118 0c0103f617f6 3120 13.7. Example 6: 3122 Compatibility test, 2 images, simultaneous download and installation, 3123 and secure boot. 3125 The following JSON shows the intended behaviour of the manifest. 3127 { 3128 "structure-version": 1, 3129 "sequence-number": 7, 3130 "common": { 3131 "common-sequence": [ 3132 { 3133 "directive-set-var": { 3134 "vendor-id": "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe", 3135 "class-id": "1492af14-2569-5e48-bf42-9b2d51f2ab45" 3136 } 3137 }, 3138 { "directive-set-component": 0 }, 3139 { 3140 "directive-set-var": { 3141 "digest": "00112233445566778899aabbccddeeff" 3142 "0123456789abcdeffedcba9876543210", 3143 "size": 34768 3144 } 3145 }, 3146 { "directive-set-component": 1 }, 3147 { 3148 "directive-set-var": { 3149 "digest": "0123456789abcdeffedcba9876543210" 3150 "00112233445566778899aabbccddeeff", 3151 "size": 76834 3152 } 3153 }, 3154 { "condition-vendor-id": null }, 3155 { "condition-class-id": null } 3156 ], 3157 "components": [ 3158 [ 3159 "Flash", 3160 78848 3161 ], 3162 [ 3163 "Flash", 3164 132096 3165 ] 3166 ] 3167 }, 3168 "apply-image": [ 3169 { "directive-set-component": 0 }, 3170 { 3171 "directive-set-var": { 3172 "uri": "http://example.com/file1.bin" 3173 } 3174 }, 3175 { "directive-set-component": 1 }, 3176 { 3177 "directive-set-var": { 3178 "uri": "http://example.com/file2.bin" 3179 } 3180 }, 3181 { "directive-set-component": true }, 3182 { "directive-fetch": null } 3183 ], 3184 "run-image": [ 3185 { "directive-set-component": true }, 3186 { "condition-image": null }, 3187 { "directive-set-component": 0 }, 3188 { "directive-run": null } 3190 ] 3191 } 3193 Converted into the SUIT manifest, this produces: 3195 { 3196 / auth object / 1 : h'd28443a10126a1044874657374206b6579f65840d00c' 3197 h'd62be643247904621f2956b11b97fcbcd22f87701dd9' 3198 h'008e949f8c801f55d7095b545d6db0060bd47c5f78ee' 3199 h'5cb1fea17c875a36a599aec4e8b876cfdae7', 3200 / manifest / 2 : h'a5010102070358a4a20257828245466c6173684300340182' 3201 h'45466c617368430004020458878e13a20350fa6b4a53d5ad' 3202 h'5fdfbe9de663e4d41ffe04501492af1425695e48bf429b2d' 3203 h'51f2ab450c0013a20b8202582000112233445566778899aa' 3204 h'bbccddeeff0123456789abcdeffedcba98765432100c1987' 3205 h'd00c0113a20b820258200123456789abcdeffedcba987654' 3206 h'321000112233445566778899aabbccddeeff0c1a00012c22' 3207 h'01f602f609584b8c0c0013a106781c687474703a2f2f6578' 3208 h'616d706c652e636f6d2f66696c65312e62696e0c0113a106' 3209 h'781c687474703a2f2f6578616d706c652e636f6d2f66696c' 3210 h'65322e62696e0cf515f60c49880cf503f60c0017f6' \ 3211 { 3212 / structure-version / 1 : 1, 3213 / sequence-number / 2 : 7, 3214 / common / 3 : h'a20257828245466c617368430034018245466c61736843' 3215 h'0004020458878e13a20350fa6b4a53d5ad5fdfbe9de663' 3216 h'e4d41ffe04501492af1425695e48bf429b2d51f2ab450c' 3217 h'0013a20b8202582000112233445566778899aabbccddee' 3218 h'ff0123456789abcdeffedcba98765432100c1987d00c01' 3219 h'13a20b820258200123456789abcdeffedcba9876543210' 3220 h'00112233445566778899aabbccddeeff0c1a00012c2201' 3221 h'f602f6' \ { 3222 / components / 2 : h'828245466c617368430034018245466c617368' 3223 h'43000402' \ 3224 [ 3225 [h'466c617368', h'003401'], 3226 [h'466c617368', h'000402'], 3227 ], 3228 / common-sequence / 4 : h'8e13a20350fa6b4a53d5ad5fdfbe9de6' 3229 h'63e4d41ffe04501492af1425695e48bf' 3230 h'429b2d51f2ab450c0013a20b82025820' 3231 h'00112233445566778899aabbccddeeff' 3232 h'0123456789abcdeffedcba9876543210' 3233 h'0c1987d00c0113a20b82025820012345' 3234 h'6789abcdeffedcba9876543210001122' 3235 h'33445566778899aabbccddeeff0c1a00' 3236 h'012c2201f602f6' \ [ 3237 / set-vars / 19, { 3238 / vendor-id / 3 : h'fa6b4a53d5ad5fdfbe9de663e4d41f' 3239 h'fe', 3240 / class-id / 4 : h'1492af1425695e48bf429b2d51f2ab45', 3241 }, 3242 / set-component-index / 12, 0, 3243 / set-vars / 19, { 3244 / digest / 11 : [ 2, 3245 h'00112233445566778899aabbccddeeff0123456789ab' 3246 h'cdeffedcba9876543210' ], 3247 / size / 12 : 34768, 3248 }, 3249 / set-component-index / 12, 1, 3250 / set-vars / 19, { 3251 / digest / 11 : [ 2, 3252 h'0123456789abcdeffedcba9876543210001122334455' 3253 h'66778899aabbccddeeff' ], 3254 / size / 12 : 76834, 3255 }, 3256 / condition-vendor-id / 1, None, 3257 / condition-class-id / 2, None, 3258 ], 3259 }, 3260 / apply-image / 9 : h'8c0c0013a106781c687474703a2f2f6578616d70' 3261 h'6c652e636f6d2f66696c65312e62696e0c0113a1' 3262 h'06781c687474703a2f2f6578616d706c652e636f' 3263 h'6d2f66696c65322e62696e0cf515f6' \ [ 3264 / set-component-index / 12, 0, 3265 / set-vars / 19, { 3266 / uri / 6 : http://example.com/file1.bin 3267 }, 3268 / set-component-index / 12, 1, 3269 / set-vars / 19, { 3270 / uri / 6 : http://example.com/file2.bin 3271 }, 3272 / set-component-index / 12, True, 3273 / fetch / 21, None, 3274 ], 3275 / run-image / 12 : h'880cf503f60c0017f6' \ [ 3276 / set-component-index / 12, True, 3277 / condition-image / 3, None, 3278 / set-component-index / 12, 0, 3279 / run / 23, None, 3280 ], 3281 } 3282 } 3284 Total size of outer wrapper without COSE authentication object: 268 3285 Outer: 3287 a201f602590105a5010102070358a4a20257828245466c617368430034018245466c6173 3288 68430004020458878e13a20350fa6b4a53d5ad5fdfbe9de663e4d41ffe04501492af1425 3289 695e48bf429b2d51f2ab450c0013a20b8202582000112233445566778899aabbccddeeff 3290 0123456789abcdeffedcba98765432100c1987d00c0113a20b820258200123456789abcd 3291 effedcba987654321000112233445566778899aabbccddeeff0c1a00012c2201f602f609 3292 584b8c0c0013a106781c687474703a2f2f6578616d706c652e636f6d2f66696c65312e62 3293 696e0c0113a106781c687474703a2f2f6578616d706c652e636f6d2f66696c65322e6269 3294 6e0cf515f60c49880cf503f60c0017f6 3296 Total size of outer wrapper with COSE authentication object: 353 3298 Signed Outer: 3300 a2015854d28443a10126a1044874657374206b6579f65840d00cd62be643247904621f29 3301 56b11b97fcbcd22f87701dd9008e949f8c801f55d7095b545d6db0060bd47c5f78ee5cb1 3302 fea17c875a36a599aec4e8b876cfdae702590105a5010102070358a4a20257828245466c 3303 617368430034018245466c617368430004020458878e13a20350fa6b4a53d5ad5fdfbe9d 3304 e663e4d41ffe04501492af1425695e48bf429b2d51f2ab450c0013a20b82025820001122 3305 33445566778899aabbccddeeff0123456789abcdeffedcba98765432100c1987d00c0113 3306 a20b820258200123456789abcdeffedcba987654321000112233445566778899aabbccdd 3307 eeff0c1a00012c2201f602f609584b8c0c0013a106781c687474703a2f2f6578616d706c 3308 652e636f6d2f66696c65312e62696e0c0113a106781c687474703a2f2f6578616d706c65 3309 2e636f6d2f66696c65322e62696e0cf515f60c49880cf503f60c0017f6 3311 14. IANA Considerations 3313 Several registries will be required for: 3315 - standard Commands 3317 - standard Parameters 3319 - standard Algorithm identifiers 3321 - standard text values 3323 15. Security Considerations 3325 This document is about a manifest format describing and protecting 3326 firmware images and as such it is part of a larger solution for 3327 offering a standardized way of delivering firmware updates to IoT 3328 devices. A more detailed discussion about security can be found in 3329 the architecture document [Architecture] and in [Information]. 3331 16. Mailing List Information 3333 The discussion list for this document is located at the e-mail 3334 address suit@ietf.org [1]. Information on the group and information 3335 on how to subscribe to the list is at 3336 https://www1.ietf.org/mailman/listinfo/suit [2] 3338 Archives of the list can be found at: https://www.ietf.org/mail- 3339 archive/web/suit/current/index.html [3] 3341 17. Acknowledgements 3343 We would like to thank the following persons for their support in 3344 designing this mechanism: 3346 - Milosch Meriac 3348 - Geraint Luff 3350 - Dan Ros 3352 - John-Paul Stanford 3354 - Hugo Vincent 3356 - Carsten Bormann 3358 - Oeyvind Roenningstad 3360 - Frank Audun Kvamtroe 3362 - Krzysztof Chruściński 3364 - Andrzej Puzdrowski 3366 - Michael Richardson 3368 - David Brown 3370 - Emmanuel Baccelli 3372 18. References 3374 18.1. Normative References 3376 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 3377 Requirement Levels", BCP 14, RFC 2119, 3378 DOI 10.17487/RFC2119, March 1997, 3379 . 3381 [RFC4122] Leach, P., Mealling, M., and R. Salz, "A Universally 3382 Unique IDentifier (UUID) URN Namespace", RFC 4122, 3383 DOI 10.17487/RFC4122, July 2005, 3384 . 3386 [RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", 3387 RFC 8152, DOI 10.17487/RFC8152, July 2017, 3388 . 3390 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 3391 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 3392 May 2017, . 3394 18.2. Informative References 3396 [Architecture] 3397 Moran, B., "A Firmware Update Architecture for Internet of 3398 Things Devices", January 2019, 3399 . 3402 [Information] 3403 Moran, B., "Firmware Updates for Internet of Things 3404 Devices - An Information Model for Manifests", January 3405 2019, . 3408 [RFC6920] Farrell, S., Kutscher, D., Dannewitz, C., Ohlman, B., 3409 Keranen, A., and P. Hallam-Baker, "Naming Things with 3410 Hashes", RFC 6920, DOI 10.17487/RFC6920, April 2013, 3411 . 3413 18.3. URIs 3415 [1] mailto:suit@ietf.org 3417 [2] https://www1.ietf.org/mailman/listinfo/suit 3419 [3] https://www.ietf.org/mail-archive/web/suit/current/index.html 3421 Authors' Addresses 3423 Brendan Moran 3424 Arm Limited 3426 EMail: Brendan.Moran@arm.com 3428 Hannes Tschofenig 3429 Arm Limited 3431 EMail: hannes.tschofenig@arm.com 3433 Henk Birkholz 3434 Fraunhofer SIT 3436 EMail: henk.birkholz@sit.fraunhofer.de